GNUnet 0.22.2
common_logging.c File Reference

error handling API More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include <regex.h>
Include dependency graph for common_logging.c:

Go to the source code of this file.

Data Structures

struct  CustomLogger
 Linked list of active loggers. More...
 
struct  LogDef
 Represents a single logging definition. More...
 

Macros

#define BULK_DELAY_THRESHOLD   (12 * 60 * 60 * 1000LL * 1000LL)
 After how many milliseconds do we always print that "message X was repeated N times"? Use 12h. More...
 
#define BULK_REPEAT_THRESHOLD   1000
 After how many repetitions do we always print that "message X was repeated N times"? (even if we have not yet reached the delay threshold) More...
 
#define BULK_TRACK_SIZE   256
 How many characters do we use for matching of bulk messages? More...
 
#define COMP_TRACK_SIZE   32
 How many characters do we use for matching of bulk components? More...
 
#define DATE_STR_SIZE   64
 How many characters can a date/time string be at most? More...
 
#define ROTATION_KEEP   3
 How many log files to keep? More...
 
#define PATH_MAX   4096
 Assumed maximum path length (for the log file name). More...
 
#define LEN
 

Functions

static enum GNUNET_ErrorType get_type (const char *log)
 Convert a textual description of a loglevel to the respective enumeration type. More...
 
void GNUNET_abort_ ()
 Abort the process, generate a core dump if possible. More...
 
static void resize_logdefs (void)
 Utility function - reallocates logdefs array to be twice as large. More...
 
static void log_rotate (const char *new_name)
 Rotate logs, deleting the oldest log. More...
 
const char * GNUNET_b2s (const void *buf, size_t buf_size)
 Convert a buffer to an 8-character string representative of the contents. More...
 
static enum GNUNET_GenericReturnValue setup_log_file (const struct tm *tm)
 Setup the log file. More...
 
static int add_definition (const char *lcomponent, const char *file, const char *function, int from_line, int to_line, int level, int force)
 Utility function - adds a parsed definition to logdefs array. More...
 
int GNUNET_get_log_call_status (int caller_level, const char *comp, const char *file, const char *function, int line)
 Decides whether a particular logging call should or should not be allowed to be made. More...
 
static int parse_definitions (const char *constname, int force)
 Utility function - parses a definition. More...
 
static void parse_all_definitions ()
 Utility function - parses GNUNET_LOG and GNUNET_FORCE_LOG. More...
 
enum GNUNET_GenericReturnValue GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
 Setup logging. More...
 
void GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls)
 Add a custom logger. More...
 
void GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls)
 Remove a custom logger. More...
 
static void output_message (enum GNUNET_ErrorType kind, const char *comp, const char *datestr, const char *msg)
 Actually output the log message. More...
 
static void flush_bulk (const char *datestr)
 Flush an existing bulk report to the output. More...
 
void GNUNET_log_skip (int n, int check_reset)
 Ignore the next n calls to the log function. More...
 
int GNUNET_get_log_skip ()
 Get the number of log calls that are going to be skipped. More...
 
static void mylog (enum GNUNET_ErrorType kind, const char *comp, const char *message, va_list va)
 Output a log message using the default mechanism. More...
 
void GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message,...)
 Main log function. More...
 
void GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp, const char *message,...)
 Log function that specifies an alternative component. More...
 
const char * GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
 Convert error type to string. More...
 
const char * GNUNET_h2s (const struct GNUNET_HashCode *hc)
 Convert a hash to a string (for printing debug messages). More...
 
const char * GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
 Convert a hash to a string (for printing debug messages). More...
 
const char * GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
 Convert a public key value to a string (for printing debug messages). More...
 
const char * GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
 Convert a public key value to a string (for printing debug messages). More...
 
const char * GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
 Convert a public key value to a string (for printing debug messages). More...
 
const char * GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
 Convert a public key value to a string (for printing debug messages). More...
 
const char * GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
 Convert a short hash value to a string (for printing debug messages). More...
 
const char * GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
 Convert a UUID to a string (for printing debug messages). More...
 
const char * GNUNET_h2s_full (const struct GNUNET_HashCode *hc)
 Convert a hash to a string (for printing debug messages). More...
 
const char * GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
 Convert a peer identity to a string (for printing debug messages). More...
 
const char * GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid)
 Convert a peer identity to a string (for printing debug messages). More...
 
const char * GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid)
 Convert a peer identity to a string (for printing debug messages). More...
 
const char * GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
 Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages). More...
 
void GNUNET_log_config_missing (enum GNUNET_ErrorType kind, const char *section, const char *option)
 Log error message about missing configuration option. More...
 
void GNUNET_log_config_invalid (enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
 Log error message about invalid configuration option value. More...
 
void GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid, struct GNUNET_AsyncScopeSave *old_scope)
 Set the async scope for the current thread. More...
 
void GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope)
 Clear the current thread's async scope. More...
 
void GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret)
 Generate a fresh async scope identifier. More...
 
void GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret)
 Get the current async scope. More...
 
size_t GNUNET_hex2b (const char *src, void *dst, size_t dstlen, int invert)
 Parse an ascii-encoded hexadecimal string into the buffer. More...
 
void GNUNET_print_bytes (const void *buf, size_t buf_len, int fold, int in_be)
 Print a byte string in hexadecimal ascii notation. More...
 
void GNUNET_util_cl_init (void)
 
void __attribute__ ((constructor))
 Initializer. More...
 
void GNUNET_util_cl_fini (void)
 
void __attribute__ ((destructor))
 Destructor. More...
 

Variables

static GNUNET_THREAD_LOCAL struct GNUNET_AsyncScopeSave current_async_scope
 Asynchronous scope of the current thread, or NULL if we have not entered an async scope yet. More...
 
static GNUNET_THREAD_LOCAL char last_bulk[256] __nonstring
 The last "bulk" error message that we have been logging. More...
 
static GNUNET_THREAD_LOCAL enum GNUNET_ErrorType last_bulk_kind
 Type of the last bulk message. More...
 
static GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time
 Time of the last bulk error message (0 for none) More...
 
static GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat
 Number of times that bulk message has been repeated since. More...
 
static GNUNET_THREAD_LOCAL char last_bulk_comp [32+1]
 Component when the last bulk was logged. More...
 
static char * component
 Running component. More...
 
static char * component_nopid
 Running component (without pid). More...
 
static char * log_file_name
 Format string describing the name of the log file. More...
 
static enum GNUNET_ErrorType min_level
 Minimum log level. More...
 
static struct CustomLoggerloggers
 Linked list of our custom loggres. More...
 
static GNUNET_THREAD_LOCAL int skip_log = 0
 Number of log calls to ignore. More...
 
static FILE * GNUNET_stderr
 File descriptor to use for "stderr", or NULL for none. More...
 
static struct LogDeflogdefs
 Dynamic array of logging definitions. More...
 
static int logdefs_size
 Allocated size of logdefs array (in units) More...
 
static int logdefs_len
 The number of units used in logdefs array. More...
 
static int gnunet_log_parsed
 GNUNET_YES if GNUNET_LOG environment variable is already parsed. More...
 
static int gnunet_force_log_parsed
 GNUNET_YES if GNUNET_FORCE_LOG environment variable is already parsed. More...
 
static int gnunet_force_log_present
 GNUNET_YES if at least one definition with forced == 1 is available. More...
 

Detailed Description

error handling API

Author
Christian Grothoff

Definition in file common_logging.c.

Macro Definition Documentation

◆ BULK_DELAY_THRESHOLD

#define BULK_DELAY_THRESHOLD   (12 * 60 * 60 * 1000LL * 1000LL)

After how many milliseconds do we always print that "message X was repeated N times"? Use 12h.

Definition at line 36 of file common_logging.c.

◆ BULK_REPEAT_THRESHOLD

#define BULK_REPEAT_THRESHOLD   1000

After how many repetitions do we always print that "message X was repeated N times"? (even if we have not yet reached the delay threshold)

Definition at line 43 of file common_logging.c.

◆ BULK_TRACK_SIZE

#define BULK_TRACK_SIZE   256

How many characters do we use for matching of bulk messages?

Definition at line 49 of file common_logging.c.

◆ COMP_TRACK_SIZE

#define COMP_TRACK_SIZE   32

How many characters do we use for matching of bulk components?

Definition at line 55 of file common_logging.c.

◆ DATE_STR_SIZE

#define DATE_STR_SIZE   64

How many characters can a date/time string be at most?

Definition at line 61 of file common_logging.c.

◆ ROTATION_KEEP

#define ROTATION_KEEP   3

How many log files to keep?

Definition at line 66 of file common_logging.c.

◆ PATH_MAX

#define PATH_MAX   4096

Assumed maximum path length (for the log file name).

Definition at line 72 of file common_logging.c.

◆ LEN

#define LEN
Value:
GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
(1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
#define GNUNET_MAX(a, b)

Function Documentation

◆ get_type()

static enum GNUNET_ErrorType get_type ( const char *  log)
static

Convert a textual description of a loglevel to the respective enumeration type.

Parameters
logloglevel to parse
Returns
GNUNET_ERROR_TYPE_INVALID if log does not parse

Definition at line 254 of file common_logging.c.

255{
256 if (NULL == log)
258 if (0 == strcasecmp (log, "DEBUG"))
260 if (0 == strcasecmp (log, "INFO"))
262 if (0 == strcasecmp (log, "MESSAGE"))
264 if (0 == strcasecmp (log, "WARNING"))
266 if (0 == strcasecmp (log, "ERROR"))
268 if (0 == strcasecmp (log, "NONE"))
271}
@ GNUNET_ERROR_TYPE_UNSPECIFIED
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_NONE
@ GNUNET_ERROR_TYPE_INVALID
@ GNUNET_ERROR_TYPE_MESSAGE
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_INVALID, GNUNET_ERROR_TYPE_MESSAGE, GNUNET_ERROR_TYPE_NONE, GNUNET_ERROR_TYPE_UNSPECIFIED, and GNUNET_ERROR_TYPE_WARNING.

Referenced by GNUNET_log_setup(), and parse_definitions().

Here is the caller graph for this function:

◆ resize_logdefs()

static void resize_logdefs ( void  )
static

Utility function - reallocates logdefs array to be twice as large.

Definition at line 289 of file common_logging.c.

290{
291 logdefs_size = (logdefs_size + 1) * 2;
292 logdefs = GNUNET_realloc (logdefs, logdefs_size * sizeof(struct LogDef));
293}
static int logdefs_size
Allocated size of logdefs array (in units)
static struct LogDef * logdefs
Dynamic array of logging definitions.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
Represents a single logging definition.

References GNUNET_realloc, logdefs, and logdefs_size.

Referenced by add_definition().

Here is the caller graph for this function:

◆ log_rotate()

static void log_rotate ( const char *  new_name)
static

Rotate logs, deleting the oldest log.

Parameters
new_namenew name to add to the rotation

Definition at line 302 of file common_logging.c.

303{
304 static char *rotation[ROTATION_KEEP];
305 static unsigned int rotation_off;
306 char *discard;
307
308 if ('\0' == *new_name)
309 return; /* not a real log file name */
310 discard = rotation[rotation_off % ROTATION_KEEP];
311 if (NULL != discard)
312 {
313 /* Note: can't log errors during logging (recursion!), so this
314 operation MUST silently fail... */
315 (void) unlink (discard);
316 GNUNET_free (discard);
317 }
318 rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
319 rotation_off++;
320}
#define ROTATION_KEEP
How many log files to keep?
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_free, GNUNET_strdup, and ROTATION_KEEP.

Referenced by setup_log_file().

Here is the caller graph for this function:

◆ setup_log_file()

static enum GNUNET_GenericReturnValue setup_log_file ( const struct tm *  tm)
static

Setup the log file.

Parameters
tmtimestamp for which we should setup logging
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 352 of file common_logging.c.

353{
354 static char last_fn[PATH_MAX + 1];
355 char fn[PATH_MAX + 1];
356 int altlog_fd;
357 int dup_return;
358 FILE *altlog;
359 char *leftsquare;
360
361 if (NULL == log_file_name)
362 return GNUNET_SYSERR;
363 if (0 == strftime (fn, sizeof(fn), log_file_name, tm))
364 return GNUNET_SYSERR;
365 leftsquare = strrchr (fn, '[');
366 if ((NULL != leftsquare) && (']' == leftsquare[1]))
367 {
368 char *logfile_copy = GNUNET_strdup (fn);
369
370 logfile_copy[leftsquare - fn] = '\0';
371 logfile_copy[leftsquare - fn + 1] = '\0';
372 snprintf (fn,
373 PATH_MAX,
374 "%s%d%s",
375 logfile_copy,
376 getpid (),
377 &logfile_copy[leftsquare - fn + 2]);
378 GNUNET_free (logfile_copy);
379 }
380 if (0 == strcmp (fn, last_fn))
381 return GNUNET_OK; /* no change */
382 log_rotate (last_fn);
383 strcpy (last_fn, fn);
385 {
386 fprintf (stderr,
387 "Failed to create directory for `%s': %s\n",
388 fn,
389 strerror (errno));
390 return GNUNET_SYSERR;
391 }
392 altlog_fd = open (fn,
393 O_APPEND | O_WRONLY | O_CREAT,
394 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
395
396 if (-1 != altlog_fd)
397 {
398 if (NULL != GNUNET_stderr)
399 fclose (GNUNET_stderr);
400 dup_return = dup2 (altlog_fd, 2);
401 (void) close (altlog_fd);
402 if (-1 != dup_return)
403 {
404 altlog = fdopen (2, "ab");
405 if (NULL == altlog)
406 {
407 (void) close (2);
408 altlog_fd = -1;
409 }
410 }
411 else
412 {
413 altlog_fd = -1;
414 }
415 }
416 if (-1 == altlog_fd)
417 {
419 return GNUNET_SYSERR;
420 }
421 GNUNET_stderr = altlog;
422 return GNUNET_OK;
423}
static void log_rotate(const char *new_name)
Rotate logs, deleting the oldest log.
static char * log_file_name
Format string describing the name of the log file.
static FILE * GNUNET_stderr
File descriptor to use for "stderr", or NULL for none.
#define PATH_MAX
Assumed maximum path length (for the log file name).
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:606
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

References GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_strerror_file, GNUNET_OK, GNUNET_stderr, GNUNET_strdup, GNUNET_SYSERR, log_file_name, log_rotate(), and PATH_MAX.

Referenced by GNUNET_log_setup(), and mylog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_definition()

static int add_definition ( const char *  lcomponent,
const char *  file,
const char *  function,
int  from_line,
int  to_line,
int  level,
int  force 
)
static

Utility function - adds a parsed definition to logdefs array.

Parameters
componentsee struct LogDef, can't be NULL
filesee struct LogDef, can't be NULL
functionsee struct LogDef, can't be NULL
from_linesee struct LogDef
to_linesee struct LogDef
levelsee struct LogDef, must be >= 0
forcesee struct LogDef
Returns
0 on success, regex-specific error otherwise

Definition at line 439 of file common_logging.c.

446{
447 struct LogDef n;
448 int r;
449
452 memset (&n, 0, sizeof(n));
453 if (0 == strlen (lcomponent))
454 lcomponent = (char *) ".*";
455 r = regcomp (&n.component_regex, (const char *) lcomponent, REG_NOSUB);
456 if (0 != r)
457 {
458 return r;
459 }
460 if (0 == strlen (file))
461 file = (char *) ".*";
462 r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
463 if (0 != r)
464 {
465 regfree (&n.component_regex);
466 return r;
467 }
468 if ((NULL == function) || (0 == strlen (function)))
469 function = (char *) ".*";
470 r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
471 if (0 != r)
472 {
473 regfree (&n.component_regex);
474 regfree (&n.file_regex);
475 return r;
476 }
477 n.from_line = from_line;
478 n.to_line = to_line;
479 n.level = level;
480 n.force = force;
481 logdefs[logdefs_len++] = n;
482 return 0;
483}
static int logdefs_len
The number of units used in logdefs array.
static void resize_logdefs(void)
Utility function - reallocates logdefs array to be twice as large.
int to_line
Highest line at which this definition matches.
int from_line
Lowest line at which this definition matches.
int force
1 if this definition comes from GNUNET_FORCE_LOG, which means that it overrides any configuration opt...
int level
Maximal log level allowed for calls that match this definition.

References LogDef::component_regex, LogDef::file_regex, LogDef::force, LogDef::from_line, LogDef::function_regex, LogDef::level, logdefs, logdefs_len, logdefs_size, resize_logdefs(), and LogDef::to_line.

Referenced by parse_definitions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_definitions()

static int parse_definitions ( const char *  constname,
int  force 
)
static

Utility function - parses a definition.

Definition format: component;file;function;from_line-to_line;level[/component...] All entries are mandatory, but may be empty. Empty entries for component, file and function are treated as "matches anything". Empty line entry is treated as "from 0 to INT_MAX" Line entry with only one line is treated as "this line only" Entry for level MUST NOT be empty. Entries for component, file and function that consist of a single character "*" are treated (at the moment) the same way empty entries are treated (wildcard matching is not implemented (yet?)). file entry is matched to the end of FILE. That is, it might be a base name, or a base name with leading directory names (some compilers define FILE to absolute file path).

Parameters
constnamename of the environment variable from which to get the string to be parsed
force1 if definitions found in constname are to be forced
Returns
number of added definitions

Definition at line 570 of file common_logging.c.

571{
572 char *def;
573 const char *tmp;
574 char *comp = NULL;
575 char *file = NULL;
576 char *function = NULL;
577 char *p;
578 char *start;
579 char *t;
580 short state;
581 int level;
582 int from_line, to_line;
583 int counter = 0;
584 int keep_looking = 1;
585
586 tmp = getenv (constname);
587 if (NULL == tmp)
588 return 0;
589 def = GNUNET_strdup (tmp);
590 from_line = 0;
591 to_line = INT_MAX;
592 for (p = def, state = 0, start = def; keep_looking; p++)
593 {
594 switch (p[0])
595 {
596 case ';': /* found a field separator */
597 p[0] = '\0';
598 switch (state)
599 {
600 case 0: /* within a component name */
601 comp = start;
602 break;
603
604 case 1: /* within a file name */
605 file = start;
606 break;
607
608 case 2: /* within a function name */
609 /* after a file name there must be a function name */
610 function = start;
611 break;
612
613 case 3: /* within a from-to line range */
614 if (strlen (start) > 0)
615 {
616 errno = 0;
617 from_line = strtol (start, &t, 10);
618 if ((0 != errno) || (from_line < 0))
619 {
620 GNUNET_free (def);
621 return counter;
622 }
623 if ((t < p) && ('-' == t[0]))
624 {
625 errno = 0;
626 start = t + 1;
627 to_line = strtol (start, &t, 10);
628 if ((0 != errno) || (to_line < 0) || (t != p))
629 {
630 GNUNET_free (def);
631 return counter;
632 }
633 }
634 else /* one number means "match this line only" */
635 to_line = from_line;
636 }
637 else /* default to 0-max */
638 {
639 from_line = 0;
640 to_line = INT_MAX;
641 }
642 break;
643
644 default:
645 fprintf (
646 stderr,
647 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
648 p);
649 break;
650 }
651 start = p + 1;
652 state++;
653 break;
654
655 case '\0': /* found EOL */
656 keep_looking = 0;
657
658 /* fall through to '/' */
659 case '/': /* found a definition separator */
660 switch (state)
661 {
662 case 4: /* within a log level */
663 p[0] = '\0';
664 state = 0;
665 level = get_type ((const char *) start);
666 if ((GNUNET_ERROR_TYPE_INVALID == level) ||
668 (0 != add_definition (comp,
669 file,
670 function,
671 from_line,
672 to_line,
673 level,
674 force)))
675 {
676 GNUNET_free (def);
677 return counter;
678 }
679 counter++;
680 start = p + 1;
681 break;
682
683 default:
684 fprintf (
685 stderr,
686 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
687 p);
688 break;
689 }
690
691 default:
692 break;
693 }
694 }
695 GNUNET_free (def);
696 return counter;
697}
#define INT_MAX
static enum GNUNET_ErrorType get_type(const char *log)
Convert a textual description of a loglevel to the respective enumeration type.
static int add_definition(const char *lcomponent, const char *file, const char *function, int from_line, int to_line, int level, int force)
Utility function - adds a parsed definition to logdefs array.
char * getenv()
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
enum State state
current state of profiling
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178

References _, add_definition(), LogDef::force, LogDef::from_line, get_type(), getenv(), GNUNET_ERROR_TYPE_INVALID, GNUNET_ERROR_TYPE_UNSPECIFIED, GNUNET_free, GNUNET_strdup, INT_MAX, LogDef::level, p, start, state, t, and LogDef::to_line.

Referenced by parse_all_definitions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_all_definitions()

static void parse_all_definitions ( )
static

Utility function - parses GNUNET_LOG and GNUNET_FORCE_LOG.

Definition at line 704 of file common_logging.c.

705{
708 parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
710
712 parse_definitions ("GNUNET_LOG", 0);
714}
static int gnunet_force_log_present
GNUNET_YES if at least one definition with forced == 1 is available.
static int parse_definitions(const char *constname, int force)
Utility function - parses a definition.
static int gnunet_force_log_parsed
GNUNET_YES if GNUNET_FORCE_LOG environment variable is already parsed.
static int gnunet_log_parsed
GNUNET_YES if GNUNET_LOG environment variable is already parsed.
@ GNUNET_YES
@ GNUNET_NO

References gnunet_force_log_parsed, gnunet_force_log_present, gnunet_log_parsed, GNUNET_NO, GNUNET_YES, and parse_definitions().

Referenced by GNUNET_log_setup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ output_message()

static void output_message ( enum GNUNET_ErrorType  kind,
const char *  comp,
const char *  datestr,
const char *  msg 
)
static

Actually output the log message.

Parameters
kindhow severe was the issue
compcomponent responsible
datestrcurrent date/time
msgthe actual message

Definition at line 820 of file common_logging.c.

824{
825 static int have_journald = -1;
826 struct CustomLogger *pos;
827 const char *optional_newline = "\n";
828
829 if ((strlen (msg) > 0) &&
830 ('\n' == msg[strlen (msg) - 1]))
831 optional_newline = "";
832
833 if (-1 == have_journald)
834 {
835 /* systemd after version 231 sets this environment
836 variable if we are logging to journald. In this
837 case, skip outputting our component name, PID
838 and timestamp as journald already adds those. (#8032) */
839 if (NULL != getenv ("JOURNAL_STREAM"))
840 have_journald = 1;
841 else
842 have_journald = 0;
843 }
844
845 /* only use the standard logger if no custom loggers are present */
846 if ((NULL != GNUNET_stderr) && (NULL == loggers))
847 {
848 if (kind == GNUNET_ERROR_TYPE_MESSAGE)
849 {
850 /* The idea here is to produce "normal" output messages
851 * for end users while still having the power of the
852 * logging engine for developer needs. So ideally this
853 * is what it should look like when CLI tools are used
854 * interactively, yet the same message shouldn't look
855 * this way if the output is going to logfiles or robots
856 * instead.
857 */
858 fprintf (GNUNET_stderr, "* %s%s", msg, optional_newline);
859 }
861 {
862 static GNUNET_THREAD_LOCAL char id_buf[27];
863 char *end;
864
865 /* We're logging, so skip_log must be currently 0. */
866 skip_log = 100;
868 sizeof(struct GNUNET_AsyncScopeId),
869 id_buf,
870 sizeof(id_buf) - 1);
871 GNUNET_assert (NULL != end);
872 *end = '\0';
873 skip_log = 0;
874 if (have_journald)
875 fprintf (GNUNET_stderr,
876 "(%s) %s %s%s",
877 id_buf,
879 msg,
880 optional_newline);
881 else
882 fprintf (GNUNET_stderr,
883 "%s %s(%s) %s %s%s",
884 datestr,
885 comp,
886 id_buf,
888 msg,
889 optional_newline);
890 }
891 else
892 {
893 if (have_journald)
894 fprintf (GNUNET_stderr,
895 "%s %s%s",
897 msg,
898 optional_newline);
899 else
900 fprintf (GNUNET_stderr,
901 "%s %s %s %s%s",
902 datestr,
903 comp,
905 msg,
906 optional_newline);
907 }
908 fflush (GNUNET_stderr);
909 }
910 pos = loggers;
911 while (NULL != pos)
912 {
913 pos->logger (pos->logger_cls, kind, comp, datestr, msg);
914 pos = pos->next;
915 }
916}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static GNUNET_THREAD_LOCAL int skip_log
Number of log calls to ignore.
static struct CustomLogger * loggers
Linked list of our custom loggres.
static GNUNET_THREAD_LOCAL struct GNUNET_AsyncScopeSave current_async_scope
Asynchronous scope of the current thread, or NULL if we have not entered an async scope yet.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
int have_scope
GNUNET_YES unless this saved scope is the unnamed root scope.
struct GNUNET_AsyncScopeId scope_id
Saved scope.
const char * GNUNET_error_type_to_string(enum GNUNET_ErrorType kind)
Convert error type to string.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:732
#define GNUNET_THREAD_LOCAL
Definition: platform.h:247
Linked list of active loggers.
void * logger_cls
Closure for logger.
struct CustomLogger * next
This is a linked list.
GNUNET_Logger logger
Log function.
Identifier for an asynchronous execution context.

References current_async_scope, end, getenv(), GNUNET_assert, GNUNET_ERROR_TYPE_MESSAGE, GNUNET_error_type_to_string(), GNUNET_stderr, GNUNET_STRINGS_data_to_string(), GNUNET_THREAD_LOCAL, GNUNET_YES, GNUNET_AsyncScopeSave::have_scope, CustomLogger::logger, CustomLogger::logger_cls, loggers, msg, CustomLogger::next, GNUNET_AsyncScopeSave::scope_id, and skip_log.

Referenced by flush_bulk(), and mylog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ flush_bulk()

static void flush_bulk ( const char *  datestr)
static

Flush an existing bulk report to the output.

Parameters
datestrour current timestamp

Definition at line 925 of file common_logging.c.

926{
927 char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
928 int rev;
929 char *last;
930 const char *ft;
931
932 if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
933 return;
934 rev = 0;
935 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
936 if (last == NULL)
937 last = &last_bulk[BULK_TRACK_SIZE - 1];
938 else if (last != last_bulk)
939 last--;
940 if (last[0] == '\n')
941 {
942 rev = 1;
943 last[0] = '\0';
944 }
945 ft =
948 GNUNET_YES);
949 snprintf (msg,
950 sizeof(msg),
951 _ ("Message `%.*s' repeated %u times in the last %s\n"),
953 last_bulk,
955 ft);
956 if (rev == 1)
957 last[0] = '\n';
961}
static GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time
Time of the last bulk error message (0 for none)
static GNUNET_THREAD_LOCAL char last_bulk_comp[32+1]
Component when the last bulk was logged.
static GNUNET_THREAD_LOCAL enum GNUNET_ErrorType last_bulk_kind
Type of the last bulk message.
static void output_message(enum GNUNET_ErrorType kind, const char *comp, const char *datestr, const char *msg)
Actually output the log message.
static GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat
Number of times that bulk message has been repeated since.
#define DATE_STR_SIZE
How many characters can a date/time string be at most?
#define BULK_TRACK_SIZE
How many characters do we use for matching of bulk messages?
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:438
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:579
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
uint64_t abs_value_us
The actual value.

References _, GNUNET_TIME_Absolute::abs_value_us, BULK_TRACK_SIZE, DATE_STR_SIZE, GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_duration(), GNUNET_YES, last_bulk_comp, last_bulk_kind, last_bulk_repeat, last_bulk_time, msg, and output_message().

Referenced by mylog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mylog()

static void mylog ( enum GNUNET_ErrorType  kind,
const char *  comp,
const char *  message,
va_list  va 
)
static

Output a log message using the default mechanism.

Parameters
kindhow severe was the issue
compcomponent responsible
messagethe actual message
vaarguments to the format string "message"

Definition at line 1004 of file common_logging.c.

1008{
1009 char date[DATE_STR_SIZE];
1010 char date2[DATE_STR_SIZE];
1011 struct tm *tmptr;
1012 size_t size;
1013 va_list vacp;
1014
1015 va_copy (vacp, va);
1016 size = vsnprintf (NULL, 0, message, vacp) + 1;
1017 GNUNET_assert (0 != size);
1018 va_end (vacp);
1019 memset (date, 0, DATE_STR_SIZE);
1020 {
1021 char buf[size];
1022 long long offset;
1023
1024 struct timeval timeofday;
1025
1026 gettimeofday (&timeofday, NULL);
1027 offset = GNUNET_TIME_get_offset ();
1028 if (offset > 0)
1029 {
1030 timeofday.tv_sec += offset / 1000LL;
1031 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1032 if (timeofday.tv_usec > 1000000LL)
1033 {
1034 timeofday.tv_usec -= 1000000LL;
1035 timeofday.tv_sec++;
1036 }
1037 }
1038 else
1039 {
1040 timeofday.tv_sec += offset / 1000LL;
1041 if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1042 {
1043 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1044 }
1045 else
1046 {
1047 timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1048 timeofday.tv_sec--;
1049 }
1050 }
1051 tmptr = localtime (&timeofday.tv_sec);
1052 if (NULL == tmptr)
1053 {
1054 strcpy (date, "localtime error");
1055 }
1056 else
1057 {
1058 /* RFC 3339 timestamp, with snprintf placeholder for microseconds */
1059 if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z",
1060 tmptr))
1061 abort ();
1062 /* Fill in microseconds */
1063 if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1064 abort ();
1065 }
1066
1067 vsnprintf (buf, size, message, va);
1068#if ! defined(GNUNET_CULL_LOGGING)
1069 if (NULL != tmptr)
1070 (void) setup_log_file (tmptr);
1071#endif
1072 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1074 (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1075 {
1080 flush_bulk (date);
1081 return;
1082 }
1083 flush_bulk (date);
1084 GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
1085 last_bulk_repeat = 0;
1086 last_bulk_kind = kind;
1089 output_message (kind, comp, date, buf);
1090 }
1091}
#define BULK_DELAY_THRESHOLD
After how many milliseconds do we always print that "message X was repeated N times"?...
#define BULK_REPEAT_THRESHOLD
After how many repetitions do we always print that "message X was repeated N times"?...
static enum GNUNET_GenericReturnValue setup_log_file(const struct tm *tm)
Setup the log file.
static void flush_bulk(const char *datestr)
Flush an existing bulk report to the output.
@ GNUNET_ERROR_TYPE_BULK
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:137
long long GNUNET_TIME_get_offset(void)
Get the timestamp offset for this instance.
Definition: time.c:56
static unsigned int size
Size of the "table".
Definition: peer.c:68
uint64_t rel_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, BULK_DELAY_THRESHOLD, BULK_REPEAT_THRESHOLD, DATE_STR_SIZE, flush_bulk(), GNUNET_assert, GNUNET_ERROR_TYPE_BULK, GNUNET_strlcpy(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_get_offset(), last_bulk_comp, last_bulk_kind, last_bulk_repeat, last_bulk_time, output_message(), GNUNET_TIME_Relative::rel_value_us, setup_log_file(), and size.

Referenced by GNUNET_log_from_nocheck(), and GNUNET_log_nocheck().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_log_nocheck()

void GNUNET_log_nocheck ( enum GNUNET_ErrorType  kind,
const char *  message,
  ... 
)

Main log function.

Parameters
kindhow serious is the error?
messagewhat is the message (format string)
...arguments for format string

Definition at line 1102 of file common_logging.c.

1103{
1104 va_list va;
1105
1106 va_start (va, message);
1107 mylog (kind, component, message, va);
1108 va_end (va);
1109}
static void mylog(enum GNUNET_ErrorType kind, const char *comp, const char *message, va_list va)
Output a log message using the default mechanism.
static char * component
Running component.

References component, and mylog().

Here is the call graph for this function:

◆ GNUNET_log_from_nocheck()

void GNUNET_log_from_nocheck ( enum GNUNET_ErrorType  kind,
const char *  comp,
const char *  message,
  ... 
)

Log function that specifies an alternative component.

This function should be used by plugins.

Parameters
kindhow serious is the error?
compcomponent responsible for generating the message
messagewhat is the message (format string)
...arguments for format string

Definition at line 1122 of file common_logging.c.

1126{
1127 va_list va;
1128 char comp_w_pid[128];
1129
1130 if (comp == NULL)
1131 comp = component_nopid;
1132
1133 va_start (va, message);
1134 GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
1135 mylog (kind, comp_w_pid, message, va);
1136 va_end (va);
1137}
static char * component_nopid
Running component (without pid).
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.

References component_nopid, GNUNET_snprintf(), and mylog().

Here is the call graph for this function:

◆ GNUNET_util_cl_init()

void GNUNET_util_cl_init ( void  )

◆ __attribute__() [1/2]

void __attribute__ ( (constructor)  )

Initializer.

Definition at line 1584 of file common_logging.c.

1586{
1587 GNUNET_stderr = stderr;
1588}

References GNUNET_stderr.

◆ GNUNET_util_cl_fini()

void GNUNET_util_cl_fini ( void  )

◆ __attribute__() [2/2]

void __attribute__ ( (destructor)  )

Destructor.

Definition at line 1597 of file common_logging.c.

1599{
1600
1601}

Variable Documentation

◆ current_async_scope

GNUNET_THREAD_LOCAL struct GNUNET_AsyncScopeSave current_async_scope
static

Asynchronous scope of the current thread, or NULL if we have not entered an async scope yet.

Definition at line 102 of file common_logging.c.

Referenced by GNUNET_async_scope_enter(), GNUNET_async_scope_get(), GNUNET_async_scope_restore(), and output_message().

◆ __nonstring

GNUNET_THREAD_LOCAL char last_bulk [ 256 ] __nonstring
static

The last "bulk" error message that we have been logging.

Note that this message maybe truncated to the first BULK_TRACK_SIZE characters, in which case it is NOT 0-terminated!

Definition at line 109 of file common_logging.c.

◆ last_bulk_kind

GNUNET_THREAD_LOCAL enum GNUNET_ErrorType last_bulk_kind
static

Type of the last bulk message.

Definition at line 114 of file common_logging.c.

Referenced by flush_bulk(), and mylog().

◆ last_bulk_time

GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time
static

Time of the last bulk error message (0 for none)

Definition at line 119 of file common_logging.c.

Referenced by flush_bulk(), and mylog().

◆ last_bulk_repeat

GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat
static

Number of times that bulk message has been repeated since.

Definition at line 124 of file common_logging.c.

Referenced by flush_bulk(), and mylog().

◆ last_bulk_comp

GNUNET_THREAD_LOCAL char last_bulk_comp[32+1]
static

Component when the last bulk was logged.

Will be 0-terminated.

Definition at line 129 of file common_logging.c.

Referenced by flush_bulk(), and mylog().

◆ component

char* component
static

Running component.

Definition at line 134 of file common_logging.c.

Referenced by GNUNET_log_nocheck(), and GNUNET_log_setup().

◆ component_nopid

char* component_nopid
static

Running component (without pid).

Definition at line 139 of file common_logging.c.

Referenced by GNUNET_get_log_call_status(), GNUNET_log_from_nocheck(), and GNUNET_log_setup().

◆ log_file_name

char* log_file_name
static

Format string describing the name of the log file.

Definition at line 144 of file common_logging.c.

Referenced by GNUNET_log_setup(), and setup_log_file().

◆ min_level

enum GNUNET_ErrorType min_level
static

Minimum log level.

Definition at line 149 of file common_logging.c.

Referenced by GNUNET_get_log_call_status(), and GNUNET_log_setup().

◆ loggers

struct CustomLogger* loggers
static

Linked list of our custom loggres.

Definition at line 154 of file common_logging.c.

Referenced by GNUNET_logger_add(), GNUNET_logger_remove(), and output_message().

◆ skip_log

GNUNET_THREAD_LOCAL int skip_log = 0
static

Number of log calls to ignore.

Definition at line 159 of file common_logging.c.

Referenced by GNUNET_get_log_skip(), GNUNET_log_skip(), and output_message().

◆ GNUNET_stderr

FILE* GNUNET_stderr
static

File descriptor to use for "stderr", or NULL for none.

Definition at line 164 of file common_logging.c.

Referenced by __attribute__(), output_message(), and setup_log_file().

◆ logdefs

struct LogDef* logdefs
static

Dynamic array of logging definitions.

Definition at line 217 of file common_logging.c.

Referenced by add_definition(), GNUNET_get_log_call_status(), and resize_logdefs().

◆ logdefs_size

int logdefs_size
static

Allocated size of logdefs array (in units)

Definition at line 222 of file common_logging.c.

Referenced by add_definition(), and resize_logdefs().

◆ logdefs_len

int logdefs_len
static

The number of units used in logdefs array.

Definition at line 227 of file common_logging.c.

Referenced by add_definition(), and GNUNET_get_log_call_status().

◆ gnunet_log_parsed

int gnunet_log_parsed
static

GNUNET_YES if GNUNET_LOG environment variable is already parsed.

Definition at line 232 of file common_logging.c.

Referenced by parse_all_definitions().

◆ gnunet_force_log_parsed

int gnunet_force_log_parsed
static

GNUNET_YES if GNUNET_FORCE_LOG environment variable is already parsed.

Definition at line 237 of file common_logging.c.

Referenced by parse_all_definitions().

◆ gnunet_force_log_present

int gnunet_force_log_present
static

GNUNET_YES if at least one definition with forced == 1 is available.

Definition at line 242 of file common_logging.c.

Referenced by GNUNET_get_log_call_status(), and parse_all_definitions().