CDI SDK
SDK for transporting chunks of data reliably and with low latency using a polled mode network driver.
Loading...
Searching...
No Matches
logger.c File Reference

This file contains definitions and functions for a logger and associated logs. More...

#include "cdi_logger_api.h"
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include "cdi_core_api.h"
#include "cdi_os_api.h"
#include "list_api.h"
#include "singly_linked_list_api.h"

Data Structures

struct  CdiLoggerState
 Structure used to hold state data for a single logger. More...
 
struct  ComponentStateData
 Structure used to hold component state data for a single component. More...
 
struct  LogCallbackData
 Structure used to hold state data that is unique to a callback log. Calback log CdiLogState instances that use the same log message callback address and user callback parameter will share a single instance of this data. More...
 
struct  LogFileData
 Structure used to hold state data that is unique to a file log. File log CdiLogState instances that use the same filename will share a single instance of this data. More...
 
struct  CdiLogState
 Structure used to hold state data for a single log of any type (stdout, callback or file). More...
 
struct  CdiMultilineLogBufferState
 Structure used to hold a buffer for a multiline log message. More...
 

Macros

#define MAX_LOG_TIME_STRING_LENGTH   (64)
 Maximum length of log time string.
 
#define MAX_LOG_FILENAME_LENGTH   (1024)
 Maximum length of log filename string.
 
#define MULTILINE_LOG_MESSAGE_BUFFER_GROW_SIZE   (20*CDI_MAX_LOG_STRING_LENGTH)
 Maximum grow length of log buffer.
 

Typedefs

typedef struct CdiLogState CdiLogState
 Forward declaration to create pointer to log state when used.
 
typedef struct CdiLoggerState CdiLoggerState
 Forward declaration to create pointer to logger state when used.
 

Functions

static CdiLogHandle GetLogHandleToUse (CdiLogHandle handle)
 
static bool LogBufferGrow (CdiMultilineLogBufferState *state_ptr)
 
static CdiMultilineLogBufferStateLogBufferGet (void)
 
static void LogBufferPut (CdiMultilineLogBufferState *log_buffer_ptr)
 
static int GetUsageRefCount (CdiLogHandle handle)
 
static int IncDecUsageRefCount (CdiLogHandle handle, bool increment)
 
static CdiLogStateListGetNextEntry (CdiListIterator *iterator_ptr)
 
static LogCallbackDataSearchForExistingLogCallbackInList (const CdiLogCallbackData *callback_data_ptr)
 
static LogFileDataSearchForExistingLogFileInList (const char *log_filename_str)
 
static bool CreateCommonLog (CdiLoggerHandle logger_handle, CdiConnectionHandle con_handle, CdiLogMethod log_method, CdiLogHandle *ret_log_handle_ptr)
 
static int AppendLineEnding (char *log_msg_str, int buffer_size, int char_count)
 
static int WriteLineToBuffer (char *dest_log_buffer_str, int dest_buffer_size, CdiLogLevel log_level, bool multiline, char *log_str)
 
static int LogToBuffer (CdiLogHandle handle, const char *function_name_str, int line_number, const char *format_str, va_list vars, char *dest_log_msg_buffer_str)
 
static void OutputToFileHandle (CdiFileID file_handle, CdiLogLevel log_level, const char *log_str, int char_count)
 Send the log message to stderr if enabled.
 
static void WriteLineToLog (CdiLogHandle handle, CdiLogLevel log_level, bool multiline, char *log_str)
 
static void InvokeLogCallback (CdiLogHandle handle, CdiLogComponent component, CdiLogLevel log_level, const char *function_name_str, int line_number, int line_count, const char *message_str)
 
bool CdiLoggerInitialize (void)
 
bool CdiLoggerCreate (CdiLogLevel default_log_level, CdiLoggerHandle *ret_logger_handle_ptr)
 
bool CdiLoggerCreateLog (CdiLoggerHandle logger_handle, CdiConnectionHandle con_handle, const CdiLogMethodData *log_method_data_ptr, CdiLogHandle *ret_log_handle_ptr)
 
bool CdiLoggerCreateFileLog (CdiLoggerHandle logger_handle, const char *filename_str, CdiLogHandle *ret_log_handle_ptr)
 
void CdiLogger (CdiLogHandle handle, CdiLogComponent component, CdiLogLevel log_level, const char *function_name_str, int line_number, const char *format_str,...)
 
void CdiLoggerMultilineBegin (CdiLogHandle handle, CdiLogComponent component, CdiLogLevel log_level, const char *function_name_str, int line_number, CdiLogMultilineState *state_ptr)
 
void CdiLoggerMultiline (CdiLogMultilineState *state_ptr, const char *format_str,...)
 
char * CdiLoggerMultilineGetBuffer (CdiLogMultilineState *state_ptr)
 
void CdiLoggerMultilineEnd (CdiLogMultilineState *state_ptr)
 
void CdiLoggerLogFromCallback (CdiLogHandle handle, const CdiLogMessageCbData *cb_data_ptr)
 
bool CdiLoggerThreadLogSet (CdiLogHandle handle)
 
void CdiLoggerThreadLogUnset (void)
 
CdiLogHandle CdiLoggerThreadLogGet (void)
 
bool CdiLoggerIsEnabled (CdiLogHandle handle, CdiLogComponent component, CdiLogLevel log_level)
 
CdiReturnStatus CdiLoggerComponentEnable (CdiLogHandle handle, CdiLogComponent component, bool enable)
 
bool CdiLoggerComponentIsEnabled (CdiLogHandle handle, CdiLogComponent component)
 
CdiReturnStatus CdiLoggerLevelSet (CdiLogHandle handle, CdiLogComponent component, CdiLogLevel level)
 
CdiReturnStatus CdiLoggerComponentEnableGlobal (CdiLogComponent component, bool enable)
 
CdiReturnStatus CdiLoggerLevelSetGlobal (CdiLogComponent component, CdiLogLevel level)
 
CdiReturnStatus CdiLoggerStderrEnable (bool enable, CdiLogLevel level)
 
void CdiLoggerDestroyLog (CdiLogHandle handle)
 
void CdiLoggerDestroyLogger (CdiLoggerHandle logger_handle)
 
void CdiLoggerFlushAllFileLogs (void)
 
void CdiLoggerShutdown (bool force)
 

Variables

static CdiStaticMutexType logger_context_mutex_lock = CDI_STATIC_MUTEX_INITIALIZER
 Statically allocated mutex used to make initialization of logger data thread-safe.
 
static int initialization_ref_count = 0
 Logger module initialization reference count. If zero, logger has not been initialized. If 1 or greater, logger has been initialized.
 
static CdiCsID log_state_list_lock = NULL
 Lock used to protect multi-thread access to the log state list.
 
static CdiList log_state_list
 List of log state objects (CdiLogState).
 
static CdiLogHandle stdout_log_handle = NULL
 stdout log handle.
 
static LogFileData stdout_log_file_data
 stdout log file data.
 
static bool log_thread_data_valid = false
 If true, log_thread_data is valid (it can be zero and be valid).
 
static CdiThreadData log_thread_data = 0
 Data used to hold pointer to CdiLogState for each thread.
 
static CdiCsID multiline_free_list_lock = NULL
 Lock used to protect multi-thread access to multiline_free_list.
 
static CdiSinglyLinkedList multiline_free_list = { 0 }
 List of pointers to multiline free log line structures (CdiMultilineLogBufferState).
 
static ComponentStateData global_component_state_array [kLogComponentLast]
 Array of global, default component state data.
 
static bool stderr_enable = false
 Enable output to stderr in addition to log files (if log files are enabled).
 
static CdiLogLevel stderr_log_level = kLogLast
 Log level to output to stderr.
 
static int time_string_length = -1
 String length of this session's time-date.
 

Detailed Description

This file contains definitions and functions for a logger and associated logs.

Function Documentation

◆ AppendLineEnding()

static int AppendLineEnding ( char * log_msg_str,
int buffer_size,
int char_count )
static

Append line ending and new '\0' to a log message string at the specified character offset. Assumes the size of the string cannot exceed buffer_size characters in length. It will overwrite the last character if char_count is at the end of the buffer.

Parameters
log_msg_strPointer to log message string.
buffer_sizeSize of log message buffer in bytes.
char_countOffset to place the linefeed and new '\0'.
Returns
Adjusted character count.

◆ CdiLogger()

void CdiLogger ( CdiLogHandle handle,
CdiLogComponent component,
CdiLogLevel log_level,
const char * function_name_str,
int line_number,
const char * format_str,
... )

Function used to generate a formatted log line.

Parameters
handleLog handle.
componentComponent that is generating this message.
log_levelLevel of logging for this message.
function_name_strPointer to name of function the log line is being generated from. If NULL, function name and source code line number are not used.
line_numberSource code line number the log message is being generated from.
format_strPointer to string used for formatting the message.
The remaining parameters contain a variable length list of arguments used by the format string to generate the log message.

◆ CdiLoggerComponentEnable()

CdiReturnStatus CdiLoggerComponentEnable ( CdiLogHandle handle,
CdiLogComponent component,
bool enable )

◆ CdiLoggerComponentEnableGlobal()

CdiReturnStatus CdiLoggerComponentEnableGlobal ( CdiLogComponent component,
bool enable )

◆ CdiLoggerComponentIsEnabled()

bool CdiLoggerComponentIsEnabled ( CdiLogHandle handle,
CdiLogComponent component )

◆ CdiLoggerCreate()

bool CdiLoggerCreate ( CdiLogLevel default_log_level,
CdiLoggerHandle * ret_logger_handle_ptr )

Create an instance of the logger.

Parameters
default_log_levelThe default log level to use.
ret_logger_handle_ptrPointer to returned handle of the new logger.
Returns
true successfully initialized; false if not.

◆ CdiLoggerCreateFileLog()

bool CdiLoggerCreateFileLog ( CdiLoggerHandle logger_handle,
const char * filename_str,
CdiLogHandle * ret_log_handle_ptr )

Create a file log.

Parameters
logger_handleHandle of logger to create file log in.
filename_strString representing the log file to create. If NULL, then output will be directed to stdout.
ret_log_handle_ptrPointer to returned handle of the new log.
Returns
true successfully initialized; false if not.

◆ CdiLoggerCreateLog()

bool CdiLoggerCreateLog ( CdiLoggerHandle logger_handle,
CdiConnectionHandle con_handle,
const CdiLogMethodData * log_method_data_ptr,
CdiLogHandle * ret_log_handle_ptr )

Create a log using the specified log configuration data.

Parameters
logger_handleHandle of logger to create log in.
con_handleHandle of connection to associate with this log. If NULL, the global log is assumed.
log_method_data_ptrPointer to log method configuration data.
ret_log_handle_ptrPointer to returned handle of the new log.
Returns
true if successful, false if not.

◆ CdiLoggerDestroyLog()

void CdiLoggerDestroyLog ( CdiLogHandle handle)

Closes a log file and destroys the resources used by the instance of the specified log.

Parameters
handleLog handle.

◆ CdiLoggerDestroyLogger()

void CdiLoggerDestroyLogger ( CdiLoggerHandle logger_handle)

Destroys the resources used by the instance of the specified logger.

Parameters
logger_handleLogger handle.

◆ CdiLoggerFlushAllFileLogs()

void CdiLoggerFlushAllFileLogs ( void )

Flush all file logs.

◆ CdiLoggerInitialize()

bool CdiLoggerInitialize ( void )

Initialize the logger. Must be called once before using any other functions in the logger.

◆ CdiLoggerIsEnabled()

bool CdiLoggerIsEnabled ( CdiLogHandle handle,
CdiLogComponent component,
CdiLogLevel log_level )

Determine if a specific log component and level is enabled for logging.

Parameters
handleLog handle.
componentComponent to check.
log_levelLevel to check.
Returns
True if enabled, otherwise false.

◆ CdiLoggerLevelSet()

CdiReturnStatus CdiLoggerLevelSet ( CdiLogHandle handle,
CdiLogComponent component,
CdiLogLevel level )
See also
CdiLogLevelSet

◆ CdiLoggerLevelSetGlobal()

CdiReturnStatus CdiLoggerLevelSetGlobal ( CdiLogComponent component,
CdiLogLevel level )

◆ CdiLoggerLogFromCallback()

void CdiLoggerLogFromCallback ( CdiLogHandle handle,
const CdiLogMessageCbData * cb_data_ptr )

Generate a formatted log line from logger callback data.

Parameters
handleLog handle to write the message to. Must be using a kLogMethodStdout or kLogMethodFile log method.
cb_data_ptrLogger callback data used to generate the log message.

◆ CdiLoggerMultiline()

void CdiLoggerMultiline ( CdiLogMultilineState * state_ptr,
const char * format_str,
... )

Add a line to a multiline log message buffer.

Parameters
state_ptrPointer to multiline state data created using CdiLoggerMultilineBegin().
format_strPointer to string used for formatting the message.
The remaining parameters contain a variable length list of arguments used by the format string to generate the console message.

◆ CdiLoggerMultilineBegin()

void CdiLoggerMultilineBegin ( CdiLogHandle handle,
CdiLogComponent component,
CdiLogLevel log_level,
const char * function_name_str,
int line_number,
CdiLogMultilineState * state_ptr )

Begin a multiline log message, creating a buffer to hold the log message lines.

Parameters
handleLog handle.
componentComponent that is generating this message.
log_levelLevel of logging for this message.
function_name_strPointer to name of function the log line is being generated from. If NULL, function name and source code line number are not used.
line_numberSource code line number the log message is being generated from.
state_ptrPointer to address where to write returned multiline state data.

◆ CdiLoggerMultilineEnd()

void CdiLoggerMultilineEnd ( CdiLogMultilineState * state_ptr)

End the multiline lo message and write to the log as a single message. Resources used by the multiline log will be released.

Parameters
state_ptrPointer to multiline state data created using CdiLoggerMultilineBegin().

◆ CdiLoggerMultilineGetBuffer()

char * CdiLoggerMultilineGetBuffer ( CdiLogMultilineState * state_ptr)

Return pointer to multiline log buffer. Marks the buffer as used, so CdiLoggerMultilineEnd() won't generate any output.

Parameters
state_ptrPointer to multiline state data created using CdiLoggerMultilineBegin().
Returns
Pointer to log buffer or NULL when logger is disabled.

◆ CdiLoggerShutdown()

void CdiLoggerShutdown ( bool force)

Shutdown the logger. Must be called once for each time CdiLoggerInitialize() has been called. An internal reference counter is maintained. When it reaches zero or the provided "force" parameter is true, the resources are freed.

Parameters
forceUse true to forcibly shutdown the logger closing any open files. Should only be used in abnormal shutdown conditions, otherwise should always be false.

◆ CdiLoggerStderrEnable()

CdiReturnStatus CdiLoggerStderrEnable ( bool enable,
CdiLogLevel level )

◆ CdiLoggerThreadLogGet()

CdiLogHandle CdiLoggerThreadLogGet ( void )

Get log handle associated with the calling thread.

Returns
Log handle associated with calling thread or NULL when the logger has not been initialized.

◆ CdiLoggerThreadLogSet()

bool CdiLoggerThreadLogSet ( CdiLogHandle handle)

Associate the specified log with the calling thread. Subsequent calls to non-global CdiLog functions by this thread will write to the specified log.

Parameters
handleLog handle.
Returns
true successfully initialized; false if not.

◆ CdiLoggerThreadLogUnset()

void CdiLoggerThreadLogUnset ( void )

Remove any association of the calling thread with a logger. Subsequent calls to non-global CdiLog functions by this thread will write to the global logger (if one exists) or to stdout.

◆ CreateCommonLog()

static bool CreateCommonLog ( CdiLoggerHandle logger_handle,
CdiConnectionHandle con_handle,
CdiLogMethod log_method,
CdiLogHandle * ret_log_handle_ptr )
static

Create the common log data for a new CdiLogState instance.

Parameters
logger_handleHandle of logger.
con_handleHandle of connection to associate this log to. Use NULL if no connection.
log_methodMethod to use for the log (file, callback or stdout).
ret_log_handle_ptrPointer to returned log handle.
Returns
True if successful, otherwise false.

◆ GetLogHandleToUse()

static CdiLogHandle GetLogHandleToUse ( CdiLogHandle handle)
static

Get the log handle to use. If the specified handle is NULL, check the global handle. If that handle is also NULL then default to using the stdout log handle.

Parameters
handleCurrent Log handle.
Returns
Log handle to use.

◆ GetUsageRefCount()

static int GetUsageRefCount ( CdiLogHandle handle)
inlinestatic

Given a log handle, return

Parameters
handleLog handle.
Returns
Pointer to usage_ref_count, or NULL.

◆ IncDecUsageRefCount()

static int IncDecUsageRefCount ( CdiLogHandle handle,
bool increment )
inlinestatic

Given a log handle, increment or decrement its usage reference count and return the new value. NOTE: Before calling this function, the critical section called "log_state_list_lock" must be reserved.

Parameters
handleLog handle.
incrementtrue=increment, false=decrement
Returns
New reference count.

◆ InvokeLogCallback()

static void InvokeLogCallback ( CdiLogHandle handle,
CdiLogComponent component,
CdiLogLevel log_level,
const char * function_name_str,
int line_number,
int line_count,
const char * message_str )
static

Invoke a user registered log callback function to send a log message.

Parameters
handleLog handle. If NULL, stdout is used.
log_levellog level of this log message.
componentComponent that generated the message.
function_name_strPointer to name of function that generated the message.
line_numberSource code line number that generated the message.
line_countNumber of lines in the message.
message_strPointer to log message string to write. If it contains multiple lines, each line must be terminated with a '\0'.

◆ ListGetNextEntry()

static CdiLogState * ListGetNextEntry ( CdiListIterator * iterator_ptr)
static

Get next entry in the log state list.

Parameters
iterator_ptrPointer to CdiLogState list iterator. Must have been initialized using CdiListIteratorInit().
Returns
Pointer to next CdiLogState object, otherwise NULL.

◆ LogBufferGet()

static CdiMultilineLogBufferState * LogBufferGet ( void )
static

Get a log buffer from the dynamic pool.

Returns
CdiMultilineLogBufferState* Pointer to returned log buffer. If NULL, unable to allocate memory.

◆ LogBufferGrow()

static bool LogBufferGrow ( CdiMultilineLogBufferState * state_ptr)
static

Allocate memory for a log buffer. If the pointer to the buffer is currently NULL, a new buffer is created. Otherwise the size of the existing buffer is increased by re-allocating memory and copying the existing data to the new buffer.

Parameters
state_ptr
Returns
bool True if successfully grew buffer, otherwise false.

◆ LogBufferPut()

static void LogBufferPut ( CdiMultilineLogBufferState * log_buffer_ptr)
static

Return a log buffer to the dynamic pool.

Parameters
log_buffer_ptrPointer to log buffer to return to pool.

◆ LogToBuffer()

static int LogToBuffer ( CdiLogHandle handle,
const char * function_name_str,
int line_number,
const char * format_str,
va_list vars,
char * dest_log_msg_buffer_str )
static

Write a log message with optional source code function name and line number to a buffer.

Parameters
handleLog handle.
function_name_strPointer to name of function the log line is being generated from. If NULL, function name and source code line number are not used.
line_numberSource code line number the log message is being generated from.
format_strPointer to string used for formatting the message.
varsVariable length list of arguments used to generate the log message from the format_str.
dest_log_msg_buffer_strPointer to where to write the formatted log message to.
Returns
Number of characters written to the buffer, including the string terminator '\0'.

◆ OutputToFileHandle()

static void OutputToFileHandle ( CdiFileID file_handle,
CdiLogLevel log_level,
const char * log_str,
int char_count )
static

Send the log message to stderr if enabled.

Parameters
file_handleFile handle.
log_levellog level of this log message.
log_strPointer to log message string to send to stderr.
char_countNumber of characters in the message string, not including the terminating '\0'.

◆ SearchForExistingLogCallbackInList()

static LogCallbackData * SearchForExistingLogCallbackInList ( const CdiLogCallbackData * callback_data_ptr)
static

Search the log list for a matching log callback. NOTE: The lock called "log_state_list_lock" must be reserved before using this function.

Parameters
callback_data_ptrPointer to log callback data to search for.
Returns
If found, a pointer to the matching LogCallbackData structure is returned. Otherwise, NULL is returned.

◆ SearchForExistingLogFileInList()

static LogFileData * SearchForExistingLogFileInList ( const char * log_filename_str)
static

Search the log list for a matching log file. NOTE: The lock called "log_state_list_lock" must be reserved before using this function.

Parameters
log_filename_strPointer to log filename to search for.
Returns
If found, a pointer to the matching LogFileData structure is returned. Otherwise, NULL is returned.

◆ WriteLineToBuffer()

static int WriteLineToBuffer ( char * dest_log_buffer_str,
int dest_buffer_size,
CdiLogLevel log_level,
bool multiline,
char * log_str )
static

Write a single log message line to the specified log.

Parameters
dest_log_buffer_strLog handle. If NULL, stdout is used.
dest_buffer_sizeSize of destination buffer in bytes.
log_levellog level of this log message.
multilineTrue if this message is part of a multiline message.
log_strPointer to log message string to write.

◆ WriteLineToLog()

static void WriteLineToLog ( CdiLogHandle handle,
CdiLogLevel log_level,
bool multiline,
char * log_str )
static

Write a single log message line to the specified log.

Parameters
handleLog handle. If NULL, stdout is used.
log_levellog level of this log message.
multilineTrue if this message is part of a multiline message.
log_strPointer to log message string to write.