diff options
author | Guillaume Friloux <guillaume.friloux@gmail.com> | 2013-12-20 16:46:51 +0100 |
---|---|---|
committer | Guillaume Friloux <guillaume.friloux@gmail.com> | 2013-12-20 16:46:51 +0100 |
commit | 67efd371f4c5f17bbecb7e0dbe60f00ee00c03ec (patch) | |
tree | 20765b30c4c855c4841b11c6f2e94f247111c652 /src | |
parent | ceac6266f34b4c014fa5c95c467a9c382579265c (diff) |
Make Smman able to filter logs and tag them.
Next step is turning logs into JSON and send them to ES.
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/Makefile.mk | 4 | ||||
-rw-r--r-- | src/bin/filter.c | 59 | ||||
-rw-r--r-- | src/bin/log.c | 113 | ||||
-rw-r--r-- | src/bin/main.c | 11 | ||||
-rw-r--r-- | src/bin/smman.h | 18 | ||||
-rw-r--r-- | src/include/Rules.h | 1 | ||||
-rw-r--r-- | src/include/Spy.h | 5 | ||||
-rw-r--r-- | src/lib/Makefile.mk | 3 | ||||
-rw-r--r-- | src/lib/rules/rules_private.h | 2 | ||||
-rw-r--r-- | src/lib/spy/spy_file.c | 15 | ||||
-rw-r--r-- | src/lib/spy/spy_line.c | 14 | ||||
-rw-r--r-- | src/lib/spy/spy_main.c | 2 |
12 files changed, 228 insertions, 19 deletions
diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index 6ab1a81..4547c5d 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk | |||
@@ -8,9 +8,11 @@ src_bin_smman_SOURCES = \ | |||
8 | src/bin/main.c \ | 8 | src/bin/main.c \ |
9 | src/bin/config.c \ | 9 | src/bin/config.c \ |
10 | src/bin/filter.c \ | 10 | src/bin/filter.c \ |
11 | src/bin/log.c \ | ||
11 | src/bin/smman.h | 12 | src/bin/smman.h |
12 | src_bin_smman_CPPFLAGS = @BIN_CFLAGS@ $(EXTRA_CPPFLAGS) | 13 | src_bin_smman_CPPFLAGS = @BIN_CFLAGS@ $(EXTRA_CPPFLAGS) |
13 | src_bin_smman_LDFLAGS = @BIN_LIBS@ | 14 | src_bin_smman_LDFLAGS = @BIN_LIBS@ |
14 | src_bin_smman_LDADD = \ | 15 | src_bin_smman_LDADD = \ |
15 | src/lib/libconf.la \ | 16 | src/lib/libconf.la \ |
16 | src/lib/librules.la | 17 | src/lib/librules.la \ |
18 | src/lib/libspy.la | ||
diff --git a/src/bin/filter.c b/src/bin/filter.c index ef05a49..274f0cb 100644 --- a/src/bin/filter.c +++ b/src/bin/filter.c | |||
@@ -1,4 +1,25 @@ | |||
1 | #include "smman.h" | 1 | #include "smman.h" |
2 | #include <glob.h> | ||
3 | |||
4 | static void | ||
5 | _filter_rules_free(void *data) | ||
6 | { | ||
7 | rules_rule_free((Rule *)data); | ||
8 | } | ||
9 | |||
10 | Filter * | ||
11 | _filter_find(Smman *smman, | ||
12 | const char *filename) | ||
13 | { | ||
14 | Filter *filter; | ||
15 | |||
16 | EINA_INLIST_FOREACH(smman->filters, filter) | ||
17 | { | ||
18 | if (!strcmp(filter->filename, filename)) | ||
19 | return filter; | ||
20 | } | ||
21 | return NULL; | ||
22 | } | ||
2 | 23 | ||
3 | void | 24 | void |
4 | filter_load(void *data, | 25 | filter_load(void *data, |
@@ -6,6 +27,11 @@ filter_load(void *data, | |||
6 | Rule *rule) | 27 | Rule *rule) |
7 | { | 28 | { |
8 | Smman *smman; | 29 | Smman *smman; |
30 | Filter *filter; | ||
31 | int r; | ||
32 | glob_t files; | ||
33 | char **s; | ||
34 | size_t i; | ||
9 | 35 | ||
10 | smman = data; | 36 | smman = data; |
11 | if (smman->rules != rules) | 37 | if (smman->rules != rules) |
@@ -18,6 +44,38 @@ filter_load(void *data, | |||
18 | rule->name, rule->spec.filename, rule->spec.source_host, | 44 | rule->name, rule->spec.filename, rule->spec.source_host, |
19 | rule->spec.source_path, rule->spec.tags, | 45 | rule->spec.source_path, rule->spec.tags, |
20 | (rule->spec.todel) ? "EINA_TRUE" : "EINA_FALSE"); | 46 | (rule->spec.todel) ? "EINA_TRUE" : "EINA_FALSE"); |
47 | |||
48 | /* Loop with globbing to write here! */ | ||
49 | r = glob(rule->spec.filename, GLOB_MARK, 0, &files); | ||
50 | if (r) | ||
51 | { | ||
52 | ERR("Unable to find files matching \"%s\"", rule->spec.filename); | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | for (s = files.gl_pathv, i = files.gl_pathc; i; s++, i--) | ||
57 | { | ||
58 | DBG("Corresponding file %s", *s); | ||
59 | |||
60 | /* We have to check the files affected by this rule */ | ||
61 | filter = _filter_find(smman,*s); | ||
62 | if (filter) | ||
63 | goto add_rule; | ||
64 | |||
65 | DBG("No filter found for %s, creating new one", *s); | ||
66 | filter = calloc(1, sizeof(Filter)); | ||
67 | filter->sf = spy_file_new(smman->spy, *s); | ||
68 | spy_file_data_set(filter->sf, filter); | ||
69 | filter->filename = strdup(*s); | ||
70 | filter->rules = eina_hash_string_superfast_new(_filter_rules_free); | ||
71 | smman->filters = eina_inlist_append(smman->filters, | ||
72 | EINA_INLIST_GET(filter)); | ||
73 | |||
74 | add_rule: | ||
75 | DBG("Adding rule[%p][%s] to filter[%p][%s]", | ||
76 | rule, rule->name, filter, filter->filename); | ||
77 | eina_hash_add(filter->rules, rule->name, rule); | ||
78 | } | ||
21 | } | 79 | } |
22 | 80 | ||
23 | void | 81 | void |
@@ -33,7 +91,6 @@ filter_load_done(void *data, | |||
33 | DBG("smman[%p] rules[%p]", smman, rules); | 91 | DBG("smman[%p] rules[%p]", smman, rules); |
34 | } | 92 | } |
35 | 93 | ||
36 | |||
37 | void | 94 | void |
38 | filter_load_error(void *data, | 95 | filter_load_error(void *data, |
39 | Rules *rules, | 96 | Rules *rules, |
diff --git a/src/bin/log.c b/src/bin/log.c new file mode 100644 index 0000000..4ebc053 --- /dev/null +++ b/src/bin/log.c | |||
@@ -0,0 +1,113 @@ | |||
1 | #include "smman.h" | ||
2 | |||
3 | typedef struct _Log | ||
4 | { | ||
5 | const char *filename, | ||
6 | *source_host, | ||
7 | *source_path, | ||
8 | *message; | ||
9 | Eina_Strbuf *tags; | ||
10 | Eina_Bool todel; | ||
11 | } Log; | ||
12 | |||
13 | Eina_Bool | ||
14 | _log_line_match(const char *log, Rule *rule) | ||
15 | { | ||
16 | Rule_Regex *rr; | ||
17 | Eina_Bool excluded = EINA_FALSE; | ||
18 | int r; | ||
19 | |||
20 | EINA_INLIST_FOREACH(rule->spec.regex, rr) | ||
21 | { | ||
22 | size_t nmatch = 2; | ||
23 | regmatch_t pmatch[nmatch]; | ||
24 | |||
25 | r = regexec(&(rr->preg), log, nmatch, pmatch, 0); | ||
26 | if (r == rr->must_match) | ||
27 | { | ||
28 | NFO("Log \"%s\" is not affected by rule %s", log, rule->name); | ||
29 | excluded = EINA_TRUE; | ||
30 | break; | ||
31 | } | ||
32 | } | ||
33 | return (excluded) ? EINA_FALSE : EINA_TRUE; | ||
34 | } | ||
35 | |||
36 | Eina_Bool | ||
37 | log_line_event(void *data, | ||
38 | int type EINA_UNUSED, | ||
39 | void *event) | ||
40 | { | ||
41 | Smman *smman = data; | ||
42 | Spy_Line *sl = event; | ||
43 | Spy_File *sf = spy_line_spyfile_get(sl); | ||
44 | Filter *filter = spy_file_data_get(sf); | ||
45 | Log *log; | ||
46 | Rule *rule; | ||
47 | Eina_Iterator *it; | ||
48 | Eina_Hash_Tuple *t; | ||
49 | Eina_Bool r; | ||
50 | |||
51 | DBG("smman[%p] sl[%p][%s] filter[%p][%s]", | ||
52 | smman, sl, spy_file_name_get(sf), filter, filter->filename); | ||
53 | |||
54 | log = calloc(1, sizeof(Log)); | ||
55 | eina_stringshare_replace(&log->message, spy_line_get(sl)); | ||
56 | eina_stringshare_replace(&log->filename, filter->filename); | ||
57 | eina_stringshare_replace(&log->source_host, smman->cfg.host); | ||
58 | eina_stringshare_replace(&log->source_path, filter->filename); | ||
59 | log->tags = eina_strbuf_new(); | ||
60 | |||
61 | /* Now we apply rules */ | ||
62 | it = eina_hash_iterator_tuple_new(filter->rules); | ||
63 | while (eina_iterator_next(it, (void **)&t)) | ||
64 | { | ||
65 | const char *name; | ||
66 | |||
67 | name = t->key; | ||
68 | rule = t->data; | ||
69 | DBG("rule[%p][%s]", rule, name); | ||
70 | |||
71 | r = _log_line_match(spy_line_get(sl), rule); | ||
72 | if (!r) | ||
73 | continue; | ||
74 | |||
75 | if (rule->spec.todel) | ||
76 | { | ||
77 | log->todel = EINA_TRUE; | ||
78 | break; | ||
79 | } | ||
80 | |||
81 | if (rule->spec.source_host) | ||
82 | eina_stringshare_replace(&log->source_host, rule->spec.source_host); | ||
83 | |||
84 | if (rule->spec.source_path) | ||
85 | eina_stringshare_replace(&log->source_path, rule->spec.source_path); | ||
86 | |||
87 | if (rule->spec.tags) | ||
88 | { | ||
89 | if (eina_strbuf_length_get(log->tags)) | ||
90 | eina_strbuf_append(log->tags, ","); | ||
91 | eina_strbuf_append(log->tags, rule->spec.tags); | ||
92 | } | ||
93 | } | ||
94 | eina_iterator_free(it); | ||
95 | |||
96 | if (log->todel) | ||
97 | return EINA_TRUE; | ||
98 | |||
99 | |||
100 | DBG("Log to index :\n" | ||
101 | "\tmessage = %s\n" | ||
102 | "\tfilename = %s\n" | ||
103 | "\tsource_host = %s\n" | ||
104 | "\tsource_path = %s\n" | ||
105 | "\ttags = %s\n", | ||
106 | log->message, | ||
107 | log->filename, | ||
108 | log->source_host, | ||
109 | log->source_path, | ||
110 | eina_strbuf_string_get(log->tags)); | ||
111 | |||
112 | return EINA_TRUE; | ||
113 | } | ||
diff --git a/src/bin/main.c b/src/bin/main.c index e7f0ece..6f85a98 100644 --- a/src/bin/main.c +++ b/src/bin/main.c | |||
@@ -48,7 +48,7 @@ init(void) | |||
48 | { | 48 | { |
49 | Smman *smman; | 49 | Smman *smman; |
50 | 50 | ||
51 | smman_log_dom_global = eina_log_domain_register("smman", EINA_COLOR_YELLOW); | 51 | smman_log_dom_global = eina_log_domain_register("smman", EINA_COLOR_CYAN); |
52 | if (smman_log_dom_global < 0) | 52 | if (smman_log_dom_global < 0) |
53 | { | 53 | { |
54 | EINA_LOG_ERR("Smman can not create a general log domain"); | 54 | EINA_LOG_ERR("Smman can not create a general log domain"); |
@@ -69,6 +69,14 @@ init(void) | |||
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
71 | 71 | ||
72 | smman->spy = spy_new(); | ||
73 | if (!smman->spy) | ||
74 | { | ||
75 | ERR("Failed to create new spy"); | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | smman->ev.sl = ecore_event_handler_add(SPY_EVENT_LINE,log_line_event, smman); | ||
72 | return smman; | 80 | return smman; |
73 | } | 81 | } |
74 | 82 | ||
@@ -103,6 +111,7 @@ int main(int argc, char **argv) | |||
103 | 111 | ||
104 | conf_init(); | 112 | conf_init(); |
105 | rules_init(); | 113 | rules_init(); |
114 | spy_init(); | ||
106 | 115 | ||
107 | smman = init(); | 116 | smman = init(); |
108 | if (!smman) | 117 | if (!smman) |
diff --git a/src/bin/smman.h b/src/bin/smman.h index a532b86..d75452b 100644 --- a/src/bin/smman.h +++ b/src/bin/smman.h | |||
@@ -8,20 +8,36 @@ | |||
8 | #include <Eio.h> | 8 | #include <Eio.h> |
9 | #include <Conf.h> | 9 | #include <Conf.h> |
10 | #include <Rules.h> | 10 | #include <Rules.h> |
11 | #include <Spy.h> | ||
11 | 12 | ||
12 | int smman_log_dom_global; | 13 | int smman_log_dom_global; |
13 | 14 | ||
14 | typedef struct _Smman | 15 | typedef struct _Smman |
15 | { | 16 | { |
16 | Rules *rules; | 17 | Rules *rules; |
18 | Spy *spy; | ||
19 | Eina_Inlist *filters; | ||
17 | 20 | ||
18 | struct | 21 | struct |
19 | { | 22 | { |
20 | const char *server, | 23 | const char *server, |
21 | *host; | 24 | *host; |
22 | } cfg; | 25 | } cfg; |
26 | |||
27 | struct | ||
28 | { | ||
29 | Ecore_Event_Handler *sl; /* SPY_EVENT_LINE */ | ||
30 | } ev; | ||
23 | } Smman; | 31 | } Smman; |
24 | 32 | ||
33 | typedef struct _Filter | ||
34 | { | ||
35 | EINA_INLIST; | ||
36 | const char *filename; | ||
37 | Spy_File *sf; | ||
38 | Eina_Hash *rules; | ||
39 | } Filter; | ||
40 | |||
25 | #define ERR(...) EINA_LOG_DOM_ERR(smman_log_dom_global, __VA_ARGS__) | 41 | #define ERR(...) EINA_LOG_DOM_ERR(smman_log_dom_global, __VA_ARGS__) |
26 | #define DBG(...) EINA_LOG_DOM_DBG(smman_log_dom_global, __VA_ARGS__) | 42 | #define DBG(...) EINA_LOG_DOM_DBG(smman_log_dom_global, __VA_ARGS__) |
27 | #define NFO(...) EINA_LOG_DOM_INFO(smman_log_dom_global, __VA_ARGS__) | 43 | #define NFO(...) EINA_LOG_DOM_INFO(smman_log_dom_global, __VA_ARGS__) |
@@ -34,3 +50,5 @@ void config_error(void *data, Conf *conf, const char *errstr); | |||
34 | void filter_load(void *data, Rules *rules, Rule *rule); | 50 | void filter_load(void *data, Rules *rules, Rule *rule); |
35 | void filter_load_done(void *data, Rules *rules); | 51 | void filter_load_done(void *data, Rules *rules); |
36 | void filter_load_error(void *data, Rules *rules, const char *errstr); | 52 | void filter_load_error(void *data, Rules *rules, const char *errstr); |
53 | |||
54 | Eina_Bool log_line_event(void *data, int type, void *event); | ||
diff --git a/src/include/Rules.h b/src/include/Rules.h index e20e2a5..86d93ac 100644 --- a/src/include/Rules.h +++ b/src/include/Rules.h | |||
@@ -46,4 +46,5 @@ int rules_shutdown(void); | |||
46 | Rules * rules_new(const char *directory); | 46 | Rules * rules_new(const char *directory); |
47 | Eina_Bool rules_load(Rules *rules, Rules_Progress_Cb progress_cb, Rules_Done_Cb done_cb, Rules_Error_Cb error_cb, void *data); | 47 | Eina_Bool rules_load(Rules *rules, Rules_Progress_Cb progress_cb, Rules_Done_Cb done_cb, Rules_Error_Cb error_cb, void *data); |
48 | 48 | ||
49 | void rules_rule_free(Rule *rule); | ||
49 | #endif | 50 | #endif |
diff --git a/src/include/Spy.h b/src/include/Spy.h index d1b182d..b24c42b 100644 --- a/src/include/Spy.h +++ b/src/include/Spy.h | |||
@@ -18,9 +18,10 @@ void spy_free(Spy *spy); | |||
18 | 18 | ||
19 | Spy_File * spy_file_new(Spy *spy, const char *file); | 19 | Spy_File * spy_file_new(Spy *spy, const char *file); |
20 | Spy_File * spy_file_get(Spy *spy, const char *file); | 20 | Spy_File * spy_file_get(Spy *spy, const char *file); |
21 | const char * spy_line_get(Spy_Line *sl); | ||
22 | const char * spy_file_name_get(Spy_File *sf); | 21 | const char * spy_file_name_get(Spy_File *sf); |
23 | void spy_file_data_set(Spy_File *sf, const void *data); | 22 | void spy_file_data_set(Spy_File *sf, const void *data); |
24 | const void * spy_file_data_get(Spy_File *sf); | 23 | void * spy_file_data_get(Spy_File *sf); |
25 | 24 | ||
25 | const char * spy_line_get(Spy_Line *sl); | ||
26 | Spy_File * spy_line_spyfile_get(Spy_Line *sl); | ||
26 | #endif | 27 | #endif |
diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk index 860a1b4..bb78459 100644 --- a/src/lib/Makefile.mk +++ b/src/lib/Makefile.mk | |||
@@ -14,8 +14,9 @@ src_lib_libconf_la_CFLAGS = $(LIBS_CFLAGS) $(EXTRA_CPPFLAGS) | |||
14 | src_lib_libconf_la_LDFLAGS = $(LIBS_LIBS) | 14 | src_lib_libconf_la_LDFLAGS = $(LIBS_LIBS) |
15 | 15 | ||
16 | src_lib_libspy_la_SOURCES = \ | 16 | src_lib_libspy_la_SOURCES = \ |
17 | src/lib/spy/spy_file.c \ | ||
18 | src/lib/spy/spy_main.c \ | 17 | src/lib/spy/spy_main.c \ |
18 | src/lib/spy/spy_file.c \ | ||
19 | src/lib/spy/spy_line.c \ | ||
19 | src/lib/spy/spy_private.h \ | 20 | src/lib/spy/spy_private.h \ |
20 | src/include/Spy.h | 21 | src/include/Spy.h |
21 | src_lib_libspy_la_CFLAGS = $(LIBS_CFLAGS) $(EXTRA_CPPFLAGS) | 22 | src_lib_libspy_la_CFLAGS = $(LIBS_CFLAGS) $(EXTRA_CPPFLAGS) |
diff --git a/src/lib/rules/rules_private.h b/src/lib/rules/rules_private.h index f20293e..1d74d95 100644 --- a/src/lib/rules/rules_private.h +++ b/src/lib/rules/rules_private.h | |||
@@ -27,8 +27,6 @@ typedef struct _Rules_Load | |||
27 | } cb; | 27 | } cb; |
28 | } Rules_Load; | 28 | } Rules_Load; |
29 | 29 | ||
30 | void rules_rule_free(Rule *rule); | ||
31 | |||
32 | Eina_Bool rules_load_ls_filter(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); | 30 | Eina_Bool rules_load_ls_filter(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); |
33 | void rules_load_ls(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); | 31 | void rules_load_ls(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); |
34 | void rules_load_ls_done(void *data, Eio_File *handler); | 32 | void rules_load_ls_done(void *data, Eio_File *handler); |
diff --git a/src/lib/spy/spy_file.c b/src/lib/spy/spy_file.c index 49efbbf..944f326 100644 --- a/src/lib/spy/spy_file.c +++ b/src/lib/spy/spy_file.c | |||
@@ -87,7 +87,7 @@ _spy_file_cb(void *data, | |||
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | 89 | ||
90 | fseeko(sf->read.fd, sf->read.offset, SEEK_SET); | 90 | fseeko(sf->read.fd, sf->read.offset - 1, SEEK_SET); |
91 | left = sf->read.length; | 91 | left = sf->read.length; |
92 | 92 | ||
93 | while (nbr != (size_t)sf->read.length) | 93 | while (nbr != (size_t)sf->read.length) |
@@ -185,15 +185,9 @@ spy_file_poll(void *data) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | const char * | 187 | const char * |
188 | spy_line_get(Spy_Line *sl) | ||
189 | { | ||
190 | return sl->line; | ||
191 | } | ||
192 | |||
193 | |||
194 | const char * | ||
195 | spy_file_name_get(Spy_File *sf) | 188 | spy_file_name_get(Spy_File *sf) |
196 | { | 189 | { |
190 | EINA_SAFETY_ON_NULL_RETURN_VAL(sf, NULL); | ||
197 | return sf->name; | 191 | return sf->name; |
198 | } | 192 | } |
199 | 193 | ||
@@ -204,8 +198,9 @@ spy_file_data_set(Spy_File *sf, | |||
204 | sf->data = (const void *)data; | 198 | sf->data = (const void *)data; |
205 | } | 199 | } |
206 | 200 | ||
207 | const void * | 201 | void * |
208 | spy_file_data_get(Spy_File *sf) | 202 | spy_file_data_get(Spy_File *sf) |
209 | { | 203 | { |
210 | return sf->data; | 204 | EINA_SAFETY_ON_NULL_RETURN_VAL(sf, NULL); |
205 | return (void *)sf->data; | ||
211 | } | 206 | } |
diff --git a/src/lib/spy/spy_line.c b/src/lib/spy/spy_line.c new file mode 100644 index 0000000..0768027 --- /dev/null +++ b/src/lib/spy/spy_line.c | |||
@@ -0,0 +1,14 @@ | |||
1 | #include "spy_private.h" | ||
2 | |||
3 | const char * | ||
4 | spy_line_get(Spy_Line *sl) | ||
5 | { | ||
6 | return sl->line; | ||
7 | } | ||
8 | |||
9 | Spy_File * | ||
10 | spy_line_spyfile_get(Spy_Line *sl) | ||
11 | { | ||
12 | return sl->sf; | ||
13 | } | ||
14 | |||
diff --git a/src/lib/spy/spy_main.c b/src/lib/spy/spy_main.c index 139afed..bb171b3 100644 --- a/src/lib/spy/spy_main.c +++ b/src/lib/spy/spy_main.c | |||
@@ -90,7 +90,7 @@ spy_file_new(Spy *spy, const char *file) | |||
90 | } | 90 | } |
91 | 91 | ||
92 | sf->poll.size = st.st_size; | 92 | sf->poll.size = st.st_size; |
93 | sf->poll.timer = ecore_timer_add(5.0, spy_file_poll, sf); | 93 | sf->poll.timer = ecore_timer_add(0.3, spy_file_poll, sf); |
94 | 94 | ||
95 | spy->files = eina_inlist_append(spy->files, EINA_INLIST_GET(sf)); | 95 | spy->files = eina_inlist_append(spy->files, EINA_INLIST_GET(sf)); |
96 | DBG("spy_file[%p] size[%zd]", sf, st.st_size); | 96 | DBG("spy_file[%p] size[%zd]", sf, st.st_size); |