Commit ec3fa1b1 ec3fa1b18321ac99a62a00321ad6a059b6d30a27 by Sergey Poznyakoff

Implement severity suppression in log streams; other minor fixes.

* include/mailutils/stream.h (MU_LOGSTREAM_ADVANCE_LOCUS_LINE)
(MU_LOGSTREAM_ADVANCE_LOCUS_COL): Rename to MU_IOCTL_.*.  All
uses updated.
(MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY)
(MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME): New ioctls.
* include/mailutils/sys/logstream.h (_mu_log_stream)<threshold>: New
member.
* include/mailutils/syslog.h (mu_log_severity_threshold): New extern.
* libmailutils/cfg/parser.y (_cfg_default_printer): Remove leftover
static function.
* libmailutils/stream/logstream.c (mu_severity_from_string)
(mu_severity_to_string): New functions.
(_log_write): Fix double free.
Implement severity suppression.
(_log_ioctl): Handle MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY.
* libmu_cfg/common.c (mu_logging_param): New parameter
"severity".
1 parent 7fbb4fd0
......@@ -111,12 +111,22 @@ enum mu_buffer_type
Arg: NULL (increment by 1)
int *
*/
#define MU_LOGSTREAM_ADVANCE_LOCUS_LINE 24
#define MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE 24
/* Advance locus column.
Arg: NULL (increment by 1)
int *
*/
#define MU_LOGSTREAM_ADVANCE_LOCUS_COL 25
#define MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL 25
/* Suppress output of messages having severity lower than the
given threshold.
Arg: int *
*/
#define MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY 26
/* Same as above, but:
Arg: const char *
*/
#define MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME 27
#define MU_TRANSPORT_INPUT 0
#define MU_TRANSPORT_OUTPUT 1
......
......@@ -22,11 +22,13 @@
struct _mu_log_stream
{
struct _mu_stream base;
mu_stream_t transport;
unsigned severity;
int logmode;
struct mu_locus locus;
struct _mu_stream base; /* Base stream */
mu_stream_t transport; /* Transport stream */
unsigned severity; /* Default severity */
unsigned threshold; /* Suppress the output of severities below
this threshold */
int logmode; /* Mode flags */
struct mu_locus locus; /* Location */
};
#endif
......
......@@ -28,6 +28,8 @@ extern int mu_log_syslog;
extern int mu_log_facility;
extern char *mu_log_tag;
extern int mu_log_print_severity;
extern unsigned mu_log_severity_threshold;
#define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name)
int mu_string_to_syslog_facility (const char *str, int *pfacility);
......
......@@ -379,13 +379,6 @@ opt_sc : /* empty */
%%
static int
_cfg_default_printer (void *unused, mu_log_level_t level, const char *str)
{
fprintf (stderr, "%s", str);
return 0;
}
void
mu_cfg_set_debug ()
{
......
......@@ -132,3 +132,4 @@ int mu_log_syslog = 0;
int mu_log_facility = LOG_FACILITY;
char *mu_log_tag = NULL;
int mu_log_print_severity = 0;
unsigned mu_log_severity_threshold = MU_LOG_DEBUG;
......
......@@ -119,6 +119,9 @@ mu_stdstream_strerr_setup (int type)
int mode = MU_LOGMODE_SEVERITY;
mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
}
if (mu_log_severity_threshold > MU_LOG_DEBUG)
mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY,
&mu_log_severity_threshold);
mu_stream_destroy (&mu_strerr);
mu_strerr = str;
}
......
......@@ -24,6 +24,7 @@
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
#include <mailutils/log.h>
#include <mailutils/nls.h>
......@@ -42,6 +43,31 @@ char *_mu_severity_str[] = {
};
int _mu_severity_num = MU_ARRAY_SIZE (_mu_severity_str);
int
mu_severity_from_string (const char *str, unsigned *pn)
{
int i;
for (i = 0; i < _mu_severity_num; i++)
{
if (mu_c_strcasecmp (_mu_severity_str[i], str) == 0)
{
*pn = i;
return 0;
}
}
return MU_ERR_NOENT;
}
int
mu_severity_to_string (unsigned n, const char **pstr)
{
if (n >= _mu_severity_num)
return MU_ERR_NOENT;
*pstr = _mu_severity_str[n];
return 0;
}
static int
_locus_set_file (struct mu_locus *loc, const char *file, size_t len)
{
......@@ -167,13 +193,30 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
if (severity >= _mu_severity_num)
severity = MU_LOG_EMERG;
if (fname)
{
loc.mu_file = NULL;
_locus_set_file (&loc, fname, flen);
}
if (save_locus)
{
_locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file));
_locus_set_line (&sp->locus, loc.mu_line);
_locus_set_col (&sp->locus, loc.mu_col);
}
if (severity < sp->threshold)
{
if (fname)
free (loc.mu_file);
return 0;
}
mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
if (logmode & MU_LOGMODE_LOCUS)
{
if (fname)
_locus_set_file (&loc, fname, flen);
if (loc.mu_file)
{
mu_stream_write (sp->transport, loc.mu_file,
......@@ -188,13 +231,6 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
}
}
if (save_locus)
{
_locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file));
_locus_set_line (&sp->locus, loc.mu_line);
_locus_set_col (&sp->locus, loc.mu_col);
}
if (fname)
free (loc.mu_file);
......@@ -332,20 +368,35 @@ _log_ctl (struct _mu_stream *str, int op, void *arg)
break;
}
case MU_LOGSTREAM_ADVANCE_LOCUS_LINE:
case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE:
if (!arg)
sp->locus.mu_line++;
else
sp->locus.mu_line += *(int*)arg;
break;
case MU_LOGSTREAM_ADVANCE_LOCUS_COL:
case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL:
if (!arg)
sp->locus.mu_col++;
else
sp->locus.mu_col += *(int*)arg;
break;
case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY:
if (!arg)
sp->threshold = MU_LOG_DEBUG;
else if (*(unsigned*)arg >= _mu_severity_num)
return MU_ERR_NOENT;
sp->threshold = *(unsigned*)arg;
break;
case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME:
if (!arg)
sp->threshold = MU_LOG_DEBUG;
else
return mu_severity_from_string ((const char *) arg, &sp->threshold);
break;
default:
return ENOSYS;
}
......
......@@ -143,11 +143,30 @@ cb_facility (void *data, mu_config_value_t *val)
return 0;
}
static int
cb_severity (void *data, mu_config_value_t *val)
{
unsigned n;
if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
return 1;
if (mu_severity_from_string (val->v.string, &n))
{
mu_error (_("unknown severity `%s'"), val->v.string);
return 1;
}
mu_log_severity_threshold = n;
return 0;
}
static struct mu_cfg_param mu_logging_param[] = {
{ "syslog", mu_cfg_bool, &mu_log_syslog, 0, NULL,
N_("Send diagnostics to syslog.") },
{ "print-severity", mu_cfg_bool, &mu_log_print_severity, 0, NULL,
N_("Print message severity levels.") },
{ "severity", mu_cfg_callback, NULL, 0, cb_severity,
N_("Output only messages with a severity equal to or greater than "
"this one.") },
{ "facility", mu_cfg_callback, NULL, 0, cb_facility,
N_("Set syslog facility. Arg is one of the following: user, daemon, "
"auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
......
......@@ -27,7 +27,7 @@ source_readline (void *closure, int cont MU_ARG_UNUSED)
if (getline (&buf, &s, fp) >= 0)
{
mu_rtrim_class (buf, MU_CTYPE_SPACE);
mu_stream_ioctl (mu_strerr, MU_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL);
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL);
return buf;
}
......