Skip to content

Commit

Permalink
Document core:log
Browse files Browse the repository at this point in the history
  • Loading branch information
Lperlind committed Nov 7, 2024
1 parent fe9240f commit ff84f6b
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 9 deletions.
84 changes: 77 additions & 7 deletions core/log/file_console_logger.odin
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ File_Type :: enum {
os2,
}

/*
Implements a logger that writes to a file stream, such as stdout, or a file on the system.
This logger is compatible both with `os` and `os2`.
- To make a logger that writes to an `os.Handle` refer to `make_file_logger_os`
- To make a logger that writes to an `^os2.File` refer to `make_file_logger_os2`
- To make a logger that writes to `stdout` and `stderr` refer to `make_console_logger`
*/
File_Console_Logger_Data :: struct {
type: File_Type,
file_handle_os: os.Handle,
Expand All @@ -50,17 +58,54 @@ File_Console_Logger_Data :: struct {
allocator: runtime.Allocator
}

make_file_logger_os :: proc(h: os.Handle, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", close_file_on_delete := false, allocator := context.allocator) -> (res: Logger, err: runtime.Allocator_Error) {
data := new(File_Console_Logger_Data, allocator) or_return
/*
Makes a new logger that will write to the provided `os.Handle`
*Allocates Using Provided Allocator*
Inputs:
- h: An os handle that the logger will write to
- lowest: The lowest level logging to accept
- opt: The wanted logging options
- ident: An identifier that will be written alongside the logged message
- close_file_on_delete: Sets the logger to close the handle when delete_file_logger is called if `true`
- allocator: (default: context.allocator)
- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The new file logger
- res: An allocator error if one occured, `nil` otherwise
*/
make_file_logger_os :: proc(h: os.Handle, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", close_file_on_delete := false, allocator := context.allocator, loc := #caller_location) -> (res: Logger, err: runtime.Allocator_Error) {
data := new(File_Console_Logger_Data, allocator, loc) or_return
data.type = .os
data.file_handle_os = h
data.ident = ident
data.allocator = allocator
data.close_file_on_delete = close_file_on_delete
return Logger{file_console_logger_proc, data, lowest, opt}, nil
}
make_file_logger_os2 :: proc(f: ^os2.File, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", close_file_on_delete := false, allocator := context.allocator) -> (res: Logger, err: runtime.Allocator_Error) {
data := new(File_Console_Logger_Data, allocator) or_return

/*
Makes a new logger that will write to the provided `^os2.File`
*Allocates Using Provided Allocator*
Inputs:
- f: An os2 file that the logger will write to
- lowest: The lowest level logging to accept
- opt: The wanted logging options
- ident: An identifier that will be written alongside the logged message
- close_file_on_delete: Sets the logger to close the file when delete_file_logger is called if `true`
- allocator: (default: context.allocator)
- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The new file logger
- res: An allocator error if one occured, `nil` otherwise
*/
make_file_logger_os2 :: proc(f: ^os2.File, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", close_file_on_delete := false, allocator := context.allocator, loc := #caller_location) -> (res: Logger, err: runtime.Allocator_Error) {
data := new(File_Console_Logger_Data, allocator, loc) or_return
data.type = .os2
data.file_handle_os2 = f
data.ident = ident
Expand All @@ -73,8 +118,25 @@ make_file_logger :: proc {
make_file_logger_os2,
}

make_console_logger :: proc(lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", allocator := context.allocator) -> (res: Logger, err: runtime.Allocator_Error) {
data := new(File_Console_Logger_Data, allocator) or_return
/*
Makes a new logger that will write to `stdout` and `stderr`. `Stdout` will be written to
if the log level is below `Level.Error`, otherwise `stderr` will be written to
*Allocates Using Provided Allocator*
Inputs:
- lowest: The lowest level logging to accept
- opt: The wanted logging options
- ident: An identifier that will be written alongside the logged message
- allocator: (default: context.allocator)
- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The new file logger
- res: An allocator error if one occured, `nil` otherwise
*/
make_console_logger :: proc(lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", allocator := context.allocator, loc := #caller_location) -> (res: Logger, err: runtime.Allocator_Error) {
data := new(File_Console_Logger_Data, allocator, loc) or_return
data.type = .console
data.ident = ident
data.allocator = allocator
Expand All @@ -93,6 +155,14 @@ create_console_logger :: proc(lowest := Level.Debug, opt := Default_Console_Logg
return logger
}

/*
Deletes a logger made with `make_console_logger` and `make_file_logger`.
If a logger was created with `make_file_logger` and `close_file_on_delete` was
set to true then the logger will try to close the file handle it was provided.
Inputs:
- log: The logger to delete
*/
delete_console_logger :: proc(log: Logger) {
data := cast(^File_Console_Logger_Data)log.data
if data.close_file_on_delete {
Expand Down Expand Up @@ -139,7 +209,7 @@ file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string

//TODO(Hoej): When we have better atomics and such, make this thread-safe
switch data.type {
case .console: fmt.fprintf(level <= Level.Error ? os.stdout : os.stderr, "%s%s\n", strings.to_string(buf), text)
case .console: fmt.fprintf(level < Level.Error ? os.stdout : os.stderr, "%s%s\n", strings.to_string(buf), text)
case .os: fmt.fprintf(data.file_handle_os, "%s%s\n", strings.to_string(buf), text)
case .os2: fmt.wprintf(data.file_handle_os2.stream, "%s%s\n", strings.to_string(buf), text)
}
Expand Down
19 changes: 17 additions & 2 deletions core/log/multi_logger.odin
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,31 @@ Multi_Logger_Data :: struct {
allocator: runtime.Allocator
}

@(deprecated = "Use make_multi_logger instead")
create_multi_logger :: proc(logs: ..Logger) -> Logger {
logger, _ := make_multi_logger(..logs, allocator = context.allocator)
return logger
}

make_multi_logger :: proc(logs: ..Logger, allocator := context.allocator) -> (res: Logger, err: runtime.Allocator_Error) {
/*
Makes a new logger that will write to several other loggers.
*Allocates Using Provided Allocator*
Inputs:
- logs: The loggers this logger will write to
- allocator: (default: context.allocator)
- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The new multi logger
- res: An allocator error if one occured, `nil` otherwise
*/
make_multi_logger :: proc(logs: ..Logger, allocator := context.allocator, loc := #caller_location) -> (res: Logger, err: runtime.Allocator_Error) {
logger_size := mem.align_forward_int(size_of(Multi_Logger_Data), align_of(Logger))
content_size := len(mem.slice_to_bytes(logs))

data_bytes := make([]byte, logger_size + content_size, allocator) or_return
data_bytes := make([]byte, logger_size + content_size, allocator, loc) or_return
data := cast(^Multi_Logger_Data)raw_data(data_bytes)
data.loggers = slice.reinterpret([]Logger, data_bytes[logger_size:])
assert(len(data.loggers) == len(logs))
Expand Down

0 comments on commit ff84f6b

Please sign in to comment.