2 * UCW Library -- Logging: Configuration of Log Streams
4 * (c) 2009 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
13 #include "ucw/simple-lists.h"
16 #include <syslog.h> // FIXME
18 struct stream_config {
22 char *syslog_facility;
23 clist substreams; // simple_list of names
24 struct log_stream *ls;
25 int mark; // Used temporarily in log_config_commit()
29 stream_commit(void *ptr)
31 struct stream_config *c = ptr;
33 if (c->file_name && c->syslog_facility)
34 return "Both FileName and SyslogFacility selected";
38 static struct cf_section stream_config = {
39 CF_TYPE(struct stream_config),
40 CF_COMMIT(stream_commit),
42 #define P(x) PTR_TO(struct stream_config, x)
43 CF_STRING("Name", P(name)),
44 CF_STRING("FileName", P(file_name)),
45 CF_STRING("SyslogFacility", P(syslog_facility)),
46 CF_LIST("Substream", P(substreams), &cf_string_list_config),
52 static clist log_stream_confs;
54 static struct stream_config *
55 stream_find(const char *name)
57 CLIST_FOR_EACH(struct stream_config *, c, log_stream_confs)
58 if (!strcmp(c->name, name))
64 stream_resolve(struct stream_config *c)
69 return cf_printf("Log stream `%s' has substreams which refer to itself", c->name);
73 CLIST_FOR_EACH(simp_node *, s, c->substreams)
75 struct stream_config *d = stream_find(s->s);
77 return cf_printf("Log stream `%s' refers to unknown substream `%s'", c->name, s->s);
78 if (err = stream_resolve(d))
86 log_config_commit(void *ptr UNUSED)
88 // Verify uniqueness of names
89 CLIST_FOR_EACH(struct stream_config *, c, log_stream_confs)
90 if (stream_find(c->name) != c)
91 return cf_printf("Log stream `%s' defined twice", c->name);
93 // Check that all substreams resolve and that there are no cycles
95 CLIST_FOR_EACH(struct stream_config *, c, log_stream_confs)
96 if (err = stream_resolve(c))
102 static struct cf_section log_config = {
103 CF_COMMIT(log_config_commit),
105 CF_LIST("Stream", &log_stream_confs, &stream_config),
110 static void CONSTRUCTOR
111 log_config_init(void)
113 cf_declare_section("Logging", &log_config, 0);
117 log_check_configured(const char *name)
119 if (stream_find(name))
122 return cf_printf("Log stream `%s' not found", name);
125 static struct log_stream *
126 do_new_configured(struct stream_config *c)
128 struct log_stream *ls;
135 ls = log_new_file(c->file_name);
136 else if (c->syslog_facility)
137 ls = log_new_syslog(LOG_USER, NULL); // FIXME: Facility
139 ls = log_new_stream(sizeof(*ls));
141 CLIST_FOR_EACH(simp_node *, s, c->substreams)
142 log_add_substream(ls, do_new_configured(stream_find(s->s)));
149 log_new_configured(const char *name)
151 struct stream_config *c = stream_find(name);
153 die("Unable to find log stream %s", name);
155 return log_ref_stream(c->ls);
156 return do_new_configured(c);
161 #include "ucw/getopt.h"
163 int main(int argc, char **argv)
167 while ((c = cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL)) >= 0)
168 die("No options here.");
170 struct log_stream *ls = log_new_configured("combined");
171 msg(L_INFO | ls->regnum, "Hello, universe!");