corosync  2.4.3
logsys.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2004 MontaVista Software, Inc.
3  * Copyright (c) 2006-2012 Red Hat, Inc.
4  *
5  * Author: Steven Dake (sdake@redhat.com)
6  * Author: Lon Hohberger (lhh@redhat.com)
7  * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
8  *
9  * All rights reserved.
10  *
11  * This software licensed under BSD license, the text of which follows:
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * - Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  * - Redistributions in binary form must reproduce the above copyright notice,
19  * this list of conditions and the following disclaimer in the documentation
20  * and/or other materials provided with the distribution.
21  * - Neither the name of the MontaVista Software, Inc. nor the names of its
22  * contributors may be used to endorse or promote products derived from this
23  * software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <config.h>
39 
40 #include <stdint.h>
41 #include <ctype.h>
42 #include <assert.h>
43 #include <stdio.h>
44 #include <string.h>
45 
46 #include <qb/qbdefs.h>
47 #include <qb/qbutil.h>
48 #include <qb/qblog.h>
49 
50 #include <corosync/list.h>
51 #include <corosync/logsys.h>
52 
53 /*
54  * syslog prioritynames, facility names to value mapping
55  * Some C libraries build this in to their headers, but it is non-portable
56  * so logsys supplies its own version.
57  */
58 struct syslog_names {
59  const char *c_name;
60  int c_val;
61 };
62 
63 static struct syslog_names prioritynames[] =
64 {
65  { "alert", LOG_ALERT },
66  { "crit", LOG_CRIT },
67  { "debug", LOG_DEBUG },
68  { "emerg", LOG_EMERG },
69  { "err", LOG_ERR },
70  { "error", LOG_ERR },
71  { "info", LOG_INFO },
72  { "notice", LOG_NOTICE },
73  { "warning", LOG_WARNING },
74  { NULL, -1 }
75 };
76 
77 #define MAX_FILES_PER_SUBSYS 32
78 #ifdef HAVE_SMALL_MEMORY_FOOTPRINT
79 #define IPC_LOGSYS_SIZE 8192*64
80 #else
81 #define IPC_LOGSYS_SIZE 8192*1024
82 #endif
83 
84 /*
85  * need unlogical order to preserve 64bit alignment
86  */
87 struct logsys_logger {
88  char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]; /* subsystem name */
89  char *logfile; /* log to file */
90  unsigned int mode; /* subsystem mode */
91  unsigned int debug; /* debug on|off|trace */
92  int syslog_priority; /* priority */
93  int logfile_priority; /* priority to file */
94  int init_status; /* internal field to handle init queues
95  for subsystems */
96  int32_t target_id;
97  char *files[MAX_FILES_PER_SUBSYS];
98  int32_t file_idx;
99  int32_t dirty;
100 };
101 
102 /* values for logsys_logger init_status */
103 #define LOGSYS_LOGGER_INIT_DONE 0
104 #define LOGSYS_LOGGER_NEEDS_INIT 1
105 
106 static int logsys_system_needs_init = LOGSYS_LOGGER_NEEDS_INIT;
107 
108 static struct logsys_logger logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT + 1];
109 
110 static pthread_mutex_t logsys_config_mutex = PTHREAD_MUTEX_INITIALIZER;
111 
112 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode);
113 static void _logsys_config_apply_per_file(int32_t s, const char *filename);
114 static void _logsys_config_apply_per_subsys(int32_t s);
115 static void _logsys_subsys_filename_add (int32_t s, const char *filename);
116 static void logsys_file_format_get(char* file_format, int buf_len);
117 
118 static char *format_buffer=NULL;
119 
120 static int logsys_thread_started = 0;
121 
122 static int _logsys_config_subsys_get_unlocked (const char *subsys)
123 {
124  unsigned int i;
125 
126  if (!subsys) {
128  }
129 
130  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
131  if (strcmp (logsys_loggers[i].subsys, subsys) == 0) {
132  return i;
133  }
134  }
135 
136  return (-1);
137 }
138 
139 
140 /*
141  * we need a version that can work when somebody else is already
142  * holding a config mutex lock or we will never get out of here
143  */
144 static int logsys_config_file_set_unlocked (
145  int subsysid,
146  const char **error_string,
147  const char *file)
148 {
149  static char error_string_response[512];
150  int i;
151  char file_format[128];
152 
153  if (logsys_loggers[subsysid].target_id > 0) {
154  int32_t f;
155  for (f = 0; f < logsys_loggers[subsysid].file_idx; f++) {
156  qb_log_filter_ctl(logsys_loggers[subsysid].target_id,
157  QB_LOG_FILTER_REMOVE,
158  QB_LOG_FILTER_FILE,
159  logsys_loggers[subsysid].files[f],
160  LOG_TRACE);
161  }
162  }
163 
164  logsys_loggers[subsysid].dirty = QB_TRUE;
165  if (file == NULL) {
166  return (0);
167  }
168 
169  if (logsys_loggers[subsysid].target_id > 0 &&
170  logsys_loggers[subsysid].logfile != NULL &&
171  strcmp(file, logsys_loggers[subsysid].logfile) == 0) {
172  return (0);
173  }
174 
175  if (strlen(file) >= PATH_MAX) {
176  snprintf (error_string_response,
177  sizeof(error_string_response),
178  "%s: logfile name exceed maximum system filename length",
179  logsys_loggers[subsysid].subsys);
180  *error_string = error_string_response;
181  return (-1);
182  }
183 
184  if (logsys_loggers[subsysid].logfile != NULL) {
185  free(logsys_loggers[subsysid].logfile);
186  logsys_loggers[subsysid].logfile = NULL;
187  }
188 
189  logsys_loggers[subsysid].logfile = strdup(file);
190 
191  if (logsys_loggers[subsysid].logfile == NULL) {
192  snprintf (error_string_response,
193  sizeof(error_string_response),
194  "Unable to allocate memory for logfile '%s'",
195  file);
196  *error_string = error_string_response;
197  return (-1);
198  }
199 
200  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
201  if ((logsys_loggers[i].logfile != NULL) &&
202  (strcmp (logsys_loggers[i].logfile, file) == 0) &&
203  (i != subsysid)) {
204  /* we have found another subsys with this config file
205  * so add a filter
206  */
207  logsys_loggers[subsysid].target_id = logsys_loggers[i].target_id;
208  return (0);
209  }
210  }
211 
212  if (logsys_loggers[subsysid].target_id > 0) {
213  int num_using_current = 0;
214  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
215  if (logsys_loggers[subsysid].target_id ==
216  logsys_loggers[i].target_id) {
217  num_using_current++;
218  }
219  }
220  if (num_using_current == 1) {
221  /* no one else is using this close it */
222  qb_log_file_close(logsys_loggers[subsysid].target_id);
223  }
224  }
225 
226  logsys_loggers[subsysid].target_id = qb_log_file_open(file);
227  if (logsys_loggers[subsysid].target_id < 0) {
228  int err = -logsys_loggers[subsysid].target_id;
229  char error_str[LOGSYS_MAX_PERROR_MSG_LEN];
230  const char *error_ptr;
231  error_ptr = qb_strerror_r(err, error_str, sizeof(error_str));
232 
233  free(logsys_loggers[subsysid].logfile);
234  logsys_loggers[subsysid].logfile = NULL;
235  snprintf (error_string_response,
236  sizeof(error_string_response),
237  "Can't open logfile '%s' for reason: %s (%d)",
238  file, error_ptr, err);
239  *error_string = error_string_response;
240  return (-1);
241  }
242  logsys_file_format_get(file_format, 128);
243  qb_log_format_set(logsys_loggers[subsysid].target_id, file_format);
244 
245  qb_log_ctl(logsys_loggers[subsysid].target_id,
246  QB_LOG_CONF_ENABLED,
247  (logsys_loggers[subsysid].mode & LOGSYS_MODE_OUTPUT_FILE));
248  if (logsys_thread_started) {
249  qb_log_ctl(logsys_loggers[subsysid].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
250  }
251 
252  return (0);
253 }
254 
255 static void logsys_subsys_init (
256  const char *subsys,
257  int subsysid)
258 {
259  if (logsys_system_needs_init == LOGSYS_LOGGER_NEEDS_INIT) {
260  logsys_loggers[subsysid].init_status =
262  } else {
263  logsys_loggers[subsysid].mode = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].mode;
264  logsys_loggers[subsysid].debug = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].debug;
265  logsys_loggers[subsysid].syslog_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].syslog_priority;
266  logsys_loggers[subsysid].logfile_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].logfile_priority;
267  logsys_loggers[subsysid].init_status = LOGSYS_LOGGER_INIT_DONE;
268  }
269  strncpy (logsys_loggers[subsysid].subsys, subsys,
270  sizeof (logsys_loggers[subsysid].subsys));
271  logsys_loggers[subsysid].subsys[
272  sizeof (logsys_loggers[subsysid].subsys) - 1] = '\0';
273  logsys_loggers[subsysid].file_idx = 0;
274 }
275 
276 static const char *_logsys_tags_stringify(uint32_t tags)
277 {
278  if (tags == QB_LOG_TAG_LIBQB_MSG) {
279  return "QB";
280  } else {
281  return logsys_loggers[tags].subsys;
282  }
283 }
284 
286 {
287  int i;
288  int f;
289  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
290  free(logsys_loggers[i].logfile);
291  for (f = 0; f < logsys_loggers[i].file_idx; f++) {
292  free(logsys_loggers[i].files[f]);
293  }
294  }
295 
296  qb_log_fini ();
297 }
298 
299 /*
300  * Internal API - exported
301  */
302 
304  const char *mainsystem,
305  unsigned int mode,
306  int syslog_facility,
307  int syslog_priority)
308 {
309  int i;
310  int32_t fidx;
311  char tempsubsys[LOGSYS_MAX_SUBSYS_NAMELEN];
312  int blackbox_enable_res;
313 
314  if ((mainsystem == NULL) ||
315  (strlen(mainsystem) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
316  return -1;
317  }
318 
319  /*
320  * Setup libqb as a subsys
321  */
322  i = _logsys_subsys_create ("QB", "array.c,log.c,log_syslog.c,log_blackbox.c,log_format.c,"
323  "log_file.c,log_dcs.c,log_thread.c,ipc_shm.c,ipcs.c,ipc_us.c,loop.c,"
324  "loop_poll_epoll.c,loop_job.c,loop_poll_poll.c,loop_poll_kqueue.c,"
325  "loop_timerlist.c,loop_poll.c,ringbuffer.c,ringbuffer_helper.c,trie.c,"
326  "map.c,skiplist.c,rpl_sem.c,hdb.c,unix.c,hashtable.c,strlcpy.c,ipc_socket.c,"
327  "strchrnul.c,ipc_setup.c,strlcat.c");
328  if (i < 0) {
329  return -1;
330  }
331 
332  /*
333  * name clash
334  * _logsys_subsys_filename_add (i, "util.c");
335  */
336 
337  /*
338  * This file (logsys.c) is not exactly QB. We need tag for logsys.c if flightrecorder init
339  * fails, and QB seems to be closest.
340  */
341  _logsys_subsys_filename_add (i, "logsys.c");
342 
344 
345  pthread_mutex_lock (&logsys_config_mutex);
346 
347  snprintf(logsys_loggers[i].subsys,
349  "%s", mainsystem);
350 
351  logsys_loggers[i].mode = mode;
352  logsys_loggers[i].debug = LOGSYS_DEBUG_OFF;
353  logsys_loggers[i].file_idx = 0;
354  logsys_loggers[i].logfile_priority = syslog_priority;
355  logsys_loggers[i].syslog_priority = syslog_priority;
356 
357  qb_log_init(mainsystem, syslog_facility, syslog_priority);
358  if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_STDERR) {
359  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
360  } else {
361  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
362  }
363  if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_SYSLOG) {
364  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
365  } else {
366  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
367  }
368  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG);
369 
370  qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
371  QB_LOG_FILTER_FILE, "*", LOG_TRACE);
372  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, IPC_LOGSYS_SIZE);
373  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_THREADED, QB_FALSE);
374  blackbox_enable_res = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
375 
376  if (logsys_format_set(NULL) == -1) {
377  return -1;
378  }
379 
380  qb_log_tags_stringify_fn_set(_logsys_tags_stringify);
381 
382  logsys_loggers[i].init_status = LOGSYS_LOGGER_INIT_DONE;
383  logsys_system_needs_init = LOGSYS_LOGGER_INIT_DONE;
384 
385  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
386  if ((strcmp (logsys_loggers[i].subsys, "") != 0) &&
387  (logsys_loggers[i].init_status ==
389  fidx = logsys_loggers[i].file_idx;
390  strncpy (tempsubsys, logsys_loggers[i].subsys,
391  sizeof (tempsubsys));
392  tempsubsys[sizeof (tempsubsys) - 1] = '\0';
393  logsys_subsys_init(tempsubsys, i);
394  logsys_loggers[i].file_idx = fidx;
395  _logsys_config_mode_set_unlocked(i, logsys_loggers[i].mode);
396  _logsys_config_apply_per_subsys(i);
397  }
398  }
399 
400  if (blackbox_enable_res < 0) {
401  LOGSYS_PERROR (-blackbox_enable_res, LOGSYS_LEVEL_WARNING,
402  "Unable to initialize log flight recorder. "\
403  "The most common cause of this error is " \
404  "not enough space on /dev/shm. Corosync will continue work, " \
405  "but blackbox will not be available");
406  }
407 
408  pthread_mutex_unlock (&logsys_config_mutex);
409 
410  return (0);
411 }
412 
413 
414 static void _logsys_subsys_filename_add (int32_t s, const char *filename)
415 {
416  int i;
417 
418  if (filename == NULL) {
419  return;
420  }
421  assert(logsys_loggers[s].file_idx < MAX_FILES_PER_SUBSYS);
422  assert(logsys_loggers[s].file_idx >= 0);
423 
424  for (i = 0; i < logsys_loggers[s].file_idx; i++) {
425  if (strcmp(logsys_loggers[s].files[i], filename) == 0) {
426  return;
427  }
428  }
429  logsys_loggers[s].files[logsys_loggers[s].file_idx++] = strdup(filename);
430 
431  if (logsys_system_needs_init == LOGSYS_LOGGER_INIT_DONE) {
432  _logsys_config_apply_per_file(s, filename);
433  }
434 }
435 
436 int _logsys_subsys_create (const char *subsys, const char *filename)
437 {
438  int i;
439 
440  if ((subsys == NULL) ||
441  (strlen(subsys) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
442  return -1;
443  }
444 
445  pthread_mutex_lock (&logsys_config_mutex);
446 
447  i = _logsys_config_subsys_get_unlocked (subsys);
448  if ((i > -1) && (i < LOGSYS_MAX_SUBSYS_COUNT)) {
449  _logsys_subsys_filename_add(i, filename);
450  pthread_mutex_unlock (&logsys_config_mutex);
451  return i;
452  }
453 
454  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
455  if (strcmp (logsys_loggers[i].subsys, "") == 0) {
456  logsys_subsys_init(subsys, i);
457  _logsys_subsys_filename_add(i, filename);
458  break;
459  }
460  }
461 
462  if (i >= LOGSYS_MAX_SUBSYS_COUNT) {
463  i = -1;
464  }
465 
466  pthread_mutex_unlock (&logsys_config_mutex);
467  return i;
468 }
469 
470 int _logsys_config_subsys_get (const char *subsys)
471 {
472  unsigned int i;
473 
474  pthread_mutex_lock (&logsys_config_mutex);
475 
476  i = _logsys_config_subsys_get_unlocked (subsys);
477 
478  pthread_mutex_unlock (&logsys_config_mutex);
479 
480  return i;
481 }
482 
483 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode)
484 {
485  if ( logsys_loggers[subsysid].mode == new_mode) {
486  return 0;
487  }
488  if (logsys_loggers[subsysid].target_id > 0) {
489  qb_log_ctl(logsys_loggers[subsysid].target_id,
490  QB_LOG_CONF_ENABLED,
491  (new_mode & LOGSYS_MODE_OUTPUT_FILE));
492  }
493 
494  if (subsysid == LOGSYS_MAX_SUBSYS_COUNT) {
495  qb_log_ctl(QB_LOG_STDERR,
496  QB_LOG_CONF_ENABLED,
497  (new_mode & LOGSYS_MODE_OUTPUT_STDERR));
498  qb_log_ctl(QB_LOG_SYSLOG,
499  QB_LOG_CONF_ENABLED,
500  (new_mode & LOGSYS_MODE_OUTPUT_SYSLOG));
501  }
502  logsys_loggers[subsysid].mode = new_mode;
503  return 0;
504 }
505 
506 int logsys_config_mode_set (const char *subsys, unsigned int mode)
507 {
508  int i;
509 
510  pthread_mutex_lock (&logsys_config_mutex);
511  if (subsys != NULL) {
512  i = _logsys_config_subsys_get_unlocked (subsys);
513  if (i >= 0) {
514  i = _logsys_config_mode_set_unlocked(i, mode);
515  }
516  } else {
517  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
518  _logsys_config_mode_set_unlocked(i, mode);
519  }
520  i = 0;
521  }
522 
523  pthread_mutex_unlock (&logsys_config_mutex);
524 
525  return i;
526 }
527 
528 unsigned int logsys_config_mode_get (const char *subsys)
529 {
530  int i;
531 
532  i = _logsys_config_subsys_get (subsys);
533  if (i < 0) {
534  return i;
535  }
536 
537  return logsys_loggers[i].mode;
538 }
539 
541  const char *subsys,
542  const char **error_string,
543  const char *file)
544 {
545  int i;
546  int res;
547 
548  pthread_mutex_lock (&logsys_config_mutex);
549 
550  if (subsys != NULL) {
551  i = _logsys_config_subsys_get_unlocked (subsys);
552  if (i < 0) {
553  res = i;
554  } else {
555  res = logsys_config_file_set_unlocked(i, error_string, file);
556  }
557  } else {
558  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
559  res = logsys_config_file_set_unlocked(i, error_string, file);
560  if (res < 0) {
561  break;
562  }
563  }
564  }
565 
566  pthread_mutex_unlock (&logsys_config_mutex);
567  return res;
568 }
569 
570 static void
571 logsys_file_format_get(char* file_format, int buf_len)
572 {
573  char *per_t;
574  file_format[0] = '\0';
575  per_t = strstr(format_buffer, "%t");
576  if (per_t) {
577  strcpy(file_format, "%t [%P] %H %N");
578  per_t += 2;
579  strncat(file_format, per_t, buf_len - strlen("%t [%P] %H %N"));
580  } else {
581  strcpy(file_format, "[%P] %H %N");
582  strncat(file_format, format_buffer, buf_len - strlen("[%P] %H %N"));
583  }
584 }
585 
586 int logsys_format_set (const char *format)
587 {
588  int i;
589  int c;
590  int w;
591  int reminder;
592  char syslog_format[128];
593  char file_format[128];
594 
595  if (format_buffer) {
596  free(format_buffer);
597  format_buffer = NULL;
598  }
599 
600  format_buffer = strdup(format ? format : "%7p [%6g] %b");
601  if (format_buffer == NULL) {
602  return -1;
603  }
604 
605  qb_log_format_set(QB_LOG_STDERR, format_buffer);
606 
607  logsys_file_format_get(file_format, 128);
608  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
609  if (logsys_loggers[i].target_id > 0) {
610  qb_log_format_set(logsys_loggers[i].target_id, file_format);
611  }
612  }
613 
614  /*
615  * This just goes through and remove %t and %p from
616  * the format string for syslog.
617  */
618  w = 0;
619  memset(syslog_format, '\0', sizeof(syslog_format));
620  for (c = 0; c < strlen(format_buffer); c++) {
621  if (format_buffer[c] == '%') {
622  reminder = c;
623  for (c++; c < strlen(format_buffer); c++) {
624  if (isdigit(format_buffer[c])) {
625  continue;
626  }
627  if (format_buffer[c] == 't' ||
628  format_buffer[c] == 'p') {
629  c++;
630  } else {
631  c = reminder;
632  }
633  break;
634  }
635  }
636  syslog_format[w] = format_buffer[c];
637  w++;
638  }
639  qb_log_format_set(QB_LOG_SYSLOG, syslog_format);
640 
641  return 0;
642 }
643 
644 char *logsys_format_get (void)
645 {
646  return format_buffer;
647 }
648 
650  const char *subsys,
651  unsigned int facility)
652 {
653  return qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, facility);
654 }
655 
657  const char *subsys,
658  unsigned int priority)
659 {
660  int i;
661 
662  pthread_mutex_lock (&logsys_config_mutex);
663  if (subsys != NULL) {
664  i = _logsys_config_subsys_get_unlocked (subsys);
665  if (i >= 0) {
666  logsys_loggers[i].syslog_priority = priority;
667  logsys_loggers[i].dirty = QB_TRUE;
668 
669  i = 0;
670  }
671  } else {
672  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
673  logsys_loggers[i].syslog_priority = priority;
674  logsys_loggers[i].dirty = QB_TRUE;
675  }
676  i = 0;
677  }
678  pthread_mutex_unlock (&logsys_config_mutex);
679 
680  return i;
681 }
682 
684  const char *subsys,
685  unsigned int priority)
686 {
687  int i;
688 
689  pthread_mutex_lock (&logsys_config_mutex);
690  if (subsys != NULL) {
691  i = _logsys_config_subsys_get_unlocked (subsys);
692  if (i >= 0) {
693  logsys_loggers[i].logfile_priority = priority;
694  logsys_loggers[i].dirty = QB_TRUE;
695  i = 0;
696  }
697  } else {
698  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
699  logsys_loggers[i].logfile_priority = priority;
700  logsys_loggers[i].dirty = QB_TRUE;
701  }
702  i = 0;
703  }
704  pthread_mutex_unlock (&logsys_config_mutex);
705 
706  return i;
707 }
708 
709 
710 static void _logsys_config_apply_per_file(int32_t s, const char *filename)
711 {
712  uint32_t syslog_priority = logsys_loggers[s].syslog_priority;
713  uint32_t logfile_priority = logsys_loggers[s].logfile_priority;
714 
715  qb_log_filter_ctl(s, QB_LOG_TAG_SET, QB_LOG_FILTER_FILE,
716  filename, LOG_TRACE);
717 
718  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_REMOVE,
719  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
720  qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
721  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
722  if (logsys_loggers[s].target_id > 0) {
723  qb_log_filter_ctl(logsys_loggers[s].target_id,
724  QB_LOG_FILTER_REMOVE,
725  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
726  }
727 
728  if (logsys_loggers[s].debug != LOGSYS_DEBUG_OFF) {
729  switch (logsys_loggers[s].debug) {
730  case LOGSYS_DEBUG_ON:
731  syslog_priority = LOG_DEBUG;
732  logfile_priority = LOG_DEBUG;
733  break;
734  case LOGSYS_DEBUG_TRACE:
735  syslog_priority = LOG_TRACE;
736  logfile_priority = LOG_TRACE;
737  break;
738  default:
739  assert(0);
740  }
741  }
742  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
743  QB_LOG_FILTER_FILE, filename,
744  syslog_priority);
745  qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
746  QB_LOG_FILTER_FILE, filename,
747  logfile_priority);
748  if (logsys_loggers[s].target_id > 0) {
749  qb_log_filter_ctl(logsys_loggers[s].target_id,
750  QB_LOG_FILTER_ADD,
751  QB_LOG_FILTER_FILE, filename,
752  logfile_priority);
753  }
754 }
755 
756 static void _logsys_config_apply_per_subsys(int32_t s)
757 {
758  int32_t f;
759  for (f = 0; f < logsys_loggers[s].file_idx; f++) {
760  _logsys_config_apply_per_file(s, logsys_loggers[s].files[f]);
761  }
762  if (logsys_loggers[s].target_id > 0) {
763  qb_log_ctl(logsys_loggers[s].target_id,
764  QB_LOG_CONF_ENABLED,
765  (logsys_loggers[s].mode & LOGSYS_MODE_OUTPUT_FILE));
766  }
767  logsys_loggers[s].dirty = QB_FALSE;
768 }
769 
771 {
772  int32_t s;
773 
774  for (s = 0; s <= LOGSYS_MAX_SUBSYS_COUNT; s++) {
775  if (strcmp(logsys_loggers[s].subsys, "") == 0) {
776  continue;
777  }
778  _logsys_config_apply_per_subsys(s);
779  }
780 }
781 
783  const char *subsys,
784  unsigned int debug)
785 {
786  int i;
787 
788  pthread_mutex_lock (&logsys_config_mutex);
789  if (subsys != NULL) {
790  i = _logsys_config_subsys_get_unlocked (subsys);
791  if (i >= 0) {
792  logsys_loggers[i].dirty = QB_TRUE;
793  logsys_loggers[i].debug = debug;
794  i = 0;
795  }
796  } else {
797  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
798  logsys_loggers[i].debug = debug;
799  logsys_loggers[i].dirty = QB_TRUE;
800  }
801  i = 0;
802  }
803  pthread_mutex_unlock (&logsys_config_mutex);
804 
805  return i;
806 }
807 
808 int logsys_priority_id_get (const char *name)
809 {
810  unsigned int i;
811 
812  for (i = 0; prioritynames[i].c_name != NULL; i++) {
813  if (strcasecmp(name, prioritynames[i].c_name) == 0) {
814  return (prioritynames[i].c_val);
815  }
816  }
817  return (-1);
818 }
819 
821 {
822  int i;
823  int err;
824 
825  err = qb_log_thread_start();
826  if (err != 0) {
827  return (err);
828  }
829 
830  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
831  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
832  if (logsys_loggers[i].target_id > 0) {
833  qb_log_ctl(logsys_loggers[i].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
834  }
835  }
836 
837  logsys_thread_started = 1;
838 
839  return (0);
840 }
#define LOGSYS_DEBUG_TRACE
Definition: logsys.h:92
#define LOGSYS_MAX_PERROR_MSG_LEN
Definition: logsys.h:85
char * logsys_format_get(void)
logsys_format_get
Definition: logsys.c:644
int logsys_config_debug_set(const char *subsys, unsigned int debug)
enabling debug, disable message priority filtering.
Definition: logsys.c:782
#define IPC_LOGSYS_SIZE
Definition: logsys.c:81
int logsys_config_mode_set(const char *subsys, unsigned int mode)
logsys_config_mode_set
Definition: logsys.c:506
int logsys_thread_start(void)
logsys_thread_start
Definition: logsys.c:820
#define LOGSYS_MAX_SUBSYS_NAMELEN
Definition: logsys.h:84
int syslog_priority
Definition: logsys.c:92
#define LOGSYS_DEBUG_ON
Definition: logsys.h:91
#define LOGSYS_PERROR(err_num, level, fmt, args...)
The LOGSYS_PERROR macro.
Definition: logsys.h:313
#define LOGSYS_MODE_OUTPUT_FILE
Definition: logsys.h:58
int logsys_config_logfile_priority_set(const char *subsys, unsigned int priority)
logsys_config_logfile_priority_set
Definition: logsys.c:683
int logsys_config_syslog_priority_set(const char *subsys, unsigned int priority)
logsys_config_syslog_priority_set
Definition: logsys.c:656
int32_t target_id
Definition: logsys.c:96
int logfile_priority
Definition: logsys.c:93
#define LOGSYS_LEVEL_WARNING
Definition: logsys.h:71
#define LOGSYS_MAX_SUBSYS_COUNT
Definition: logsys.h:83
void logsys_config_apply(void)
logsys_config_apply
Definition: logsys.c:770
int logsys_priority_id_get(const char *name)
logsys_priority_id_get
Definition: logsys.c:808
#define LOGSYS_LOGGER_NEEDS_INIT
Definition: logsys.c:104
char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]
Definition: logsys.c:88
int logsys_config_file_set(const char *subsys, const char **error_string, const char *file)
to close a logfile, just invoke this function with a NULL file or if you want to change logfile...
Definition: logsys.c:540
#define LOGSYS_MODE_OUTPUT_SYSLOG
Definition: logsys.h:60
int32_t dirty
Definition: logsys.c:99
Linked list API.
#define LOGSYS_DEBUG_OFF
Definition: logsys.h:90
int logsys_format_set(const char *format)
configuration bits that can only be done for the whole system
Definition: logsys.c:586
void logsys_system_fini(void)
logsys_system_fini
Definition: logsys.c:285
#define MAX_FILES_PER_SUBSYS
Definition: logsys.c:77
int c_val
Definition: logsys.c:60
unsigned int logsys_config_mode_get(const char *subsys)
logsys_config_mode_get
Definition: logsys.c:528
int init_status
Definition: logsys.c:94
unsigned int mode
Definition: logsys.c:90
int logsys_config_syslog_facility_set(const char *subsys, unsigned int facility)
per system/subsystem settings.
Definition: logsys.c:649
const char * c_name
Definition: logsys.c:59
#define LOGSYS_LOGGER_INIT_DONE
Definition: logsys.c:103
unsigned int debug
Definition: logsys.c:91
int32_t file_idx
Definition: logsys.c:98
int _logsys_system_setup(const char *mainsystem, unsigned int mode, int syslog_facility, int syslog_priority)
_logsys_system_setup
Definition: logsys.c:303
char * logfile
Definition: logsys.c:89
int _logsys_subsys_create(const char *subsys, const char *filename)
_logsys_subsys_create
Definition: logsys.c:436
char * files[MAX_FILES_PER_SUBSYS]
Definition: logsys.c:97
#define LOGSYS_MODE_OUTPUT_STDERR
Definition: logsys.h:59
int _logsys_config_subsys_get(const char *subsys)
_logsys_config_subsys_get
Definition: logsys.c:470