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.
This commit is contained in:
Dirk-Jan C. Binnema 2020-05-30 13:24:53 +03:00
parent 73be015cd0
commit 3e233cba9a
18 changed files with 68 additions and 548 deletions

49
HACKING
View File

@ -19,7 +19,7 @@
on the same line as the statement, except for functions. Tabs for on the same line as the statement, except for functions. Tabs for
indentation, space for alignment; use 8-char tabs. indentation, space for alignment; use 8-char tabs.
2. Lines should not exceed 80 characters (C) or 100 characters (C++) 2. Lines should not exceed 100 characters
3. Functions should not exceed 35 lines (with few exceptions). You can easily 3. Functions should not exceed 35 lines (with few exceptions). You can easily
check if any functions violate this rule with 'make line35', which lists check if any functions violate this rule with 'make line35', which lists
@ -27,45 +27,34 @@
4. Source files should not exceed 1000 lines 4. Source files should not exceed 1000 lines
5. A function's cyclomatic complexity should not exceed 10 (there could be 5. Non-static C-functions have the prefix based on their module, e.g.,
rare exceptions, see the toplevel ~Makefile.am~). You can test the ~mu-foo.h~ declares a function of 'mu_foo_bar (int a);', mu-foo.c implements
cyclomatic complexity with the ~pmccabe~ tool; if you installed that, you this. C++ functions using the Mu namespace
can use 'make cc10' to list all functions that violate this rule; there
should be none.
6. Filenames have their components separated with dashes (e.g, ~mu-log.h~), and 6. Non-global functions *don't* have the module prefix, and are declared
start with ~mu-~ where appropriate.
7. Global functions have the prefix based on their module, e.g., ~mu-foo.h~
declares a function of 'mu_foo_bar (int a);', mu-foo.c implements this.
8. Non-global functions *don't* have the module prefix, and are declared
static. static.
9. Functions have their return type on a separate line before the function 7. Functions have their return type on a separate line before the function
name, so: name, so:
#+BEGIN_EXAMPLE #+BEGIN_EXAMPLE
int static int
foo (const char *bar) foo (const char *bar)
{ {
.... ....
} }
#+END_EXAMPLE #+END_EXAMPLE
There is no non-aesthetic reason for this. 8. In C code, variable-declarations are at the beginning of a block.
10. In C code, variable-declarations are at the beginning of a block; in In C code, the declaration does *not* initialize the variable. This will
principle, C++ follows that same guideline, unless for heavy yet give the compiler a chance to warn us if the variable is not initialized
uncertain initializations following RAII. in a certain code path.
In C code, the declaration does *not* initialize the variable. This will 9. Returned strings of type char* must be freed by the caller; if they are
give the compiler a chance to warn us if the variable is not initialized
in a certain code path.
11. Returned strings of type char* must be freed by the caller; if they are
not to be freed, 'const char*' should be used instead not to be freed, 'const char*' should be used instead
12. Functions calls have a space between function name and arguments, unless 10. Functions calls have a space between function name and arguments, unless
there are none, so: there are none, so:
~foo (12, 3)~; ~foo (12, 3)~;
@ -76,11 +65,11 @@
after a comma, a space should follow. after a comma, a space should follow.
13. Functions that do not take arguments are explicitly declared as 11. C-functions that do not take arguments are explicitly declared as
f(void) and not f(). Reason: f() means that the arguments are f(void) and not f(). Reason: f() means that the arguments are
/unspecified/ (in C) /unspecified/ (in C)
14. C-code should not use ~//~ comments. 12. C-code should not use ~//~ comments.
** Logging ** Logging
@ -89,8 +78,7 @@
except when logging may not have been initialized. except when logging may not have been initialized.
The logging system redirects most logging to the log file (typically, The logging system redirects most logging to the log file (typically,
~/.cache/mu/mu.log). g_warning, g_message and g_critical are shown to the user, =~/.cache/mu/mu.log=). ~g_critical~ messages are written to stderr.
except when running with --quiet, in which case g_message is *not* shown.
- ~g_message~ is for non-error messages the user will see (unless running with - ~g_message~ is for non-error messages the user will see (unless running with
~--quiet~) ~--quiet~)
@ -100,9 +88,6 @@
friends use this). (and they are written on ~stderr~) friends use this). (and they are written on ~stderr~)
- don't use ~g_error~ - don't use ~g_error~
If you just want to log something in the log file without writing to screen,
use ~MU_LOG_WRITE~, as defined in ~mu-util.h~.
** Compiling from git ** Compiling from git
For hacking, you're strongly advised to use the latest git version. For hacking, you're strongly advised to use the latest git version.

View File

@ -5,6 +5,9 @@
*** mu *** mu
- Where available (and with suitable glib), log to the systemd journal
instead of a =~/.cache/mu.log=
- Follow symlinks in maildirs, and support moving messsages between across - Follow symlinks in maildirs, and support moving messsages between across
multiple filesystems (but note that that is quite a bit slower than the multiple filesystems (but note that that is quite a bit slower than the
single-filesystem case) single-filesystem case)

View File

@ -86,7 +86,7 @@ mu_guile_init_instance (const char *muhome)
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
if (!mu_runtime_init (muhome, "guile")) if (!mu_runtime_init (muhome, "guile", FALSE))
return FALSE; return FALSE;
err = NULL; err = NULL;

View File

@ -257,7 +257,8 @@ on_run_maildir_dir (const char* fullpath, gboolean enter,
data->_user_data); data->_user_data);
if (err) { if (err) {
MU_WRITE_LOG ("%s: %s", __func__, err->message); g_warning("%s: error handling %s: %s", __func__,
fullpath, err->message);
g_clear_error(&err); g_clear_error(&err);
} }

View File

@ -119,10 +119,7 @@ mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex, GError **err)
{ {
g_return_val_if_fail (path, FALSE); g_return_val_if_fail (path, FALSE);
MU_WRITE_LOG ("%s (%s, %o, %s)", __func__, if (!create_maildir (path, mode, err))
path, mode, noindex ? "TRUE" : "FALSE");
if (!create_maildir (path, mode, err))
return FALSE; return FALSE;
if (noindex && !create_noindex (path, err)) if (noindex && !create_noindex (path, err))

View File

@ -241,7 +241,7 @@ try_requery (MuQuery *self, const char* searchexpr, MuMsgFieldId sortfieldid,
/* let's assume that infinite regression is /* let's assume that infinite regression is
* impossible */ * impossible */
self->db().reopen(); self->db().reopen();
MU_WRITE_LOG ("reopening db after modification"); g_message ("reopening db after modification");
return mu_query_run (self, searchexpr, sortfieldid, return mu_query_run (self, searchexpr, sortfieldid,
maxnum, flags, err); maxnum, flags, err);

View File

@ -19,6 +19,7 @@
#include "mu-runtime.h" #include "mu-runtime.h"
#include "utils/mu-util.h" #include "utils/mu-util.h"
#include "utils/mu-logger.hh"
#include <locale.h> /* for setlocale() */ #include <locale.h> /* for setlocale() */
@ -29,24 +30,25 @@ static std::unordered_map<MuRuntimePath, std::string> RuntimePaths;
constexpr auto PartsDir = "parts"; constexpr auto PartsDir = "parts";
constexpr auto LogDir = "log"; constexpr auto LogDir = "log";
constexpr auto XapianDir = "xapian"; constexpr auto XapianDir = "xapian";
constexpr auto Mu = "mu"; constexpr auto MuName = "mu";
constexpr auto Bookmarks = "bookmarks"; constexpr auto Bookmarks = "bookmarks";
static const std::string Sepa{G_DIR_SEPARATOR_S}; static const std::string Sepa{G_DIR_SEPARATOR_S};
static void static void
init_paths_xdg () init_paths_xdg ()
{ {
RuntimePaths.emplace(MU_RUNTIME_PATH_XAPIANDB, g_get_user_cache_dir() + RuntimePaths.emplace(MU_RUNTIME_PATH_XAPIANDB, g_get_user_cache_dir() +
Sepa + Mu + Sepa + XapianDir); Sepa + MuName + Sepa + XapianDir);
RuntimePaths.emplace(MU_RUNTIME_PATH_CACHE, g_get_user_cache_dir() + RuntimePaths.emplace(MU_RUNTIME_PATH_CACHE, g_get_user_cache_dir() +
Sepa + Mu); Sepa + MuName);
RuntimePaths.emplace(MU_RUNTIME_PATH_MIMECACHE, g_get_user_cache_dir() + RuntimePaths.emplace(MU_RUNTIME_PATH_MIMECACHE, g_get_user_cache_dir() +
Sepa + Mu + Sepa + PartsDir); Sepa + MuName + Sepa + PartsDir);
RuntimePaths.emplace(MU_RUNTIME_PATH_LOGDIR, g_get_user_cache_dir() + RuntimePaths.emplace(MU_RUNTIME_PATH_LOGDIR, g_get_user_cache_dir() +
Sepa + Mu); Sepa + MuName);
RuntimePaths.emplace(MU_RUNTIME_PATH_BOOKMARKS, g_get_user_config_dir() + RuntimePaths.emplace(MU_RUNTIME_PATH_BOOKMARKS, g_get_user_config_dir() +
Sepa + Mu); Sepa + MuName);
} }
static void static void
@ -60,7 +62,7 @@ init_paths_muhome (const char *muhome)
} }
gboolean gboolean
mu_runtime_init (const char* muhome, const char *name) mu_runtime_init (const char* muhome, const char *name, gboolean debug)
{ {
g_return_val_if_fail (RuntimePaths.empty(), FALSE); g_return_val_if_fail (RuntimePaths.empty(), FALSE);
g_return_val_if_fail (name, FALSE); g_return_val_if_fail (name, FALSE);
@ -92,10 +94,12 @@ mu_runtime_init (const char* muhome, const char *name)
const auto log_path = RuntimePaths[MU_RUNTIME_PATH_LOGDIR] + const auto log_path = RuntimePaths[MU_RUNTIME_PATH_LOGDIR] +
Sepa + name + ".log"; Sepa + name + ".log";
if (!mu_log_init (log_path.c_str(), MU_LOG_OPTIONS_BACKUP)) { using namespace Mu;
mu_runtime_uninit(); LogOptions opts{LogOptions::None};
return FALSE; if (debug)
} opts |= (LogOptions::Debug | LogOptions::None);
Mu::log_init(log_path, opts);
return TRUE; return TRUE;
} }
@ -104,7 +108,7 @@ void
mu_runtime_uninit (void) mu_runtime_uninit (void)
{ {
RuntimePaths.clear(); RuntimePaths.clear();
mu_log_uninit(); Mu::log_uninit();
} }
const char* const char*

View File

@ -21,7 +21,6 @@
#define __MU_RUNTIME_H__ #define __MU_RUNTIME_H__
#include <glib.h> #include <glib.h>
#include <utils/mu-log.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -32,10 +31,12 @@ G_BEGIN_DECLS
* @param muhome path where to find the mu home directory (typically, ~/.cache/mu) * @param muhome path where to find the mu home directory (typically, ~/.cache/mu)
* @param name of the main program, ie. 'mu', 'mug' or * @param name of the main program, ie. 'mu', 'mug' or
* 'procmule'. this influences the name of the e.g. the logfile * 'procmule'. this influences the name of the e.g. the logfile
* @param debug debug-mode
* *
* @return TRUE if succeeded, FALSE in case of error * @return TRUE if succeeded, FALSE in case of error
*/ */
gboolean mu_runtime_init (const char *muhome, const char *name); gboolean mu_runtime_init (const char *muhome, const char *name,
gboolean debug);
/** /**
* free all resources * free all resources
@ -47,7 +48,7 @@ void mu_runtime_uninit (void);
typedef enum { typedef enum {
MU_RUNTIME_PATH_XAPIANDB, /* mu xapian db path */ MU_RUNTIME_PATH_XAPIANDB, /* mu xapian db path */
MU_RUNTIME_PATH_BOOKMARKS, /* mu bookmarks file path */ MU_RUNTIME_PATH_BOOKMARKS, /* mu bookmarks file path */
MU_RUNTIME_PATH_CACHE, /* mu cache path for attachments etc. */ MU_RUNTIME_PATH_CACHE, /* mu cache path */
MU_RUNTIME_PATH_MIMECACHE, /* mu cache path for attachments etc. */ MU_RUNTIME_PATH_MIMECACHE, /* mu cache path for attachments etc. */
MU_RUNTIME_PATH_LOGDIR, /* mu path for log files */ MU_RUNTIME_PATH_LOGDIR, /* mu path for log files */

View File

@ -49,8 +49,8 @@ libmu_utils_la_SOURCES= \
mu-date.c \ mu-date.c \
mu-date.h \ mu-date.h \
mu-error.hh \ mu-error.hh \
mu-log.c \ mu-logger.cc \
mu-log.h \ mu-logger.hh \
mu-command-parser.cc \ mu-command-parser.cc \
mu-command-parser.hh \ mu-command-parser.hh \
mu-readline.cc \ mu-readline.cc \

View File

@ -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);
}

View File

@ -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__*/

View File

@ -309,20 +309,6 @@ typedef gpointer XapianEnquire;
} while (0) } 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) #define MU_G_ERROR_CODE(GE) ((GE)&&(*(GE))?(*(GE))->code:MU_ERROR)

View File

@ -1,7 +1,5 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/* /*
** Copyright (C) 2008-2016 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -37,7 +35,6 @@
#include "mu-runtime.h" #include "mu-runtime.h"
#include "utils/mu-util.h" #include "utils/mu-util.h"
#include "utils/mu-log.h"
static gboolean MU_CAUGHT_SIGNAL; static gboolean MU_CAUGHT_SIGNAL;
@ -180,22 +177,14 @@ show_time (unsigned t, unsigned processed, gboolean color)
g_print ("\n"); g_print ("\n");
} }
/* when logging to console, print a newline before doing so; this
* makes it more clear when something happens during the
* indexing/cleanup progress output */
#define newline_before_on() \
mu_log_options_set(mu_log_options_get() | MU_LOG_OPTIONS_NEWLINE)
#define newline_before_off() \
mu_log_options_set(mu_log_options_get() & ~MU_LOG_OPTIONS_NEWLINE)
static MuError static MuError
cleanup_missing (MuIndex *midx, MuConfig *opts, MuIndexStats *stats, cleanup_missing (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
GError **err) GError **err)
{ {
MuError rv; MuError rv;
time_t t; time_t t;
IndexData idata; IndexData idata;
gboolean show_progress; gboolean show_progress;
if (!opts->quiet) if (!opts->quiet)
g_print ("cleaning up messages [%s]\n", g_print ("cleaning up messages [%s]\n",
@ -206,14 +195,12 @@ cleanup_missing (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
t = time (NULL); t = time (NULL);
idata.color = !opts->nocolor; idata.color = !opts->nocolor;
newline_before_on();
rv = mu_index_cleanup rv = mu_index_cleanup
(midx, stats, (midx, stats,
show_progress ? show_progress ?
(MuIndexCleanupDeleteCallback)index_msg_cb : (MuIndexCleanupDeleteCallback)index_msg_cb :
(MuIndexCleanupDeleteCallback)index_msg_silent_cb, (MuIndexCleanupDeleteCallback)index_msg_silent_cb,
&idata, err); &idata, err);
newline_before_off();
if (!opts->quiet) { if (!opts->quiet) {
print_stats (stats, TRUE, !opts->nocolor); print_stats (stats, TRUE, !opts->nocolor);
@ -235,8 +222,6 @@ cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats, GError **err)
show_progress = !opts->quiet && isatty(fileno(stdout)); show_progress = !opts->quiet && isatty(fileno(stdout));
idata.color = !opts->nocolor; idata.color = !opts->nocolor;
newline_before_on();
rv = mu_index_run (midx, rv = mu_index_run (midx,
opts->rebuild, opts->rebuild,
opts->lazycheck, stats, opts->lazycheck, stats,
@ -244,11 +229,9 @@ cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats, GError **err)
(MuIndexMsgCallback)index_msg_cb : (MuIndexMsgCallback)index_msg_cb :
(MuIndexMsgCallback)index_msg_silent_cb, (MuIndexMsgCallback)index_msg_silent_cb,
NULL, &idata); NULL, &idata);
newline_before_off();
if (rv == MU_OK || rv == MU_STOP) { if (rv == MU_OK || rv == MU_STOP) {
MU_WRITE_LOG ("index: processed: %u; updated/new: %u", g_message ("index: processed: %u; updated/new: %u",
stats->_processed, stats->_updated); stats->_processed, stats->_updated);
} else } else
mu_util_g_set_error (err, rv, "error while indexing"); mu_util_g_set_error (err, rv, "error while indexing");

View File

@ -33,7 +33,6 @@
#include "mu-runtime.h" #include "mu-runtime.h"
#include "mu-flags.h" #include "mu-flags.h"
#include "utils/mu-log.h"
#include "utils/mu-util.h" #include "utils/mu-util.h"
#include "utils/mu-str.h" #include "utils/mu-str.h"
#include "utils/mu-date.h" #include "utils/mu-date.h"
@ -342,15 +341,15 @@ foreach_msg_file (MuStore *store, MuConfig *opts,
if (!check_file_okay (path, TRUE)) { if (!check_file_okay (path, TRUE)) {
all_ok = FALSE; all_ok = FALSE;
MU_WRITE_LOG ("not a valid message file: %s", path); g_warning ("not a valid message file: %s", path);
continue; continue;
} }
if (!foreach_func (store, path, err)) { if (!foreach_func (store, path, err)) {
all_ok = FALSE; all_ok = FALSE;
MU_WRITE_LOG ("error with %s: %s", path, g_warning ("error with %s: %s", path,
(err&&*err) ? (*err)->message : (err&&*err) ? (*err)->message :
"something went wrong"); "something went wrong");
g_clear_error (err); g_clear_error (err);
continue; continue;
} }
@ -656,23 +655,6 @@ check_params (MuConfig *opts, GError **err)
return TRUE; return TRUE;
} }
static void
set_log_options (MuConfig *opts)
{
MuLogOptions logopts;
logopts = MU_LOG_OPTIONS_NONE;
if (opts->quiet)
logopts |= MU_LOG_OPTIONS_QUIET;
if (!opts->nocolor)
logopts |= MU_LOG_OPTIONS_COLOR;
if (opts->log_stderr)
logopts |= MU_LOG_OPTIONS_STDERR;
if (opts->debug)
logopts |= MU_LOG_OPTIONS_DEBUG;
}
MuError MuError
mu_cmd_execute (MuConfig *opts, GError **err) mu_cmd_execute (MuConfig *opts, GError **err)
{ {
@ -683,8 +665,6 @@ mu_cmd_execute (MuConfig *opts, GError **err)
if (!check_params(opts, err)) if (!check_params(opts, err))
return MU_G_ERROR_CODE(err); return MU_G_ERROR_CODE(err);
set_log_options (opts);
switch (opts->cmd) { switch (opts->cmd) {
/* already handled in mu-config.c */ /* already handled in mu-config.c */
@ -692,10 +672,10 @@ mu_cmd_execute (MuConfig *opts, GError **err)
/* no store needed */ /* no store needed */
case MU_CONFIG_CMD_MKDIR: merr = cmd_mkdir (opts, err); break; case MU_CONFIG_CMD_MKDIR: merr = cmd_mkdir (opts, err); break;
case MU_CONFIG_CMD_SCRIPT: merr = mu_cmd_script (opts, err); break; case MU_CONFIG_CMD_SCRIPT: merr = mu_cmd_script (opts, err); break;
case MU_CONFIG_CMD_VIEW: merr = cmd_view (opts, err); break; case MU_CONFIG_CMD_VIEW: merr = cmd_view (opts, err); break;
case MU_CONFIG_CMD_VERIFY: merr = cmd_verify (opts, err); break; case MU_CONFIG_CMD_VERIFY: merr = cmd_verify (opts, err); break;
case MU_CONFIG_CMD_EXTRACT: merr = mu_cmd_extract (opts, err); break; case MU_CONFIG_CMD_EXTRACT: merr = mu_cmd_extract (opts, err); break;
/* read-only store */ /* read-only store */

View File

@ -17,9 +17,7 @@
** **
*/ */
#if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <glib.h> #include <glib.h>
#include <string.h> /* memset */ #include <string.h> /* memset */

View File

@ -97,8 +97,8 @@ struct _MuConfig {
char *cmdstr; /* cmd string, for user char *cmdstr; /* cmd string, for user
* info */ * info */
/* general options */ /* general options */
gboolean quiet; /* don't give any output */ gboolean quiet; /* don't give any output */
gboolean debug; /* spew out debug info */ gboolean debug; /* log debug-level info */
gchar *muhome; /* the House of Mu */ gchar *muhome; /* the House of Mu */
gboolean version; /* request mu version */ gboolean version; /* request mu version */
gboolean log_stderr; /* log to stderr (not logfile) */ gboolean log_stderr; /* log to stderr (not logfile) */

View File

@ -91,9 +91,9 @@ handle_error (MuConfig *conf, MuError merr, GError **err)
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
GError *err; GError *err;
MuError rv; MuError rv;
MuConfig *conf; MuConfig *conf;
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
@ -113,7 +113,7 @@ main (int argc, char *argv[])
if (conf->cmd == MU_CONFIG_CMD_NONE) if (conf->cmd == MU_CONFIG_CMD_NONE)
return 0; return 0;
if (!mu_runtime_init (conf->muhome, PACKAGE_NAME)) { if (!mu_runtime_init (conf->muhome, PACKAGE_NAME, conf->debug)) {
mu_config_uninit (conf); mu_config_uninit (conf);
return 1; return 1;
} }

View File

@ -402,7 +402,7 @@ main (int argc, char *argv[])
} }
g_option_context_free (octx); g_option_context_free (octx);
mu_runtime_init (mugdata.muhome, "mug"); mu_runtime_init (mugdata.muhome, "mug", FALSE);
mugshell = mug_shell (&mugdata); mugshell = mug_shell (&mugdata);
g_signal_connect (G_OBJECT (mugshell), "destroy", g_signal_connect (G_OBJECT (mugshell), "destroy",