]> arthur.barton.de Git - netdata.git/blob - src/registry_log.c
dns_query_time plugin: replace "." with "_" in dimensions
[netdata.git] / src / registry_log.c
1 #include "registry_internals.h"
2
3 void registry_log(const char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name) {
4     if(likely(registry.log_fp)) {
5         if(unlikely(fprintf(registry.log_fp, "%c\t%08x\t%s\t%s\t%s\t%s\n",
6                 action,
7                 p->last_t,
8                 p->guid,
9                 m->guid,
10                 name,
11                 u->url) < 0))
12             error("Registry: failed to save log. Registry data may be lost in case of abnormal restart.");
13
14         // we increase the counter even on failures
15         // so that the registry will be saved periodically
16         registry.log_count++;
17
18         // this must be outside the log_lock(), or a deadlock will happen.
19         // registry_db_save() checks the same inside the log_lock, so only
20         // one thread will save the db
21         if(unlikely(registry_db_should_be_saved()))
22             registry_db_save();
23     }
24 }
25
26 int registry_log_open(void) {
27     if(registry.log_fp)
28         fclose(registry.log_fp);
29
30     registry.log_fp = fopen(registry.log_filename, "a");
31     if(registry.log_fp) {
32         if (setvbuf(registry.log_fp, NULL, _IOLBF, 0) != 0)
33             error("Cannot set line buffering on registry log file.");
34         return 0;
35     }
36
37     error("Cannot open registry log file '%s'. Registry data will be lost in case of netdata or server crash.", registry.log_filename);
38     return -1;
39 }
40
41 void registry_log_close(void) {
42     if(registry.log_fp) {
43         fclose(registry.log_fp);
44         registry.log_fp = NULL;
45     }
46 }
47
48 void registry_log_recreate(void) {
49     if(registry.log_fp != NULL) {
50         registry_log_close();
51
52         // open it with truncate
53         registry.log_fp = fopen(registry.log_filename, "w");
54         if(registry.log_fp) fclose(registry.log_fp);
55         else error("Cannot truncate registry log '%s'", registry.log_filename);
56
57         registry.log_fp = NULL;
58         registry_log_open();
59     }
60 }
61
62 ssize_t registry_log_load(void) {
63     ssize_t line = -1;
64
65     // closing the log is required here
66     // otherwise we will append to it the values we read
67     registry_log_close();
68
69     debug(D_REGISTRY, "Registry: loading active db from: %s", registry.log_filename);
70     FILE *fp = fopen(registry.log_filename, "r");
71     if(!fp)
72         error("Registry: cannot open registry file: %s", registry.log_filename);
73     else {
74         char *s, buf[4096 + 1];
75         line = 0;
76         size_t len = 0;
77
78         while ((s = fgets_trim_len(buf, 4096, fp, &len))) {
79             line++;
80
81             switch (s[0]) {
82                 case 'A': // accesses
83                 case 'D': // deletes
84
85                     // verify it is valid
86                     if (unlikely(len < 85 || s[1] != '\t' || s[10] != '\t' || s[47] != '\t' || s[84] != '\t')) {
87                         error("Registry: log line %zd is wrong (len = %zu).", line, len);
88                         continue;
89                     }
90                     s[1] = s[10] = s[47] = s[84] = '\0';
91
92                     // get the variables
93                     time_t when = strtoul(&s[2], NULL, 16);
94                     char *person_guid = &s[11];
95                     char *machine_guid = &s[48];
96                     char *name = &s[85];
97
98                     // skip the name to find the url
99                     char *url = name;
100                     while(*url && *url != '\t') url++;
101                     if(!*url) {
102                         error("Registry: log line %zd does not have a url.", line);
103                         continue;
104                     }
105                     *url++ = '\0';
106
107                     // make sure the person exists
108                     // without this, a new person guid will be created
109                     REGISTRY_PERSON *p = registry_person_find(person_guid);
110                     if(!p) p = registry_person_allocate(person_guid, when);
111
112                     if(s[0] == 'A')
113                         registry_request_access(p->guid, machine_guid, url, name, when);
114                     else
115                         registry_request_delete(p->guid, machine_guid, url, name, when);
116
117                     registry.log_count++;
118                     break;
119
120                 default:
121                     error("Registry: ignoring line %zd of filename '%s': %s.", line, registry.log_filename, s);
122                     break;
123             }
124         }
125
126         fclose(fp);
127     }
128
129     // open the log again
130     registry_log_open();
131
132     return line;
133 }