1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 * Authors: William Jon McCann <mccann@jhu.edu>
20 *
21 */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <unistd.h>
29
30 #include <syslog.h>
31
32 #include <glib.h>
33 #include <glib/gstdio.h>
34
35 #include "ck-log.h"
36
37 static gboolean initialized = FALSE;
38 static int syslog_levels = (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
39
40 static void
log_level_to_priority_and_prefix(GLogLevelFlags log_level,int * priorityp,const char ** prefixp)41 log_level_to_priority_and_prefix (GLogLevelFlags log_level,
42 int *priorityp,
43 const char **prefixp)
44 {
45 int priority;
46 const char *prefix;
47
48 /* Process the message prefix and priority */
49 switch (log_level & G_LOG_LEVEL_MASK) {
50 case G_LOG_FLAG_FATAL:
51 priority = LOG_EMERG;
52 prefix = "FATAL";
53 break;
54 case G_LOG_LEVEL_ERROR:
55 priority = LOG_ERR;
56 prefix = "ERROR";
57 break;
58 case G_LOG_LEVEL_CRITICAL:
59 priority = LOG_CRIT;
60 prefix = "CRITICAL";
61 break;
62 case G_LOG_LEVEL_WARNING:
63 priority = LOG_WARNING;
64 prefix = "WARNING";
65 break;
66 case G_LOG_LEVEL_MESSAGE:
67 priority = LOG_NOTICE;
68 prefix = "MESSAGE";
69 break;
70 case G_LOG_LEVEL_INFO:
71 priority = LOG_INFO;
72 prefix = "INFO";
73 break;
74 case G_LOG_LEVEL_DEBUG:
75 /* if debug was requested then bump this up to ERROR
76 * to ensure it is seen in a log */
77 if (syslog_levels & G_LOG_LEVEL_DEBUG) {
78 priority = LOG_WARNING;
79 } else {
80 priority = LOG_DEBUG;
81 }
82 prefix = "DEBUG";
83 break;
84 default:
85 priority = LOG_DEBUG;
86 prefix = "UNKNOWN";
87 break;
88 }
89
90 if (priorityp != NULL) {
91 *priorityp = priority;
92 }
93 if (prefixp != NULL) {
94 *prefixp = prefix;
95 }
96 }
97
98 void
ck_log_default_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer unused_data)99 ck_log_default_handler (const gchar *log_domain,
100 GLogLevelFlags log_level,
101 const gchar *message,
102 gpointer unused_data)
103 {
104 GString *gstring;
105 int priority;
106 const char *level_prefix;
107 char *string;
108 gboolean do_log;
109 gboolean is_fatal;
110
111 is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
112
113 do_log = (log_level & syslog_levels);
114 if (! do_log) {
115 return;
116 }
117
118 if (! initialized) {
119 ck_log_init ();
120 }
121
122 log_level_to_priority_and_prefix (log_level,
123 &priority,
124 &level_prefix);
125
126 gstring = g_string_new (NULL);
127
128 if (log_domain != NULL) {
129 g_string_append (gstring, log_domain);
130 g_string_append_c (gstring, '-');
131 }
132 g_string_append (gstring, level_prefix);
133
134 g_string_append (gstring, ": ");
135 if (message == NULL) {
136 g_string_append (gstring, "(NULL) message");
137 } else {
138 g_string_append (gstring, message);
139 }
140 if (is_fatal) {
141 g_string_append (gstring, "\naborting...\n");
142 } else {
143 g_string_append (gstring, "\n");
144 }
145
146 string = g_string_free (gstring, FALSE);
147
148 syslog (priority, "%s", string);
149
150 g_free (string);
151 }
152
153 void
ck_log_toggle_debug(void)154 ck_log_toggle_debug (void)
155 {
156 if (syslog_levels & G_LOG_LEVEL_DEBUG) {
157 g_debug ("Debugging disabled");
158 syslog_levels &= ~G_LOG_LEVEL_DEBUG;
159 } else {
160 syslog_levels |= G_LOG_LEVEL_DEBUG;
161 g_debug ("Debugging enabled");
162 }
163 }
164
165 void
ck_log_set_debug(gboolean debug)166 ck_log_set_debug (gboolean debug)
167 {
168 if (debug) {
169 syslog_levels |= G_LOG_LEVEL_DEBUG;
170 g_debug ("Debugging enabled");
171 } else {
172 g_debug ("Debugging disabled");
173 syslog_levels &= ~G_LOG_LEVEL_DEBUG;
174 }
175 }
176
177 void
ck_log_init(void)178 ck_log_init (void)
179 {
180 const char *prg_name;
181 int options;
182
183 g_log_set_default_handler (ck_log_default_handler, NULL);
184
185 prg_name = g_get_prgname ();
186
187 options = LOG_PID;
188 #ifdef LOG_PERROR
189 options |= LOG_PERROR;
190 #endif
191
192 openlog (prg_name, options, LOG_DAEMON);
193
194 initialized = TRUE;
195 }
196
197 void
ck_log_shutdown(void)198 ck_log_shutdown (void)
199 {
200 closelog ();
201 initialized = FALSE;
202 }
203
204