root/src/noit_check_log.c

Revision 88a71780101cbf23034aa0cb840f9f0368fda2dd, 9.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 years ago)

fixes #126

  • 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
63 static void
64 handle_extra_feeds(noit_check_t *check,
65                    int (*log_f)(noit_log_stream_t ls, noit_check_t *check)) {
66   noit_log_stream_t ls;
67   noit_skiplist_node *curr, *next;
68   const char *feed_name;
69
70   if(!check->feeds) return;
71   curr = next = noit_skiplist_getlist(check->feeds);
72   while(curr) {
73     /* We advance next here (before we try to use curr).
74      * We may need to remove the node we're looking at and that would
75      * disturb the iterator, so advance in advance. */
76     noit_skiplist_next(check->feeds, &next);
77     feed_name = (char *)curr->data;
78     ls = noit_log_stream_find(feed_name);
79     if(!ls || log_f(ls, check)) {
80       noit_check_transient_remove_feed(check, feed_name);
81       /* noit_skiplisti_remove(check->feeds, curr, free); */
82     }
83     curr = next;
84   }
85   /* We're done... we may have destroyed the last feed.
86    * that combined with transience means we should kill the check */
87   /* noit_check_transient_remove_feed(check, NULL); */
88 }
89
90 static int
91 _noit_check_log_check(noit_log_stream_t ls,
92                       noit_check_t *check) {
93   struct timeval __now;
94   char uuid_str[37];
95
96   uuid_unparse_lower(check->checkid, uuid_str);
97   gettimeofday(&__now, NULL);
98   return noit_log(ls, &__now, __FILE__, __LINE__,
99                   "C\t%lu.%03lu\t%s\t%s\t%s\t%s\n",
100                   SECPART(&__now), MSECPART(&__now),
101                   uuid_str, check->target, check->module, check->name);
102 }
103
104 void
105 noit_check_log_check(noit_check_t *check) {
106   handle_extra_feeds(check, _noit_check_log_check);
107   if(!(check->flags & NP_TRANSIENT)) {
108     SETUP_LOG(check, return);
109     _noit_check_log_check(check_log, check);
110   }
111 }
112
113 static int
114 _noit_check_log_status(noit_log_stream_t ls,
115                        noit_check_t *check) {
116   stats_t *c;
117   char uuid_str[37];
118
119   uuid_unparse_lower(check->checkid, uuid_str);
120   c = &check->stats.current;
121   return noit_log(ls, &c->whence, __FILE__, __LINE__,
122                   "S\t%lu.%03lu\t%s\t%c\t%c\t%d\t%s\n",
123                   SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
124                   (char)c->state, (char)c->available, c->duration, c->status);
125 }
126 void
127 noit_check_log_status(noit_check_t *check) {
128   handle_extra_feeds(check, _noit_check_log_status);
129   if(!(check->flags & NP_TRANSIENT)) {
130     SETUP_LOG(status, return);
131     _noit_check_log_status(status_log, check);
132   }
133 }
134 static int
135 _noit_check_log_metrics(noit_log_stream_t ls, noit_check_t *check) {
136   int rv = 0;
137   int srv;
138   char uuid_str[37];
139   noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
140   const char *key;
141   int klen;
142   stats_t *c;
143   void *vm;
144
145   uuid_unparse_lower(check->checkid, uuid_str);
146   c = &check->stats.current;
147   while(noit_hash_next(&c->metrics, &iter, &key, &klen, &vm)) {
148     /* If we apply the filter set and it returns false, we don't log */
149     metric_t *m = (metric_t *)vm;
150     if(!noit_apply_filterset(check->filterset, check, m)) continue;
151     if(!ls->enabled) continue;
152
153     srv = 0;
154     if(!m->metric_value.s) { /* they are all null */
155       srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
156                      "M\t%lu.%03lu\t%s\t%s\t%c\t[[null]]\n",
157                      SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
158                      m->metric_name, m->metric_type);
159     }
160     else {
161       switch(m->metric_type) {
162         case METRIC_INT32:
163           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
164                          "M\t%lu.%03lu\t%s\t%s\t%c\t%d\n",
165                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
166                          m->metric_name, m->metric_type, *(m->metric_value.i));
167           break;
168         case METRIC_UINT32:
169           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
170                          "M\t%lu.%03lu\t%s\t%s\t%c\t%u\n",
171                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
172                          m->metric_name, m->metric_type, *(m->metric_value.I));
173           break;
174         case METRIC_INT64:
175           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
176                          "M\t%lu.%03lu\t%s\t%s\t%c\t%lld\n",
177                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
178                          m->metric_name, m->metric_type, *(m->metric_value.l));
179           break;
180         case METRIC_UINT64:
181           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
182                          "M\t%lu.%03lu\t%s\t%s\t%c\t%llu\n",
183                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
184                          m->metric_name, m->metric_type, *(m->metric_value.L));
185           break;
186         case METRIC_DOUBLE:
187           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
188                          "M\t%lu.%03lu\t%s\t%s\t%c\t%.12e\n",
189                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
190                          m->metric_name, m->metric_type, *(m->metric_value.n));
191           break;
192         case METRIC_STRING:
193           srv = noit_log(ls, &c->whence, __FILE__, __LINE__,
194                          "M\t%lu.%03lu\t%s\t%s\t%c\t%s\n",
195                          SECPART(&c->whence), MSECPART(&c->whence), uuid_str,
196                          m->metric_name, m->metric_type, m->metric_value.s);
197           break;
198         default:
199           noitL(noit_error, "Unknown metric type '%c' 0x%x\n",
200                 m->metric_type, m->metric_type);
201       }
202     }
203     if(srv) rv = srv;
204   }
205   return rv;
206 }
207 void
208 noit_check_log_metrics(noit_check_t *check) {
209   handle_extra_feeds(check, _noit_check_log_metrics);
210   if(!(check->flags & NP_TRANSIENT)) {
211     SETUP_LOG(metrics, return);
212     _noit_check_log_metrics(metrics_log, check);
213   }
214 }
215
216 int
217 noit_stats_snprint_metric(char *b, int l, metric_t *m) {
218   int rv;
219   if(!m->metric_value.s) { /* they are all null */
220     rv = snprintf(b, l, "%s[%c] = [[null]]", m->metric_name, m->metric_type);
221   }
222   else {
223     switch(m->metric_type) {
224       case METRIC_INT32:
225         rv = snprintf(b, l, "%s[%c] = %d",
226                       m->metric_name, m->metric_type, *(m->metric_value.i));
227         break;
228       case METRIC_UINT32:
229         rv = snprintf(b, l, "%s[%c] = %u",
230                       m->metric_name, m->metric_type, *(m->metric_value.I));
231         break;
232       case METRIC_INT64:
233         rv = snprintf(b, l, "%s[%c] = %lld",
234                       m->metric_name, m->metric_type, *(m->metric_value.l));
235         break;
236       case METRIC_UINT64:
237         rv = snprintf(b, l, "%s[%c] = %llu",
238                       m->metric_name, m->metric_type, *(m->metric_value.L));
239         break;
240       case METRIC_DOUBLE:
241         rv = snprintf(b, l, "%s[%c] = %.12e",
242                       m->metric_name, m->metric_type, *(m->metric_value.n));
243         break;
244       case METRIC_STRING:
245         rv = snprintf(b, l, "%s[%c] = %s",
246                       m->metric_name, m->metric_type, m->metric_value.s);
247         break;
248       default:
249         rv = snprintf(b, l, "%s has unknown metric type 0%02x",
250                       m->metric_name, m->metric_type);
251     }
252   }
253   return rv;
254 }
Note: See TracBrowser for help on using the browser.