root/src/modules/selfcheck.c

Revision 84d6f13ffc15b3f1bb50df2ac835b56f70179b3e, 5.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

closes #78

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2009, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <errno.h>
11 #include <assert.h>
12 #include <math.h>
13
14 #include "noit_module.h"
15 #include "noit_check.h"
16 #include "noit_check_tools.h"
17 #include "utils/noit_log.h"
18 #include "utils/noit_hash.h"
19
20 typedef struct {
21   noit_module_t *self;
22   noit_check_t *check;
23   noit_hash_table attrs;
24   size_t logsize;
25   int timed_out;
26 } selfcheck_info_t;
27
28 static noit_log_stream_t nlerr = NULL;
29 static noit_log_stream_t nldeb = NULL;
30
31 static void selfcheck_cleanup(noit_module_t *self, noit_check_t *check) {
32   selfcheck_info_t *ci = check->closure;
33   if(ci) {
34     noit_check_release_attrs(&ci->attrs);
35     memset(ci, 0, sizeof(*ci));
36   }
37 }
38 static void jobq_thread_helper(eventer_jobq_t *jobq, void *closure) {
39   int s32;
40   char buffer[128];
41   stats_t *current = (stats_t *)closure;
42   s32 = jobq->concurrency;
43   if(s32 == 0) return; /* omit if no concurrency */
44   snprintf(buffer, sizeof(buffer), "%s_threads", jobq->queue_name);
45   noit_stats_set_metric(current, buffer, METRIC_INT32, &s32);
46 }
47 static void selfcheck_log_results(noit_module_t *self, noit_check_t *check) {
48   char buff[128];
49   int64_t s64;
50   int32_t s32;
51   stats_t current;
52   struct timeval duration, epoch, diff;
53   selfcheck_info_t *ci = check->closure;
54
55   noit_check_stats_clear(&current);
56
57   gettimeofday(&current.whence, NULL);
58   sub_timeval(current.whence, check->last_fire_time, &duration);
59   current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
60   current.available = NP_UNAVAILABLE;
61   current.state = NP_BAD;
62   if(ci->timed_out) current.status = "timeout";
63   else {
64     current.available = NP_AVAILABLE;
65     current.state = NP_GOOD;
66     current.status = "ok";
67   }
68   /* Set all the metrics here */
69   s64 = (int64_t)ci->logsize;
70   noit_stats_set_metric(&current, "feed_bytes", METRIC_INT64, &s64);
71   s32 = noit_poller_check_count();
72   noit_stats_set_metric(&current, "check_cnt", METRIC_INT32, &s32);
73   s32 = noit_poller_transient_check_count();
74   noit_stats_set_metric(&current, "transient_cnt", METRIC_INT32, &s32);
75   if(eventer_get_epoch(&epoch)) s64 = 0;
76   else {
77     sub_timeval(current.whence, epoch, &diff);
78     s64 = diff.tv_sec;
79   }
80   noit_stats_set_metric(&current, "uptime", METRIC_INT64, &s64);
81   eventer_jobq_process_each(jobq_thread_helper, &current);
82   noit_build_version(buff, sizeof(buff));
83   noit_stats_set_metric(&current, "version", METRIC_STRING, buff);
84
85   noit_check_set_stats(self, check, &current);
86 }
87
88 #define FETCH_CONFIG_OR(key, str) do { \
89   if(!noit_hash_retrieve(check->config, #key, strlen(#key), (void **)&key)) \
90     key = str; \
91 } while(0)
92
93 static int selfcheck_log_size(eventer_t e, int mask, void *closure,
94                               struct timeval *now) {
95   selfcheck_info_t *ci = closure;
96   noit_check_t *check = ci->check;
97   const char *feedname;
98   char feedname_buff[128];
99   noit_log_stream_t feed;
100
101   if(mask & (EVENTER_READ | EVENTER_WRITE)) {
102     /* this case is impossible from the eventer.  It is called as
103      * such on the synchronous completion of the event.
104      */
105     selfcheck_log_results(ci->self, ci->check);
106     selfcheck_cleanup(ci->self, ci->check);
107     check->flags &= ~NP_RUNNING;
108     return 0;
109   }
110   switch(mask) {
111     case EVENTER_ASYNCH_WORK:
112       /* Check the length of the log */
113       FETCH_CONFIG_OR(feedname, "feed");
114       noit_check_interpolate(feedname_buff, sizeof(feedname_buff), feedname,
115                              &ci->attrs, check->config);
116       feed = noit_log_stream_find(feedname_buff);
117       if(!feed) ci->logsize = -1;
118       else ci->logsize = noit_log_stream_size(feed);
119       ci->timed_out = 0;
120       return 0;
121       break;
122     case EVENTER_ASYNCH_CLEANUP:
123       /* This sets us up for a completion call. */
124       e->mask = EVENTER_READ | EVENTER_WRITE;
125       break;
126     default:
127       abort();
128   }
129   return 0;
130 }
131
132 static int selfcheck_initiate(noit_module_t *self, noit_check_t *check) {
133   selfcheck_info_t *ci = check->closure;
134   struct timeval __now;
135
136   /* We cannot be running */
137   assert(!(check->flags & NP_RUNNING));
138   check->flags |= NP_RUNNING;
139
140   ci->self = self;
141   ci->check = check;
142
143   ci->timed_out = 1;
144   noit_check_make_attrs(check, &ci->attrs);
145   gettimeofday(&__now, NULL);
146   memcpy(&check->last_fire_time, &__now, sizeof(__now));
147
148   /* Register a handler for the worker */
149   noit_check_run_full_asynch(check, selfcheck_log_size);
150   return 0;
151 }
152
153 static int selfcheck_initiate_check(noit_module_t *self, noit_check_t *check,
154                                    int once, noit_check_t *parent) {
155   if(!check->closure) check->closure = calloc(1, sizeof(selfcheck_info_t));
156   INITIATE_CHECK(selfcheck_initiate, self, check);
157   return 0;
158 }
159
160 static int selfcheck_onload(noit_image_t *self) {
161   nlerr = noit_log_stream_find("error/selfcheck");
162   nldeb = noit_log_stream_find("debug/selfcheck");
163   if(!nlerr) nlerr = noit_stderr;
164   if(!nldeb) nldeb = noit_debug;
165
166   eventer_name_callback("selfcheck/selfcheck_log_size", selfcheck_log_size);
167   return 0;
168 }
169
170 #include "selfcheck.xmlh"
171 noit_module_t selfcheck = {
172   {
173     NOIT_MODULE_MAGIC,
174     NOIT_MODULE_ABI_VERSION,
175     "selfcheck",
176     "noitd self-checker",
177     selfcheck_xml_description,
178     selfcheck_onload
179   },
180   NULL,
181   NULL,
182   selfcheck_initiate_check,
183   selfcheck_cleanup
184 };
185
Note: See TracBrowser for help on using the browser.