forked from lda/telodendria
Write man page for Log
This commit is contained in:
parent
70bdf81df7
commit
8045c583ba
3 changed files with 159 additions and 101 deletions
2
TODO.txt
2
TODO.txt
|
@ -36,7 +36,7 @@ Due: January 1, 2023
|
|||
[ ] Http
|
||||
[ ] HttpServer
|
||||
[ ] Json
|
||||
[ ] Log
|
||||
[x] Log
|
||||
[ ] Matrix
|
||||
[x] Queue
|
||||
[ ] Routes
|
||||
|
|
156
man/man3/Log.3
Normal file
156
man/man3/Log.3
Normal file
|
@ -0,0 +1,156 @@
|
|||
.Dd $Mdocdate: November 25 2022 $
|
||||
.Dt LOG 3
|
||||
.Os Telodendria Project
|
||||
.Sh NAME
|
||||
.Nm Log
|
||||
.Nd A simple logging framework for logging to files, standard output,
|
||||
or the system log.
|
||||
.Sh SYNOPSIS
|
||||
.In Log.h
|
||||
.Ft LogConfig *
|
||||
.Fn LogConfigCreate "void"
|
||||
.Ft void
|
||||
.Fn LogConfigFree "LogConfig *"
|
||||
.Ft void
|
||||
.Fn LogConfigLevelSet "LogConfig *" "int"
|
||||
.Ft void
|
||||
.Fn LogConfigIndent "LogConfig *"
|
||||
.Ft void
|
||||
.Fn LogConfigUnindent "LogConfig *"
|
||||
.Ft void
|
||||
.Fn LogConfigIndentSet "LogConfig *" "size_t"
|
||||
.Ft void
|
||||
.Fn LogConfigOutputSet "LogConfig *" "FILE *"
|
||||
.Ft void
|
||||
.Fn LogConfigFlagSet "LogConfig *" "int"
|
||||
.Ft void
|
||||
.Fn LogConfigFlagClear "LogConfig *" "int"
|
||||
.Ft void
|
||||
.Fn LogConfigTimeStampFormatSet "LogConfig *" "char *"
|
||||
.Ft void
|
||||
.Fn Log "LogConfig *" "int" "const char *" "..."
|
||||
.Sh DESCRIPTION
|
||||
.Pp
|
||||
A heavily-modifed version of Shlog, a simple C logging library facility
|
||||
that allows for colorful outputs, timestamps, and custom log levels.
|
||||
This library differs from Shlog in that the naming conventions have
|
||||
been updated to be consistent with Telodendria, and system log support
|
||||
has been added.
|
||||
.Pp
|
||||
Shlog was originally a learning project. It worked well and produced
|
||||
elegant logging output, so it was chosen to be the main logging
|
||||
mechanism of Telodendria. The original Shlog project is now dead; Shlog
|
||||
lives on now only as Telodendria's logging mechanism.
|
||||
.Pp
|
||||
One of the design choices made in this library, which unfortunately
|
||||
makes code using it a little more verbose, is that multiple logging
|
||||
configurations can exist in a program. No global variables are used,
|
||||
and all functions are thread-safe.
|
||||
.Pp
|
||||
.Fn LogConfigCreate
|
||||
creates a new log configuration with sane defaults that can be used
|
||||
immediately. Note that every call to
|
||||
.Fn Log
|
||||
requires a valid configuration pointer.
|
||||
.Fn LogConfigFree
|
||||
frees all memory associated with that configuration, invalidating
|
||||
it. Passing an invalid configuration pointer into any of the
|
||||
functions defined here result in undefined behavior. The
|
||||
.Fn LogConfig*Set
|
||||
functions manipulate the data pointed to by the pointer returned
|
||||
by
|
||||
.Fn LogConfigCreate .
|
||||
.Pp
|
||||
.Fn LogConfigLevelSet
|
||||
sets the current log level on the specified log configuration. This
|
||||
indicates that only messages at or above this level should be
|
||||
logged; all other messages are silently discarded by the
|
||||
.Fn Log
|
||||
function. The passed log level should be one of the log levels
|
||||
defined by
|
||||
.Xr syslog 3 .
|
||||
Refer to that page for a complete list of acceptable log levels,
|
||||
and note that passing in an invalid or unknown log level will
|
||||
result in undefined behavior.
|
||||
.Pp
|
||||
.Fn LogConfigIndent
|
||||
causes the output of
|
||||
.Fn Log
|
||||
to be indented two more spaces than it was previously. This can be
|
||||
helpful when generating stack traces, or otherwise producing
|
||||
hierarchical output. After calling this function, all future
|
||||
messages using the given config will be indented two more spaces
|
||||
than they were before. This is just a wrapper function around
|
||||
.Fn LogConfigIndentSet ,
|
||||
which allows the caller to specify an arbitrary indentation in
|
||||
spaces.
|
||||
.Fn LogConfigUnindent
|
||||
does the exact opposite of
|
||||
.Fn LogConfigIndent ;
|
||||
it subtracts two spaces from the indentation level, unless there
|
||||
is no indent, then it does nothing.
|
||||
.Pp
|
||||
.Fn LogConfigOutputSet
|
||||
sets the file stream that logging output should be written to. This
|
||||
defaults to standard output, but it can be standard error, or some
|
||||
other file stream. Passing a NULL value for the file pointer sets
|
||||
the log output to standard output. Note that the output file stream
|
||||
is only used if FLAG_OUTPUT_SYSLOG is not set.
|
||||
.Pp
|
||||
.Fn LogConfigFlagSet
|
||||
and
|
||||
.Fn LogConfigFlagClear
|
||||
are used for setting a number of boolean options on a log
|
||||
configuration. They utilize bitwise operators, so multiple options
|
||||
can be set or cleared with a single function call using bitwise OR
|
||||
operators. The flags defined as preprocessor macros, and are as
|
||||
follows:
|
||||
.Bl -tag -width Ds
|
||||
.It LOG_FLAG_COLOR
|
||||
When set, enable color-coded output on TTYs. Note that colors are
|
||||
implemented as ANSI escape sequences, and are not written to file
|
||||
streams that are not actually connected to a TTY, to prevent those
|
||||
sequences from being written to a file.
|
||||
.Xr isatty 3
|
||||
is checked before writing ANSI sequences.
|
||||
.It LOG_FLAG_SYSLOG
|
||||
When enabled, log output to the syslog using
|
||||
.Xr syslog 3 ,
|
||||
instead of logging to the file set by
|
||||
.Fn LogConfigOutputSet .
|
||||
This flag always overrides the file stream set by that function,
|
||||
regardless of when it was set.
|
||||
.El
|
||||
.Pp
|
||||
.Fn LogConfigTimeStampFormatSet
|
||||
allows a custom timestamp to be prepended to each message
|
||||
if the output is not going to the system log. Consult your
|
||||
system's documentation for
|
||||
.Xr strftime 3 .
|
||||
A value of NULL disables outputting a timestamp before messages.
|
||||
.Pp
|
||||
The
|
||||
.Fn Log
|
||||
function actually writes a log message to a console, file, system
|
||||
log, or other supported output device using the given configuration.
|
||||
This function is thread-safe; it locks a mutex before writing a
|
||||
message, and then unlocks it after the message was written. Each
|
||||
log configuration has its own mutex, so this function can be used
|
||||
with mutiple active log configurations.
|
||||
.Pp
|
||||
This function only logs messages if their level is above or equal to
|
||||
the currently configured log level, making it easy to turn some
|
||||
messages on or off. The function has the same usage as
|
||||
.Xr printf 3 .
|
||||
.Sh RETURN VALUES
|
||||
.Pp
|
||||
.Fn LogConfigCreate
|
||||
returns a pointer to a configuration structure on the heap, or NULL
|
||||
if there was an error allocating memory for it. The returned
|
||||
structure is opaque to the caller; the
|
||||
.Fn LogConfig*
|
||||
functions should be used to manipulate it.
|
||||
.Pp
|
||||
All other functions do not return anything. They are simply
|
||||
assumed to always succeed. If any arguments are NULL, then the
|
||||
functions do nothing, unless otherwise specifically noted.
|
|
@ -29,101 +29,26 @@
|
|||
#include <stddef.h>
|
||||
#include <syslog.h>
|
||||
|
||||
/*
|
||||
* The possible flags that can be applied to alter the behavior of
|
||||
* the logger.
|
||||
*/
|
||||
typedef enum LogFlag
|
||||
{
|
||||
LOG_FLAG_COLOR = (1 << 0), /* Enable color output on TTYs */
|
||||
LOG_FLAG_SYSLOG = (1 << 1) /* Log to the syslog instead of a
|
||||
* file */
|
||||
} LogFlag;
|
||||
#define LOG_FLAG_COLOR (1 << 0)
|
||||
#define LOG_FLAG_SYSLOG (1 << 1)
|
||||
|
||||
/*
|
||||
* The log configurations structure in which all settings exist.
|
||||
* It's not super elegant to pass around a pointer to the logging
|
||||
* configuration, but this really is the best way without having a
|
||||
* global variable. It allows multiple loggers to exist if necessary,
|
||||
* and makes things more thread safe.
|
||||
*/
|
||||
typedef struct LogConfig LogConfig;
|
||||
|
||||
/*
|
||||
* Create a new log configuration on the heap. This will be passed to
|
||||
* every Log() call after it is configured.
|
||||
*
|
||||
* Return: A pointer to a new LogConfig that can be configured and used
|
||||
* for logging. It should have sane defaults; in other words, you should
|
||||
* be able to immediately start logging with it.
|
||||
*/
|
||||
extern LogConfig *
|
||||
LogConfigCreate(void);
|
||||
|
||||
/*
|
||||
* Free a log configuration. Future attempts to log with the passed
|
||||
* configuration will fail in an undefined way, such as by hanging the
|
||||
* process or segfaulting.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* (LogConfig *) The configuration to free. All memory associated with
|
||||
* configuring the logging mechanism will be
|
||||
* invalidated.
|
||||
*/
|
||||
extern void
|
||||
LogConfigFree(LogConfig *);
|
||||
|
||||
/*
|
||||
* Set the current log level on the specified log configuration. This
|
||||
* indicates that only messages at or above this level should be
|
||||
* logged; all other messages are ignored by the Log() function.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* (LogConfig *) The log configuration to set the log level on.
|
||||
* (int) The log level to set.
|
||||
*/
|
||||
extern void
|
||||
LogConfigLevelSet(LogConfig *, int);
|
||||
|
||||
/*
|
||||
* Indent the log output by two spaces. This can be helpful in
|
||||
* generating stack traces, or otherwise producing hierarchical output.
|
||||
* After calling this function, all future log messages using this
|
||||
* configuration will be indented.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* (LogConfig *) The log configuration to indent.
|
||||
*/
|
||||
extern void
|
||||
LogConfigIndent(LogConfig *);
|
||||
|
||||
/*
|
||||
* Decrease the log output indent by two spaces. This can be helpful in
|
||||
* generating stack traces, or otherwise producing hierarchical output.
|
||||
* After calling this function, all future log messages using this
|
||||
* configuration will be unindented, unless there was no indentation
|
||||
* to begin with; in that case, this function will do nothing.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* (LogConfig *) The log configuration to unindent.
|
||||
*/
|
||||
extern void
|
||||
LogConfigUnindent(LogConfig *);
|
||||
|
||||
/*
|
||||
* Set the log output indent to an arbitrary amount. This can be helpful
|
||||
* in generating stack traces, or otherwise producing hierarchical
|
||||
* output. After calling this function, all future log messages using
|
||||
* this configuration will be indented by the given amount.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* (LogConfig *) The log configuration to apply the indent to.
|
||||
*/
|
||||
extern void
|
||||
LogConfigIndentSet(LogConfig *, size_t);
|
||||
|
||||
|
@ -139,29 +64,6 @@ extern void
|
|||
extern void
|
||||
LogConfigTimeStampFormatSet(LogConfig *, char *);
|
||||
|
||||
/*
|
||||
* Actually log a message to a console, file, or other output device,
|
||||
* using the given log configuration. This function is thread-safe; it
|
||||
* locks a mutex before writing a message, and then unlocks it after
|
||||
* the message was written. It should therefore work well in
|
||||
* multithreaded environments, and with multiple different log
|
||||
* configurations, as each one has its own mutex.
|
||||
*
|
||||
* This function only logs messages if they are above the currently
|
||||
* configured log level. In this way, it is easy to turn some messages
|
||||
* on and off.
|
||||
*
|
||||
* This function is a printf() style function; it takes a format
|
||||
* string and any number of parameters to format.
|
||||
*
|
||||
* Params:
|
||||
*
|
||||
* (LogConfig *) The logging configuration.
|
||||
* (int) The level of the message to log.
|
||||
* (const char *) The format string, or a plain message string.
|
||||
* (...) Any items to map into the format string, printf()
|
||||
* style.
|
||||
*/
|
||||
extern void
|
||||
Log(LogConfig *, int, const char *,...);
|
||||
|
||||
|
|
Loading…
Reference in a new issue