slog2_register()

Updated: April 19, 2023

Register and allocate a new slog2 buffer set

Synopsis:

#include <sys/slog2.h>

int slog2_register( slog2_buffer_set_config_t *config,
                    slog2_buffer_t *handles,
                    uint32_t flags );

Arguments:

config
A pointer to a slog2 buffer configuration object; see below.
handles
An array that the function fills with opaque handles for the buffers it allocates. The number of entries must be at least the value of the num_buffers member of the config structure.
flags
Options for buffer management (see flags below).

Library:

libslog2

Use the -l slog2 option to qcc to link against this library.

Description:

The slog2_register() function registers a new instance of a slog2 buffer set. Each buffer set contains one or more buffers; specify the size of each buffer as a multiple of 4 KB pages. The maximum number of buffers is specified by SLOG2_MAX_BUFFERS.

Use slog2_reset() to unregister the buffer set.

flags

Use the flags argument to specify options for buffer management. It is a bitwise OR of zero or more of the following bits:

SLOG2_ALLOC_TYPE_PHYSICAL
Back buffer sets against a known range of physical memory to make it possible for them to be recovered after a warm reset. Applies only when slogger2 is started with either -d or -D.
Note:

If you specify both SLOG2_ALLOC_TYPE_SHMEM and SLOG2_ALLOC_TYPE_PHYSICAL, the result of the OR is that SLOG2_ALLOC_TYPE_SHMEM overrides SLOG2_ALLOC_TYPE_PHYSICAL, so behavior will be as stated for SLOG2_ALLOC_TYPE_SHMEM.

You can use the SLOG2_ALLOC_TYPE environment variable to achieve the same result. That is, you can set SLOG2_ALLOC_TYPE to shmem to overrride the SLOG2_ALLOC_TYPE_PHYSICAL bit, but if you have set the SLOG2_ALLOC_TYPE_SHMEM bit, setting SLOG2_ALLOC_TYPE to phys has no effect.

SLOG2_ALLOC_TYPE_SHMEM
Don't back buffer sets against a known range of physical memory. Overrides the default behavior when slogger2 is started with either -d or -D.
See the note under SLOG2_ALLOC_TYPE_PHYSICAL above for behavior if both SLOG2_ALLOC_TYPE_SHMEM and SLOG2_ALLOC_TYPE_PHYSICAL are speficied.
SLOG2_DISCARD_NEWLINE
Discard newline (\n) characters.
Note: The newline characters are stripped on the post-processing side (i.e., by slog2_dump_logs_to_file() and slog2info). Newline characters in a string are replaced by a space; consecutive newline characters are replaced by a single space.
SLOG2_HINT_SKIP_BUFFER_0, SLOG2_HINT_SKIP_BUFFER_1, SLOG2_HINT_SKIP_BUFFER_2, SLOG2_HINT_SKIP_BUFFER_3
A hint to ignore buffer 0 through 3, respectively, when parsing. To force the parsing of these hidden/skipped buffers, invoke slog2info with the -v option.
SLOG2_LIMIT_RETRIES
Limit the number of times that slogger2 retries to obtain a buffer. Use the max_retries member of the slog2_buffer_set_config_t structure to specify the limit.
There can be contention between threads when they're trying to write to a buffer, or between threads trying to write and another utility that's reading and dynamically following new writes (e.g,. with slog2info -w), although the latter is extremely unlikely to cause issues. The SLOG2_LIMIT_RETRIES flag ensures that in the extremely unlikely event that a thread can never obtain the right to write to the buffer or to update the tracker for dynamically following, it won't loop infinitely.
SLOG2_QUIET
Don't emit error information on stderr for the buffer set that's being configured.
SLOG2_TRY_REUSE_BUFFER_SET
Before registering a new buffer set, try to find and reuse an existing buffer set in this process having an identical buffer set configuration.

slog2_buffer_config_t and slog2_buffer_set_config_t structures

The slog2_buffer_config_t structure contains the configuration data for a single slog2 buffer:

typedef struct
{
    const char    *buffer_name;
    int            num_pages;
} slog2_buffer_config_t;

The fields include:

buffer_name
The name you want to use for the buffer.
num_pages
The number of 4 KB pages this buffer contains.
Note: This is not necessarily the number of system pages because some architectures support larger page sizes (e.g., 64 KB on AArch64). So this field doesn't necessarily equate to the number of MMU-managed pages. On systems where the system page size is not 4 KB, think of this field as 4 KB “blocks”.

The slog2_buffer_set_config_t structure contains the configuration data for a slog2 buffer set. Each buffer set contains one or more buffers; the maximum number of buffers is specified by SLOG2_MAX_BUFFERS.

typedef struct
{
    int                   num_buffers;
    const char           *buffer_set_name;
    uint8_t               verbosity_level;
    slog2_buffer_config_t buffer_config[ SLOG2_MAX_BUFFERS ];
    uint32_t              max_retries;
} slog2_buffer_set_config_t;
num_buffers
The number of buffers to configure.
buffer_set_name
The process name, or other descriptor. We recommend that you use the name of your process for this.
verbosity_level
The minimum severity to log; one of:
  • SLOG2_SHUTDOWN — shut down the system now (e.g., for OEM use).
  • SLOG2_CRITICAL — unexpected unrecoverable error (e.g., hard disk error).
  • SLOG2_ERROR — unexpected recoverable error (e.g., you need to reset a hardware controller).
  • SLOG2_WARNING — expected error (e.g., parity error on a serial port).
  • SLOG2_NOTICE — warning (e.g., out of paper).
  • SLOG2_INFO — information (e.g., printing page 3).
  • SLOG2_DEBUG1 — debug messages (e.g., normal detail).
  • SLOG2_DEBUG2 — debug messages (e.g., fine detail).

All buffers in the set have the same level of verbosity.

buffer_config
An array of slog2_buffer_config_t structures that define the buffers.
max_retries
(QNX Neutrino 7.0.4 or later) The number of times that slogger2 retries to obtain a buffer if you specify SLOG2_LIMIT_RETRIES in the flags argument. A value of UINT32_MAX or (uint32_t)-1 means no limit.

If the number of retries is exceeded, calls to slog2c, slog2f, slog2fa, vslog2f, and vslog2fa fail with an error of EBUSY.

Returns:

0
Success.
-1
An error occurred (errno is set). The handle data isn't guaranteed.

Errors:

EACCES
Permission to create the shared memory object was denied.
EAGAIN
The shared memory mapping couldn't be locked in memory because of a lack of resources.
EBADF
The slogger2 channel no longer exists.
EFAULT
A fault occurred while the function was communicating with slogger2.
EINTR
The function was interrupted by a signal while connecting to slogger2, communicating with slogger2, or opening a shared memory object.
EINVAL
A parameter or a value in the configuration data structure was invalid.
EMFILE
All file descriptors available to the process were already open when the function was connecting to slogger2 or opening a shared memory object.
ENAMETOOLONG
There's a shared memory name collision, and it cannot be resolved.
ENFILE
One of the following occurred:
  • Too many files were open in the system when the function was connecting to slogger2 or opening a shared memory object.
  • The number of mapped regions reached the limit when the function was mapping shared memory.
ENOENT
The slogger2 file doesn't exist (slogger2 is probably not running), or the shared memory file hasn't been created.
ENOMEM
One of the following occurred:
  • An instance of slog2 couldn't be created.
  • The shared memory mapping couldn't be locked into memory because there wasn't enough memory.
  • slogger2 couldn't allocate memory for itself.
  • The shared memory object couldn't be resized.
ENOSPC
Not enough space to create the shared memory object.
EPERM
The process lacks permission to map the shared memory object, or slogger2 couldn't change permissions on a shared memory object.
ESRCH
slogger2 died while the function was waiting for a reply from it.
ESRVRFAULT
A fault occurred in slogger2's address space while the function was communicating with it.

Examples:

#include <stdio.h>
#include <stdlib.h>
#include <sys/slog2.h>
 
/* Pull in the executable name. */
extern char *__progname;
 
int main(int argc, char **argv)
{
    slog2_buffer_set_config_t   buffer_config;
    slog2_buffer_t              buffer_handle[2];
 
    /* A local variable used to demonstrate the slog2fa() API call below. */
    int                         some_number = 5108;
 
    /* You should use the name of your process to name the buffer set. */
    buffer_config.buffer_set_name = __progname;
 
    /* These two buffers are configured below. */
    buffer_config.num_buffers = 2;
 
    /* Request an initial verbosity level. */
      
    buffer_config.verbosity_level = SLOG2_INFO;
 
    /* Configure the first buffer, using 7 x 4 KB pages.  This larger 
       buffer will be used for very chatty logging. Our goal is to have
       30-60 seconds of history at any given time, so we will want to
       log at a rate of around one log line with a string of 16 bytes
       long every 150 milliseconds.
    */

    buffer_config.buffer_config[0].buffer_name = "hi_rate_logging";
    buffer_config.buffer_config[0].num_pages = 7;
 
    /* Configure the second buffer, which we will use for high-level 
       info logging that is very infrequent, but we want a longer history
       (hours or maybe even over a day or two). This buffer uses 1 x 4 KB.
    */

    buffer_config.buffer_config[1].buffer_name = "lo_rate_logging";
    buffer_config.buffer_config[1].num_pages = 1;
 
    /* Register the buffer set. */

    if( -1 == slog2_register( &buffer_config, buffer_handle, 0 ) ) {
        fprintf( stderr, "Error registering slogger2 buffer!\n" );
        return -1;
    }
 
    /* slog2f()
       - is the SLOWEST (though most convenient) of the slog2 APIs
       - CANNOT be used with interrupts off because va_args handling
         could use interrupts
    */

    slog2f( buffer_handle[0], 0, SLOG2_INFO,
        "Writing a formatted string into the buffer: %s", argv[0] );
 
    /* slog2c()
       - is the FASTEST slog2 API
       - is interrupt safe
    */

    slog2c( buffer_handle[0], 0, SLOG2_INFO,
        "Writing a constant string into the buffer." );
 
   /* slog2fa()
      - provides a VERY FAST and INTERRUPT SAFE alternative to slog2f()
      - uses special formatting macros to ensure that va_args does
        NOT trigger interrupt use
   */

   slog2fa( buffer_handle[0], 0, SLOG2_WARNING, "string:%s, some_number:%d",
                                              SLOG2_FA_STRING( "Hello world" ),
                                              SLOG2_FA_SIGNED( some_number ),
                                              SLOG2_FA_END );
 
    /* Write something to the 'lo rate' buffer (i.e., buffer 1). */
    slog2c( buffer_handle[1], 0, SLOG2_NOTICE,
        "This string will be logged." );
 
    /* The verbosity level will prevent this from being written to the
       slog2 buffer (severity > verbosity_level). */

    slog2c( buffer_handle[0], 0, SLOG2_DEBUG1,
        "This string should not be logged." );
 
    return 0;
}

The example of slog2_parse_static_buffer() parses the logs produced by this program.

Classification:

QNX Neutrino

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes