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 ...@@ -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
196 if (fname)
197 {
198 loc.mu_file = NULL;
199 _locus_set_file (&loc, fname, flen);
200 }
201
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)
210 {
211 if (fname)
212 free (loc.mu_file);
213 return 0;
214 }
215
170 mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity); 216 mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
171 217
172 if (logmode & MU_LOGMODE_LOCUS) 218 if (logmode & MU_LOGMODE_LOCUS)
173 { 219 {
174 if (fname)
175 _locus_set_file (&loc, fname, flen);
176
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;
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;
348 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
......