#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <sys/param.h>
#include "config.h"
#include "util.h"
#include "logging.h"
#include "path_utils.h"
Go to the source code of this file.
Defines | |
#define | DEFAULT_LOG_FILEPATH PKGLOGDIR "/" PACKAGE_NAME ".log" |
The default path name for our log file. | |
Functions | |
int | log_init () |
Initialize the logging subsystem. | |
int | log_fini () |
Close the logging subsystem, release resources. | |
int | log_close () |
Close the logging subsystem, release resources. | |
int | log_close_file () |
Close the log file, further log file write will be disabled. | |
int | log_set_filepath (const char *path) |
Close existing log file, set the current path of the log file, potentially reopen. | |
int | log_set_level (int level) |
Set the current logging level. | |
int | log_to_console (bool flag) |
Set boolean flag indicating log messages should appear on the console. | |
int | log_to_file (bool flag) |
Set boolean flag indicating log messages should be written to log file. | |
int | log_set_show_level (bool show) |
Set boolean flag indicating if the logging level should appear in log messages. | |
int | log_set_show_file (bool show) |
Set boolean flag indicating if the file name should appear in log messages. | |
int | log_set_show_line (bool show) |
Set boolean flag indicating if the line number should appear in log messages. | |
int | log_set_show_function (bool show) |
Set boolean flag indicating if the function name should appear in log messages. | |
int | log_set_show_time (bool show) |
Set boolean flag indicating if a timestamp should appear in log messages. | |
int | log_set_time_format (const char *format) |
Set the time format (as per strftime()) for log message timestamps. | |
void | log_msg1 (int level, const char *file, int line, const char *function, const char *fmt,...) |
If not filtered by the log level format a log message and emit it on each enabled output stream. | |
int | log_level_from_string (const char *level_str, int *level) |
Parse a log level in case insensitive manner, set variable to log level enumeration. | |
Variables | |
static char | log_filepath [PATH_MAX] = DEFAULT_LOG_FILEPATH |
path name of log file | |
static int | log_level = LOG_WARN |
current logging level | |
static bool | log_to_console_flag = false |
boolean flag if log messages should be written to the console | |
static int | log_console_fd = 1 |
the file descriptor for console logging | |
static bool | log_to_file_flag = true |
boolean flag if log messages should be written to the log file | |
static int | log_file_fd = -1 |
the file descriptor for log file logging | |
static char | log_time_format [128] = "" |
strftime style format for timestamps | |
Flags for optional components in a log message | |
static bool | show_level = false |
true if the log level appears in messages | |
static bool | show_file = false |
true if the file name appears in messages | |
static bool | show_line = false |
true if the line number appears in messages | |
static bool | show_function = false |
true if the function name appears in messages | |
static bool | show_time = false |
true if a timestamp appears in messages |
Definition in file logging.c.
#define DEFAULT_LOG_FILEPATH PKGLOGDIR "/" PACKAGE_NAME ".log" |
The default path name for our log file.
On the assumption the package name is "lwatch" this typically expands to: /var/log/lwatch/lwatch.log
Definition at line 42 of file logging.c.
Referenced by log_set_filepath().
int log_close | ( | void | ) |
Close the logging subsystem, release resources.
Definition at line 140 of file logging.c.
Referenced by log_fini().
00141 { 00142 int error = SUCCESS; 00143 00144 error = log_close_file(); 00145 log_to_console(false); 00146 return error; 00147 }
int log_close_file | ( | void | ) |
Close the log file, further log file write will be disabled.
Definition at line 154 of file logging.c.
Referenced by log_close().
00155 { 00156 int error = SUCCESS; 00157 00158 if (log_file_fd >= 0) { 00159 if (close(log_file_fd) < 0) { 00160 error = errno; 00161 } 00162 log_file_fd = -1; 00163 } 00164 return error; 00165 }
int log_fini | ( | void | ) |
Close the logging subsystem, release resources.
Definition at line 126 of file logging.c.
Referenced by main().
00127 { 00128 return log_close(); 00129 }
int log_init | ( | void | ) |
Initialize the logging subsystem.
Definition at line 107 of file logging.c.
Referenced by main().
00108 { 00109 int error = SUCCESS; 00110 00111 error = log_set_filepath(NULL); 00112 return error; 00113 }
int log_level_from_string | ( | const char * | level_str, | |
int * | level | |||
) |
Parse a log level in case insensitive manner, set variable to log level enumeration.
[in] | level_str | Pointer to string containing log level, leading white space ignored |
[out] | level | Pointer to variable to receive log level enumeration |
Definition at line 451 of file logging.c.
Referenced by main().
00452 { 00453 const char *p; 00454 00455 for (p = level_str; *p && isspace(*p); p++); /* skip white space */ 00456 if (!*p) return EINVAL; 00457 00458 if (strcasecmp("error", p) == 0) { 00459 *level = LOG_ERROR; 00460 return SUCCESS; 00461 } 00462 00463 if ((strcasecmp("warn", p) == 0) || 00464 (strcasecmp("warning", p) == 0)) { 00465 *level = LOG_WARN; 00466 return SUCCESS; 00467 } 00468 00469 if (strcasecmp("info", p) == 0) { 00470 *level = LOG_INFO; 00471 return SUCCESS; 00472 } 00473 00474 if (strcasecmp("debug", p) == 0) { 00475 *level = LOG_DEBUG; 00476 return SUCCESS; 00477 } 00478 00479 if (strcasecmp("verbose_debug", p) == 0) { 00480 *level = LOG_VERBOSE_DEBUG; 00481 return SUCCESS; 00482 } 00483 00484 return EINVAL; 00485 }
void log_msg1 | ( | int | level, | |
const char * | file, | |||
int | line, | |||
const char * | function, | |||
const char * | fmt, | |||
... | ||||
) |
If not filtered by the log level format a log message and emit it on each enabled output stream.
[in] | level | The log level associated with this message |
[in] | file | The source code file name |
[in] | line | The line number in the source code file |
[in] | function | The name of the containing function |
[in] | fmt | The printf style format string |
[in] | ... | Optional printf style arguments |
Definition at line 368 of file logging.c.
00369 { 00370 static __thread char buf[4096]; /* thread local static buffer */ 00371 bool do_prefix; 00372 char *p, *buf_end; 00373 int msg_len; 00374 va_list ap; 00375 00376 if (log_level < level) return; 00377 00378 p = buf; /* current position in buffer */ 00379 buf_end = &buf[sizeof(buf)]; /* non-inclusive end of buffer */ 00380 *p = 0; 00381 00382 do_prefix = show_level ||show_file || show_line || show_function || show_time; 00383 if (do_prefix) { 00384 p += snprintf(p, buf_end - p, "["); 00385 if (p >= buf_end) goto fail; 00386 } 00387 00388 if (show_level) { 00389 switch(level) { 00390 case LOG_ERROR: p += snprintf(p, buf_end - p, "ERROR "); if (p >= buf_end) goto fail; break; 00391 case LOG_WARN: p += snprintf(p, buf_end - p, "WARNING "); if (p >= buf_end) goto fail; break; 00392 case LOG_INFO: p += snprintf(p, buf_end - p, "INFO "); if (p >= buf_end) goto fail; break; 00393 case LOG_DEBUG: p += snprintf(p, buf_end - p, "DEBUG "); if (p >= buf_end) goto fail; break; 00394 case LOG_VERBOSE_DEBUG: p += snprintf(p, buf_end - p, "VERBOSE_DEBUG "); if (p >= buf_end) goto fail; break; 00395 } 00396 } 00397 00398 if (show_file) { 00399 p += snprintf(p, buf_end - p, "%s ", file); 00400 if (p >= buf_end) goto fail; 00401 } 00402 00403 if (show_line) { 00404 if (show_file) p[-1] = ':'; 00405 p += snprintf(p, buf_end - p, "%d ", line); 00406 if (p >= buf_end) goto fail; 00407 } 00408 00409 if (show_function) { 00410 p += snprintf(p, buf_end - p, "%s() ", function); 00411 if (p >= buf_end) goto fail; 00412 } 00413 00414 if (show_time) { 00415 p += snprintf(p, buf_end - p, "%s ", time_string(time(NULL), true, log_time_format[0] ? log_time_format : NULL)); 00416 if (p >= buf_end) goto fail; 00417 } 00418 00419 if (do_prefix) { 00420 p--; /* remove trailing space in prefix */ 00421 p += snprintf(p, buf_end - p, "] "); 00422 if (p >= buf_end) goto fail; 00423 } 00424 00425 va_start(ap, fmt); 00426 if (fmt) { 00427 p += vsnprintf(p, buf_end - p, fmt, ap); 00428 if (p >= buf_end) goto fail; 00429 } 00430 00431 msg_len = p - buf; 00432 output: 00433 if (log_to_console_flag && log_console_fd >= 0) write(log_console_fd, buf, msg_len); 00434 if (log_to_file_flag && log_file_fd >= 0) write(log_file_fd, buf, msg_len); 00435 return; 00436 00437 fail: 00438 /* exhausted the buffer; NULL terminate then output truncated string */ 00439 buf_end[-1] = 0; /* should already be NULL terminated, but be safe */ 00440 msg_len = buf_end - buf; 00441 goto output; 00442 }
int log_set_filepath | ( | const char * | path | ) |
Close existing log file, set the current path of the log file, potentially reopen.
[in] | path | The new path name of the log file, if NULL use default log file |
Definition at line 180 of file logging.c.
Referenced by log_init(), and main().
00181 { 00182 int error = SUCCESS; 00183 00184 if (log_file_fd >= 0) { 00185 close(log_file_fd); 00186 log_file_fd = -1; 00187 } 00188 00189 if (path) { 00190 if ((error = copy_path(log_filepath, path, sizeof(log_filepath))) != SUCCESS) { 00191 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), path, error_string(error)); 00192 return error; 00193 } 00194 } else { 00195 if ((error = copy_path(log_filepath, DEFAULT_LOG_FILEPATH, sizeof(log_filepath))) != SUCCESS) { 00196 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), DEFAULT_LOG_FILEPATH, error_string(error)); 00197 return error; 00198 } 00199 } 00200 00201 if (log_to_file_flag) { 00202 log_file_fd = open(log_filepath, O_WRONLY | O_CREAT | O_TRUNC, 0664); 00203 error = errno; 00204 } 00205 00206 return error; 00207 }
int log_set_level | ( | int | level | ) |
Set the current logging level.
[in] | level | The new logging level |
Definition at line 221 of file logging.c.
Referenced by main().
00222 { 00223 switch(level) { 00224 case LOG_ERROR: 00225 case LOG_WARN: 00226 case LOG_INFO: 00227 log_level = level; 00228 return SUCCESS; 00229 case LOG_DEBUG: 00230 case LOG_VERBOSE_DEBUG: 00231 log_level = level; 00232 debug = 1; 00233 return SUCCESS; 00234 default: 00235 return EINVAL; 00236 } 00237 }
int log_set_show_file | ( | bool | show | ) |
int log_set_show_function | ( | bool | show | ) |
Set boolean flag indicating if the function name should appear in log messages.
[in] | show | True if the function name should appear in log messages, false otherwise |
Definition at line 305 of file logging.c.
Referenced by main().
00306 { 00307 show_function = show; 00308 return SUCCESS; 00309 }
int log_set_show_level | ( | bool | show | ) |
Set boolean flag indicating if the logging level should appear in log messages.
[in] | show | True if the logging level should appear in log messages, false otherwise |
Definition at line 269 of file logging.c.
Referenced by main().
00270 { 00271 show_level = show; 00272 return SUCCESS; 00273 }
int log_set_show_line | ( | bool | show | ) |
int log_set_show_time | ( | bool | show | ) |
int log_set_time_format | ( | const char * | format | ) |
Set the time format (as per strftime()) for log message timestamps.
[in] | format | The strftime() style time format string |
Definition at line 329 of file logging.c.
00330 { 00331 int error; 00332 00333 error = SUCCESS; 00334 strncpy(log_time_format, format, sizeof(log_time_format)); 00335 if (format[sizeof(log_time_format) - 1] != 0) { 00336 error = ENOBUFS; 00337 log_msg(LOG_ERROR, _("failed to fully copy time format \"%s\" (%s)\n"), format, error_string(error)); 00338 } 00339 return error; 00340 }
int log_to_console | ( | bool | flag | ) |
Set boolean flag indicating log messages should appear on the console.
[in] | flag | True if log messages should appear on the console, false otherwise. |
Definition at line 245 of file logging.c.
Referenced by log_close(), and main().
00246 { 00247 log_to_console_flag = flag; 00248 return SUCCESS; 00249 }
int log_to_file | ( | bool | flag | ) |
Set boolean flag indicating log messages should be written to log file.
[in] | flag | True if log messages should be written to log file, false otherwise. |
Definition at line 257 of file logging.c.
Referenced by main().
00258 { 00259 log_to_file_flag = flag; 00260 return SUCCESS; 00261 }