1
/*********************************************************
2
* Copyright (C) 2010 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
22
* Logger that writes to syslog(3). Since there's only one "syslog connection"
23
* for the whole application, this code does reference counting to allow
24
* different domains to be configured with a "syslog" handler, and still be
25
* able to call closelog(3) when appropriate.
28
#include "glibUtils.h"
33
typedef struct SysLogger {
40
static SysLogger *gSysLogger;
41
static GStaticMutex gSysLoggerLock = G_STATIC_MUTEX_INIT;
45
*******************************************************************************
46
* SysLoggerLog -- */ /**
48
* @brief Sends the given log message to syslog.
50
* @param[in] domain Unused.
51
* @param[in] level Log level.
52
* @param[in] message Message to log.
53
* @param[in] data Unused.
55
******************************************************************************
59
SysLoggerLog(const gchar *domain,
67
/* glib and syslog disagree about critical / error. */
68
if (level & G_LOG_LEVEL_ERROR) {
70
} else if (level & G_LOG_LEVEL_CRITICAL) {
72
} else if (level & G_LOG_LEVEL_WARNING) {
73
priority = LOG_WARNING;
74
} else if (level & G_LOG_LEVEL_MESSAGE) {
75
priority = LOG_NOTICE;
76
} else if (level & G_LOG_LEVEL_INFO) {
82
local = g_locale_from_utf8(message, -1, NULL, NULL, NULL);
84
syslog(priority, "%s", local);
87
syslog(priority, "%s", message);
93
*******************************************************************************
94
* SysLoggerUnref -- */ /**
96
* @brief Decreases the ref count and closes syslog if it reaches 0.
98
* @param[in] data Unused.
100
*******************************************************************************
104
SysLoggerUnref(gpointer data)
106
g_return_if_fail(data == gSysLogger);
107
g_return_if_fail(gSysLogger->refcount > 0);
108
g_static_mutex_lock(&gSysLoggerLock);
109
gSysLogger->refcount -= 1;
110
if (gSysLogger->refcount == 0) {
112
g_free(gSysLogger->domain);
116
g_static_mutex_unlock(&gSysLoggerLock);
121
*******************************************************************************
122
* GlibUtils_CreateSysLogger -- */ /**
124
* @brief Initializes syslog if it hasn't been done yet.
126
* Since syslog is shared, it's not recommended to change the default domain
127
* during the lifetime of the application, since that may not reflect on the
128
* syslogs (and, when it does, it might be confusing).
130
* @param[in] domain Application name, used as the syslog identity.
131
* @param[in] facility Facility to use. One of: "daemon", "local[0-7]",
134
* @return Syslog logger data.
136
*******************************************************************************
140
GlibUtils_CreateSysLogger(const char *domain,
141
const char *facility)
143
g_static_mutex_lock(&gSysLoggerLock);
144
if (gSysLogger == NULL) {
145
int facid = LOG_USER;
147
if (facility != NULL) {
149
if (strcmp(facility, "daemon") == 0) {
151
} else if (sscanf(facility, "local%d", &idx) == 1) {
186
g_message("Invalid local facility for %s: %s\n", domain, facility);
189
} else if (strcmp(facility, "user") != 0) {
190
g_message("Invalid syslog facility for %s: %s\n", domain, facility);
194
gSysLogger = g_new0(SysLogger, 1);
195
gSysLogger->handler.addsTimestamp = TRUE;
196
gSysLogger->handler.shared = FALSE;
197
gSysLogger->handler.logfn = SysLoggerLog;
198
gSysLogger->handler.dtor = SysLoggerUnref;
200
gSysLogger->domain = g_strdup(domain);
201
gSysLogger->refcount = 1;
202
openlog(gSysLogger->domain, LOG_CONS | LOG_PID, facid);
204
gSysLogger->refcount += 1;
206
g_static_mutex_unlock(&gSysLoggerLock);
207
return &gSysLogger->handler;