Greenbone Vulnerability Management Libraries 22.8.0
logging.c File Reference

Implementation of logging methods. More...

#include "logging.h"
#include "gvm_sentry.h"
#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
Include dependency graph for logging.c:

Go to the source code of this file.

Data Structures

struct  gvm_logging_t
 Logging stores the parameters loaded from a log configuration. More...
 

Macros

#define SYSLOG_NAMES
 
#define G_LOG_DOMAIN   "libgvm base"
 GLib log domain.
 

Functions

gchar * get_time (gchar *time_fmt)
 Returns time as specified in time_fmt strftime format.
 
static gint level_int_from_string (const gchar *level)
 Return the integer corresponding to a log level string.
 
static gint facility_int_from_string (const gchar *facility)
 Return the integer corresponding to a syslog facility string.
 
GSList * load_log_configuration (gchar *config_file)
 Loads parameters from a config file into a linked list.
 
void free_log_configuration (GSList *log_domain_list)
 Frees all resources loaded by the config loader.
 
void gvm_log_silent (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer gvm_log_config_list)
 Returns immediately.
 
static void gvm_log_lock_init (void)
 Initialize logger_mutex mutex if it was not done before.
 
void gvm_log_lock (void)
 Try to lock logger_mutex.
 
void gvm_log_unlock (void)
 Unlock logger_mutex.
 
void set_log_reference (char *ref)
 Set the log reference object.
 
char * get_log_reference (void)
 Get the log reference object.
 
void free_log_reference (void)
 Free the log reference object.
 
void gvm_log_func (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer gvm_log_config_list)
 Creates the formatted string and outputs it to the log destination.
 
void log_func_for_gnutls (int level, const char *message)
 This function logs debug messages from gnutls.
 
static int check_log_file (gvm_logging_t *log_domain_entry)
 Check permissions of log file and log file directory.
 
int setup_log_handlers (GSList *gvm_log_config_list)
 Sets up routing of logdomains to log handlers.
 

Variables

static GMutex * logger_mutex = NULL
 
static char * reference = NULL
 

Detailed Description

Implementation of logging methods.

This file contains all methods needed for logging. To enable logging, methods in this file are called.

The module reuses glib datatypes and api for memory management and logging.

Definition in file logging.c.

Macro Definition Documentation

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "libgvm base"

GLib log domain.

Definition at line 35 of file logging.c.

◆ SYSLOG_NAMES

#define SYSLOG_NAMES

Definition at line 25 of file logging.c.

Function Documentation

◆ check_log_file()

static int check_log_file ( gvm_logging_t log_domain_entry)
static

Check permissions of log file and log file directory.

Do not check permissions if log file is syslog or empty string.

Parameters
log_domain_entryLog domain entry.
Returns
0 on success, -1 on error.

Definition at line 833 of file logging.c.

834{
835 GIOChannel *channel = NULL;
836 GError *error = NULL;
837 gchar *log_file = NULL;
838
839 if (log_domain_entry->log_file)
840 log_file = log_domain_entry->log_file;
841
842 // No log file was specified or log file is empty in the openvas_log.conf.
843 // stderr will be used as default later on. See gvm_log_func.
844 if (!log_file)
845 return 0;
846 if (!g_strcmp0 (log_file, ""))
847 return 0;
848
849 // If syslog is used we do not need to check the log file permissions.
850 if (g_ascii_strcasecmp (log_file, "syslog") == 0)
851 return 0;
852
853 channel = g_io_channel_new_file (log_file, "a", &error);
854 if (!channel)
855 {
856 gchar *log = g_strdup (log_file);
857 gchar *dir = dirname (log);
858
859 /* Ensure directory exists. */
860 if (g_mkdir_with_parents (dir, 0755)) /* "rwxr-xr-x" */
861 {
862 g_free (log);
863 return -1;
864 }
865 g_free (log);
866
867 /* Try again. */
868 error = NULL;
869 channel = g_io_channel_new_file (log_file, "a", &error);
870 if (!channel)
871 return -1;
872 }
873 return 0;
874}
gchar * log_file
Where to log to.
Definition: logging.c:47

References gvm_logging_t::log_file.

Referenced by setup_log_handlers().

Here is the caller graph for this function:

◆ facility_int_from_string()

static gint facility_int_from_string ( const gchar *  facility)
static

Return the integer corresponding to a syslog facility string.

Parameters
facilityFacility name.
Returns
Facility integer if facility matches a facility name, else LOG_LOCAL0.

Definition at line 123 of file logging.c.

124{
125 if (facility && strlen (facility) > 0)
126 {
127 int i = 0;
128 while (facilitynames[i].c_name != NULL)
129 {
130 if (g_ascii_strcasecmp (facility, facilitynames[i].c_name) == 0)
131 return facilitynames[i].c_val;
132 i++;
133 }
134 }
135 return LOG_LOCAL0;
136}

Referenced by gvm_log_func().

Here is the caller graph for this function:

◆ free_log_configuration()

void free_log_configuration ( GSList *  log_domain_list)

Frees all resources loaded by the config loader.

Parameters
log_domain_listHead of the link list.

Definition at line 277 of file logging.c.

278{
279 GSList *log_domain_list_tmp;
280
281 /* Free the struct fields then the struct and then go the next
282 * item in the link list.
283 */
284
285 /* Go to the head of the list. */
286 log_domain_list_tmp = log_domain_list;
287 while (log_domain_list_tmp != NULL)
288 {
289 gvm_logging_t *log_domain_entry;
290
291 /* Get the list data which is an gvm_logging_t struct. */
292 log_domain_entry = log_domain_list_tmp->data;
293
294 /* Free the struct contents. */
295 g_free (log_domain_entry->log_domain);
296 g_free (log_domain_entry->prepend_string);
297 g_free (log_domain_entry->prepend_time_format);
298 g_free (log_domain_entry->log_file);
299 g_free (log_domain_entry->default_level);
300 g_free (log_domain_entry->syslog_ident);
301 g_free (log_domain_entry->prepend_separator);
302
303 /* Drop the reference to the GIOChannel. */
304 if (log_domain_entry->log_channel)
305 g_io_channel_unref (log_domain_entry->log_channel);
306
307 /* Free the struct. */
308 g_free (log_domain_entry);
309
310 /* Go to the next item. */
311 log_domain_list_tmp = g_slist_next (log_domain_list_tmp);
312 }
313 /* Free the link list. */
314 g_slist_free (log_domain_list);
315}
Logging stores the parameters loaded from a log configuration.
Definition: logging.c:43
gchar * prepend_string
Prepend this string before every message.
Definition: logging.c:45
gchar * prepend_time_format
If prependstring has t, format for strftime.
Definition: logging.c:46
gchar * syslog_ident
Syslog ident to use for syslog logging.
Definition: logging.c:51
gchar * prepend_separator
Definition: logging.c:52
GIOChannel * log_channel
Gio Channel - FD holder for logfile.
Definition: logging.c:49
gchar * log_domain
Affected logdomain e.g libnasl.
Definition: logging.c:44
GLogLevelFlags * default_level
What severity level to use as default.
Definition: logging.c:48

References gvm_logging_t::default_level, gvm_logging_t::log_channel, gvm_logging_t::log_domain, gvm_logging_t::log_file, gvm_logging_t::prepend_separator, gvm_logging_t::prepend_string, gvm_logging_t::prepend_time_format, and gvm_logging_t::syslog_ident.

◆ free_log_reference()

void free_log_reference ( void  )

Free the log reference object.

The reference object is used to detect corresponding logs.

Definition at line 416 of file logging.c.

417{
418 if (reference)
419 g_free ((char *) reference);
420 reference = NULL;
421}
static char * reference
Definition: logging.c:372

References reference.

◆ get_log_reference()

char * get_log_reference ( void  )

Get the log reference object.

This function returns the current log reference. This enables the possibility to save or modify the current reference value.

Returns
char*

Definition at line 404 of file logging.c.

405{
406 return (char *) reference;
407}

References reference.

◆ get_time()

gchar * get_time ( gchar *  time_fmt)

Returns time as specified in time_fmt strftime format.

Parameters
time_fmtptr to the string format to use. The strftime man page documents the conversion specification. An example time_fmt string is "%Y-%m-%d %H:%M:%S".
Returns
NULL in case the format string is NULL. A ptr to a string that contains the formatted date time value. This value must be freed using glib's g_free.

Definition at line 68 of file logging.c.

69{
70 time_t now;
71 struct tm ts;
72 gchar buf[80];
73
74 /* Get the current time. */
75 now = time (NULL);
76
77 /* Format and print the time, "ddd yyyy-mm-dd hh:mm:ss zzz." */
78 localtime_r (&now, &ts);
79 strftime (buf, sizeof (buf), time_fmt, &ts);
80
81 return g_strdup_printf ("%s", buf);
82}

Referenced by gvm_log_func().

Here is the caller graph for this function:

◆ gvm_log_func()

void gvm_log_func ( const char *  log_domain,
GLogLevelFlags  log_level,
const char *  message,
gpointer  gvm_log_config_list 
)

Creates the formatted string and outputs it to the log destination.

Parameters
log_domainA string containing the message's log domain.
log_levelFlags defining the message's log level.
messageA string containing the log message.
gvm_log_config_listA pointer to the configuration linked list.

Definition at line 432 of file logging.c.

434{
435 gchar *prepend;
436 gchar *prepend_buf;
437 gchar *prepend_tmp;
438 gchar *prepend_tmp1;
439 gchar *tmp;
440 gchar *tmpstr;
441 int messagelen;
442
443 /* For link list operations. */
444 GSList *log_domain_list_tmp;
445 gvm_logging_t *log_domain_entry = NULL;
446
447 /* Channel to log through. */
448 GIOChannel *channel;
449 GError *error = NULL;
450
451 /* The default parameters to be used. The group '*' will override
452 * these defaults if it's found.
453 */
454 gchar *prepend_format = "%t %s %p - ";
455 gchar *time_format = "%Y-%m-%d %Hh%M.%S %Z";
456 gchar *log_separator = ":";
457 gchar *log_file = "-";
458 GLogLevelFlags default_level = G_LOG_LEVEL_DEBUG;
459 channel = NULL;
460 gchar *syslog_facility = "local0";
461 gchar *syslog_ident = NULL;
462
463 /* Let's load the default configuration file directives from the
464 * linked list. Scanning the link list twice is inefficient but
465 * leaves the source cleaner.
466 */
467 if (gvm_log_config_list != NULL && log_domain != NULL)
468 {
469 /* Go to the head of the list. */
470 log_domain_list_tmp = (GSList *) gvm_log_config_list;
471
472 while (log_domain_list_tmp != NULL)
473 {
474 gvm_logging_t *entry;
475
476 entry = log_domain_list_tmp->data;
477
478 /* Override defaults if the current linklist group name is '*'. */
479 if (g_ascii_strcasecmp (entry->log_domain, "*") == 0)
480 {
481 /* Get the list data for later use. */
482 log_domain_entry = entry;
483
484 /* Override defaults if the group items are not null. */
485 if (log_domain_entry->prepend_string)
486 prepend_format = log_domain_entry->prepend_string;
487 if (log_domain_entry->prepend_time_format)
488 time_format = log_domain_entry->prepend_time_format;
489 if (log_domain_entry->log_file)
490 log_file = log_domain_entry->log_file;
491 if (log_domain_entry->default_level)
492 default_level = *log_domain_entry->default_level;
493 if (log_domain_entry->log_channel)
494 channel = log_domain_entry->log_channel;
495 if (log_domain_entry->syslog_facility)
496 syslog_facility = log_domain_entry->syslog_facility;
497 if (log_domain_entry->prepend_separator)
498 log_separator = log_domain_entry->prepend_separator;
499 break;
500 }
501
502 /* Go to the next item. */
503 log_domain_list_tmp = g_slist_next (log_domain_list_tmp);
504 }
505 }
506
507 /* Let's load the configuration file directives if a linked list item for
508 * the log domain group exists.
509 */
510 if (gvm_log_config_list != NULL && log_domain != NULL)
511 {
512 /* Go to the head of the list. */
513 log_domain_list_tmp = (GSList *) gvm_log_config_list;
514
515 while (log_domain_list_tmp != NULL)
516 {
517 gvm_logging_t *entry;
518
519 entry = log_domain_list_tmp->data;
520
521 /* Search for the log domain in the link list. */
522 if (g_ascii_strcasecmp (entry->log_domain, log_domain) == 0)
523 {
524 /* Get the list data which is an gvm_logging_t struct. */
525 log_domain_entry = entry;
526
527 /* Get the struct contents. */
528 if (log_domain_entry->prepend_string)
529 prepend_format = log_domain_entry->prepend_string;
530 time_format = log_domain_entry->prepend_time_format;
531 log_file = log_domain_entry->log_file;
532 if (log_domain_entry->default_level)
533 default_level = *log_domain_entry->default_level;
534 channel = log_domain_entry->log_channel;
535 syslog_facility = log_domain_entry->syslog_facility;
536 syslog_ident = log_domain_entry->syslog_ident;
537 if (log_domain_entry->prepend_separator)
538 log_separator = log_domain_entry->prepend_separator;
539 break;
540 }
541
542 /* Go to the next item. */
543 log_domain_list_tmp = g_slist_next (log_domain_list_tmp);
544 }
545 }
546
547 /* If the current log entry is less severe than the specified log level,
548 * let's exit.
549 */
550 if (default_level < log_level)
551 return;
552
553 /* Prepend buf is a newly allocated empty string. Makes life easier. */
554 prepend_buf = g_strdup ("");
555
556 /* Make the tmp pointer (for iteration) point to the format string. */
557 tmp = prepend_format;
558
559 while (*tmp != '\0')
560 {
561 /* If the current char is a % and the next one is a p, get the pid. */
562 if ((*tmp == '%') && (*(tmp + 1) == 'p'))
563 {
564 if (reference)
565 {
566 prepend_tmp =
567 g_strdup_printf ("%s%d%s%s", prepend_buf, (int) getpid (),
568 log_separator, reference);
569 }
570 else
571 {
572 /* Use g_strdup, a new string returned. Store it in a tmp var
573 * until we free the old one. */
574 prepend_tmp =
575 g_strdup_printf ("%s%d", prepend_buf, (int) getpid ());
576 }
577 /* Free the old string. */
578 g_free (prepend_buf);
579 /* Point the buf ptr to the new string. */
580 prepend_buf = prepend_tmp;
581 /* Skip over the two chars we've processed '%p'. */
582 tmp += 2;
583 }
584 else if ((*tmp == '%') && (*(tmp + 1) == 't'))
585 {
586 /* Get time returns a newly allocated string.
587 * Store it in a tmp var.
588 */
589 prepend_tmp1 = get_time (time_format);
590 /* Use g_strdup. New string returned. Store it in a tmp var until
591 * we free the old one.
592 */
593 prepend_tmp = g_strdup_printf ("%s%s", prepend_buf, prepend_tmp1);
594 /* Free the time tmp var. */
595 g_free (prepend_tmp1);
596 /* Free the old string. */
597 g_free (prepend_buf);
598 /* Point the buf ptr to the new string. */
599 prepend_buf = prepend_tmp;
600 /* Skip over the two chars we've processed '%t.' */
601 tmp += 2;
602 }
603 else if ((*tmp == '%') && (*(tmp + 1) == 's'))
604 {
605 /* Use g_strdup. New string returned. Store it in a tmp var until
606 * we free the old one.
607 */
608 prepend_tmp = g_strdup_printf ("%s%s", prepend_buf, log_separator);
609 /* Free the old string. */
610 g_free (prepend_buf);
611 /* Point the buf ptr to the new string. */
612 prepend_buf = prepend_tmp;
613 /* Skip over the two chars we've processed '%s.' */
614 tmp += 2;
615 }
616 else
617 {
618 /* Jump to the next character. */
619 tmp++;
620 }
621 }
622
623 /* Step through all possible messages prefixing them with an appropriate
624 * tag.
625 */
626 switch (log_level)
627 {
628 case G_LOG_FLAG_RECURSION:
629 prepend = g_strdup_printf ("RECURSION%s%s", log_separator, prepend_buf);
630 break;
631
632 case G_LOG_FLAG_FATAL:
633 prepend = g_strdup_printf ("FATAL%s%s", log_separator, prepend_buf);
634 break;
635
636 case G_LOG_LEVEL_ERROR:
637 prepend = g_strdup_printf ("ERROR%s%s", log_separator, prepend_buf);
638 break;
639
640 case G_LOG_LEVEL_CRITICAL:
641 prepend = g_strdup_printf ("CRITICAL%s%s", log_separator, prepend_buf);
642 break;
643
644 case G_LOG_LEVEL_WARNING:
645 prepend = g_strdup_printf ("WARNING%s%s", log_separator, prepend_buf);
646 break;
647
648 case G_LOG_LEVEL_MESSAGE:
649 prepend = g_strdup_printf ("MESSAGE%s%s", log_separator, prepend_buf);
650 break;
651
652 case G_LOG_LEVEL_INFO:
653 prepend = g_strdup_printf (" INFO%s%s", log_separator, prepend_buf);
654 break;
655
656 case G_LOG_LEVEL_DEBUG:
657 prepend = g_strdup_printf (" DEBUG%s%s", log_separator, prepend_buf);
658 break;
659
660 default:
661 prepend = g_strdup_printf ("UNKNOWN%s%s", log_separator, prepend_buf);
662 break;
663 }
664
665 /* If the current log entry is more severe than the specified log
666 * level, print out the message. In case MESSAGE already ends in a
667 * LF and there is not only the LF, remove the LF to avoid empty
668 * lines in the log.
669 */
670 messagelen = message ? strlen (message) : 0;
671 if (messagelen > 1 && message[messagelen - 1] == '\n')
672 messagelen--;
673 tmpstr = g_strdup_printf ("%s%s%s%s %.*s\n", log_domain ? log_domain : "",
674 log_separator, prepend, log_separator, messagelen,
675 message);
676 g_free (prepend);
677
678 if (log_level <= G_LOG_LEVEL_WARNING)
679 gvm_sentry_log (message);
680
681 gvm_log_lock ();
682 /* Output everything to stderr if logfile is "-". */
683 if (g_ascii_strcasecmp (log_file, "-") == 0)
684 {
685 fprintf (stderr, "%s", tmpstr);
686 fflush (stderr);
687 }
688 /* Output everything to syslog if logfile is "syslog" */
689 else if (g_ascii_strcasecmp (log_file, "syslog") == 0)
690 {
691 int facility = facility_int_from_string (syslog_facility);
692 int syslog_level = LOG_INFO;
693
694 openlog (syslog_ident, LOG_CONS | LOG_PID | LOG_NDELAY, facility);
695
696 switch (log_level)
697 {
698 case G_LOG_FLAG_FATAL:
699 syslog_level = LOG_ALERT;
700 break;
701 case G_LOG_LEVEL_ERROR:
702 syslog_level = LOG_ERR;
703 break;
704 case G_LOG_LEVEL_CRITICAL:
705 syslog_level = LOG_CRIT;
706 break;
707 case G_LOG_LEVEL_WARNING:
708 syslog_level = LOG_WARNING;
709 break;
710 case G_LOG_LEVEL_MESSAGE:
711 syslog_level = LOG_NOTICE;
712 break;
713 case G_LOG_LEVEL_INFO:
714 syslog_level = LOG_INFO;
715 break;
716 case G_LOG_LEVEL_DEBUG:
717 syslog_level = LOG_DEBUG;
718 break;
719 default:
720 syslog_level = LOG_INFO;
721 break;
722 }
723
724 /* Syslog doesn't support messages longer than 1kb. The overflow data
725 will not be logged or will be shown in the hypervisor console
726 if it runs on a virtual machine. */
727 if (messagelen > 1000)
728 {
729 int pos;
730 char *message_aux, *message_aux2;
731 char buffer[1000];
732
733 message_aux2 = g_strdup (message);
734 message_aux = message_aux2;
735 for (pos = 0; pos <= messagelen; pos = pos + sizeof (buffer) - 1)
736 {
737 memcpy (buffer, message_aux, sizeof (buffer) - 1);
738 buffer[sizeof (buffer) - 1] = '\0';
739 message_aux = &(message_aux[sizeof (buffer) - 1]);
740 syslog (syslog_level, "%s", buffer);
741 }
742 g_free (message_aux2);
743 }
744 else
745 syslog (syslog_level, "%s", message);
746
747 closelog ();
748 }
749 else
750 {
751 /* Open a channel and store it in the struct or
752 * retrieve and use an already existing channel.
753 */
754 if (channel == NULL)
755 {
756 channel = g_io_channel_new_file (log_file, "a", &error);
757 if (!channel)
758 {
759 gchar *log = g_strdup (log_file);
760 gchar *dir = dirname (log);
761
762 /* Check error. In case of the directory does not exist, it will
763 * be handle below. In other case a message is printed to the
764 * stderr since the channel is still not created/accessible.
765 */
766 if (error->code != G_FILE_ERROR_NOENT)
767 fprintf (stderr, "Can not open '%s' logfile: %s\n", log_file,
768 error->message);
769 g_error_free (error);
770
771 /* Ensure directory exists. */
772 if (g_mkdir_with_parents (dir, 0755)) /* "rwxr-xr-x" */
773 {
774 g_warning ("Failed to create log file directory %s: %s", dir,
775 strerror (errno));
776 g_free (log);
777 g_free (tmpstr);
778 g_free (prepend_buf);
779 return;
780 }
781 g_free (log);
782
783 /* Try again. */
784 error = NULL;
785 channel = g_io_channel_new_file (log_file, "a", &error);
786 if (!channel)
787 {
788 g_error ("Can not open '%s' logfile: %s", log_file,
789 error->message);
790 }
791 }
792
793 /* Store it in the struct for later use. */
794 if (log_domain_entry != NULL)
795 log_domain_entry->log_channel = channel;
796 }
797 g_io_channel_write_chars (channel, (const gchar *) tmpstr, -1, NULL,
798 &error);
799 g_io_channel_flush (channel, NULL);
800 }
802 g_free (tmpstr);
803 g_free (prepend_buf);
804}
void gvm_sentry_log(const char *message)
Send a message to Sentry server if it was initialized.
Definition: gvm_sentry.c:97
gchar * get_time(gchar *time_fmt)
Returns time as specified in time_fmt strftime format.
Definition: logging.c:68
void gvm_log_unlock(void)
Unlock logger_mutex.
Definition: logging.c:367
void gvm_log_lock(void)
Try to lock logger_mutex.
Definition: logging.c:355
static gint facility_int_from_string(const gchar *facility)
Return the integer corresponding to a syslog facility string.
Definition: logging.c:123
gchar * syslog_facility
Syslog facility to use for syslog logging.
Definition: logging.c:50

References gvm_logging_t::default_level, facility_int_from_string(), get_time(), gvm_log_lock(), gvm_log_unlock(), gvm_sentry_log(), gvm_logging_t::log_channel, gvm_logging_t::log_domain, gvm_logging_t::log_file, gvm_logging_t::prepend_separator, gvm_logging_t::prepend_string, gvm_logging_t::prepend_time_format, reference, gvm_logging_t::syslog_facility, and gvm_logging_t::syslog_ident.

Referenced by setup_log_handlers().

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

◆ gvm_log_lock()

void gvm_log_lock ( void  )

Try to lock logger_mutex.

Definition at line 355 of file logging.c.

356{
357 /* Initialize logger lock if not done already. */
359
360 g_mutex_lock (logger_mutex);
361}
static GMutex * logger_mutex
Definition: logging.c:336
static void gvm_log_lock_init(void)
Initialize logger_mutex mutex if it was not done before.
Definition: logging.c:342

References gvm_log_lock_init(), and logger_mutex.

Referenced by gvm_log_func().

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

◆ gvm_log_lock_init()

static void gvm_log_lock_init ( void  )
static

Initialize logger_mutex mutex if it was not done before.

Definition at line 342 of file logging.c.

343{
344 if (logger_mutex == NULL)
345 {
346 logger_mutex = g_malloc (sizeof (*logger_mutex));
347 g_mutex_init (logger_mutex);
348 }
349}

References logger_mutex.

Referenced by gvm_log_lock().

Here is the caller graph for this function:

◆ gvm_log_silent()

void gvm_log_silent ( const char *  log_domain,
GLogLevelFlags  log_level,
const char *  message,
gpointer  gvm_log_config_list 
)

Returns immediately.

Parameters
log_domainA string containing the message's log domain.
log_levelFlags defining the message's log level.
messageA string containing the log message.
gvm_log_config_listA pointer to the configuration linked list.

Definition at line 326 of file logging.c.

328{
329 (void) log_domain;
330 (void) log_level;
331 (void) message;
332 (void) gvm_log_config_list;
333 return;
334}

◆ gvm_log_unlock()

void gvm_log_unlock ( void  )

Unlock logger_mutex.

Definition at line 367 of file logging.c.

368{
369 g_mutex_unlock (logger_mutex);
370}

References logger_mutex.

Referenced by gvm_log_func().

Here is the caller graph for this function:

◆ level_int_from_string()

static gint level_int_from_string ( const gchar *  level)
static

Return the integer corresponding to a log level string.

Parameters
levelLevel name or integer.
Returns
Log level integer if level matches a level name, else 0.

Definition at line 92 of file logging.c.

93{
94 if (level && strlen (level) > 0)
95 {
96 if (level[0] >= '0' && level[0] <= '9')
97 return atoi (level);
98 if (strcasecmp (level, "critical") == 0)
99 return G_LOG_LEVEL_CRITICAL;
100 if (strcasecmp (level, "debug") == 0)
101 return G_LOG_LEVEL_DEBUG;
102 if (strcasecmp (level, "error") == 0)
103 return G_LOG_LEVEL_ERROR;
104 if (strcasecmp (level, "info") == 0)
105 return G_LOG_LEVEL_INFO;
106 if (strcasecmp (level, "message") == 0)
107 return G_LOG_LEVEL_MESSAGE;
108 if (strcasecmp (level, "warning") == 0)
109 return G_LOG_LEVEL_WARNING;
110 }
111 return 0;
112}

Referenced by load_log_configuration().

Here is the caller graph for this function:

◆ load_log_configuration()

GSList * load_log_configuration ( gchar *  config_file)

Loads parameters from a config file into a linked list.

Parameters
config_fileA string containing the path to the configuration file to load.
Returns
NULL in case the config file could not be loaded or an error occurred otherwise, a singly linked list of parameter groups is returned.

Definition at line 149 of file logging.c.

150{
151 GKeyFile *key_file;
152 GKeyFileFlags flags;
153 GError *error = NULL;
154 /* key_file *_has_* functions requires this. */
155
156 // FIXME: If a g_* function that takes error fails, then free error.
157
158 /* Groups found in the conf file. */
159 gchar **groups;
160 /* Temp variable to iterate over groups. */
161 gchar **group;
162
163 /* The link list for the structure above and it's tmp helper */
164 GSList *log_domain_list = NULL;
165
166 /* Create a new GKeyFile object and a bitwise list of flags. */
167 key_file = g_key_file_new ();
168 flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
169
170 /* Load the GKeyFile from conf or return. */
171 if (!g_key_file_load_from_file (key_file, config_file, flags, &error))
172 {
173 g_error ("%s: %s", config_file, error->message);
174 }
175
176 /* Get all the groups available. */
177 groups = g_key_file_get_groups (key_file, NULL);
178
179 /* Point to the group head. */
180 group = groups;
181 /* Iterate till we get to the end of the array. */
182 while (*group != NULL)
183 {
184 /* Structure to hold per group settings. */
185 gvm_logging_t *log_domain_entry;
186 /* Create the struct. */
187 log_domain_entry = g_malloc (sizeof (gvm_logging_t));
188 /* Set the logdomain. */
189 log_domain_entry->log_domain = g_strdup (*group);
190 /* Initialize everything else to NULL. */
191 log_domain_entry->prepend_string = NULL;
192 log_domain_entry->prepend_time_format = NULL;
193 log_domain_entry->log_file = NULL;
194 log_domain_entry->default_level = NULL;
195 log_domain_entry->log_channel = NULL;
196 log_domain_entry->syslog_facility = NULL;
197 log_domain_entry->syslog_ident = NULL;
198 log_domain_entry->prepend_separator = NULL;
199
200 /* Look for the prepend string. */
201 if (g_key_file_has_key (key_file, *group, "prepend", &error))
202 {
203 log_domain_entry->prepend_string =
204 g_key_file_get_value (key_file, *group, "prepend", &error);
205 }
206
207 /* Look for the log_separator string. */
208 if (g_key_file_has_key (key_file, *group, "separator", &error))
209 {
210 log_domain_entry->prepend_separator =
211 g_key_file_get_value (key_file, *group, "separator", &error);
212 }
213
214 /* Look for the prepend time format string. */
215 if (g_key_file_has_key (key_file, *group, "prepend_time_format", &error))
216 {
217 log_domain_entry->prepend_time_format = g_key_file_get_value (
218 key_file, *group, "prepend_time_format", &error);
219 }
220
221 /* Look for the log file string. */
222 if (g_key_file_has_key (key_file, *group, "file", &error))
223 {
224 log_domain_entry->log_file =
225 g_key_file_get_value (key_file, *group, "file", &error);
226 }
227
228 /* Look for the prepend log level string. */
229 if (g_key_file_has_key (key_file, *group, "level", &error))
230 {
231 gchar *level;
232
233 level = g_key_file_get_value (key_file, *group, "level", &error);
234 level = g_strchug (level);
235 log_domain_entry->default_level = g_malloc (sizeof (gint));
236 *log_domain_entry->default_level = level_int_from_string (level);
237 g_free (level);
238 }
239
240 /* Look for the syslog_facility string. */
241 if (g_key_file_has_key (key_file, *group, "syslog_facility", &error))
242 {
243 log_domain_entry->syslog_facility =
244 g_key_file_get_value (key_file, *group, "syslog_facility", &error);
245 }
246 else
247 log_domain_entry->syslog_facility = "local0";
248
249 /* Look for the syslog_ident string. */
250 if (g_key_file_has_key (key_file, *group, "syslog_ident", &error))
251 {
252 log_domain_entry->syslog_ident =
253 g_key_file_get_value (key_file, *group, "syslog_ident", &error);
254 }
255 else
256 log_domain_entry->syslog_ident = g_strdup (*group);
257
258 /* Attach the struct to the list. */
259 log_domain_list = g_slist_prepend (log_domain_list, log_domain_entry);
260 group++;
261 }
262 /* Free the groups array. */
263 g_strfreev (groups);
264
265 /* Free the key file. */
266 g_key_file_free (key_file);
267
268 return log_domain_list;
269}
static gint level_int_from_string(const gchar *level)
Return the integer corresponding to a log level string.
Definition: logging.c:92

References gvm_logging_t::default_level, level_int_from_string(), gvm_logging_t::log_channel, gvm_logging_t::log_domain, gvm_logging_t::log_file, gvm_logging_t::prepend_separator, gvm_logging_t::prepend_string, gvm_logging_t::prepend_time_format, gvm_logging_t::syslog_facility, and gvm_logging_t::syslog_ident.

Here is the call graph for this function:

◆ log_func_for_gnutls()

void log_func_for_gnutls ( int  level,
const char *  message 
)

This function logs debug messages from gnutls.

Parameters
levelGnuTLS log level (integer from 0 to 99 according to GnuTLS documentation.
messageGnuTLS log message.

To enable GNUTLS debug messages, the environment variable OPENVAS_GNUTLS_DEBUG is to be set to the desired log level as described in the GNUTLS manual.

Definition at line 818 of file logging.c.

819{
820 g_log ("x gnutls", G_LOG_LEVEL_INFO, "tls(%d): %s", level, message);
821}

◆ set_log_reference()

void set_log_reference ( char *  ref)

Set the log reference object.

In order to be able to see which logs are related to each other, we define a common reference for them. E.g. when multiple scans in OpenVAS are running simultaniousely it is possible to detect all log corresponding to the same scan. The log reference is optional and must be set before calling setup_log_handlers. The data given must be freed by calling free_log_reference(). If called multiple times the old reference gets freed and the new one is set instead.

Parameters
ref

Definition at line 388 of file logging.c.

389{
390 if (reference)
391 g_free ((char *) reference);
392 reference = ref;
393}

References reference.

◆ setup_log_handlers()

int setup_log_handlers ( GSList *  gvm_log_config_list)

Sets up routing of logdomains to log handlers.

Iterates over the link list and adds the groups to the handler.

Parameters
gvm_log_config_listA pointer to the configuration linked list.
Returns
0 on success, -1 if not able to create log file directory or open log file for some domain.

Definition at line 887 of file logging.c.

888{
889 GSList *log_domain_list_tmp;
890 int err;
891 int ret = 0;
892
893 if (gvm_log_config_list != NULL)
894 {
895 /* Go to the head of the list. */
896 log_domain_list_tmp = (GSList *) gvm_log_config_list;
897
898 while (log_domain_list_tmp != NULL)
899 {
900 gvm_logging_t *log_domain_entry;
901
902 /* Get the list data which is an gvm_logging_t struct. */
903 log_domain_entry = log_domain_list_tmp->data;
904
905 err = check_log_file (log_domain_entry);
906 if (err)
907 {
908 ret = -1;
909 /* Go to the next item. */
910 log_domain_list_tmp = g_slist_next (log_domain_list_tmp);
911 continue;
912 }
913
914 GLogFunc logfunc =
915#if 0
916 (!strcmp (log_domain_entry, "syslog")) ? gvm_syslog_func :
917#endif
919
920 if (g_ascii_strcasecmp (log_domain_entry->log_domain, "*"))
921 {
922 g_log_set_handler (
923 log_domain_entry->log_domain,
924 (GLogLevelFlags) (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO
925 | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING
926 | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR
927 | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION),
928 (GLogFunc) logfunc, gvm_log_config_list);
929 }
930 else
931 {
932 g_log_set_default_handler ((GLogFunc) logfunc,
933 gvm_log_config_list);
934 }
935
936 /* Go to the next item. */
937 log_domain_list_tmp = g_slist_next (log_domain_list_tmp);
938 }
939 }
940 g_log_set_handler (
941 "",
942 (GLogLevelFlags) (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE
943 | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL
944 | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL
945 | G_LOG_FLAG_RECURSION),
946 (GLogFunc) gvm_log_func, gvm_log_config_list);
947
948 return ret;
949}
static int check_log_file(gvm_logging_t *log_domain_entry)
Check permissions of log file and log file directory.
Definition: logging.c:833
void gvm_log_func(const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer gvm_log_config_list)
Creates the formatted string and outputs it to the log destination.
Definition: logging.c:432

References check_log_file(), gvm_log_func(), and gvm_logging_t::log_domain.

Here is the call graph for this function:

Variable Documentation

◆ logger_mutex

GMutex* logger_mutex = NULL
static

Definition at line 336 of file logging.c.

Referenced by gvm_log_lock(), gvm_log_lock_init(), and gvm_log_unlock().

◆ reference

char* reference = NULL
static

Definition at line 372 of file logging.c.

Referenced by free_log_reference(), get_log_reference(), gvm_log_func(), and set_log_reference().