logging.odin 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //+private
  2. package testing
  3. import "base:runtime"
  4. import "core:fmt"
  5. import pkg_log "core:log"
  6. import "core:strings"
  7. import "core:sync/chan"
  8. import "core:time"
  9. when USING_SHORT_LOGS {
  10. Default_Test_Logger_Opts :: runtime.Logger_Options {
  11. .Level,
  12. .Terminal_Color,
  13. .Short_File_Path,
  14. .Line,
  15. }
  16. } else {
  17. Default_Test_Logger_Opts :: runtime.Logger_Options {
  18. .Level,
  19. .Terminal_Color,
  20. .Short_File_Path,
  21. .Line,
  22. .Procedure,
  23. .Date, .Time,
  24. }
  25. }
  26. Log_Message :: struct {
  27. level: runtime.Logger_Level,
  28. text: string,
  29. time: time.Time,
  30. // `text` may be allocated differently, depending on where a log message
  31. // originates from.
  32. allocator: runtime.Allocator,
  33. }
  34. test_logger_proc :: proc(logger_data: rawptr, level: runtime.Logger_Level, text: string, options: runtime.Logger_Options, location := #caller_location) {
  35. t := cast(^T)logger_data
  36. if level >= .Error {
  37. t.error_count += 1
  38. }
  39. cloned_text, clone_error := strings.clone(text, t._log_allocator)
  40. assert(clone_error == nil, "Error while cloning string in test thread logger proc.")
  41. now := time.now()
  42. chan.send(t.channel, Event_Log_Message {
  43. level = level,
  44. text = cloned_text,
  45. time = now,
  46. formatted_text = format_log_text(level, text, options, location, now, t._log_allocator),
  47. })
  48. }
  49. runner_logger_proc :: proc(logger_data: rawptr, level: runtime.Logger_Level, text: string, options: runtime.Logger_Options, location := #caller_location) {
  50. log_messages := cast(^[dynamic]Log_Message)logger_data
  51. now := time.now()
  52. append(log_messages, Log_Message {
  53. level = level,
  54. text = format_log_text(level, text, options, location, now),
  55. time = now,
  56. allocator = context.allocator,
  57. })
  58. }
  59. format_log_text :: proc(level: runtime.Logger_Level, text: string, options: runtime.Logger_Options, location: runtime.Source_Code_Location, at_time: time.Time, allocator := context.allocator) -> string{
  60. backing: [1024]byte
  61. buf := strings.builder_from_bytes(backing[:])
  62. pkg_log.do_level_header(options, &buf, level)
  63. pkg_log.do_time_header(options, &buf, at_time)
  64. pkg_log.do_location_header(options, &buf, location)
  65. return fmt.aprintf("%s%s", strings.to_string(buf), text, allocator = allocator)
  66. }