libnslog
Classes | Macros | Typedefs | Enumerations | Functions
nslog.h File Reference
#include <stdarg.h>

Go to the source code of this file.

Classes

struct  nslog_category_s
 
struct  nslog_entry_context_s
 

Macros

#define NSLOG_LEVEL_DD   NSLOG_LEVEL_DEEPDEBUG
 
#define NSLOG_LEVEL_DBG   NSLOG_LEVEL_DEBUG
 
#define NSLOG_LEVEL_CHAT   NSLOG_LEVEL_VERBOSE
 
#define NSLOG_LEVEL_WARN   NSLOG_LEVEL_WARNING
 
#define NSLOG_LEVEL_ERR   NSLOG_LEVEL_ERROR
 
#define NSLOG_LEVEL_CRIT   NSLOG_LEVEL_CRITICAL
 
#define NSLOG_COMPILED_MIN_LEVEL   NSLOG_LEVEL_DEBUG
 
#define NSLOG_DECLARE_CATEGORY(catname)    extern nslog_category_t __nslog_category_##catname
 
#define NSLOG_DEFINE_CATEGORY(catname, description)
 
#define NSLOG_DEFINE_SUBCATEGORY(parentcatname, catname, description)
 
#define NSLOG(catname, level, logmsg, args...)
 

Typedefs

typedef struct nslog_category_s nslog_category_t
 
typedef struct nslog_entry_context_s nslog_entry_context_t
 
typedef void(* nslog_callback) (void *context, nslog_entry_context_t *ctx, const char *fmt, va_list args)
 
typedef struct nslog_filter_s nslog_filter_t
 

Enumerations

enum  nslog_level {
  NSLOG_LEVEL_DEEPDEBUG = 0 , NSLOG_LEVEL_DEBUG = 1 , NSLOG_LEVEL_VERBOSE = 2 , NSLOG_LEVEL_INFO = 3 ,
  NSLOG_LEVEL_WARNING = 4 , NSLOG_LEVEL_ERROR = 5 , NSLOG_LEVEL_CRITICAL = 6
}
 
enum  nslog_error { NSLOG_NO_ERROR = 0 , NSLOG_NO_MEMORY = 1 , NSLOG_UNCORKED = 2 , NSLOG_PARSE_ERROR = 3 }
 

Functions

const char * nslog_level_name (nslog_level level)
 
const char * nslog_short_level_name (nslog_level level)
 
void nslog__log (nslog_entry_context_t *ctx, const char *pattern,...) __attribute__((format(printf
 
nslog_error nslog_set_render_callback (nslog_callback cb, void *context)
 
nslog_error nslog_uncork (void)
 
void nslog_cleanup (void)
 
nslog_error nslog_filter_category_new (const char *catname, nslog_filter_t **filter)
 
nslog_error nslog_filter_level_new (nslog_level level, nslog_filter_t **filter)
 
nslog_error nslog_filter_filename_new (const char *filename, nslog_filter_t **filter)
 
nslog_error nslog_filter_dirname_new (const char *dirname, nslog_filter_t **filter)
 
nslog_error nslog_filter_funcname_new (const char *funcname, nslog_filter_t **filter)
 
nslog_error nslog_filter_and_new (nslog_filter_t *left, nslog_filter_t *right, nslog_filter_t **filter)
 
nslog_error nslog_filter_or_new (nslog_filter_t *left, nslog_filter_t *right, nslog_filter_t **filter)
 
nslog_error nslog_filter_xor_new (nslog_filter_t *left, nslog_filter_t *right, nslog_filter_t **filter)
 
nslog_error nslog_filter_not_new (nslog_filter_t *input, nslog_filter_t **filter)
 
nslog_filter_tnslog_filter_ref (nslog_filter_t *filter)
 
nslog_filter_tnslog_filter_unref (nslog_filter_t *filter)
 
nslog_error nslog_filter_set_active (nslog_filter_t *filter, nslog_filter_t **prev)
 
char * nslog_filter_sprintf (nslog_filter_t *filter)
 
nslog_error nslog_filter_from_text (const char *input, nslog_filter_t **output)
 

Detailed Description

NetSurf Logging

Definition in file nslog.h.

Macro Definition Documentation

◆ NSLOG

#define NSLOG (   catname,
  level,
  logmsg,
  args... 
)
Value:
do { \
if (NSLOG_LEVEL_##level >= NSLOG_COMPILED_MIN_LEVEL) { \
static nslog_entry_context_t _nslog_ctx = { \
&__nslog_category_##catname, \
NSLOG_LEVEL_##level, \
__FILE__, \
sizeof(__FILE__) - 1, \
__PRETTY_FUNCTION__, \
sizeof(__PRETTY_FUNCTION__) - 1, \
__LINE__, \
}; \
nslog__log(&_nslog_ctx, logmsg, ##args); \
} \
} while(0)
#define NSLOG_COMPILED_MIN_LEVEL
Definition: nslog.h:78
Definition: nslog.h:109

Log something

This is the primary logging macro in nslog. It needs access to the category which is to be used to log, hence header files and the NSLOG_DECLARE_CATEGORY macro.

Parameters
catnameThe category name (as a bareword)
levelThe level at which this is logged (as a bareword such as WARNING)
logmsgThe log message itself (printf format string)
argsThe arguments for the log message

Definition at line 184 of file nslog.h.

◆ NSLOG_COMPILED_MIN_LEVEL

#define NSLOG_COMPILED_MIN_LEVEL   NSLOG_LEVEL_DEBUG

The minimum log level to be compiled in.

When compiling a library or application which uses nslog, you can set the minimum level to be compiled in. By setting this, you can reduce the size of the binary and potentially improve the performance of hotspots which contain logging instructions.

Definition at line 78 of file nslog.h.

◆ NSLOG_DECLARE_CATEGORY

#define NSLOG_DECLARE_CATEGORY (   catname)     extern nslog_category_t __nslog_category_##catname

Declare a category

This macro is used to declare a category. Use it in headers to allow more than one source file to use the same category.

Parameters
catnameThe category leaf name (as a bareword)

Definition at line 127 of file nslog.h.

◆ NSLOG_DEFINE_CATEGORY

#define NSLOG_DEFINE_CATEGORY (   catname,
  description 
)
Value:
nslog_category_t __nslog_category_##catname = { \
#catname, \
description, \
NULL, \
NULL, \
0, \
NULL, \
}

Define a category

This macro is used to define the storage for a category. Use it in one of your C source files to allow the category to have some storage space.

Parameters
catnameThe category name (as a bareword)
descriptionThe category description (as a static string)

Definition at line 139 of file nslog.h.

◆ NSLOG_DEFINE_SUBCATEGORY

#define NSLOG_DEFINE_SUBCATEGORY (   parentcatname,
  catname,
  description 
)
Value:
nslog_category_t __nslog_category_##catname = { \
#catname, \
description, \
&__nslog_category_##parentcatname, \
NULL, \
0, \
NULL, \
}

Define a sub-category

This macro is used to define the storage for a category which has a parent. Use it in one of your C source files to allow the category to have some storage space. Sub-categories end up named by their parent name and their name separated by slashes. This is arbitrary in depth, allowing sub-sub-sub categories etc.

Parameters
parentcatnameThe category name of the parent category (as a bareword)
catnameThe category name (as a bareword)
descriptionThe category description (as a static string)

Definition at line 162 of file nslog.h.

◆ NSLOG_LEVEL_CHAT

#define NSLOG_LEVEL_CHAT   NSLOG_LEVEL_VERBOSE

Definition at line 64 of file nslog.h.

◆ NSLOG_LEVEL_CRIT

#define NSLOG_LEVEL_CRIT   NSLOG_LEVEL_CRITICAL

Definition at line 67 of file nslog.h.

◆ NSLOG_LEVEL_DBG

#define NSLOG_LEVEL_DBG   NSLOG_LEVEL_DEBUG

Definition at line 63 of file nslog.h.

◆ NSLOG_LEVEL_DD

#define NSLOG_LEVEL_DD   NSLOG_LEVEL_DEEPDEBUG

Definition at line 62 of file nslog.h.

◆ NSLOG_LEVEL_ERR

#define NSLOG_LEVEL_ERR   NSLOG_LEVEL_ERROR

Definition at line 66 of file nslog.h.

◆ NSLOG_LEVEL_WARN

#define NSLOG_LEVEL_WARN   NSLOG_LEVEL_WARNING

Definition at line 65 of file nslog.h.

Typedef Documentation

◆ nslog_callback

typedef void(* nslog_callback) (void *context, nslog_entry_context_t *ctx, const char *fmt, va_list args)

Callback type for logging

In order for a logging client to actually receive the messages which are logged, the client must register a logging callback. It is recommended that only the highest level client do so (for example NetSurf) but test suites can also register for log messages if you want to use that as part of your testing.

Parameters
contextThe context pointer registered for the callback
ctxThe log entry context
fmtThe log message (printf style format string)
argsThe printf arguments for the log entry

Definition at line 242 of file nslog.h.

◆ nslog_category_t

Logging category

This structure is used internally by nslog to manage categories for logging. Categories are declared by the NSLOG_DECLARE_CATEGORY and defined by either NSLOG_DEFINE_CATEGORY and NSLOG_DEFINE_SUBCATEGORY.

It is not recommended that clients of nslog look inside the category structs excepting the name (and namelen) values. In addition you should only trust those values when handling a log callback.

◆ nslog_entry_context_t

Log entry context

When logging, nslog will create an entry context and pass it to the log callback. This context tells you everything about the log entry being created (except the message) and is ephemeral (if you need the content beyond the scope of the log callback, copy it).

◆ nslog_filter_t

typedef struct nslog_filter_s nslog_filter_t

Log filter handle

nslog allows clients to set a complex filter which can be used to restrict the log messages which make their way through to the log callback.

Clients can build log filters up "by hand" or can pass a string representation of a log filter to the internal nslog parser.

Log filters are reference counted and filter builders will return a log filter with a reference, and will take automatically reference any filters passed in, so remember to unref them if you're done.

Definition at line 302 of file nslog.h.

Enumeration Type Documentation

◆ nslog_error

Log error types

When nslog is performing actions which can allocate memory or otherwise rely on internal state machines. Such functions always return an error code and any extra values in pointer-based out-parameters.

Enumerator
NSLOG_NO_ERROR 

Nothing went wrong. Have a party.

NSLOG_NO_MEMORY 

nslog ran out of memory. Worry, a great deal

NSLOG_UNCORKED 

nslog is already uncorked, don't rush it

NSLOG_PARSE_ERROR 

nslog failed to parse the given log filter

Definition at line 221 of file nslog.h.

◆ nslog_level

Log levels

When logging, you can set the 'log level' which can be used as a basic way to filter the logging which occurs. In addition, the logging level can be used to control which logging is compiled in. As such, release builds can be made where DEBUG and DEEPDEBUG are compiled out.

If logging is set at INFO then everything above INFO will be logged, including warnings, errors, etc.

Enumerator
NSLOG_LEVEL_DEEPDEBUG 
NSLOG_LEVEL_DEBUG 
NSLOG_LEVEL_VERBOSE 
NSLOG_LEVEL_INFO 
NSLOG_LEVEL_WARNING 
NSLOG_LEVEL_ERROR 
NSLOG_LEVEL_CRITICAL 

Definition at line 31 of file nslog.h.

Function Documentation

◆ nslog__log()

void nslog__log ( nslog_entry_context_t ctx,
const char *  pattern,
  ... 
)

Internal logging function

While clients of nslog will not call this function directly (preferring to use the NSLOG macro, this is the actual function which implements it.

Parameters
ctxThe log entry context for the log
patternThe printf message pattern
...The arguments for the log entry

◆ nslog_cleanup()

void nslog_cleanup ( void  )

Finalise log categories, release filter handles, etc.

Since logging categories can have memory allocated to them at runtime, and the logging filters can have references held inside the library, clients which wish to be 'valgrind clean' may wish to call this to ensure that any memory allocated inside the nslog library is released.

This does not remove the active log callback, so logging calls after this returns will still work (though will be unfiltered). Of course, they will cause memory to be allocated once more. This function can be called as many times as desired, it is idempotent.

If the logging was corked when this was called, pending corked messages will be delivered if necessary before any filters are removed.

◆ nslog_filter_and_new()

nslog_error nslog_filter_and_new ( nslog_filter_t left,
nslog_filter_t right,
nslog_filter_t **  filter 
)

Create a logical 'and' of two filters.

The returned filter succeeds if both the passed in filters pass. It will short-circuit and not evaluate the right filter if the left filter fails.

Parameters
leftThe first filter to check
rightThe second filter to check
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_category_new()

nslog_error nslog_filter_category_new ( const char *  catname,
nslog_filter_t **  filter 
)

Create a category based filter

The returned filter matches against the fully qualified category name and succeeds if the given category name is either an exact match or is a proper prefix of the category.

For example, a filter of 'foo/bar' will match 'foo/bar' 'foo/bar/baz' but not 'foo' or 'foo/barfle'.

Parameters
catnameThe category name to filter on
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_dirname_new()

nslog_error nslog_filter_dirname_new ( const char *  dirname,
nslog_filter_t **  filter 
)

Create a dirname based filter

The returned filter matches against the filename and succeeds if the entry's filename dirname matches the value of the filter.

For example, a filter of "foo" will match log entries for "foo/bar.c" or "foo/bar/baz.c" but not "baz/foo.c".

Parameters
dirnameThe directory name to filter with
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_filename_new()

nslog_error nslog_filter_filename_new ( const char *  filename,
nslog_filter_t **  filter 
)

Create a filename based filter

The returned filter matches against the filename and succeeds if the entry's filename leafname matches the value of the filter.

For example, a filter of "foo/bar.c" will match log entries for "foo/bar.c" or "baz/foo/bar.c" but not "baz/bar.c".

Parameters
filenameThe filename to filter with
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_from_text()

nslog_error nslog_filter_from_text ( const char *  input,
nslog_filter_t **  output 
)

Parse a filter's textual form.

Filters can be written in plain text and this function turns textual filters into filters which can be used by nslog.

The caller owns the reference returned to it and must unreference the filter when done with it.

Parameters
inputA pointer to filter text to be parsed
outputA pointer to fill out with the parsed filter
Returns
Whether or not this succeeds

◆ nslog_filter_funcname_new()

nslog_error nslog_filter_funcname_new ( const char *  funcname,
nslog_filter_t **  filter 
)

Create a function-name based filter

The returned filter matches against the name of the function where the NSLOG statement exists, and succeeds if the entry's function name exactly matches the value of the filter.

For example, a filter of "foo" will match log entries for foo() or foo(int) but not foobar().

Parameters
funcnameThe function name to filter on
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_level_new()

nslog_error nslog_filter_level_new ( nslog_level  level,
nslog_filter_t **  filter 
)

Create a log level based filter

The returned filter matches against the level of the log entry and succeeds if the entry's level is at least the value of the filter.

For example, a filter of NSLOG_LEVEL_WARNING will match log entries of the same level or higher (such as NSLOG_LEVEL_ERROR) but not lower levels (such as NSLOG_LEVEL_DEBUG)

Parameters
levelThe log level to filter at
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_not_new()

nslog_error nslog_filter_not_new ( nslog_filter_t input,
nslog_filter_t **  filter 
)

Create a logical 'not' of a filters.

The returned filter succeeds if the passed in filter fails.

Parameters
inputThe first filter to check
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_or_new()

nslog_error nslog_filter_or_new ( nslog_filter_t left,
nslog_filter_t right,
nslog_filter_t **  filter 
)

Create a logical 'or' of two filters.

The returned filter succeeds if either of the passed in filters pass. It will short-circuit and not evaluate the right filter if the left filter succeeds.

Parameters
leftThe first filter to check
rightThe second filter to check
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_filter_ref()

nslog_filter_t * nslog_filter_ref ( nslog_filter_t filter)

Take a reference to the passed in filter.

This increments the reference count of the given filter and returns it directly to encourage a style of:

myfilter = nslog_filter_ref(incomingfilter)

Parameters
filterA pointer to a filter to be referenced
Returns
Whether or not this succeeds

◆ nslog_filter_set_active()

nslog_error nslog_filter_set_active ( nslog_filter_t filter,
nslog_filter_t **  prev 
)

Set the passed in filter as the active filter

This sets the active filter for managing the log. If you don't pass NULL in prev, then the currently active filter is returned for you to reuse later.

Parameters
filterA pointer to a filter to be set active
prevA pointer which will be optionally filled out
Returns
Whether or not this succeeds

◆ nslog_filter_sprintf()

char * nslog_filter_sprintf ( nslog_filter_t filter)

Render a filter as its canonical textual form.

Filters can be written in plain text and this function turns filters into their canonical textual form.

The caller owns the returned string and must free() it.

Parameters
filterA pointer to a filter to be rendered as text
Returns
A string representing the filter

◆ nslog_filter_unref()

nslog_filter_t * nslog_filter_unref ( nslog_filter_t filter)

Release a reference to the passed in filter.

This decrements the reference count of the given filter and returns NULL to encourage the style of:

myfilter = nslog_filter_ref(myfilter)

Parameters
filterA pointer to a filter to be dereferenced
Returns
Whether or not this succeeds

◆ nslog_filter_xor_new()

nslog_error nslog_filter_xor_new ( nslog_filter_t left,
nslog_filter_t right,
nslog_filter_t **  filter 
)

Create a logical 'xor' of two filters.

The returned filter succeeds if one, or the other, but not both the passed in filters pass.

Parameters
leftThe first filter to check
rightThe second filter to check
filterA pointer to a filter to be filled out
Returns
Whether or not this succeeds

◆ nslog_level_name()

const char * nslog_level_name ( nslog_level  level)

Convert a logging level to a string.

The returned string is owned by the nslog library (static) and should not be freed.

Parameters
levelThe level for which you want the 'canonical' name.

◆ nslog_set_render_callback()

nslog_error nslog_set_render_callback ( nslog_callback  cb,
void *  context 
)

Set the render callback for logging

In order for the client to receive the log messages, it needs to register a nslog_callback function.

Parameters
cbThe callback function pointer
contextThe context pointer to provide to the callback
Returns
Whether or not this succeeded

◆ nslog_short_level_name()

const char * nslog_short_level_name ( nslog_level  level)

Convert a logging level to a short string.

The returned string is owned by the nslog library (static) and should not be freed. It will be exactly four characters wide and suitable for logging to a file neatly.

Parameters
levelThe level for which you want the 'short' name.

◆ nslog_uncork()

nslog_error nslog_uncork ( void  )

Uncork the log

When nslog starts up, it is corked which means that any messages logged will be saved up ready for when the client calls this function. Corked messages will be rendered when logged, so don't expect the format strings to be identical between logging before and after uncorking.

Any stored log messages will be drained before this function returns.

Returns
Whether or not the uncorking succeeded.