root/src/noit_check_log.c

Revision ec0f79b5ee03bd254353c5cb634373649f79ebc2, 9.9 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

several warning (now error) fixes on Linux

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34
35 #include <uuid/uuid.h>
36 #include <netinet/in.h>
37
38 #include "noit_check.h"
39 #include "noit_filters.h"
40 #include "utils/noit_log.h"
41 #include "jlog/jlog.h"
42
43 /* Log format is tab delimited:
44  * NOIT CONFIG (implemented in noit_conf.c):
45  *  'n' TIMESTAMP strlen(xmlconfig) base64(gzip(xmlconfig))
46  *
47  * CHECK:
48  *  'C' TIMESTAMP UUID TARGET MODULE NAME
49  *
50  * STATUS:
51  *  'S' TIMESTAMP UUID STATE AVAILABILITY DURATION STATUS_MESSAGE
52  *
53  * METRICS:
54  *  'M' TIMESTAMP UUID NAME TYPE VALUE
55  */
56
57 static noit_log_stream_t check_log = NULL;
58 static noit_log_stream_t status_log = NULL;
59 static noit_log_stream_t metrics_log = NULL;
60 #define SECPART(a) ((unsigned long)(a)->tv_sec)
61 #define MSECPART(a) ((unsigned long)((a)->tv_usec / 1000))
62 #define MAKE_CHECK_UUID_STR(uuid_str, len, ls, check) do { \
63   noit_boolean extended_id = noit_false; \
64   const char *v; \
65   v = noit_log_stream_get_property(ls, "extended_id"); \
66   if(v && !strcmp(v, "on")) extended_id = noit_true; \
67   uuid_str[0] = '\0'; \
68   if(extended_id) { \
69     strlcat(uuid_str, check->target, len-37); \
70     strlcat(uuid_str, "`", len-37); \
71     strlcat(uuid_str, check->module, len-37); \
72     strlcat(uuid_str, "`", len-37); \
73     strlcat(uuid_str, check->name, len-37); \
74     strlcat(uuid_str, "`", len-37); \
75   } \
76   uuid_unparse_lower(check->checkid, uuid_str + strlen(uuid_str)); \
77 } while(0)
78
79 static void
80 handle_extra_feeds(noit_check_t *check,
81                    int (*log_f)(noit_log_stream_t ls, noit_check_t *check)) {
82   noit_log_stream_t ls;
83   noit_skiplist_node *curr, *next;
84   const char *feed_name;
85
86   if(!check->feeds) return;
87   curr = next = noit_skiplist_getlist(check->feeds);
88   while(curr) {
89     /* We advance next here (before we try to use curr).
90      * We may need to remove the node we're looking at and that would
91      * disturb the iterator, so advance in advance. */
92     noit_skiplist_next(check->feeds, &next);
93     feed_name = (char *)curr->data;
94     ls = noit_log_stream_find(feed_name);
95     if(!ls || log_f(ls, check)) {
96       noit_check_transient_remove_feed(check, feed_name);
97       /* noit_skiplisti_remove(check->feeds, curr, free); */
98     }
99     curr = next;
100   }
101   /* We're done... we may have destroyed the last feed.
102    * that combined with transience means we should kill the check */
103   /* noit_check_transient_remove_feed(check, NULL); */
104 }
105
106 static int
107 _noit_check_log_check(noit_log_stream_t ls,
108                       noit_check_t *check) {
109   struct timeval __now;
110   char uuid_str[256*3+37];
111   SETUP_LOG(check, );
112   MAKE_CHECK_UUID_STR(uuid_str, sizeof(uuid_str), check_log, check);
113
114   gettimeofday(&__now, NULL);
115   return noit_log(ls, &__now, __FILE__, __LINE__,
116                   "C\t%lu.%03lu\t%s\t%s\t%s\t%s\n",
117                   SECPART(&__now), MSECPART(&__now),
118                   uuid_str, check->target, check->module, check->name);
119 }
120
121 void
122 noit_check_log_check(noit_check_t *check) {
123   if(!(check->flags & NP_TRANSIENT)) {
124     handle_extra_feeds(check, _noit_check_log_check);
125     SETUP_LOG(check, return);
126     _noit_check_log_check(check_log, check);
127   }
128 }
129
130 static int
131 _noit_check_log_status(noit_log_stream_t ls,
132                        noit_check_t *check) {
133   stats_t *c;
134   char uuid_str[256*3+37];
135   SETUP_LOG(status, );
136   MAKE_CHECK_UUID_STR(uuid_str, sizeof(uuid_str), status_log, check);
137
138   c = &check->stats.current;
139   return noit_log(ls, &c->whence, __FILE__, __LINE__,
140                   "S\t%lu.%03lu\t%s\t%c\t%c\t%d\t%s\n",
141                   SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
142                   (char)c->state, (char)c->available, c->duration, c->status);
143 }
144 void
145 noit_check_log_status(noit_check_t *check) {
146   handle_extra_feeds(check, _noit_check_log_status);
147   if(!(check->flags & NP_TRANSIENT)) {
148     SETUP_LOG(status, return);
149     _noit_check_log_status(status_log, check);
150   }
151 }
152 static int
153 _noit_check_log_metrics(noit_log_stream_t ls, noit_check_t *check) {
154   int rv = 0;
155   int srv;
156   char uuid_str[256*3+37];
157   noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
158   const char *key;
159   int klen;
160   stats_t *c;
161   void *vm;
162   SETUP_LOG(metrics, );
163   MAKE_CHECK_UUID_STR(uuid_str, sizeof(uuid_str), metrics_log, check);
164
165   c = &check->stats.current;
166   while(noit_hash_next(&c->metrics, &iter, &key, &klen, &vm)) {
167     /* If we apply the filter set and it returns false, we don't log */
168     metric_t *m = (metric_t *)vm;
169     if(!noit_apply_filterset(check->filterset, check, m)) continue;
170     if(!ls->enabled) continue;
171
172     srv = 0;
173     if(!m->metric_value.s) { /* they are all null */
174       srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
175                      "M\t%lu.%03lu\t%s\t%s\t%c\t[[null]]\n",
176                      SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
177                      m->metric_name, m->metric_type);
178     }
179     else {
180       switch(m->metric_type) {
181         case METRIC_INT32:
182           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
183                          "M\t%lu.%03lu\t%s\t%s\t%c\t%d\n",
184                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
185                          m->metric_name, m->metric_type, *(m->metric_value.i));
186           break;
187         case METRIC_UINT32:
188           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
189                          "M\t%lu.%03lu\t%s\t%s\t%c\t%u\n",
190                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
191                          m->metric_name, m->metric_type, *(m->metric_value.I));
192           break;
193         case METRIC_INT64:
194           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
195                          "M\t%lu.%03lu\t%s\t%s\t%c\t%lld\n",
196                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
197                          m->metric_name, m->metric_type,
198                          (long long int)*(m->metric_value.l));
199           break;
200         case METRIC_UINT64:
201           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
202                          "M\t%lu.%03lu\t%s\t%s\t%c\t%llu\n",
203                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
204                          m->metric_name, m->metric_type,
205                          (long long unsigned int)*(m->metric_value.L));
206           break;
207         case METRIC_DOUBLE:
208           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
209                          "M\t%lu.%03lu\t%s\t%s\t%c\t%.12e\n",
210                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
211                          m->metric_name, m->metric_type, *(m->metric_value.n));
212           break;
213         case METRIC_STRING:
214           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
215                          "M\t%lu.%03lu\t%s\t%s\t%c\t%s\n",
216                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
217                          m->metric_name, m->metric_type, m->metric_value.s);
218           break;
219         default:
220           noitL(noit_error, "Unknown metric type '%c' 0x%x\n",
221                 m->metric_type, m->metric_type);
222       }
223     }
224     if(srv) rv = srv;
225   }
226   return rv;
227 }
228 void
229 noit_check_log_metrics(noit_check_t *check) {
230   handle_extra_feeds(check, _noit_check_log_metrics);
231   if(!(check->flags & NP_TRANSIENT)) {
232     SETUP_LOG(metrics, return);
233     _noit_check_log_metrics(metrics_log, check);
234   }
235 }
236
237 int
238 noit_stats_snprint_metric_value(char *b, int l, metric_t *m) {
239   int rv;
240   if(!m->metric_value.s) { /* they are all null */
241     rv = snprintf(b, l, "[[null]]");
242   }
243   else {
244     switch(m->metric_type) {
245       case METRIC_INT32:
246         rv = snprintf(b, l, "%d", *(m->metric_value.i)); break;
247       case METRIC_UINT32:
248         rv = snprintf(b, l, "%u", *(m->metric_value.I)); break;
249       case METRIC_INT64:
250         rv = snprintf(b, l, "%lld", (long long int)*(m->metric_value.l)); break;
251       case METRIC_UINT64:
252         rv = snprintf(b, l, "%llu",
253                       (long long unsigned int)*(m->metric_value.L)); break;
254       case METRIC_DOUBLE:
255         rv = snprintf(b, l, "%.12e", *(m->metric_value.n)); break;
256       case METRIC_STRING:
257         rv = snprintf(b, l, "%s", m->metric_value.s); break;
258       default:
259         return -1;
260     }
261   }
262   return rv;
263 }
264 int
265 noit_stats_snprint_metric(char *b, int l, metric_t *m) {
266   int rv, nl;
267   nl = snprintf(b, l, "%s[%c] = ", m->metric_name, m->metric_type);
268   if(nl >= l || nl <= 0) return nl;
269   rv = noit_stats_snprint_metric_value(b+nl, l-nl, m);
270   if(rv == -1)
271     rv = snprintf(b+nl, l-nl, "[[unknown type]]");
272   return rv + nl;
273 }
Note: See TracBrowser for help on using the browser.