root/src/noit_check_log.c

Revision 6210da7ee0e2ed143d71a8e00b709f16e71059f8, 7.7 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 years ago)

various changes to avoid dereferencing type-punned pointers and breaking strict-aliasing rules, refs #34

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include <uuid/uuid.h>
9 #include <netinet/in.h>
10
11 #include "noit_check.h"
12 #include "noit_filters.h"
13 #include "utils/noit_log.h"
14 #include "jlog/jlog.h"
15
16 /* Log format is tab delimited:
17  * NOIT CONFIG (implemented in noit_conf.c):
18  *  'n' TIMESTAMP strlen(xmlconfig) base64(gzip(xmlconfig))
19  *
20  * CHECK:
21  *  'C' TIMESTAMP UUID TARGET MODULE NAME
22  *
23  * STATUS:
24  *  'S' TIMESTAMP UUID STATE AVAILABILITY DURATION STATUS_MESSAGE
25  *
26  * METRICS:
27  *  'M' TIMESTAMP UUID NAME TYPE VALUE
28  */
29
30 static noit_log_stream_t check_log = NULL;
31 static noit_log_stream_t status_log = NULL;
32 static noit_log_stream_t metrics_log = NULL;
33 #define SECPART(a) ((unsigned long)(a)->tv_sec)
34 #define MSECPART(a) ((unsigned long)((a)->tv_usec / 1000))
35
36 static void
37 handle_extra_feeds(noit_check_t *check,
38                    int (*log_f)(noit_log_stream_t ls, noit_check_t *check)) {
39   noit_log_stream_t ls;
40   noit_skiplist_node *curr, *next;
41   const char *feed_name;
42
43   if(!check->feeds) return;
44   curr = next = noit_skiplist_getlist(check->feeds);
45   while(curr) {
46     /* We advance next here (before we try to use curr).
47      * We may need to remove the node we're looking at and that would
48      * disturb the iterator, so advance in advance. */
49     noit_skiplist_next(check->feeds, &next);
50     feed_name = (char *)curr->data;
51     ls = noit_log_stream_find(feed_name);
52     if(!ls || log_f(ls, check)) {
53       noit_check_transient_remove_feed(check, feed_name);
54       /* noit_skiplisti_remove(check->feeds, curr, free); */
55     }
56     curr = next;
57   }
58   /* We're done... we may have destroyed the last feed.
59    * that combined with transience means we should kill the check */
60   /* noit_check_transient_remove_feed(check, NULL); */
61 }
62
63 static int
64 _noit_check_log_check(noit_log_stream_t ls,
65                       noit_check_t *check) {
66   struct timeval __now;
67   char uuid_str[37];
68
69   uuid_unparse_lower(check->checkid, uuid_str);
70   gettimeofday(&__now, NULL);
71   return noit_log(ls, &__now, __FILE__, __LINE__,
72                   "C\t%lu.%03lu\t%s\t%s\t%s\t%s\n",
73                   SECPART(&__now), MSECPART(&__now),
74                   uuid_str, check->target, check->module, check->name);
75 }
76
77 void
78 noit_check_log_check(noit_check_t *check) {
79   handle_extra_feeds(check, _noit_check_log_check);
80   if(!(check->flags & NP_TRANSIENT)) {
81     SETUP_LOG(check, return);
82     _noit_check_log_check(check_log, check);
83   }
84 }
85
86 static int
87 _noit_check_log_status(noit_log_stream_t ls,
88                        noit_check_t *check) {
89   stats_t *c;
90   char uuid_str[37];
91
92   uuid_unparse_lower(check->checkid, uuid_str);
93   c = &check->stats.current;
94   return noit_log(ls, &c->whence, __FILE__, __LINE__,
95                   "S\t%lu.%03lu\t%s\t%c\t%c\t%d\t%s\n",
96                   SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
97                   (char)c->state, (char)c->available, c->duration, c->status);
98 }
99 void
100 noit_check_log_status(noit_check_t *check) {
101   handle_extra_feeds(check, _noit_check_log_status);
102   if(!(check->flags & NP_TRANSIENT)) {
103     SETUP_LOG(status, return);
104     _noit_check_log_status(status_log, check);
105   }
106 }
107 static int
108 _noit_check_log_metrics(noit_log_stream_t ls, noit_check_t *check) {
109   int rv = 0;
110   int srv;
111   char uuid_str[37];
112   noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
113   const char *key;
114   int klen;
115   stats_t *c;
116   void *vm;
117
118   uuid_unparse_lower(check->checkid, uuid_str);
119   c = &check->stats.current;
120   while(noit_hash_next(&c->metrics, &iter, &key, &klen, &vm)) {
121     /* If we apply the filter set and it returns false, we don't log */
122     metric_t *m = (metric_t *)vm;
123     if(!noit_apply_filterset(check->filterset, check, m)) continue;
124     if(!ls->enabled) continue;
125
126     srv = 0;
127     if(!m->metric_value.s) { /* they are all null */
128       srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
129                      "M\t%lu.%03lu\t%s\t%s\t%c\t[[null]]\n",
130                      SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
131                      m->metric_name, m->metric_type);
132     }
133     else {
134       switch(m->metric_type) {
135         case METRIC_INT32:
136           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
137                          "M\t%lu.%03lu\t%s\t%s\t%c\t%d\n",
138                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
139                          m->metric_name, m->metric_type, *(m->metric_value.i));
140           break;
141         case METRIC_UINT32:
142           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
143                          "M\t%lu.%03lu\t%s\t%s\t%c\t%u\n",
144                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
145                          m->metric_name, m->metric_type, *(m->metric_value.I));
146           break;
147         case METRIC_INT64:
148           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
149                          "M\t%lu.%03lu\t%s\t%s\t%c\t%lld\n",
150                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
151                          m->metric_name, m->metric_type, *(m->metric_value.l));
152           break;
153         case METRIC_UINT64:
154           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
155                          "M\t%lu.%03lu\t%s\t%s\t%c\t%llu\n",
156                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
157                          m->metric_name, m->metric_type, *(m->metric_value.L));
158           break;
159         case METRIC_DOUBLE:
160           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
161                          "M\t%lu.%03lu\t%s\t%s\t%c\t%.12e\n",
162                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
163                          m->metric_name, m->metric_type, *(m->metric_value.n));
164           break;
165         case METRIC_STRING:
166           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
167                          "M\t%lu.%03lu\t%s\t%s\t%c\t%s\n",
168                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
169                          m->metric_name, m->metric_type, m->metric_value.s);
170           break;
171         default:
172           noitL(noit_error, "Unknown metric type '%c' 0x%x\n",
173                 m->metric_type, m->metric_type);
174       }
175     }
176     if(srv) rv = srv;
177   }
178   return rv;
179 }
180 void
181 noit_check_log_metrics(noit_check_t *check) {
182   handle_extra_feeds(check, _noit_check_log_metrics);
183   if(!(check->flags & NP_TRANSIENT)) {
184     SETUP_LOG(metrics, return);
185     _noit_check_log_metrics(metrics_log, check);
186   }
187 }
188
189 int
190 noit_stats_snprint_metric(char *b, int l, metric_t *m) {
191   int rv;
192   if(!m->metric_value.s) { /* they are all null */
193     rv = snprintf(b, l, "%s[%c] = [[null]]", m->metric_name, m->metric_type);
194   }
195   else {
196     switch(m->metric_type) {
197       case METRIC_INT32:
198         rv = snprintf(b, l, "%s[%c] = %d",
199                       m->metric_name, m->metric_type, *(m->metric_value.i));
200         break;
201       case METRIC_UINT32:
202         rv = snprintf(b, l, "%s[%c] = %u",
203                       m->metric_name, m->metric_type, *(m->metric_value.I));
204         break;
205       case METRIC_INT64:
206         rv = snprintf(b, l, "%s[%c] = %lld",
207                       m->metric_name, m->metric_type, *(m->metric_value.l));
208         break;
209       case METRIC_UINT64:
210         rv = snprintf(b, l, "%s[%c] = %llu",
211                       m->metric_name, m->metric_type, *(m->metric_value.L));
212         break;
213       case METRIC_DOUBLE:
214         rv = snprintf(b, l, "%s[%c] = %.12e",
215                       m->metric_name, m->metric_type, *(m->metric_value.n));
216         break;
217       case METRIC_STRING:
218         rv = snprintf(b, l, "%s[%c] = %s",
219                       m->metric_name, m->metric_type, m->metric_value.s);
220         break;
221       default:
222         rv = snprintf(b, l, "%s has unknown metric type 0%02x",
223                       m->metric_name, m->metric_type);
224     }
225   }
226   return rv;
227 }
Note: See TracBrowser for help on using the browser.