librnr  1.14.5
RoadNarrows Robotics Common Library 1
log.c File Reference

Logger definitions. More...

#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include "rnr/rnrconfig.h"
#include "rnr/log.h"
#include "rnr/new.h"

Go to the source code of this file.

Macros

#define LOG_VAR_FILENAME   LOGNS_PUT(LogFileName)
 define in namespace
 
#define LOG_VAR_FP   LOGNS_PUT(LogFp)
 define in namespace
 

Functions

static const char * LOGNS_PUT (LogFileName)
 Log File Name.
 
static FILE * LOGNS_PUT (LogFp)
 Opened Log file.
 
int LOG_SET_THRESHOLD (int nLevel)
 Set new logging threshold level. More...
 
int LOG_GET_THRESHOLD ()
 Get current logging threshold level. More...
 
void LOG_SET_COLOR_ENABLE (bool_t enable)
 Enable/disable logging in color. More...
 
void LOG_SET_TIMESTAMP_ENABLE (bool_t enable)
 Enable/disable log timestamps. More...
 
int LOG_SET_LOGFILE (const char *sLogFileName)
 Set new logging output file. More...
 
const char * LOG_GET_LOGFILE ()
 Get logging output stream file name. More...
 
void LOG_ATTACH_LOGFP (FILE *fp, const char *sFpFileName)
 Attach opened file pointer as the new logging output stream. More...
 
FILE * LOG_GET_LOGFP ()
 Get current logging output stream file pointer. More...
 
void LOGGER (const char *sFmt,...)
 Print loggging diagnostics, debug, error, and system error messages to log output stream.. More...
 
static int LogVaFmtType (char *sFmt)
 Parse function call argument format string to determine type. More...
 
void LOGGER_CALL (const char *sPreface, int nLevel, const char *sFile, int nLine, const char *sFuncName,...)
 Print function call diagnostics tracing to log output stream.. More...
 

Variables

int LOG_VAR_THRESHOLD = LOG_LEVEL_DFT
 Log threshold level (log iff level <= threshold)
 
bool_t LOG_VAR_COLOR_EN = LOG_COLOR_EN_DFT
 Log in color (false = disable, true = enable)
 
static bool_t LOG_VAR_TIMESTAMP_EN = LOG_TIMESTAMP_EN_DFT
 Timestamp logging (false = disable, true = enable)
 
static pthread_mutex_t MutexLog = PTHREAD_MUTEX_INITIALIZER
 

Detailed Description

Logger definitions.

LastChangedDate
2014-12-06 13:48:30 -0700 (Sat, 06 Dec 2014)
Rev
3823

Logging supports error and diagnostics (debugging) reports to stderr or a specified file. Logging reporting is filtered by a simple threshold level.

Author
Robin Knight (robin.nosp@m..kni.nosp@m.ght@r.nosp@m.oadn.nosp@m.arrow.nosp@m.s.co.nosp@m.m)

Definition in file log.c.

Function Documentation

void LOG_ATTACH_LOGFP ( FILE *  fp,
const char *  sFpFileName 
)

Attach opened file pointer as the new logging output stream.

Actual Identifier: <LOGNS>LogAttachLogFp()

Parameters
fpOpened FILE*.
sFpFileNameFile name associated with fp.

Definition at line 282 of file log.c.

References LOG_VAR_FILENAME, LOG_VAR_FP, and new_strdup().

283 {
284  LOG_VAR_FP = fp;
285  delete((char *)LOG_VAR_FILENAME);
286  LOG_VAR_FILENAME = new_strdup(sFpFileName);
287 }
#define LOG_VAR_FILENAME
define in namespace
Definition: log.c:63
char * new_strdup(const char *s)
Duplicate a string.
Definition: new.c:176
#define LOG_VAR_FP
define in namespace
Definition: log.c:64
const char* LOG_GET_LOGFILE ( )

Get logging output stream file name.

Actual Identifier: <LOGNS>LogGetFileName()

Returns
On success, returns 0. On failure, return -1 with errno set appropriately.

Definition at line 260 of file log.c.

References LOG_FILENAME_DFT, LOG_VAR_FILENAME, and NULL.

261 {
262  if( LOG_VAR_FILENAME != NULL )
263  {
264  return LOG_VAR_FILENAME;
265  }
266  else
267  {
268  return LOG_FILENAME_DFT;
269  }
270 }
#define LOG_VAR_FILENAME
define in namespace
Definition: log.c:63
#define NULL
null pointer
Definition: rnrconfig.h:199
#define LOG_FILENAME_DFT
default log filename
Definition: log.h:212
FILE* LOG_GET_LOGFP ( )

Get current logging output stream file pointer.

This function is handing if an application has some complicated output for the logging stream.

Actual Identifier: <LOGNS>LogGetLogFp()

Returns
FILE*

Definition at line 301 of file log.c.

References LOG_VAR_FP.

Referenced by init(), and NewSearchPathDList().

302 {
303  return LOG_VAR_FP;
304 }
#define LOG_VAR_FP
define in namespace
Definition: log.c:64
int LOG_GET_THRESHOLD ( )

Get current logging threshold level.

This function is always defined to safeley determine if logging is available.

Actual Identifier: <LOGNS>LogGetThresholdLevel()

Returns
Current logging threshold. If logging is not available, (i.e. LOG was not defined) then LOGGING_NA is returned.

Definition at line 142 of file log.c.

References LOG_VAR_THRESHOLD, and LOGGING_NA.

143 {
144 #ifdef LOG
145  return LOG_VAR_THRESHOLD;
146 #else
147  return LOGGING_NA;
148 #endif // LOG
149 }
int LOG_VAR_THRESHOLD
Log threshold level (log iff level <= threshold)
Definition: log.c:67
#define LOGGING_NA
logging not available (not compiled)
Definition: log.h:178
void LOG_SET_COLOR_ENABLE ( bool_t  enable)

Enable/disable logging in color.

This function is always defined to allow blind sets.

Actual Identifier: <LOGNS>LogSetColorEnable()

Parameters
enableEnable(true) or disable(false).

Definition at line 160 of file log.c.

References LOG_VAR_COLOR_EN.

Referenced by OptsLogDisableColor().

161 {
162 #ifdef LOG
163  LOG_VAR_COLOR_EN = enable;
164 #endif // LOG
165 }
bool_t LOG_VAR_COLOR_EN
Log in color (false = disable, true = enable)
Definition: log.c:70
int LOG_SET_LOGFILE ( const char *  sLogFileName)

Set new logging output file.

The file is opened and truncated.

This function is always defined allow blind sets.

Actual Identifier: <LOGNS>LogSetLogFile()

Todo:
On file open add time-stamp first entry.
Parameters
sLogFileNameName of new log file.
Returns
On success, returns 0. On failure, return -1 with errno set appropriately.

Definition at line 199 of file log.c.

References LOG_FILENAME_STDERR, LOG_FILENAME_STDOUT, LOG_VAR_FILENAME, LOG_VAR_FP, LOGDIAG1, LOGSYSERROR, new_strdup(), and NULL.

Referenced by OptsLogSetFile().

200 {
201 #ifdef LOG
202  FILE *fp;
203 
204  // already opened
205  if( (LOG_VAR_FILENAME != NULL) && !strcmp(sLogFileName, LOG_VAR_FILENAME) )
206  {
207  return 0;
208  }
209 
210  //
211  // "Open" new log file.
212  //
213  if( !strcmp(sLogFileName, LOG_FILENAME_STDERR) )
214  {
215  fp = stderr;
216  }
217  else if( !strcmp(sLogFileName, LOG_FILENAME_STDOUT) )
218  {
219  fp = stdout;
220  }
221  else if( (fp = fopen(sLogFileName, "a+")) == NULL )
222  {
223  LOGSYSERROR("%s", sLogFileName);
224  return -1;
225  }
226 
227  LOGDIAG1("--- End Of Log %s ---", LOG_VAR_FILENAME);
228 
229  //
230  // Close old log file.
231  //
232  if( (LOG_VAR_FILENAME != NULL)
235  {
236  fclose(LOG_VAR_FP);
237  }
238 
239  //
240  // Set new log file data
241  //
242  LOG_VAR_FP = fp;
243  delete((char *)LOG_VAR_FILENAME);
244  LOG_VAR_FILENAME = new_strdup(sLogFileName);
245  LOGDIAG1("--- Start Of Log %s ---", LOG_VAR_FILENAME);
246 #endif // LOG
247 
248  return 0;
249 }
#define LOG_VAR_FILENAME
define in namespace
Definition: log.c:63
char * new_strdup(const char *s)
Duplicate a string.
Definition: new.c:176
#define NULL
null pointer
Definition: rnrconfig.h:199
#define LOGDIAG1(fmt,...)
Standard Diagnostic Level 1 logging.
Definition: log.h:407
#define LOGSYSERROR(fmt,...)
Standard System Error logging.
Definition: log.h:509
#define LOG_FILENAME_STDOUT
&#39;stdout&#39; log filename
Definition: log.h:211
#define LOG_VAR_FP
define in namespace
Definition: log.c:64
#define LOG_FILENAME_STDERR
&#39;stderr&#39; log filename
Definition: log.h:210
int LOG_SET_THRESHOLD ( int  nLevel)

Set new logging threshold level.

All logging at the level <= threshold level will be enabled.

This function is always defined allow blind sets.

Actual Identifier: <LOGNS>LogSetThresholdLevel()

Parameters
nLevelNew threshold level.
Returns
New adjusted logging level. If logging is not availble (i.e. LOG was not defined) then LOGGING_NA is returned.

Definition at line 96 of file log.c.

References LOG_LEVEL_DIAG1, LOG_LEVEL_OFF, LOG_VAR_COLOR_EN, LOG_VAR_THRESHOLD, LOGARGS_DIAG, LOGARGS_DIAG_PLAIN, LOGGER(), and LOGGING_NA.

Referenced by CmdLog(), main(), and OptsLogSetLevel().

97 {
98 #ifdef LOG
99  int nOldLevel;
100 
101  nOldLevel = LOG_VAR_THRESHOLD;
102 
103  if( nLevel < LOG_LEVEL_OFF )
104  {
106  }
107  else
108  {
109  LOG_VAR_THRESHOLD = nLevel;
110  }
111 
112  if( (nOldLevel >= LOG_LEVEL_DIAG1) || (LOG_VAR_THRESHOLD >= LOG_LEVEL_DIAG1) )
113  {
114  if( LOG_VAR_COLOR_EN )
115  {
116  LOGGER(LOGARGS_DIAG(2, "Logging level set to %d", LOG_VAR_THRESHOLD));
117  }
118  else
119  {
120  LOGGER(LOGARGS_DIAG_PLAIN(2, "Logging level set to %d",
122  }
123  }
124 
125  return LOG_VAR_THRESHOLD;
126 #else
127  return LOGGING_NA;
128 #endif // LOG
129 }
#define LOGARGS_DIAG(level, fmt,...)
Standard diagnostic logging output arguments with compiled color.
Definition: log.h:269
#define LOG_LEVEL_OFF
turn off all non-error logging
Definition: log.h:179
#define LOGARGS_DIAG_PLAIN(level, fmt,...)
Standard diagnostic logging output arguments in plain text.
Definition: log.h:279
bool_t LOG_VAR_COLOR_EN
Log in color (false = disable, true = enable)
Definition: log.c:70
int LOG_VAR_THRESHOLD
Log threshold level (log iff level <= threshold)
Definition: log.c:67
#define LOGGING_NA
logging not available (not compiled)
Definition: log.h:178
#define LOG_LEVEL_DIAG1
diagnostic level 1
Definition: log.h:181
void LOGGER(const char *sFmt,...)
Print loggging diagnostics, debug, error, and system error messages to log output stream...
Definition: log.c:317
void LOG_SET_TIMESTAMP_ENABLE ( bool_t  enable)

Enable/disable log timestamps.

This function is always defined to allow blind sets.

Actual Identifier: <LOGNS>LogSetTimestampEnable()

Parameters
enableEnable(true) or disable(false).

Definition at line 176 of file log.c.

References LOG_VAR_TIMESTAMP_EN.

Referenced by OptsLogDisableTimestamp().

177 {
178 #ifdef LOG
179  LOG_VAR_TIMESTAMP_EN = enable;
180 #endif // LOG
181 }
static bool_t LOG_VAR_TIMESTAMP_EN
Timestamp logging (false = disable, true = enable)
Definition: log.c:73
void LOGGER ( const char *  sFmt,
  ... 
)

Print loggging diagnostics, debug, error, and system error messages to log output stream..

Actual Identifier: <LOGNS>LogPrintf()

Parameters
sFmtFormat string.
...Variable format arguments.

Definition at line 317 of file log.c.

References LOG_FILENAME_STDERR, LOG_FP_DFT, LOG_VAR_FILENAME, LOG_VAR_FP, LOG_WITH_TIMESTAMP, new_strdup(), and NULL.

Referenced by LOG_SET_THRESHOLD().

318 {
319  va_list ap;
320 
321  pthread_mutex_lock(&MutexLog);
322 
323  // lazy init
324  if( LOG_VAR_FP == NULL )
325  {
328  }
329 
330  if( LOG_WITH_TIMESTAMP() )
331  {
332  struct timespec tsNow;
333 
334  clock_gettime(CLOCK_REALTIME, &tsNow);
335  fprintf(LOG_VAR_FP, "[%ld.%09ld] ", tsNow.tv_sec, tsNow.tv_nsec);
336  }
337 
338  va_start(ap, sFmt);
339  vfprintf(LOG_VAR_FP, sFmt, ap);
340  fprintf(LOG_VAR_FP, "\n");
341  va_end(ap);
342  fflush(LOG_VAR_FP);
343 
344  pthread_mutex_unlock(&MutexLog);
345 }
#define LOG_WITH_TIMESTAMP()
Test if logging includes timestamps.
Definition: log.h:205
#define LOG_FP_DFT
default log out stream
Definition: log.h:213
#define LOG_VAR_FILENAME
define in namespace
Definition: log.c:63
char * new_strdup(const char *s)
Duplicate a string.
Definition: new.c:176
#define NULL
null pointer
Definition: rnrconfig.h:199
#define LOG_VAR_FP
define in namespace
Definition: log.c:64
#define LOG_FILENAME_STDERR
&#39;stderr&#39; log filename
Definition: log.h:210
void LOGGER_CALL ( const char *  sPreface,
int  nLevel,
const char *  sFile,
int  nLine,
const char *  sFuncName,
  ... 
)

Print function call diagnostics tracing to log output stream..

Actual Identifier: <LOGNS>LogCallPrintf()

Parameters
sPrefaceLogging preface string.
nLevelLogging level.
sFileFile holding function definition.
nLineFile line number.
sFuncNameFunction name string.
...Pairs of function format_string,argument pairs terminated by NULL,0

Definition at line 445 of file log.c.

References LOG_COLOR_DIAG, LOG_COLOR_POST, LOG_FILENAME_STDERR, LOG_FP_DFT, LOG_VAR_FILENAME, LOG_VAR_FP, LOG_WITH_TIMESTAMP, LogColorEnable, LogVaFmtType(), new_strdup(), and NULL.

447 {
448  bool_t bIsOk = true;
449  char *sArgFmt;
450  char *sSep = "";
451  va_list ap;
452 
453  pthread_mutex_lock(&MutexLog);
454 
455  // lazy init
456  if( LOG_VAR_FP == NULL )
457  {
460  }
461 
462  if( LOG_WITH_TIMESTAMP() )
463  {
464  struct timespec tsNow;
465 
466  clock_gettime(CLOCK_REALTIME, &tsNow);
467  fprintf(LOG_VAR_FP, "[%ld.%09ld] ", tsNow.tv_sec, tsNow.tv_nsec);
468  }
469 
470  va_start(ap, sFuncName);
471 
472  if( LogColorEnable )
473  {
474  fprintf(LOG_VAR_FP,
475  "%s" LOG_COLOR_DIAG "Diag%d: %s[%d] " LOG_COLOR_POST "%s(",
476  sPreface, nLevel-1, sFile, nLine, sFuncName);
477  }
478  else
479  {
480  fprintf(LOG_VAR_FP,
481  "%s" "Diag%d: %s[%d] " "%s(",
482  sPreface, nLevel-1, sFile, nLine, sFuncName);
483  }
484 
485  while( bIsOk )
486  {
487  // function call argument format
488  sArgFmt = va_arg(ap, char *);
489  if( sArgFmt == NULL )
490  {
491  break;
492  }
493 
494  // separator
495  fprintf(LOG_VAR_FP, "%s", sSep);
496  sSep = ",";
497 
498  // function call argument type and print
499  switch( LogVaFmtType(sArgFmt) )
500  {
501  case 'd':
502  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, int));
503  break;
504  case 'l':
505  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, long));
506  break;
507  case 'u':
508  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, unsigned int));
509  break;
510  case 'U':
511  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, unsigned long));
512  break;
513  case 'f':
514  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, double));
515  break;
516  case 's':
517  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, char *));
518  break;
519  case 'p':
520  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, void *));
521  break;
522  case 'c':
523  fprintf(LOG_VAR_FP, sArgFmt, va_arg(ap, int));
524  break;
525  default:
526  fprintf(LOG_VAR_FP, "UNKNOWN_FORMAT");
527  bIsOk = false;
528  break;
529  }
530  }
531 
532  fprintf(LOG_VAR_FP, ")\n");
533  va_end(ap);
534 
535  fflush(LOG_VAR_FP);
536 
537  pthread_mutex_unlock(&MutexLog);
538 }
#define LOG_WITH_TIMESTAMP()
Test if logging includes timestamps.
Definition: log.h:205
#define LOG_FP_DFT
default log out stream
Definition: log.h:213
#define LOG_VAR_FILENAME
define in namespace
Definition: log.c:63
char * new_strdup(const char *s)
Duplicate a string.
Definition: new.c:176
#define NULL
null pointer
Definition: rnrconfig.h:199
#define LOG_COLOR_POST
color escape sequence postfix
Definition: log.h:231
int bool_t
"boolean" T/F
Definition: rnrconfig.h:187
#define LOG_VAR_FP
define in namespace
Definition: log.c:64
static int LogVaFmtType(char *sFmt)
Parse function call argument format string to determine type.
Definition: log.c:359
bool_t LogColorEnable
color logging is [not] enabled
#define LOG_FILENAME_STDERR
&#39;stderr&#39; log filename
Definition: log.h:210
#define LOG_COLOR_DIAG
diagnostics color
Definition: log.h:247
static int LogVaFmtType ( char *  sFmt)
static

Parse function call argument format string to determine type.

Type range is determined by what va_arg() takes.

Parameters
sFmtArgument format string.
Returns
Quasi-specifier as in fprintf(3). Returns '?' for unreckonized formats.

Definition at line 359 of file log.c.

Referenced by LOGGER_CALL().

360 {
361  bool_t bPercent = false;
362  char *s;
363  char last;
364  char length = 'i';
365 
366  for(last=0, s=sFmt; s && *s; last = *s, s++)
367  {
368  if( *s == '%')
369  {
370  if( last == '%' )
371  {
372  bPercent = false;
373  length = 'i';
374  }
375  else
376  {
377  bPercent = true;
378  }
379  }
380 
381  else if( bPercent )
382  {
383  switch( *s )
384  {
385  case 'h':
386  length = 'h'; // short
387  break;
388  case 'l':
389  length = 'l'; // long
390  break;
391  case 'c':
392  return 'c'; // char
393  case 'e':
394  case 'E':
395  case 'f':
396  case 'F':
397  case 'g':
398  case 'G':
399  return 'f'; // double
400  case 'd':
401  case 'i':
402  switch( length )
403  {
404  case 'l':
405  return 'l'; // long integer
406  default:
407  return 'd'; // integer
408  }
409  break;
410  case 'o':
411  case 'u':
412  case 'x':
413  case 'X':
414  switch( length )
415  {
416  case 'l':
417  return 'U'; // long unsigned
418  default:
419  return 'u'; // unsigned integer
420  }
421  break;
422  case 's':
423  return 's'; // string
424  case 'p':
425  return 'p'; // pointer
426  }
427  }
428  }
429  return '?';
430 }
int bool_t
"boolean" T/F
Definition: rnrconfig.h:187