corosync  2.3.2
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;
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 (strlen(file) >= PATH_MAX) {
170  snprintf (error_string_response,
171  sizeof(error_string_response),
172  "%s: logfile name exceed maximum system filename lenght",
173  logsys_loggers[subsysid].subsys);
174  *error_string = error_string_response;
175  return (-1);
176  }
177 
178  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
179  if ((logsys_loggers[i].logfile != NULL) &&
180  (strcmp (logsys_loggers[i].logfile, file) == 0) &&
181  (i != subsysid)) {
182  /* we have found another subsys with this config file
183  * so add a filter
184  */
185  logsys_loggers[subsysid].target_id = logsys_loggers[i].target_id;
186  return (0);
187  }
188  }
189  logsys_loggers[subsysid].logfile = strdup(file);
190  if (logsys_loggers[subsysid].logfile == NULL) {
191  snprintf (error_string_response,
192  sizeof(error_string_response),
193  "Unable to allocate memory for logfile '%s'",
194  file);
195  *error_string = error_string_response;
196  return (-1);
197  }
198 
199  if (logsys_loggers[subsysid].target_id > 0) {
200  int num_using_current = 0;
201  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
202  if (logsys_loggers[subsysid].target_id ==
203  logsys_loggers[i].target_id) {
204  num_using_current++;
205  }
206  }
207  if (num_using_current == 1) {
208  /* no one else is using this close it */
209  qb_log_file_close(logsys_loggers[subsysid].target_id);
210  }
211  }
212 
213  logsys_loggers[subsysid].target_id = qb_log_file_open(file);
214  if (logsys_loggers[subsysid].target_id < 0) {
215  int err = -logsys_loggers[subsysid].target_id;
216  char error_str[LOGSYS_MAX_PERROR_MSG_LEN];
217  const char *error_ptr;
218  error_ptr = qb_strerror_r(err, error_str, sizeof(error_str));
219 
220  free(logsys_loggers[subsysid].logfile);
221  logsys_loggers[subsysid].logfile = NULL;
222  snprintf (error_string_response,
223  sizeof(error_string_response),
224  "Can't open logfile '%s' for reason: %s (%d)",
225  file, error_ptr, err);
226  *error_string = error_string_response;
227  return (-1);
228  }
229  logsys_file_format_get(file_format, 128);
230  qb_log_format_set(logsys_loggers[subsysid].target_id, file_format);
231 
232  qb_log_ctl(logsys_loggers[subsysid].target_id,
233  QB_LOG_CONF_ENABLED,
234  (logsys_loggers[subsysid].mode & LOGSYS_MODE_OUTPUT_FILE));
235  if (logsys_thread_started) {
236  qb_log_ctl(logsys_loggers[subsysid].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
237  }
238 
239  return (0);
240 }
241 
242 static void logsys_subsys_init (
243  const char *subsys,
244  int subsysid)
245 {
246  if (logsys_system_needs_init == LOGSYS_LOGGER_NEEDS_INIT) {
247  logsys_loggers[subsysid].init_status =
249  } else {
250  logsys_loggers[subsysid].mode = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].mode;
251  logsys_loggers[subsysid].debug = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].debug;
252  logsys_loggers[subsysid].syslog_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].syslog_priority;
253  logsys_loggers[subsysid].logfile_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].logfile_priority;
254  logsys_loggers[subsysid].init_status = LOGSYS_LOGGER_INIT_DONE;
255  }
256  strncpy (logsys_loggers[subsysid].subsys, subsys,
257  sizeof (logsys_loggers[subsysid].subsys));
258  logsys_loggers[subsysid].subsys[
259  sizeof (logsys_loggers[subsysid].subsys) - 1] = '\0';
260  logsys_loggers[subsysid].file_idx = 0;
261 }
262 
263 static const char *_logsys_tags_stringify(uint32_t tags)
264 {
265  if (tags == QB_LOG_TAG_LIBQB_MSG) {
266  return "QB";
267  } else {
268  return logsys_loggers[tags].subsys;
269  }
270 }
271 
273 {
274  int i;
275  int f;
276  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
277  free(logsys_loggers[i].logfile);
278  for (f = 0; f < logsys_loggers[i].file_idx; f++) {
279  free(logsys_loggers[i].files[f]);
280  }
281  }
282 
283  qb_log_fini ();
284 }
285 
286 /*
287  * Internal API - exported
288  */
289 
291  const char *mainsystem,
292  unsigned int mode,
293  int syslog_facility,
294  int syslog_priority)
295 {
296  int i;
297  int32_t fidx;
298  char tempsubsys[LOGSYS_MAX_SUBSYS_NAMELEN];
299 
300  if ((mainsystem == NULL) ||
301  (strlen(mainsystem) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
302  return -1;
303  }
304  /*
305  * Setup libqb as a subsys
306  */
307  i = _logsys_subsys_create ("QB", "array.c");
308  if (i < 0) {
309  return -1;
310  }
311 
312  _logsys_subsys_filename_add (i, "log.c");
313  _logsys_subsys_filename_add (i, "log_syslog.c");
314  _logsys_subsys_filename_add (i, "log_blackbox.c");
315  _logsys_subsys_filename_add (i, "log_format.c");
316  _logsys_subsys_filename_add (i, "log_file.c");
317  _logsys_subsys_filename_add (i, "log_dcs.c");
318  _logsys_subsys_filename_add (i, "log_thread.c");
319  _logsys_subsys_filename_add (i, "ipc_shm.c");
320  _logsys_subsys_filename_add (i, "ipcs.c");
321  _logsys_subsys_filename_add (i, "ipc_us.c");
322  _logsys_subsys_filename_add (i, "loop.c");
323  _logsys_subsys_filename_add (i, "loop_poll_epoll.c");
324  _logsys_subsys_filename_add (i, "loop_job.c");
325  _logsys_subsys_filename_add (i, "loop_poll_poll.c");
326  _logsys_subsys_filename_add (i, "loop_poll_kqueue.c");
327  _logsys_subsys_filename_add (i, "loop_timerlist.c");
328  _logsys_subsys_filename_add (i, "loop_poll.c");
329  _logsys_subsys_filename_add (i, "ringbuffer.c");
330  _logsys_subsys_filename_add (i, "ringbuffer_helper.c");
331  _logsys_subsys_filename_add (i, "trie.c");
332  _logsys_subsys_filename_add (i, "map.c");
333  _logsys_subsys_filename_add (i, "skiplist.c");
334  _logsys_subsys_filename_add (i, "rpl_sem.c");
335  _logsys_subsys_filename_add (i, "hdb.c");
336  _logsys_subsys_filename_add (i, "unix.c");
337  /*
338  * name clash
339  * _logsys_subsys_filename_add (i, "util.c");
340  */
341 
343 
344  pthread_mutex_lock (&logsys_config_mutex);
345 
346  snprintf(logsys_loggers[i].subsys,
348  "%s", mainsystem);
349 
350  logsys_loggers[i].mode = mode;
351  logsys_loggers[i].debug = LOGSYS_DEBUG_OFF;
352  logsys_loggers[i].file_idx = 0;
353  logsys_loggers[i].logfile_priority = syslog_priority;
354  logsys_loggers[i].syslog_priority = syslog_priority;
355 
356  qb_log_init(mainsystem, syslog_facility, syslog_priority);
357  if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_STDERR) {
358  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
359  } else {
360  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
361  }
362  if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_SYSLOG) {
363  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
364  } else {
365  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
366  }
367  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG);
368 
369  qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
370  QB_LOG_FILTER_FILE, "*", LOG_TRACE);
371  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, IPC_LOGSYS_SIZE);
372  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_THREADED, QB_FALSE);
373  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
374 
375  if (logsys_format_set(NULL) == -1) {
376  return -1;
377  }
378 
379  qb_log_tags_stringify_fn_set(_logsys_tags_stringify);
380 
381  logsys_loggers[i].init_status = LOGSYS_LOGGER_INIT_DONE;
382  logsys_system_needs_init = LOGSYS_LOGGER_INIT_DONE;
383 
384  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
385  if ((strcmp (logsys_loggers[i].subsys, "") != 0) &&
386  (logsys_loggers[i].init_status ==
388  fidx = logsys_loggers[i].file_idx;
389  strncpy (tempsubsys, logsys_loggers[i].subsys,
390  sizeof (tempsubsys));
391  tempsubsys[sizeof (tempsubsys) - 1] = '\0';
392  logsys_subsys_init(tempsubsys, i);
393  logsys_loggers[i].file_idx = fidx;
394  _logsys_config_mode_set_unlocked(i, logsys_loggers[i].mode);
395  _logsys_config_apply_per_subsys(i);
396  }
397  }
398 
399  pthread_mutex_unlock (&logsys_config_mutex);
400 
401  return (0);
402 }
403 
404 
405 static void _logsys_subsys_filename_add (int32_t s, const char *filename)
406 {
407  int i;
408 
409  if (filename == NULL) {
410  return;
411  }
412  assert(logsys_loggers[s].file_idx < MAX_FILES_PER_SUBSYS);
413  assert(logsys_loggers[s].file_idx >= 0);
414 
415  for (i = 0; i < logsys_loggers[s].file_idx; i++) {
416  if (strcmp(logsys_loggers[s].files[i], filename) == 0) {
417  return;
418  }
419  }
420  logsys_loggers[s].files[logsys_loggers[s].file_idx++] = strdup(filename);
421 
422  if (logsys_system_needs_init == LOGSYS_LOGGER_INIT_DONE) {
423  _logsys_config_apply_per_file(s, filename);
424  }
425 }
426 
427 int _logsys_subsys_create (const char *subsys, const char *filename)
428 {
429  int i;
430 
431  if ((subsys == NULL) ||
432  (strlen(subsys) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
433  return -1;
434  }
435 
436  pthread_mutex_lock (&logsys_config_mutex);
437 
438  i = _logsys_config_subsys_get_unlocked (subsys);
439  if ((i > -1) && (i < LOGSYS_MAX_SUBSYS_COUNT)) {
440  _logsys_subsys_filename_add(i, filename);
441  pthread_mutex_unlock (&logsys_config_mutex);
442  return i;
443  }
444 
445  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
446  if (strcmp (logsys_loggers[i].subsys, "") == 0) {
447  logsys_subsys_init(subsys, i);
448  _logsys_subsys_filename_add(i, filename);
449  break;
450  }
451  }
452 
453  if (i >= LOGSYS_MAX_SUBSYS_COUNT) {
454  i = -1;
455  }
456 
457  pthread_mutex_unlock (&logsys_config_mutex);
458  return i;
459 }
460 
461 int _logsys_config_subsys_get (const char *subsys)
462 {
463  unsigned int i;
464 
465  pthread_mutex_lock (&logsys_config_mutex);
466 
467  i = _logsys_config_subsys_get_unlocked (subsys);
468 
469  pthread_mutex_unlock (&logsys_config_mutex);
470 
471  return i;
472 }
473 
474 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode)
475 {
476  if ( logsys_loggers[subsysid].mode == new_mode) {
477  return 0;
478  }
479  if (logsys_loggers[subsysid].target_id > 0) {
480  qb_log_ctl(logsys_loggers[subsysid].target_id,
481  QB_LOG_CONF_ENABLED,
482  (new_mode & LOGSYS_MODE_OUTPUT_FILE));
483  }
484 
485  if (subsysid == LOGSYS_MAX_SUBSYS_COUNT) {
486  qb_log_ctl(QB_LOG_STDERR,
487  QB_LOG_CONF_ENABLED,
488  (new_mode & LOGSYS_MODE_OUTPUT_STDERR));
489  qb_log_ctl(QB_LOG_SYSLOG,
490  QB_LOG_CONF_ENABLED,
491  (new_mode & LOGSYS_MODE_OUTPUT_SYSLOG));
492  }
493  logsys_loggers[subsysid].mode = new_mode;
494  return 0;
495 }
496 
497 int logsys_config_mode_set (const char *subsys, unsigned int mode)
498 {
499  int i;
500 
501  pthread_mutex_lock (&logsys_config_mutex);
502  if (subsys != NULL) {
503  i = _logsys_config_subsys_get_unlocked (subsys);
504  if (i >= 0) {
505  i = _logsys_config_mode_set_unlocked(i, mode);
506  }
507  } else {
508  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
509  _logsys_config_mode_set_unlocked(i, mode);
510  }
511  i = 0;
512  }
513 
514  pthread_mutex_unlock (&logsys_config_mutex);
515 
516  return i;
517 }
518 
519 unsigned int logsys_config_mode_get (const char *subsys)
520 {
521  int i;
522 
523  i = _logsys_config_subsys_get (subsys);
524  if (i < 0) {
525  return i;
526  }
527 
528  return logsys_loggers[i].mode;
529 }
530 
532  const char *subsys,
533  const char **error_string,
534  const char *file)
535 {
536  int i;
537  int res;
538 
539  pthread_mutex_lock (&logsys_config_mutex);
540 
541  if (subsys != NULL) {
542  i = _logsys_config_subsys_get_unlocked (subsys);
543  if (i < 0) {
544  res = i;
545  } else {
546  res = logsys_config_file_set_unlocked(i, error_string, file);
547  }
548  } else {
549  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
550  res = logsys_config_file_set_unlocked(i, error_string, file);
551  if (res < 0) {
552  break;
553  }
554  }
555  }
556 
557  pthread_mutex_unlock (&logsys_config_mutex);
558  return res;
559 }
560 
561 static void
562 logsys_file_format_get(char* file_format, int buf_len)
563 {
564  char *per_t;
565  file_format[0] = '\0';
566  per_t = strstr(format_buffer, "%t");
567  if (per_t) {
568  strcpy(file_format, "%t [%P] %H %N");
569  per_t += 2;
570  strncat(file_format, per_t, buf_len - strlen("%t [%P] %H %N"));
571  } else {
572  strcpy(file_format, "[%P] %H %N");
573  strncat(file_format, format_buffer, buf_len - strlen("[%P] %H %N"));
574  }
575 }
576 
577 int logsys_format_set (const char *format)
578 {
579  int i;
580  int c;
581  int w;
582  int reminder;
583  char syslog_format[128];
584  char file_format[128];
585 
586  if (format_buffer) {
587  free(format_buffer);
588  format_buffer = NULL;
589  }
590 
591  format_buffer = strdup(format ? format : "%7p [%6g] %b");
592  if (format_buffer == NULL) {
593  return -1;
594  }
595 
596  qb_log_format_set(QB_LOG_STDERR, format_buffer);
597 
598  logsys_file_format_get(file_format, 128);
599  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
600  if (logsys_loggers[i].target_id > 0) {
601  qb_log_format_set(logsys_loggers[i].target_id, file_format);
602  }
603  }
604 
605  /*
606  * This just goes through and remove %t and %p from
607  * the format string for syslog.
608  */
609  w = 0;
610  memset(syslog_format, '\0', sizeof(syslog_format));
611  for (c = 0; c < strlen(format_buffer); c++) {
612  if (format_buffer[c] == '%') {
613  reminder = c;
614  for (c++; c < strlen(format_buffer); c++) {
615  if (isdigit(format_buffer[c])) {
616  continue;
617  }
618  if (format_buffer[c] == 't' ||
619  format_buffer[c] == 'p') {
620  c++;
621  } else {
622  c = reminder;
623  }
624  break;
625  }
626  }
627  syslog_format[w] = format_buffer[c];
628  w++;
629  }
630  qb_log_format_set(QB_LOG_SYSLOG, syslog_format);
631 
632  return 0;
633 }
634 
635 char *logsys_format_get (void)
636 {
637  return format_buffer;
638 }
639 
641  const char *subsys,
642  unsigned int facility)
643 {
644  return qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, facility);
645 }
646 
648  const char *subsys,
649  unsigned int priority)
650 {
651  int i;
652 
653  pthread_mutex_lock (&logsys_config_mutex);
654  if (subsys != NULL) {
655  i = _logsys_config_subsys_get_unlocked (subsys);
656  if (i >= 0) {
657  logsys_loggers[i].syslog_priority = priority;
658  logsys_loggers[i].dirty = QB_TRUE;
659 
660  i = 0;
661  }
662  } else {
663  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
664  logsys_loggers[i].syslog_priority = priority;
665  logsys_loggers[i].dirty = QB_TRUE;
666  }
667  i = 0;
668  }
669  pthread_mutex_unlock (&logsys_config_mutex);
670 
671  return i;
672 }
673 
675  const char *subsys,
676  unsigned int priority)
677 {
678  int i;
679 
680  pthread_mutex_lock (&logsys_config_mutex);
681  if (subsys != NULL) {
682  i = _logsys_config_subsys_get_unlocked (subsys);
683  if (i >= 0) {
684  logsys_loggers[i].logfile_priority = priority;
685  logsys_loggers[i].dirty = QB_TRUE;
686  i = 0;
687  }
688  } else {
689  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
690  logsys_loggers[i].logfile_priority = priority;
691  logsys_loggers[i].dirty = QB_TRUE;
692  }
693  i = 0;
694  }
695  pthread_mutex_unlock (&logsys_config_mutex);
696 
697  return i;
698 }
699 
700 
701 static void _logsys_config_apply_per_file(int32_t s, const char *filename)
702 {
703  uint32_t syslog_priority = logsys_loggers[s].syslog_priority;
704  uint32_t logfile_priority = logsys_loggers[s].logfile_priority;
705 
706  qb_log_filter_ctl(s, QB_LOG_TAG_SET, QB_LOG_FILTER_FILE,
707  filename, LOG_TRACE);
708 
709  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_REMOVE,
710  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
711  qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
712  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
713  if (logsys_loggers[s].target_id > 0) {
714  qb_log_filter_ctl(logsys_loggers[s].target_id,
715  QB_LOG_FILTER_REMOVE,
716  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
717  }
718 
719  if (logsys_loggers[s].debug != LOGSYS_DEBUG_OFF) {
720  switch (logsys_loggers[s].debug) {
721  case LOGSYS_DEBUG_ON:
722  syslog_priority = LOG_DEBUG;
723  logfile_priority = LOG_DEBUG;
724  break;
725  case LOGSYS_DEBUG_TRACE:
726  syslog_priority = LOG_TRACE;
727  logfile_priority = LOG_TRACE;
728  break;
729  default:
730  assert(0);
731  }
732  }
733  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
734  QB_LOG_FILTER_FILE, filename,
735  syslog_priority);
736  qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
737  QB_LOG_FILTER_FILE, filename,
738  logfile_priority);
739  if (logsys_loggers[s].target_id > 0) {
740  qb_log_filter_ctl(logsys_loggers[s].target_id,
741  QB_LOG_FILTER_ADD,
742  QB_LOG_FILTER_FILE, filename,
743  logfile_priority);
744  }
745 }
746 
747 static void _logsys_config_apply_per_subsys(int32_t s)
748 {
749  int32_t f;
750  for (f = 0; f < logsys_loggers[s].file_idx; f++) {
751  _logsys_config_apply_per_file(s, logsys_loggers[s].files[f]);
752  }
753  if (logsys_loggers[s].target_id > 0) {
754  qb_log_ctl(logsys_loggers[s].target_id,
755  QB_LOG_CONF_ENABLED,
756  (logsys_loggers[s].mode & LOGSYS_MODE_OUTPUT_FILE));
757  }
758  logsys_loggers[s].dirty = QB_FALSE;
759 }
760 
762 {
763  int32_t s;
764 
765  for (s = 0; s <= LOGSYS_MAX_SUBSYS_COUNT; s++) {
766  if (strcmp(logsys_loggers[s].subsys, "") == 0) {
767  continue;
768  }
769  _logsys_config_apply_per_subsys(s);
770  }
771 }
772 
774  const char *subsys,
775  unsigned int debug)
776 {
777  int i;
778 
779  pthread_mutex_lock (&logsys_config_mutex);
780  if (subsys != NULL) {
781  i = _logsys_config_subsys_get_unlocked (subsys);
782  if (i >= 0) {
783  logsys_loggers[i].dirty = QB_TRUE;
784  logsys_loggers[i].debug = debug;
785  i = 0;
786  }
787  } else {
788  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
789  logsys_loggers[i].debug = debug;
790  logsys_loggers[i].dirty = QB_TRUE;
791  }
792  i = 0;
793  }
794  pthread_mutex_unlock (&logsys_config_mutex);
795 
796  return i;
797 }
798 
799 int logsys_priority_id_get (const char *name)
800 {
801  unsigned int i;
802 
803  for (i = 0; prioritynames[i].c_name != NULL; i++) {
804  if (strcasecmp(name, prioritynames[i].c_name) == 0) {
805  return (prioritynames[i].c_val);
806  }
807  }
808  return (-1);
809 }
810 
812 {
813  int i;
814  int err;
815 
816  err = qb_log_thread_start();
817  if (err != 0) {
818  return (err);
819  }
820 
821  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
822  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
823  if (logsys_loggers[i].target_id > 0) {
824  qb_log_ctl(logsys_loggers[i].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
825  }
826  }
827 
828  logsys_thread_started = 1;
829 
830  return (0);
831 }
#define LOGSYS_DEBUG_TRACE
Definition: logsys.h:92
#define LOGSYS_MAX_PERROR_MSG_LEN
Definition: logsys.h:85
#define IPC_LOGSYS_SIZE
Definition: logsys.c:81
int logsys_config_file_set(const char *subsys, const char **error_string, const char *file)
Definition: logsys.c:531
#define LOGSYS_MAX_SUBSYS_NAMELEN
Definition: logsys.h:84
int syslog_priority
Definition: logsys.c:92
int _logsys_subsys_create(const char *subsys, const char *filename)
Definition: logsys.c:427
#define LOGSYS_DEBUG_ON
Definition: logsys.h:91
#define LOGSYS_MODE_OUTPUT_FILE
Definition: logsys.h:58
int32_t target_id
Definition: logsys.c:96
int logfile_priority
Definition: logsys.c:93
int logsys_config_debug_set(const char *subsys, unsigned int value)
Definition: logsys.c:773
#define LOGSYS_MAX_SUBSYS_COUNT
Definition: logsys.h:83
int logsys_config_syslog_facility_set(const char *subsys, unsigned int facility)
Definition: logsys.c:640
int logsys_config_mode_set(const char *subsys, unsigned int mode)
Definition: logsys.c:497
#define LOGSYS_LOGGER_NEEDS_INIT
Definition: logsys.c:104
char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]
Definition: logsys.c:88
int logsys_thread_start(void)
Definition: logsys.c:811
char * logsys_format_get(void)
Definition: logsys.c:635
#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_config_syslog_priority_set(const char *subsys, unsigned int priority)
Definition: logsys.c:647
int _logsys_system_setup(const char *mainsystem, unsigned int mode, int syslog_facility, int syslog_priority)
Definition: logsys.c:290
#define MAX_FILES_PER_SUBSYS
Definition: logsys.c:77
int c_val
Definition: logsys.c:60
int init_status
Definition: logsys.c:94
unsigned int mode
Definition: logsys.c:90
void logsys_config_apply(void)
Definition: logsys.c:761
int logsys_priority_id_get(const char *name)
Definition: logsys.c:799
const char * c_name
Definition: logsys.c:59
#define LOGSYS_LOGGER_INIT_DONE
Definition: logsys.c:103
unsigned int debug
Definition: logsys.c:91
int _logsys_config_subsys_get(const char *subsys)
Definition: logsys.c:461
int32_t file_idx
Definition: logsys.c:98
char * logfile
Definition: logsys.c:89
unsigned int logsys_config_mode_get(const char *subsys)
Definition: logsys.c:519
char * files[MAX_FILES_PER_SUBSYS]
Definition: logsys.c:97
int logsys_config_logfile_priority_set(const char *subsys, unsigned int priority)
Definition: logsys.c:674
#define LOGSYS_MODE_OUTPUT_STDERR
Definition: logsys.h:59
int logsys_format_set(const char *format)
Definition: logsys.c:577
void logsys_system_fini(void)
Definition: logsys.c:272