mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Clean up package log code
This commit is contained in:
+3
-1
@@ -1007,7 +1007,9 @@ fmt_enum :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, verb);
|
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, verb);
|
||||||
case 's', 'v':
|
case 's', 'v':
|
||||||
str, ok := enum_value_to_string(v);
|
str, ok := enum_value_to_string(v);
|
||||||
if !ok do str = "!%(BAD ENUM VALUE)";
|
if !ok {
|
||||||
|
str = "!%(BAD ENUM VALUE)";
|
||||||
|
}
|
||||||
strings.write_string(fi.buf, str);
|
strings.write_string(fi.buf, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,133 +5,131 @@ import "core:strings";
|
|||||||
import "core:os";
|
import "core:os";
|
||||||
import "core:time";
|
import "core:time";
|
||||||
|
|
||||||
Level_Headers := []string{
|
Level_Headers := [?]string{
|
||||||
"[DEBUG] --- ",
|
0..<10 = "[DEBUG] --- ",
|
||||||
"[INFO ] --- ",
|
10..<20 = "[INFO ] --- ",
|
||||||
"[WARN ] --- ",
|
20..<30 = "[WARN ] --- ",
|
||||||
"[ERROR] --- ",
|
30..<40 = "[ERROR] --- ",
|
||||||
"[FATAL] --- ",
|
40..<50 = "[FATAL] --- ",
|
||||||
};
|
};
|
||||||
|
|
||||||
Default_Console_Logger_Opts :: Options{
|
Default_Console_Logger_Opts :: Options{
|
||||||
.Level,
|
.Level,
|
||||||
.Terminal_Color,
|
.Terminal_Color,
|
||||||
.Short_File_Path,
|
.Short_File_Path,
|
||||||
.Line,
|
.Line,
|
||||||
.Procedure,
|
.Procedure,
|
||||||
} | Full_Timestamp_Opts;
|
} | Full_Timestamp_Opts;
|
||||||
|
|
||||||
Default_File_Logger_Opts :: Options{
|
Default_File_Logger_Opts :: Options{
|
||||||
.Level,
|
.Level,
|
||||||
.Short_File_Path,
|
.Short_File_Path,
|
||||||
.Line,
|
.Line,
|
||||||
.Procedure,
|
.Procedure,
|
||||||
} | Full_Timestamp_Opts;
|
} | Full_Timestamp_Opts;
|
||||||
|
|
||||||
|
|
||||||
File_Console_Logger_Data :: struct {
|
File_Console_Logger_Data :: struct {
|
||||||
file_handle: os.Handle,
|
file_handle: os.Handle,
|
||||||
ident : string,
|
ident: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_file_logger :: proc(h: os.Handle, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "") -> Logger {
|
create_file_logger :: proc(h: os.Handle, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "") -> Logger {
|
||||||
data := new(File_Console_Logger_Data);
|
data := new(File_Console_Logger_Data);
|
||||||
data.file_handle = h;
|
data.file_handle = h;
|
||||||
data.ident = ident;
|
data.ident = ident;
|
||||||
return Logger{file_console_logger_proc, data, lowest, opt};
|
return Logger{file_console_logger_proc, data, lowest, opt};
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_file_logger ::proc(log : ^Logger) {
|
destroy_file_logger :: proc(log: ^Logger) {
|
||||||
data := cast(^File_Console_Logger_Data)log.data;
|
data := cast(^File_Console_Logger_Data)log.data;
|
||||||
if data.file_handle != os.INVALID_HANDLE do os.close(data.file_handle);
|
if data.file_handle != os.INVALID_HANDLE do os.close(data.file_handle);
|
||||||
free(data);
|
free(data);
|
||||||
log^ = nil_logger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_console_logger :: proc(lowest := Level.Debug, opt := Default_Console_Logger_Opts, ident := "") -> Logger {
|
create_console_logger :: proc(lowest := Level.Debug, opt := Default_Console_Logger_Opts, ident := "") -> Logger {
|
||||||
data := new(File_Console_Logger_Data);
|
data := new(File_Console_Logger_Data);
|
||||||
data.file_handle = os.INVALID_HANDLE;
|
data.file_handle = os.INVALID_HANDLE;
|
||||||
data.ident = ident;
|
data.ident = ident;
|
||||||
return Logger{file_console_logger_proc, data, lowest, opt};
|
return Logger{file_console_logger_proc, data, lowest, opt};
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_console_logger ::proc(log : ^Logger) {
|
destroy_console_logger :: proc(log: ^Logger) {
|
||||||
free(log.data);
|
free(log.data);
|
||||||
log^ = nil_logger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string, options: Options, location := #caller_location) {
|
file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string, options: Options, location := #caller_location) {
|
||||||
data := cast(^File_Console_Logger_Data)logger_data;
|
data := cast(^File_Console_Logger_Data)logger_data;
|
||||||
h : os.Handle;
|
h: os.Handle;
|
||||||
if(data.file_handle != os.INVALID_HANDLE) do h = data.file_handle;
|
if(data.file_handle != os.INVALID_HANDLE) do h = data.file_handle;
|
||||||
else do h = os.stdout if level <= Level.Error else os.stderr;
|
else do h = os.stdout if level <= Level.Error else os.stderr;
|
||||||
backing: [1024]byte; //NOTE(Hoej): 1024 might be too much for a header backing, unless somebody has really long paths.
|
backing: [1024]byte; //NOTE(Hoej): 1024 might be too much for a header backing, unless somebody has really long paths.
|
||||||
buf := strings.builder_from_slice(backing[:]);
|
buf := strings.builder_from_slice(backing[:]);
|
||||||
|
|
||||||
do_level_header(options, level, &buf);
|
do_level_header(options, level, &buf);
|
||||||
|
|
||||||
when time.IS_SUPPORTED {
|
when time.IS_SUPPORTED {
|
||||||
if Full_Timestamp_Opts & options != nil {
|
if Full_Timestamp_Opts & options != nil {
|
||||||
fmt.sbprint(&buf, "[");
|
fmt.sbprint(&buf, "[");
|
||||||
t := time.now();
|
t := time.now();
|
||||||
y, m, d := time.date(t);
|
y, m, d := time.date(t);
|
||||||
h, min, s := time.clock(t);
|
h, min, s := time.clock(t);
|
||||||
if Option.Date in options do fmt.sbprintf(&buf, "%d-%02d-%02d ", y, m, d);
|
if Option.Date in options do fmt.sbprintf(&buf, "%d-%02d-%02d ", y, m, d);
|
||||||
if Option.Time in options do fmt.sbprintf(&buf, "%02d:%02d:%02d", h, min, s);
|
if Option.Time in options do fmt.sbprintf(&buf, "%02d:%02d:%02d", h, min, s);
|
||||||
fmt.sbprint(&buf, "] ");
|
fmt.sbprint(&buf, "] ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_location_header(options, &buf, location);
|
do_location_header(options, &buf, location);
|
||||||
|
|
||||||
if data.ident != "" do fmt.sbprintf(&buf, "[%s] ", data.ident);
|
if data.ident != "" do fmt.sbprintf(&buf, "[%s] ", data.ident);
|
||||||
//TODO(Hoej): When we have better atomics and such, make this thread-safe
|
//TODO(Hoej): When we have better atomics and such, make this thread-safe
|
||||||
fmt.fprintf(h, "%s %s\n", strings.to_string(buf), text);
|
fmt.fprintf(h, "%s %s\n", strings.to_string(buf), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_level_header :: proc(opts : Options, level : Level, str : ^strings.Builder) {
|
do_level_header :: proc(opts: Options, level: Level, str: ^strings.Builder) {
|
||||||
|
|
||||||
RESET :: "\x1b[0m";
|
RESET :: "\x1b[0m";
|
||||||
RED :: "\x1b[31m";
|
RED :: "\x1b[31m";
|
||||||
YELLOW :: "\x1b[33m";
|
YELLOW :: "\x1b[33m";
|
||||||
DARK_GREY :: "\x1b[90m";
|
DARK_GREY :: "\x1b[90m";
|
||||||
|
|
||||||
col := RESET;
|
col := RESET;
|
||||||
switch level {
|
switch level {
|
||||||
case Level.Debug : col = DARK_GREY;
|
case .Debug: col = DARK_GREY;
|
||||||
case Level.Info : col = RESET;
|
case .Info: col = RESET;
|
||||||
case Level.Warning : col = YELLOW;
|
case .Warning: col = YELLOW;
|
||||||
case Level.Error, Level.Fatal : col = RED;
|
case .Error, .Fatal: col = RED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if .Level in opts {
|
if .Level in opts {
|
||||||
if .Terminal_Color in opts do fmt.sbprint(str, col);
|
if .Terminal_Color in opts do fmt.sbprint(str, col);
|
||||||
fmt.sbprint(str, Level_Headers[level]);
|
fmt.sbprint(str, Level_Headers[level]);
|
||||||
if .Terminal_Color in opts do fmt.sbprint(str, RESET);
|
if .Terminal_Color in opts do fmt.sbprint(str, RESET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_location_header :: proc(opts : Options, buf : ^strings.Builder, location := #caller_location) {
|
do_location_header :: proc(opts: Options, buf: ^strings.Builder, location := #caller_location) {
|
||||||
if Location_Header_Opts & opts != nil do fmt.sbprint(buf, "["); else do return;
|
if Location_Header_Opts & opts != nil do fmt.sbprint(buf, "["); else do return;
|
||||||
|
|
||||||
file := location.file_path;
|
file := location.file_path;
|
||||||
if .Short_File_Path in opts {
|
if .Short_File_Path in opts {
|
||||||
last := 0;
|
last := 0;
|
||||||
for r, i in location.file_path do if r == '/' do last = i+1;
|
for r, i in location.file_path do if r == '/' do last = i+1;
|
||||||
file = location.file_path[last:];
|
file = location.file_path[last:];
|
||||||
}
|
}
|
||||||
|
|
||||||
if Location_File_Opts & opts != nil do fmt.sbprint(buf, file);
|
if Location_File_Opts & opts != nil do fmt.sbprint(buf, file);
|
||||||
|
|
||||||
if .Procedure in opts {
|
if .Procedure in opts {
|
||||||
if Location_File_Opts & opts != nil do fmt.sbprint(buf, ".");
|
if Location_File_Opts & opts != nil do fmt.sbprint(buf, ".");
|
||||||
fmt.sbprintf(buf, "%s()", location.procedure);
|
fmt.sbprintf(buf, "%s()", location.procedure);
|
||||||
}
|
}
|
||||||
|
|
||||||
if .Line in opts {
|
if .Line in opts {
|
||||||
if Location_File_Opts & opts != nil || .Procedure in opts do fmt.sbprint(buf, ":");
|
if Location_File_Opts & opts != nil || .Procedure in opts do fmt.sbprint(buf, ":");
|
||||||
fmt.sbprint(buf, location.line);
|
fmt.sbprint(buf, location.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.sbprint(buf, "] ");
|
fmt.sbprint(buf, "] ");
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-48
@@ -2,18 +2,19 @@ package log
|
|||||||
|
|
||||||
import "core:runtime"
|
import "core:runtime"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
import "core:sync"
|
||||||
|
|
||||||
|
|
||||||
// NOTE(bill, 2019-12-31): These are defined in `package runtime` as they are used in the `context`. This is to prevent an import definition cycle.
|
// NOTE(bill, 2019-12-31): These are defined in `package runtime` as they are used in the `context`. This is to prevent an import definition cycle.
|
||||||
|
|
||||||
Level :: runtime.Logger_Level;
|
Level :: runtime.Logger_Level;
|
||||||
/*
|
/*
|
||||||
Level :: enum {
|
Logger_Level :: enum {
|
||||||
Debug,
|
Debug = 0,
|
||||||
Info,
|
Info = 10,
|
||||||
Warning,
|
Warning = 20,
|
||||||
Error,
|
Error = 30,
|
||||||
Fatal,
|
Fatal = 40,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -67,33 +68,6 @@ Logger :: struct {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Multi_Logger_Data :: struct {
|
|
||||||
loggers : []Logger,
|
|
||||||
}
|
|
||||||
|
|
||||||
create_multi_logger :: proc(logs: ..Logger) -> Logger {
|
|
||||||
data := new(Multi_Logger_Data);
|
|
||||||
data.loggers = make([]Logger, len(logs));
|
|
||||||
copy(data.loggers, logs);
|
|
||||||
return Logger{multi_logger_proc, data, Level.Debug, nil};
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy_multi_logger :: proc(log : ^Logger) {
|
|
||||||
free(log.data);
|
|
||||||
log^ = nil_logger();
|
|
||||||
}
|
|
||||||
|
|
||||||
multi_logger_proc :: proc(logger_data: rawptr, level: Level, text: string,
|
|
||||||
options: Options, location := #caller_location) {
|
|
||||||
data := cast(^Multi_Logger_Data)logger_data;
|
|
||||||
if data.loggers == nil || len(data.loggers) == 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for log in data.loggers {
|
|
||||||
log.procedure(log.data, level, text, log.options, location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nil_logger_proc :: proc(data: rawptr, level: Level, text: string, options: Options, location := #caller_location) {
|
nil_logger_proc :: proc(data: rawptr, level: Level, text: string, options: Options, location := #caller_location) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@@ -103,28 +77,52 @@ nil_logger :: proc() -> Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bill): Should these be redesigned so that they are do not rely upon `package fmt`?
|
// TODO(bill): Should these be redesigned so that they are do not rely upon `package fmt`?
|
||||||
debugf :: proc(fmt_str : string, args : ..any, location := #caller_location) do logf(level=Level.Debug, fmt_str=fmt_str, args=args, location=location);
|
debugf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||||
infof :: proc(fmt_str : string, args : ..any, location := #caller_location) do logf(level=Level.Info, fmt_str=fmt_str, args=args, location=location);
|
logf(level=.Debug, fmt_str=fmt_str, args=args, location=location);
|
||||||
warnf :: proc(fmt_str : string, args : ..any, location := #caller_location) do logf(level=Level.Warning, fmt_str=fmt_str, args=args, location=location);
|
}
|
||||||
errorf :: proc(fmt_str : string, args : ..any, location := #caller_location) do logf(level=Level.Error, fmt_str=fmt_str, args=args, location=location);
|
infof :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||||
fatalf :: proc(fmt_str : string, args : ..any, location := #caller_location) do logf(level=Level.Fatal, fmt_str=fmt_str, args=args, location=location);
|
logf(level=.Info, fmt_str=fmt_str, args=args, location=location);
|
||||||
|
}
|
||||||
|
warnf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||||
|
logf(level=.Warning, fmt_str=fmt_str, args=args, location=location);
|
||||||
|
}
|
||||||
|
errorf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||||
|
logf(level=.Error, fmt_str=fmt_str, args=args, location=location);
|
||||||
|
}
|
||||||
|
fatalf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||||
|
logf(level=.Fatal, fmt_str=fmt_str, args=args, location=location);
|
||||||
|
}
|
||||||
|
|
||||||
debug :: proc(args : ..any, location := #caller_location) do log(level=Level.Debug, args=args, location=location);
|
debug :: proc(args: ..any, location := #caller_location) {
|
||||||
info :: proc(args : ..any, location := #caller_location) do log(level=Level.Info, args=args, location=location);
|
log(level=.Debug, args=args, location=location);
|
||||||
warn :: proc(args : ..any, location := #caller_location) do log(level=Level.Warning, args=args, location=location);
|
}
|
||||||
error :: proc(args : ..any, location := #caller_location) do log(level=Level.Error, args=args, location=location);
|
info :: proc(args: ..any, location := #caller_location) {
|
||||||
fatal :: proc(args : ..any, location := #caller_location) do log(level=Level.Fatal, args=args, location=location);
|
log(level=.Info, args=args, location=location);
|
||||||
|
}
|
||||||
|
warn :: proc(args: ..any, location := #caller_location) {
|
||||||
|
log(level=.Warning, args=args, location=location);
|
||||||
|
}
|
||||||
|
error :: proc(args: ..any, location := #caller_location) {
|
||||||
|
log(level=.Error, args=args, location=location);
|
||||||
|
}
|
||||||
|
fatal :: proc(args: ..any, location := #caller_location) {
|
||||||
|
log(level=.Fatal, args=args, location=location);
|
||||||
|
}
|
||||||
|
|
||||||
log :: proc(level : Level, args : ..any, location := #caller_location) {
|
log :: proc(level: Level, args: ..any, location := #caller_location) {
|
||||||
logger := context.logger;
|
logger := context.logger;
|
||||||
if level < logger.lowest_level do return;
|
if level < logger.lowest_level {
|
||||||
|
return;
|
||||||
|
}
|
||||||
str := fmt.tprint(..args); //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
|
str := fmt.tprint(..args); //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
|
||||||
logger.procedure(logger.data, level, str, logger.options, location);
|
logger.procedure(logger.data, level, str, logger.options, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
logf :: proc(level : Level, fmt_str : string, args : ..any, location := #caller_location) {
|
logf :: proc(level: Level, fmt_str: string, args: ..any, location := #caller_location) {
|
||||||
logger := context.logger;
|
logger := context.logger;
|
||||||
if level < logger.lowest_level do return;
|
if level < logger.lowest_level {
|
||||||
str := fmt.tprintf(fmt_str, ..args) if len(args) > 0 else fmt.tprint(fmt_str); //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
|
return;
|
||||||
|
}
|
||||||
|
str := fmt.tprintf(fmt_str, ..args);
|
||||||
logger.procedure(logger.data, level, str, logger.options, location);
|
logger.procedure(logger.data, level, str, logger.options, location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,11 +264,11 @@ Allocator :: struct {
|
|||||||
// Logging stuff
|
// Logging stuff
|
||||||
|
|
||||||
Logger_Level :: enum {
|
Logger_Level :: enum {
|
||||||
Debug,
|
Debug = 0,
|
||||||
Info,
|
Info = 10,
|
||||||
Warning,
|
Warning = 20,
|
||||||
Error,
|
Error = 30,
|
||||||
Fatal,
|
Fatal = 40,
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger_Option :: enum {
|
Logger_Option :: enum {
|
||||||
|
|||||||
Reference in New Issue
Block a user