diff options
| author | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2020-05-30 13:24:53 +0300 |
|---|---|---|
| committer | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2020-05-30 13:29:44 +0300 |
| commit | 3e233cba9af8dd31852e81f0703e0c39e724ffb7 (patch) | |
| tree | 2ead5da97863f6b63d45fa73f66ff46f9a687298 /lib/utils | |
| parent | 73be015cd0c225d9cbdd78d51be9108655ec0c64 (diff) | |
rework logging system
reimplement the old mu-log.[ch] into mu-logging.{cc,hh}
If available (and using an appropriately equipped glib), log to the
systemd journal
Only g_criticals have stderr output, all the other g_* go to the log
file / journal.
Diffstat (limited to 'lib/utils')
| -rw-r--r-- | lib/utils/Makefile.am | 4 | ||||
| -rw-r--r-- | lib/utils/mu-log.c | 319 | ||||
| -rw-r--r-- | lib/utils/mu-log.h | 99 | ||||
| -rw-r--r-- | lib/utils/mu-util.h | 14 |
4 files changed, 2 insertions, 434 deletions
diff --git a/lib/utils/Makefile.am b/lib/utils/Makefile.am index 551eb1d..9c5681d 100644 --- a/lib/utils/Makefile.am +++ b/lib/utils/Makefile.am @@ -49,8 +49,8 @@ libmu_utils_la_SOURCES= \ mu-date.c \ mu-date.h \ mu-error.hh \ - mu-log.c \ - mu-log.h \ + mu-logger.cc \ + mu-logger.hh \ mu-command-parser.cc \ mu-command-parser.hh \ mu-readline.cc \ diff --git a/lib/utils/mu-log.c b/lib/utils/mu-log.c deleted file mode 100644 index 92ea188..0000000 --- a/lib/utils/mu-log.c +++ /dev/null @@ -1,319 +0,0 @@ -/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/ - -/* -** Copyright (C) 2008-2016 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - -#if HAVE_CONFIG_H -#include <config.h> -#endif /*HAVE_CONFIG_H*/ - -#include "mu-log.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <time.h> -#include <errno.h> -#include <string.h> - -#include "mu-util.h" - -#define MU_MAX_LOG_FILE_SIZE 1000 * 1000 /* 1 MB (SI units) */ -#define MU_LOG_FILE "mu.log" - -struct _MuLog { - int _fd; /* log file descriptor */ - - MuLogOptions _opts; - - gboolean _color_stdout; /* whether to use color */ - gboolean _color_stderr; - - GLogFunc _old_log_func; -}; -typedef struct _MuLog MuLog; - -/* we use globals, because logging is a global operation as it - * globally modifies the behaviour of g_warning and friends - */ -static MuLog* MU_LOG = NULL; -static void log_write (const char* domain, GLogLevelFlags level, - const gchar *msg); - -static void -try_close (int fd) -{ - if (fd < 0) - return; - - if (close (fd) < 0) - g_printerr ("%s: close() of fd %d failed: %s\n", - __func__, fd, strerror(errno)); -} - -static void -silence (void) -{ - return; -} - -gboolean -mu_log_init_silence (void) -{ - g_return_val_if_fail (!MU_LOG, FALSE); - - MU_LOG = g_new0 (MuLog, 1); - MU_LOG->_fd = -1; - - mu_log_options_set (MU_LOG_OPTIONS_NONE); - - MU_LOG->_old_log_func = - g_log_set_default_handler ((GLogFunc)silence, NULL); - - return TRUE; -} - -static void -log_handler (const gchar* log_domain, GLogLevelFlags log_level, - const gchar* msg) -{ - if ((log_level & G_LOG_LEVEL_DEBUG) && - !(MU_LOG->_opts & MU_LOG_OPTIONS_DEBUG)) - return; - - log_write (log_domain ? log_domain : "mu", log_level, msg); -} - - -void -mu_log_options_set (MuLogOptions opts) -{ - g_return_if_fail (MU_LOG); - - MU_LOG->_opts = opts; - - /* when color is, only enable it when output is to a tty */ - if (MU_LOG->_opts & MU_LOG_OPTIONS_COLOR) { - MU_LOG->_color_stdout = isatty(fileno(stdout)); - MU_LOG->_color_stderr = isatty(fileno(stderr)); - - } -} - - -MuLogOptions -mu_log_options_get (void) -{ - g_return_val_if_fail (MU_LOG, MU_LOG_OPTIONS_NONE); - - return MU_LOG->_opts; -} - - -static gboolean -move_log_file (const char *logfile) -{ - gchar *logfile_old; - int rv; - - logfile_old = g_strdup_printf ("%s.old", logfile); - rv = rename (logfile, logfile_old); - g_free (logfile_old); - - if (rv != 0) { - g_warning ("failed to move %s to %s.old: %s", - logfile, logfile, strerror(rv)); - return FALSE; - } else - return TRUE; - -} - - -static gboolean -log_file_backup_maybe (const char *logfile) -{ - struct stat statbuf; - - if (stat (logfile, &statbuf) != 0) { - if (errno == ENOENT) - return TRUE; /* it did not exist yet, no problem */ - else { - g_warning ("failed to stat(2) %s: %s", - logfile, strerror(errno)); - return FALSE; - } - } - - /* log file is still below the max size? */ - if (statbuf.st_size <= MU_MAX_LOG_FILE_SIZE) - return TRUE; - - /* log file is too big!; we move it to <logfile>.old, overwriting */ - return move_log_file (logfile); -} - - -gboolean -mu_log_init (const char* logfile, MuLogOptions opts) -{ - int fd; - - /* only init once... */ - g_return_val_if_fail (!MU_LOG, FALSE); - g_return_val_if_fail (logfile, FALSE); - - if (opts & MU_LOG_OPTIONS_BACKUP) - if (!log_file_backup_maybe(logfile)) { - g_warning ("failed to backup log file"); - return FALSE; - } - - fd = open (logfile, O_WRONLY|O_CREAT|O_APPEND, 00600); - if (fd < 0) { - g_warning ("%s: open() of '%s' failed: %s", __func__, - logfile, strerror(errno)); - return FALSE; - } - - MU_LOG = g_new0 (MuLog, 1); - MU_LOG->_fd = fd; - - mu_log_options_set (opts); - - MU_LOG->_old_log_func = - g_log_set_default_handler ((GLogFunc)log_handler, NULL); - - MU_WRITE_LOG ("logging started"); - - return TRUE; -} - -void -mu_log_uninit (void) -{ - if (!MU_LOG) - return; - - MU_WRITE_LOG ("logging stopped"); - - try_close (MU_LOG->_fd); - g_free (MU_LOG); - - MU_LOG = NULL; -} - - -static const char* -levelstr (GLogLevelFlags level) -{ - switch (level) { - case G_LOG_LEVEL_WARNING: return " [WARN] "; - case G_LOG_LEVEL_ERROR : return " [ERR ] "; - case G_LOG_LEVEL_DEBUG: return " [DBG ] "; - case G_LOG_LEVEL_CRITICAL: return " [CRIT] "; - case G_LOG_LEVEL_MESSAGE: return " [MSG ] "; - case G_LOG_LEVEL_INFO : return " [INFO] "; - default: return " [LOG ] "; - } -} - - - -#define color_stdout_maybe(C) \ - do{if (MU_LOG->_color_stdout) fputs ((C),stdout);} while (0) -#define color_stderr_maybe(C) \ - do{if (MU_LOG->_color_stderr) fputs ((C),stderr);} while (0) - - - -static void -log_write_fd (GLogLevelFlags level, const gchar *msg) -{ - time_t now; - char timebuf [22]; - const char *mylevel; - - /* get the time/date string */ - now = time(NULL); - strftime (timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", - localtime(&now)); - - if (write (MU_LOG->_fd, timebuf, strlen (timebuf)) < 0) - goto err; - - mylevel = levelstr (level); - if (write (MU_LOG->_fd, mylevel, strlen (mylevel)) < 0) - goto err; - - if (write (MU_LOG->_fd, msg, strlen (msg)) < 0) - goto err; - - if (write (MU_LOG->_fd, "\n", strlen ("\n")) < 0) - goto err; - - return; /* all went well */ - -err: - fprintf (stderr, "%s: failed to write to log: %s\n", - __func__, strerror(errno)); -} - - -static void -log_write_stdout_stderr (GLogLevelFlags level, const gchar *msg) -{ - const char *mu; - - mu = MU_LOG->_opts & MU_LOG_OPTIONS_NEWLINE ? - "\nmu: " : "mu: "; - - if (!(MU_LOG->_opts & MU_LOG_OPTIONS_QUIET) && - (level & G_LOG_LEVEL_MESSAGE)) { - color_stdout_maybe (MU_COLOR_GREEN); - fputs (mu, stdout); - fputs (msg, stdout); - fputs ("\n", stdout); - color_stdout_maybe (MU_COLOR_DEFAULT); - } - - /* for errors, log them to stderr as well */ - if (level & G_LOG_LEVEL_ERROR || - level & G_LOG_LEVEL_CRITICAL || - level & G_LOG_LEVEL_WARNING) { - color_stderr_maybe (MU_COLOR_RED); - fputs (mu, stderr); - fputs (msg, stderr); - fputs ("\n", stderr); - color_stderr_maybe (MU_COLOR_DEFAULT); - } -} - - -static void -log_write (const char* domain, GLogLevelFlags level, const gchar *msg) -{ - g_return_if_fail (MU_LOG); - - log_write_fd (level, msg); - log_write_stdout_stderr (level, msg); -} diff --git a/lib/utils/mu-log.h b/lib/utils/mu-log.h deleted file mode 100644 index fc05d0b..0000000 --- a/lib/utils/mu-log.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: - 8 -*-*/ -/* -** Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - -#ifndef __MU_LOG_H__ -#define __MU_LOG_H__ - -#include <glib.h> - -/* mu log is the global logging system */ - -G_BEGIN_DECLS - -enum _MuLogOptions { - MU_LOG_OPTIONS_NONE = 0, - - /* when size of log file > MU_MAX_LOG_FILE_SIZE, move the log - * file to <log file>.old and start a new one. The .old file will - * overwrite existing files of that name */ - MU_LOG_OPTIONS_BACKUP = 1 << 1, - - /* quiet: don't log non-errors to stdout/stderr */ - MU_LOG_OPTIONS_QUIET = 1 << 2, - - /* should lines be preceded by \n? useful when errors come - * during indexing */ - MU_LOG_OPTIONS_NEWLINE = 1 << 3, - - /* color in output (iff output is to a tty) */ - MU_LOG_OPTIONS_COLOR = 1 << 4, - - /* log everything to stderr */ - MU_LOG_OPTIONS_STDERR = 1 << 5, - - /* debug: debug include debug-level information */ - MU_LOG_OPTIONS_DEBUG = 1 << 6 -}; -typedef enum _MuLogOptions MuLogOptions; - - -/** - * write logging information to a log file - * - * @param full path to the log file (does not have to exist yet, but - * it's directory must) - * @param opts logging options - * - * @return TRUE if initialization succeeds, FALSE otherwise - */ -gboolean mu_log_init (const char *logfile, MuLogOptions opts) - G_GNUC_WARN_UNUSED_RESULT; - -/** - * be silent except for runtime errors, which will be written to - * stderr. - * - * @return TRUE if initialization succeeds, FALSE otherwise - */ -gboolean mu_log_init_silence (void) G_GNUC_WARN_UNUSED_RESULT; - -/** - * uninitialize the logging system, and free all resources - */ -void mu_log_uninit (void); - -/** - * set logging options, a logical-OR'd value of MuLogOptions - * - * @param opts the options (logically OR'd) - */ -void mu_log_options_set (MuLogOptions opts); - -/** - * get logging options, a logical-OR'd value of MuLogOptions - * - * @param opts the options (logically OR'd) - */ -MuLogOptions mu_log_options_get (void); - -G_END_DECLS - -#endif /*__MU_LOG_H__*/ diff --git a/lib/utils/mu-util.h b/lib/utils/mu-util.h index f7147bd..071c1b4 100644 --- a/lib/utils/mu-util.h +++ b/lib/utils/mu-util.h @@ -309,20 +309,6 @@ typedef gpointer XapianEnquire; } while (0) - -/** - * log something in the log file; note, we use G_LOG_LEVEL_INFO - * for such messages - */ -#define MU_WRITE_LOG(...) \ - G_STMT_START { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_INFO, \ - __VA_ARGS__); \ - } G_STMT_END - - - #define MU_G_ERROR_CODE(GE) ((GE)&&(*(GE))?(*(GE))->code:MU_ERROR) |
