#include "ucw/simple-lists.h"
#include <string.h>
-#include <syslog.h> // FIXME
+#include <syslog.h>
struct stream_config {
cnode n;
char *name;
char *file_name;
char *syslog_facility;
+ u32 levels;
clist substreams; // simple_list of names
+ int microseconds; // Enable logging of precise timestamps
+ int syslog_pids;
struct log_stream *ls;
int mark; // Used temporarily in log_config_commit()
};
+static char *
+stream_init(void *ptr)
+{
+ struct stream_config *c = ptr;
+
+ c->levels = ~0U;
+ return NULL;
+}
+
static char *
stream_commit(void *ptr)
{
if (c->file_name && c->syslog_facility)
return "Both FileName and SyslogFacility selected";
+ if (c->syslog_facility && !log_syslog_facility_exists(c->syslog_facility))
+ return cf_printf("SyslogFacility `%s' is not recognized", c->syslog_facility);
+ if (c->syslog_facility && c->microseconds)
+ return "Syslog streams do not support microsecond precision";
return NULL;
}
+static const char * const level_names[] = {
+#define P(x) #x,
+ LOG_LEVEL_NAMES
+#undef P
+ NULL
+};
+
static struct cf_section stream_config = {
CF_TYPE(struct stream_config),
+ CF_INIT(stream_init),
CF_COMMIT(stream_commit),
CF_ITEMS {
#define P(x) PTR_TO(struct stream_config, x)
CF_STRING("Name", P(name)),
CF_STRING("FileName", P(file_name)),
CF_STRING("SyslogFacility", P(syslog_facility)),
+ CF_BITMAP_LOOKUP("Levels", P(levels), level_names),
CF_LIST("Substream", P(substreams), &cf_string_list_config),
+ CF_INT("Microseconds", P(microseconds)),
+ CF_INT("SyslogPID", P(syslog_pids)),
#undef P
CF_END
}
if (c->file_name)
ls = log_new_file(c->file_name);
else if (c->syslog_facility)
- ls = log_new_syslog(LOG_USER, NULL); // FIXME: Facility
+ ls = log_new_syslog(c->syslog_facility, (c->syslog_pids ? LOG_PID : 0));
else
ls = log_new_stream(sizeof(*ls));
CLIST_FOR_EACH(simp_node *, s, c->substreams)
log_add_substream(ls, do_new_configured(stream_find(s->s)));
+ ls->levels = c->levels;
+ if (c->microseconds)
+ ls->msgfmt |= LSFMT_USEC;
+
c->ls = ls;
return ls;
}
return do_new_configured(c);
}
+void
+log_configured(const char *name)
+{
+ struct log_stream *ls = log_new_configured(name);
+ struct log_stream *def = log_stream_by_flags(0);
+ log_rm_substream(def, NULL);
+ log_add_substream(def, ls);
+ log_close_stream(ls);
+}
+
#ifdef TEST
#include "ucw/getopt.h"
struct log_stream *ls = log_new_configured("combined");
msg(L_INFO | ls->regnum, "Hello, universe!");
+ log_close_all();
return 0;
}