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".
Showing
9 changed files
with
108 additions
and
27 deletions
... | @@ -111,12 +111,22 @@ enum mu_buffer_type | ... | @@ -111,12 +111,22 @@ enum mu_buffer_type |
111 | Arg: NULL (increment by 1) | 111 | Arg: NULL (increment by 1) |
112 | int * | 112 | int * |
113 | */ | 113 | */ |
114 | #define MU_LOGSTREAM_ADVANCE_LOCUS_LINE 24 | 114 | #define MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE 24 |
115 | /* Advance locus column. | 115 | /* Advance locus column. |
116 | Arg: NULL (increment by 1) | 116 | Arg: NULL (increment by 1) |
117 | int * | 117 | int * |
118 | */ | 118 | */ |
119 | #define MU_LOGSTREAM_ADVANCE_LOCUS_COL 25 | 119 | #define MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL 25 |
120 | |||
121 | /* Suppress output of messages having severity lower than the | ||
122 | given threshold. | ||
123 | Arg: int * | ||
124 | */ | ||
125 | #define MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY 26 | ||
126 | /* Same as above, but: | ||
127 | Arg: const char * | ||
128 | */ | ||
129 | #define MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME 27 | ||
120 | 130 | ||
121 | #define MU_TRANSPORT_INPUT 0 | 131 | #define MU_TRANSPORT_INPUT 0 |
122 | #define MU_TRANSPORT_OUTPUT 1 | 132 | #define MU_TRANSPORT_OUTPUT 1 | ... | ... |
... | @@ -22,11 +22,13 @@ | ... | @@ -22,11 +22,13 @@ |
22 | 22 | ||
23 | struct _mu_log_stream | 23 | struct _mu_log_stream |
24 | { | 24 | { |
25 | struct _mu_stream base; | 25 | struct _mu_stream base; /* Base stream */ |
26 | mu_stream_t transport; | 26 | mu_stream_t transport; /* Transport stream */ |
27 | unsigned severity; | 27 | unsigned severity; /* Default severity */ |
28 | int logmode; | 28 | unsigned threshold; /* Suppress the output of severities below |
29 | struct mu_locus locus; | 29 | this threshold */ |
30 | int logmode; /* Mode flags */ | ||
31 | struct mu_locus locus; /* Location */ | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | #endif | 34 | #endif | ... | ... |
... | @@ -28,6 +28,8 @@ extern int mu_log_syslog; | ... | @@ -28,6 +28,8 @@ extern int mu_log_syslog; |
28 | extern int mu_log_facility; | 28 | extern int mu_log_facility; |
29 | extern char *mu_log_tag; | 29 | extern char *mu_log_tag; |
30 | extern int mu_log_print_severity; | 30 | extern int mu_log_print_severity; |
31 | extern unsigned mu_log_severity_threshold; | ||
32 | |||
31 | #define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name) | 33 | #define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name) |
32 | 34 | ||
33 | int mu_string_to_syslog_facility (const char *str, int *pfacility); | 35 | int mu_string_to_syslog_facility (const char *str, int *pfacility); | ... | ... |
... | @@ -379,13 +379,6 @@ opt_sc : /* empty */ | ... | @@ -379,13 +379,6 @@ opt_sc : /* empty */ |
379 | 379 | ||
380 | %% | 380 | %% |
381 | 381 | ||
382 | static int | ||
383 | _cfg_default_printer (void *unused, mu_log_level_t level, const char *str) | ||
384 | { | ||
385 | fprintf (stderr, "%s", str); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | void | 382 | void |
390 | mu_cfg_set_debug () | 383 | mu_cfg_set_debug () |
391 | { | 384 | { | ... | ... |
... | @@ -132,3 +132,4 @@ int mu_log_syslog = 0; | ... | @@ -132,3 +132,4 @@ int mu_log_syslog = 0; |
132 | int mu_log_facility = LOG_FACILITY; | 132 | int mu_log_facility = LOG_FACILITY; |
133 | char *mu_log_tag = NULL; | 133 | char *mu_log_tag = NULL; |
134 | int mu_log_print_severity = 0; | 134 | int mu_log_print_severity = 0; |
135 | unsigned mu_log_severity_threshold = MU_LOG_DEBUG; | ... | ... |
... | @@ -119,6 +119,9 @@ mu_stdstream_strerr_setup (int type) | ... | @@ -119,6 +119,9 @@ mu_stdstream_strerr_setup (int type) |
119 | int mode = MU_LOGMODE_SEVERITY; | 119 | int mode = MU_LOGMODE_SEVERITY; |
120 | mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM_SET_MODE, &mode); | 120 | mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM_SET_MODE, &mode); |
121 | } | 121 | } |
122 | if (mu_log_severity_threshold > MU_LOG_DEBUG) | ||
123 | mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY, | ||
124 | &mu_log_severity_threshold); | ||
122 | mu_stream_destroy (&mu_strerr); | 125 | mu_stream_destroy (&mu_strerr); |
123 | mu_strerr = str; | 126 | mu_strerr = str; |
124 | } | 127 | } | ... | ... |
... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
24 | #include <mailutils/types.h> | 24 | #include <mailutils/types.h> |
25 | #include <mailutils/errno.h> | 25 | #include <mailutils/errno.h> |
26 | #include <mailutils/cctype.h> | 26 | #include <mailutils/cctype.h> |
27 | #include <mailutils/cstr.h> | ||
27 | #include <mailutils/log.h> | 28 | #include <mailutils/log.h> |
28 | 29 | ||
29 | #include <mailutils/nls.h> | 30 | #include <mailutils/nls.h> |
... | @@ -42,6 +43,31 @@ char *_mu_severity_str[] = { | ... | @@ -42,6 +43,31 @@ char *_mu_severity_str[] = { |
42 | }; | 43 | }; |
43 | int _mu_severity_num = MU_ARRAY_SIZE (_mu_severity_str); | 44 | int _mu_severity_num = MU_ARRAY_SIZE (_mu_severity_str); |
44 | 45 | ||
46 | int | ||
47 | mu_severity_from_string (const char *str, unsigned *pn) | ||
48 | { | ||
49 | int i; | ||
50 | |||
51 | for (i = 0; i < _mu_severity_num; i++) | ||
52 | { | ||
53 | if (mu_c_strcasecmp (_mu_severity_str[i], str) == 0) | ||
54 | { | ||
55 | *pn = i; | ||
56 | return 0; | ||
57 | } | ||
58 | } | ||
59 | return MU_ERR_NOENT; | ||
60 | } | ||
61 | |||
62 | int | ||
63 | mu_severity_to_string (unsigned n, const char **pstr) | ||
64 | { | ||
65 | if (n >= _mu_severity_num) | ||
66 | return MU_ERR_NOENT; | ||
67 | *pstr = _mu_severity_str[n]; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
45 | static int | 71 | static int |
46 | _locus_set_file (struct mu_locus *loc, const char *file, size_t len) | 72 | _locus_set_file (struct mu_locus *loc, const char *file, size_t len) |
47 | { | 73 | { |
... | @@ -167,13 +193,30 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, | ... | @@ -167,13 +193,30 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, |
167 | if (severity >= _mu_severity_num) | 193 | if (severity >= _mu_severity_num) |
168 | severity = MU_LOG_EMERG; | 194 | severity = MU_LOG_EMERG; |
169 | 195 | ||
170 | mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity); | 196 | if (fname) |
197 | { | ||
198 | loc.mu_file = NULL; | ||
199 | _locus_set_file (&loc, fname, flen); | ||
200 | } | ||
171 | 201 | ||
172 | if (logmode & MU_LOGMODE_LOCUS) | 202 | if (save_locus) |
203 | { | ||
204 | _locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file)); | ||
205 | _locus_set_line (&sp->locus, loc.mu_line); | ||
206 | _locus_set_col (&sp->locus, loc.mu_col); | ||
207 | } | ||
208 | |||
209 | if (severity < sp->threshold) | ||
173 | { | 210 | { |
174 | if (fname) | 211 | if (fname) |
175 | _locus_set_file (&loc, fname, flen); | 212 | free (loc.mu_file); |
213 | return 0; | ||
214 | } | ||
176 | 215 | ||
216 | mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity); | ||
217 | |||
218 | if (logmode & MU_LOGMODE_LOCUS) | ||
219 | { | ||
177 | if (loc.mu_file) | 220 | if (loc.mu_file) |
178 | { | 221 | { |
179 | mu_stream_write (sp->transport, loc.mu_file, | 222 | mu_stream_write (sp->transport, loc.mu_file, |
... | @@ -188,13 +231,6 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, | ... | @@ -188,13 +231,6 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, |
188 | } | 231 | } |
189 | } | 232 | } |
190 | 233 | ||
191 | if (save_locus) | ||
192 | { | ||
193 | _locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file)); | ||
194 | _locus_set_line (&sp->locus, loc.mu_line); | ||
195 | _locus_set_col (&sp->locus, loc.mu_col); | ||
196 | } | ||
197 | |||
198 | if (fname) | 234 | if (fname) |
199 | free (loc.mu_file); | 235 | free (loc.mu_file); |
200 | 236 | ||
... | @@ -332,20 +368,35 @@ _log_ctl (struct _mu_stream *str, int op, void *arg) | ... | @@ -332,20 +368,35 @@ _log_ctl (struct _mu_stream *str, int op, void *arg) |
332 | break; | 368 | break; |
333 | } | 369 | } |
334 | 370 | ||
335 | case MU_LOGSTREAM_ADVANCE_LOCUS_LINE: | 371 | case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE: |
336 | if (!arg) | 372 | if (!arg) |
337 | sp->locus.mu_line++; | 373 | sp->locus.mu_line++; |
338 | else | 374 | else |
339 | sp->locus.mu_line += *(int*)arg; | 375 | sp->locus.mu_line += *(int*)arg; |
340 | break; | 376 | break; |
341 | 377 | ||
342 | case MU_LOGSTREAM_ADVANCE_LOCUS_COL: | 378 | case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL: |
343 | if (!arg) | 379 | if (!arg) |
344 | sp->locus.mu_col++; | 380 | sp->locus.mu_col++; |
345 | else | 381 | else |
346 | sp->locus.mu_col += *(int*)arg; | 382 | sp->locus.mu_col += *(int*)arg; |
347 | break; | 383 | break; |
348 | 384 | ||
385 | case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY: | ||
386 | if (!arg) | ||
387 | sp->threshold = MU_LOG_DEBUG; | ||
388 | else if (*(unsigned*)arg >= _mu_severity_num) | ||
389 | return MU_ERR_NOENT; | ||
390 | sp->threshold = *(unsigned*)arg; | ||
391 | break; | ||
392 | |||
393 | case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME: | ||
394 | if (!arg) | ||
395 | sp->threshold = MU_LOG_DEBUG; | ||
396 | else | ||
397 | return mu_severity_from_string ((const char *) arg, &sp->threshold); | ||
398 | break; | ||
399 | |||
349 | default: | 400 | default: |
350 | return ENOSYS; | 401 | return ENOSYS; |
351 | } | 402 | } | ... | ... |
... | @@ -143,11 +143,30 @@ cb_facility (void *data, mu_config_value_t *val) | ... | @@ -143,11 +143,30 @@ cb_facility (void *data, mu_config_value_t *val) |
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int | ||
147 | cb_severity (void *data, mu_config_value_t *val) | ||
148 | { | ||
149 | unsigned n; | ||
150 | |||
151 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) | ||
152 | return 1; | ||
153 | if (mu_severity_from_string (val->v.string, &n)) | ||
154 | { | ||
155 | mu_error (_("unknown severity `%s'"), val->v.string); | ||
156 | return 1; | ||
157 | } | ||
158 | mu_log_severity_threshold = n; | ||
159 | return 0; | ||
160 | } | ||
161 | |||
146 | static struct mu_cfg_param mu_logging_param[] = { | 162 | static struct mu_cfg_param mu_logging_param[] = { |
147 | { "syslog", mu_cfg_bool, &mu_log_syslog, 0, NULL, | 163 | { "syslog", mu_cfg_bool, &mu_log_syslog, 0, NULL, |
148 | N_("Send diagnostics to syslog.") }, | 164 | N_("Send diagnostics to syslog.") }, |
149 | { "print-severity", mu_cfg_bool, &mu_log_print_severity, 0, NULL, | 165 | { "print-severity", mu_cfg_bool, &mu_log_print_severity, 0, NULL, |
150 | N_("Print message severity levels.") }, | 166 | N_("Print message severity levels.") }, |
167 | { "severity", mu_cfg_callback, NULL, 0, cb_severity, | ||
168 | N_("Output only messages with a severity equal to or greater than " | ||
169 | "this one.") }, | ||
151 | { "facility", mu_cfg_callback, NULL, 0, cb_facility, | 170 | { "facility", mu_cfg_callback, NULL, 0, cb_facility, |
152 | N_("Set syslog facility. Arg is one of the following: user, daemon, " | 171 | N_("Set syslog facility. Arg is one of the following: user, daemon, " |
153 | "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), " | 172 | "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), " | ... | ... |
... | @@ -27,7 +27,7 @@ source_readline (void *closure, int cont MU_ARG_UNUSED) | ... | @@ -27,7 +27,7 @@ source_readline (void *closure, int cont MU_ARG_UNUSED) |
27 | if (getline (&buf, &s, fp) >= 0) | 27 | if (getline (&buf, &s, fp) >= 0) |
28 | { | 28 | { |
29 | mu_rtrim_class (buf, MU_CTYPE_SPACE); | 29 | mu_rtrim_class (buf, MU_CTYPE_SPACE); |
30 | mu_stream_ioctl (mu_strerr, MU_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL); | 30 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL); |
31 | return buf; | 31 | return buf; |
32 | } | 32 | } |
33 | 33 | ... | ... |
-
Please register or sign in to post a comment