111
gf_log_globals_fini (void)
101
113
pthread_mutex_destroy (&THIS->ctx->log.logfile_mutex);
116
/** gf_log_fini - function to perform the cleanup of the log information
117
* @data - glusterfs context
118
* @return: success: 0
122
gf_log_fini (void *data)
124
glusterfs_ctx_t *ctx = data;
132
pthread_mutex_lock (&ctx->log.logfile_mutex);
134
if (ctx->log.logfile) {
135
if (fclose (ctx->log.logfile) != 0)
137
/* Logfile needs to be set to NULL, so that any
138
call to gf_log after calling gf_log_fini, will
139
log the message to stderr.
141
ctx->log.logfile = NULL;
144
pthread_mutex_unlock (&ctx->log.logfile_mutex);
152
* gf_get_error_message -function to get error message for given error code
153
* @error_code: error code defined by log book
155
* @return: success: string
159
gf_get_error_message (int error_code) {
160
return _gf_get_message (error_code);
165
* gf_openlog -function to open syslog specific to gluster based on
166
* existence of file /etc/glusterfs/logger.conf
167
* @ident: optional identification string similar to openlog()
168
* @option: optional value to option to openlog(). Passing -1 uses
169
* 'LOG_PID | LOG_NDELAY' as default
170
* @facility: optional facility code similar to openlog(). Passing -1
171
* uses LOG_DAEMON as default
176
gf_openlog (const char *ident, int option, int facility)
178
int _option = option;
179
int _facility = facility;
182
_option = LOG_PID | LOG_NDELAY;
184
if (-1 == _facility) {
185
_facility = LOG_LOCAL1;
188
setlocale(LC_ALL, "");
189
bindtextdomain("gluster", "/usr/share/locale");
190
textdomain("gluster");
192
openlog(ident, _option, _facility);
197
* _json_escape -function to convert string to json encoded string
199
* @buf: buffer to store encoded string
200
* @len: length of @buf
202
* @return: success: last unprocessed character position by pointer in @str
205
* Internal function. Heavily inspired by _ul_str_escape() function in
209
* [1] str = "devel error"
210
* buf = "devel error"
211
* [2] str = "devel error"
212
* buf = "devel\terror"
213
* [3] str = "I/O error on "/tmp/foo" file"
214
* buf = "I/O error on \"/tmp/foo\" file"
215
* [4] str = "I/O erroron /tmp/bar file"
216
* buf = "I/O error\u001bon /tmp/bar file"
220
_json_escape(const char *str, char *buf, size_t len)
222
static const unsigned char json_exceptions[UCHAR_MAX + 1] =
224
[0x01] = 1, [0x02] = 1, [0x03] = 1, [0x04] = 1,
225
[0x05] = 1, [0x06] = 1, [0x07] = 1, [0x08] = 1,
226
[0x09] = 1, [0x0a] = 1, [0x0b] = 1, [0x0c] = 1,
227
[0x0d] = 1, [0x0e] = 1, [0x0f] = 1, [0x10] = 1,
228
[0x11] = 1, [0x12] = 1, [0x13] = 1, [0x14] = 1,
229
[0x15] = 1, [0x16] = 1, [0x17] = 1, [0x18] = 1,
230
[0x19] = 1, [0x1a] = 1, [0x1b] = 1, [0x1c] = 1,
231
[0x1d] = 1, [0x1e] = 1, [0x1f] = 1,
232
['\\'] = 1, ['"'] = 1
234
static const char json_hex_chars[16] = "0123456789abcdef";
235
unsigned char *p = NULL;
238
if (!str || !buf || len <= 0) {
242
for (p = (unsigned char *)str;
243
*p && (pos + 1) < len;
246
if (json_exceptions[*p] == 0) {
251
if ((pos + 2) >= len) {
282
if ((pos + 6) >= len) {
290
buf[pos++] = json_hex_chars[(*p) >> 4];
291
buf[pos++] = json_hex_chars[(*p) & 0xf];
302
* gf_syslog -function to submit message to syslog specific to gluster
303
* @error_code: error code defined by log book
304
* @facility_priority: facility_priority of syslog()
305
* @format: optional format string to syslog()
310
gf_syslog (int error_code, int facility_priority, char *format, ...)
313
char json_msg[GF_JSON_MSG_LENGTH];
314
GF_UNUSED char *p = NULL;
315
const char *error_message = NULL;
316
char json_error_message[GF_JSON_MSG_LENGTH];
319
error_message = gf_get_error_message (error_code);
321
va_start (ap, format);
323
vasprintf (&msg, format, ap);
324
p = _json_escape (msg, json_msg, GF_JSON_MSG_LENGTH);
326
p = _json_escape (error_message, json_error_message,
328
syslog (facility_priority, GF_SYSLOG_CEE_FORMAT,
329
json_msg, error_code, json_error_message);
331
/* ignore the error code because no error message for it
332
and use normal syslog */
333
syslog (facility_priority, "%s", msg);
338
/* no user message: treat error_message as msg */
339
syslog (facility_priority, GF_SYSLOG_CEE_FORMAT,
340
json_error_message, error_code,
343
/* cannot produce log as neither error_message nor
349
#endif /* GF_USE_SYSLOG */
106
352
gf_log_globals_init (void *data)
113
359
ctx->log.gf_log_syslog = 1;
114
360
ctx->log.sys_log_level = GF_LOG_CRITICAL;
362
#ifndef GF_USE_SYSLOG
116
363
#ifdef GF_LINUX_HOST_OS
117
364
/* For the 'syslog' output. one can grep 'GlusterFS' in syslog
118
365
for serious logs */
119
366
openlog ("GlusterFS", LOG_PID, LOG_DAEMON);
124
gf_log_init (void *data, const char *file)
372
gf_log_init (void *data, const char *file, const char *ident)
126
374
glusterfs_ctx_t *ctx = NULL;
379
#if defined(GF_USE_SYSLOG)
381
/* use default ident and option */
382
/* TODO: make FACILITY configurable than LOG_DAEMON */
385
if (stat (GF_LOG_CONTROL_FILE, &buf) == 0) {
386
/* use syslog logging */
387
ctx->log.log_control_file_found = 1;
389
/* we need to keep this value as */
390
/* syslog uses it on every logging */
391
ctx->log.ident = gf_strdup (ident);
392
gf_openlog (ctx->log.ident, -1, LOG_DAEMON);
394
gf_openlog (NULL, -1, LOG_DAEMON);
397
/* use old style logging */
398
ctx->log.log_control_file_found = 0;
132
404
fprintf (stderr, "ERROR: no filename specified\n");
136
408
if (strcmp (file, "-") == 0) {
137
ctx->log.gf_log_logfile = stderr;
409
file = "/dev/stderr";
142
412
ctx->log.filename = gf_strdup (file);