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_set_config_t and slog2_buffer_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.
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 |