Greenbone Vulnerability Management Libraries  22.8.0
logging.c
Go to the documentation of this file.
1 /* SPDX-FileCopyrightText: 2017-2023 Greenbone AG
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  */
5 
16 #include "logging.h"
17 
18 #include "gvm_sentry.h" /* for gvm_sentry_log */
19 
20 #include <errno.h> /* for errno */
21 #include <libgen.h> /* for dirname */
22 #include <stdio.h> /* for fflush, fprintf, stderr */
23 #include <stdlib.h> /* for atoi */
24 #include <string.h> /* for strcasecmp, strlen, strerror */
25 #define SYSLOG_NAMES
26 #include <syslog.h> /* for LOG_INFO, facilitynames, closelog, openlog */
27 #undef SYSLOG_NAMES
28 #include <time.h> /* for localtime, time, time_t */
29 #include <unistd.h> /* for getpid */
30 
31 #undef G_LOG_DOMAIN
32 
35 #define G_LOG_DOMAIN "libgvm base"
36 
42 typedef struct
43 {
44  gchar *log_domain;
45  gchar *prepend_string;
47  gchar *log_file;
48  GLogLevelFlags *default_level;
49  GIOChannel *log_channel;
50  gchar *syslog_facility;
51  gchar *syslog_ident;
55 
67 gchar *
68 get_time (gchar *time_fmt)
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 }
83 
91 static gint
92 level_int_from_string (const gchar *level)
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 }
113 
122 static gint
123 facility_int_from_string (const gchar *facility)
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 }
137 
148 GSList *
149 load_log_configuration (gchar *config_file)
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 }
270 
276 void
277 free_log_configuration (GSList *log_domain_list)
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 }
316 
325 void
326 gvm_log_silent (const char *log_domain, GLogLevelFlags log_level,
327  const char *message, gpointer gvm_log_config_list)
328 {
329  (void) log_domain;
330  (void) log_level;
331  (void) message;
332  (void) gvm_log_config_list;
333  return;
334 }
335 
336 static GMutex *logger_mutex = NULL;
337 
341 static void
343 {
344  if (logger_mutex == NULL)
345  {
346  logger_mutex = g_malloc (sizeof (*logger_mutex));
347  g_mutex_init (logger_mutex);
348  }
349 }
350 
354 void
356 {
357  /* Initialize logger lock if not done already. */
359 
360  g_mutex_lock (logger_mutex);
361 }
362 
366 void
368 {
369  g_mutex_unlock (logger_mutex);
370 }
371 
372 static char *reference = NULL;
373 
387 void
388 set_log_reference (char *ref)
389 {
390  if (reference)
391  g_free ((char *) reference);
392  reference = ref;
393 }
394 
403 char *
405 {
406  return (char *) reference;
407 }
408 
415 void
417 {
418  if (reference)
419  g_free ((char *) reference);
420  reference = NULL;
421 }
422 
431 void
432 gvm_log_func (const char *log_domain, GLogLevelFlags log_level,
433  const char *message, gpointer gvm_log_config_list)
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  }
801  gvm_log_unlock ();
802  g_free (tmpstr);
803  g_free (prepend_buf);
804 }
805 
817 void
818 log_func_for_gnutls (int level, const char *message)
819 {
820  g_log ("x gnutls", G_LOG_LEVEL_INFO, "tls(%d): %s", level, message);
821 }
822 
832 static int
833 check_log_file (gvm_logging_t *log_domain_entry)
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 }
875 
886 int
887 setup_log_handlers (GSList *gvm_log_config_list)
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
918  gvm_log_func;
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 }
gvm_log_unlock
void gvm_log_unlock(void)
Unlock logger_mutex.
Definition: logging.c:367
gvm_logging_t::prepend_separator
gchar * prepend_separator
Definition: logging.c:52
gvm_logging_t::log_file
gchar * log_file
Where to log to.
Definition: logging.c:47
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.
Definition: logging.c:432
get_log_reference
char * get_log_reference(void)
Get the log reference object.
Definition: logging.c:404
gvm_log_lock_init
static void gvm_log_lock_init(void)
Initialize logger_mutex mutex if it was not done before.
Definition: logging.c:342
gvm_logging_t::log_domain
gchar * log_domain
Affected logdomain e.g libnasl.
Definition: logging.c:44
free_log_reference
void free_log_reference(void)
Free the log reference object.
Definition: logging.c:416
gvm_log_silent
void gvm_log_silent(const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer gvm_log_config_list)
Returns immediately.
Definition: logging.c:326
free_log_configuration
void free_log_configuration(GSList *log_domain_list)
Frees all resources loaded by the config loader.
Definition: logging.c:277
get_time
gchar * get_time(gchar *time_fmt)
Returns time as specified in time_fmt strftime format.
Definition: logging.c:68
gvm_logging_t::syslog_facility
gchar * syslog_facility
Syslog facility to use for syslog logging.
Definition: logging.c:50
logger_mutex
static GMutex * logger_mutex
Definition: logging.c:336
gvm_logging_t::default_level
GLogLevelFlags * default_level
What severity level to use as default.
Definition: logging.c:48
gvm_logging_t::log_channel
GIOChannel * log_channel
Gio Channel - FD holder for logfile.
Definition: logging.c:49
gvm_logging_t::prepend_time_format
gchar * prepend_time_format
If prependstring has t, format for strftime.
Definition: logging.c:46
gvm_logging_t::prepend_string
gchar * prepend_string
Prepend this string before every message.
Definition: logging.c:45
check_log_file
static int check_log_file(gvm_logging_t *log_domain_entry)
Check permissions of log file and log file directory.
Definition: logging.c:833
gvm_sentry.h
Implementation of sentry methods.
gvm_logging_t::syslog_ident
gchar * syslog_ident
Syslog ident to use for syslog logging.
Definition: logging.c:51
setup_log_handlers
int setup_log_handlers(GSList *gvm_log_config_list)
Sets up routing of logdomains to log handlers.
Definition: logging.c:887
gvm_sentry_log
void gvm_sentry_log(const char *message)
Send a message to Sentry server if it was initialized.
Definition: gvm_sentry.c:97
log_func_for_gnutls
void log_func_for_gnutls(int level, const char *message)
This function logs debug messages from gnutls.
Definition: logging.c:818
facility_int_from_string
static gint facility_int_from_string(const gchar *facility)
Return the integer corresponding to a syslog facility string.
Definition: logging.c:123
level_int_from_string
static gint level_int_from_string(const gchar *level)
Return the integer corresponding to a log level string.
Definition: logging.c:92
logging.h
Implementation of logging methods.
load_log_configuration
GSList * load_log_configuration(gchar *config_file)
Loads parameters from a config file into a linked list.
Definition: logging.c:149
set_log_reference
void set_log_reference(char *ref)
Set the log reference object.
Definition: logging.c:388
reference
static char * reference
Definition: logging.c:372
gvm_log_lock
void gvm_log_lock(void)
Try to lock logger_mutex.
Definition: logging.c:355
gvm_logging_t
Logging stores the parameters loaded from a log configuration.
Definition: logging.c:43