Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Simple Logging Library for C/C++ Programs
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
config
demo
src
srcutil
.gitignore
LICENSE
Makefile
README.pod

README.pod

YOLOG

Yolog - Free Contextual Logging For All!

DESCRIPTION

Yolog is a customizable but easy to use logging library. It allows many options for both file and screen logging.

Yolog is built from the ground up to be entirely embeddable in your project, meaning that it does not have to be built as a DSO dependency and will not conflict with other libraries or projects using Yolog (though it can also live as a DSO).

Yolog can provide contextual source-based information about logging messages (via format strings), can invoke callbacks for each message, and can be configured during compile time to make some logging operations as no-ops (helping performance).

CONCEPTS

Subsystems/Facilities

This is a user-defined facility or subsystem. Your application could (and most probably should) have different subsystem. A subsystem represents a logical component within your application which emits messages; e.g. a subsystem named io which will emit messages about I/O status and error.

Perhaps your I/O subsystem then dispatches data to a stream parser, which may emit its own messages and be called parse.

Levels/Severity

Severity is a number of 'importance' the message has to offer. Yolog defines several severity levels.

The explanation of the levels is from most to least severe, and are entirely advisory

CRIT

This is a critical message, i.e. something seriously wrong with the application.

ERROR

Messages which represent environmental or user errors

WARN

Messages about things which might be wrong or unusual

INFO

Higher level messages indicating status or events

DEBUG

Lower level messages indicating status and events

TRACE

Messages for function entry/leave, frequently repeated lines of code

RANT

Miscellaneous messages, usually temporary (i.e. the value of a certain variable at a certain point in time)

Outputs and Control

Yolog allows for multiple destinations for messages, these destinations may be configured on a per-subsystem basis.

The following targets may be configured

Screen

This is the default target and prints messages to standard error

Global Log

This is an application-wide logfile, subsystems can opt to send messages here as well

Subsystem Log

This is a per-subsystem log file, subsystems may additionally log to this file as well.

Each output can be configured to control its minimum allowable severity level. So for example, the io subsystem's DEBUG and lower messages may be logged to the screen, but not to the file.

Additionally, each output may have its own format string.

Statements

In order to avoid verbose logging statements, Yolog generates macro stubs for all subsystem+level combinations which result in identifiers which can accept the messages.

The preferred format for the identifier is

    log_<subsys>_<severity>

So e.g. a DEBUG-level message from the io subsystem would be sent as

    log_io_debug("IO Stuff...");

Macros function exactly as printf(3) and may accept printf format strings and arguments.

Output configuration

Yolog provides a config file parser which can at runtime determine and modify output control. See config/logging2.conf for an example.

HOW IT WORKS

Yolog will generate a stub header and source file for your project. These files provide the necessary support and glue for customizing your subsystems.

The header file contains the macro stubs (which can become quite large, but is not an issue since they are all expanded to a single function call during preprocessing).

The source file contains a wrapper init function, and if configured in 'static' mode, contains the source code of Yolog itself, with its symbols specially mangled to avoid conflicts.

The contents and dependencies of these headers are none, so any C compiler should be able to compile and embed the generated source code into your project without any fuss. By default, Yolog generates C99 compatible code, but has an option for generating C89 code as well (which does not make use of variadic macros)

USING

In order to use Yolog you must tell it about the names and subsystems you wish to use in your project

The file conf/sample.cnf shows a simple configuration in conjunction with a simple 'project' (located in the demo directory). This project has Makefile targets for both static and dynamic Yolog using the same codebase.

A simple configuration should look like this

    # Your app's 'namespace'. This will be prefixed to everything
    symbol_prefix myproj

    # By default, debug macros have the same prefix as the namespace. This
    # option will provide a customized prefix. Instead of myproj_debug, we can do
    macro_prefix log
    # and do log_debug

    # Environment variables to manipulate the debugging level and options
    env_color MYAPP_DEBUG_COLOR
    env_debug MYAPP_DEBUG_LEVEL
    env_prefs MYAPP_DEBUG_PREFS

    # Now, sometimes an app wants more than a single logging source. This helps
    # filter out messages based on subsystem/component rather than simple severity.
    subsys io
    subsys config
    subsys main

Now, assuming we've saved this file to myapp.conf we will do the following to generate the Yolog files

For a dynamic Yolog, do

    $ ./srcutil/genyolog.pl -c myapp.conf -o myapp_yolog

For a static Yolog:

    $ ./srcutil/genyolog.pl -c myapp.conf --static -o myapp_yolog -y /usr/src/yolog

In either case, a new directory myapp_yolog will be created, and there will be two files, myapp_yolog.c and myapp_yolog.h. The source file should be linked in with your application, and the header file included.

Assuming that the myapp_yolog directory is in your compiler's search path, the following would be done in order to use the logging libraries

    #include <myapp_yolog/myapp_yolog.h>
    /* other stuff */

    int main(void) {
        myapp_yolog_init(NULL);
        log_debug("This is a debug message");
        log_io_error("IO Error!");
        log_config_warn("Configuration Option has no effect!");
    }

Simples!

If you wanted to add some color

    $ export MYAPP_DEBUG_COLOR=1
    $ ./myapp

Or if you wanted to silence all debug output

    $ export MYAPP_DEBUG_LEVEL=1000
    $ ./myapp

If you wanted to see all TRACE and higher messages from the IO subsystem

    $ export MYAPP_DEBUG_PREFS="io:trace"
    $ ./myapp

PORTABILITY

I've managed to compile libyolog on GCC for Linux, Windows, Solaris.

The C99-mode macros should work anywhere and require little fuss.

Threads

Because yolog can be used from multiple threads, there arise two issues.

FILE* locking

The stdio's FILE pointer must be locked by each thread. On POSIX sysstems this is done with flockfile and funlockfile. I have yet to discover something like this for win32

C89 mode

C89 mode is not 'atomic' in the sense that the macros must set contextual information separately from the actual logging messages. This means a global context placeholder must exist and be set for each message. On POSIX system this global context is protected by pthreads. As I am not a win32 programmer I have not had the time to play around with windows threads here

Thread and Process IDs

Yolog's format string allows thread and process ID specifiers. On POSIX systems this is easy; on Windows systems these both fallback to -1

AUTHOR AND COPYRIGHT

Copyright 2010-2012 M. Nunberg

See LICENSE for licensing information

Something went wrong with that request. Please try again.