summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Friloux <guillaume.friloux@gmail.com>2013-12-20 16:46:51 +0100
committerGuillaume Friloux <guillaume.friloux@gmail.com>2013-12-20 16:46:51 +0100
commit67efd371f4c5f17bbecb7e0dbe60f00ee00c03ec (patch)
tree20765b30c4c855c4841b11c6f2e94f247111c652 /src
parentceac6266f34b4c014fa5c95c467a9c382579265c (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.mk4
-rw-r--r--src/bin/filter.c59
-rw-r--r--src/bin/log.c113
-rw-r--r--src/bin/main.c11
-rw-r--r--src/bin/smman.h18
-rw-r--r--src/include/Rules.h1
-rw-r--r--src/include/Spy.h5
-rw-r--r--src/lib/Makefile.mk3
-rw-r--r--src/lib/rules/rules_private.h2
-rw-r--r--src/lib/spy/spy_file.c15
-rw-r--r--src/lib/spy/spy_line.c14
-rw-r--r--src/lib/spy/spy_main.c2
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 = \
8src/bin/main.c \ 8src/bin/main.c \
9src/bin/config.c \ 9src/bin/config.c \
10src/bin/filter.c \ 10src/bin/filter.c \
11src/bin/log.c \
11src/bin/smman.h 12src/bin/smman.h
12src_bin_smman_CPPFLAGS = @BIN_CFLAGS@ $(EXTRA_CPPFLAGS) 13src_bin_smman_CPPFLAGS = @BIN_CFLAGS@ $(EXTRA_CPPFLAGS)
13src_bin_smman_LDFLAGS = @BIN_LIBS@ 14src_bin_smman_LDFLAGS = @BIN_LIBS@
14src_bin_smman_LDADD = \ 15src_bin_smman_LDADD = \
15src/lib/libconf.la \ 16src/lib/libconf.la \
16src/lib/librules.la 17src/lib/librules.la \
18src/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
4static void
5_filter_rules_free(void *data)
6{
7 rules_rule_free((Rule *)data);
8}
9
10Filter *
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
3void 24void
4filter_load(void *data, 25filter_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
23void 81void
@@ -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
37void 94void
38filter_load_error(void *data, 95filter_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
3typedef 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
13Eina_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
36Eina_Bool
37log_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
12int smman_log_dom_global; 13int smman_log_dom_global;
13 14
14typedef struct _Smman 15typedef 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
33typedef 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);
34void filter_load(void *data, Rules *rules, Rule *rule); 50void filter_load(void *data, Rules *rules, Rule *rule);
35void filter_load_done(void *data, Rules *rules); 51void filter_load_done(void *data, Rules *rules);
36void filter_load_error(void *data, Rules *rules, const char *errstr); 52void filter_load_error(void *data, Rules *rules, const char *errstr);
53
54Eina_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);
46Rules * rules_new(const char *directory); 46Rules * rules_new(const char *directory);
47Eina_Bool rules_load(Rules *rules, Rules_Progress_Cb progress_cb, Rules_Done_Cb done_cb, Rules_Error_Cb error_cb, void *data); 47Eina_Bool rules_load(Rules *rules, Rules_Progress_Cb progress_cb, Rules_Done_Cb done_cb, Rules_Error_Cb error_cb, void *data);
48 48
49void 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
19Spy_File * spy_file_new(Spy *spy, const char *file); 19Spy_File * spy_file_new(Spy *spy, const char *file);
20Spy_File * spy_file_get(Spy *spy, const char *file); 20Spy_File * spy_file_get(Spy *spy, const char *file);
21const char * spy_line_get(Spy_Line *sl);
22const char * spy_file_name_get(Spy_File *sf); 21const char * spy_file_name_get(Spy_File *sf);
23void spy_file_data_set(Spy_File *sf, const void *data); 22void spy_file_data_set(Spy_File *sf, const void *data);
24const void * spy_file_data_get(Spy_File *sf); 23void * spy_file_data_get(Spy_File *sf);
25 24
25const char * spy_line_get(Spy_Line *sl);
26Spy_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)
14src_lib_libconf_la_LDFLAGS = $(LIBS_LIBS) 14src_lib_libconf_la_LDFLAGS = $(LIBS_LIBS)
15 15
16src_lib_libspy_la_SOURCES = \ 16src_lib_libspy_la_SOURCES = \
17src/lib/spy/spy_file.c \
18src/lib/spy/spy_main.c \ 17src/lib/spy/spy_main.c \
18src/lib/spy/spy_file.c \
19src/lib/spy/spy_line.c \
19src/lib/spy/spy_private.h \ 20src/lib/spy/spy_private.h \
20src/include/Spy.h 21src/include/Spy.h
21src_lib_libspy_la_CFLAGS = $(LIBS_CFLAGS) $(EXTRA_CPPFLAGS) 22src_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
30void rules_rule_free(Rule *rule);
31
32Eina_Bool rules_load_ls_filter(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); 30Eina_Bool rules_load_ls_filter(void *data, Eio_File *handler, const Eina_File_Direct_Info *info);
33void rules_load_ls(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); 31void rules_load_ls(void *data, Eio_File *handler, const Eina_File_Direct_Info *info);
34void rules_load_ls_done(void *data, Eio_File *handler); 32void 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
187const char * 187const char *
188spy_line_get(Spy_Line *sl)
189{
190 return sl->line;
191}
192
193
194const char *
195spy_file_name_get(Spy_File *sf) 188spy_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
207const void * 201void *
208spy_file_data_get(Spy_File *sf) 202spy_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
3const char *
4spy_line_get(Spy_Line *sl)
5{
6 return sl->line;
7}
8
9Spy_File *
10spy_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);