gdp / examples / machine-mon.c @ master
History | View | Annotate | Download (5.17 KB)
1 | 4beeb239 | Eric Allman | #include <gdp/gdp.h> |
---|---|---|---|
2 | #include <ep/ep_app.h> |
||
3 | #include <ep/ep_dbg.h> |
||
4 | |||
5 | #include <jansson.h> |
||
6 | |||
7 | #include <errno.h> |
||
8 | #include <stdio.h> |
||
9 | #include <string.h> |
||
10 | #include <sysexits.h> |
||
11 | 4c776c9e | Eric Allman | #include <unistd.h> |
12 | 4beeb239 | Eric Allman | #include <sys/time.h> |
13 | |||
14 | /*
|
||
15 | ** MACHINE-MON --- monitor information on the hardware
|
||
16 | **
|
||
17 | ** This is just a sample program to demonstrate the interface.
|
||
18 | **
|
||
19 | 6b829ac5 | Eric Allman | ** To use this program:
|
20 | **
|
||
21 | ** (1) start up gdp_router on some appropriate machine.
|
||
22 | ** (2) start up gdplogd on an appropriate machine (may be the
|
||
23 | ** same one) --- this presumes you have the GDP configured
|
||
24 | ** to find the routing node.
|
||
25 | ** (3) start up this program on a program you wish to monitor,
|
||
26 | ** passing it the name of a log to hold the results.
|
||
27 | 6e2cccae | Eric Allman | ** (4) start up gdp-reader specifying a text subscription
|
28 | 6b829ac5 | Eric Allman | ** to the same log:
|
29 | 6e2cccae | Eric Allman | ** gdp-reader -s -t logname
|
30 | ** (5) you should see the gdp-reader window spit out JSON
|
||
31 | 6b829ac5 | Eric Allman | ** records every 30 seconds showing a bunch of information
|
32 | ** about the machine being monitored.
|
||
33 | 4c776c9e | Eric Allman | **
|
34 | ** The -h flag is because on the beaglebone the name is always
|
||
35 | ** "beaglebone".
|
||
36 | 4beeb239 | Eric Allman | */
|
37 | |||
38 | |||
39 | eae1d3ec | Eric Allman | gdp_gin_t *MonGin; |
40 | 4beeb239 | Eric Allman | unsigned int SampleIntvl = 60; |
41 | |||
42 | |||
43 | 59e6b4f9 | Eric Allman | #if __linux__
|
44 | |||
45 | /*
|
||
46 | ** Linux version of data collection
|
||
47 | */
|
||
48 | |||
49 | #include <sys/sysinfo.h> |
||
50 | |||
51 | void
|
||
52 | populate_info(json_t *json) |
||
53 | { |
||
54 | struct sysinfo si;
|
||
55 | |||
56 | if (sysinfo(&si) < 0) |
||
57 | { |
||
58 | // how can sysinfo fail?
|
||
59 | ep_app_abort("Sysinfo failed: %s\n",
|
||
60 | strerror(errno)); |
||
61 | } |
||
62 | |||
63 | // fill it in with some potentially interesting information
|
||
64 | json_object_set(json, "uptime", json_integer(si.uptime));
|
||
65 | json_object_set(json, "load1", json_integer(si.loads[0])); |
||
66 | json_object_set(json, "load5", json_integer(si.loads[1])); |
||
67 | json_object_set(json, "load15", json_integer(si.loads[2])); |
||
68 | json_object_set(json, "freeram", json_integer(si.freeram));
|
||
69 | json_object_set(json, "nproc", json_integer(si.procs));
|
||
70 | } |
||
71 | |||
72 | #else
|
||
73 | |||
74 | /*
|
||
75 | ** BSD/MacOS version of data collection
|
||
76 | */
|
||
77 | |||
78 | c1fe1a0e | Eric Allman | #include <sys/resource.h> |
79 | 59e6b4f9 | Eric Allman | #include <sys/sysctl.h> |
80 | |||
81 | c1fe1a0e | Eric Allman | #if !__APPLE__
|
82 | #include <vm/vm_param.h> |
||
83 | #endif
|
||
84 | |||
85 | 59e6b4f9 | Eric Allman | void
|
86 | do_sysctl(int mib0,
|
||
87 | int mib1,
|
||
88 | int mib2,
|
||
89 | unsigned int miblen, |
||
90 | void *buf,
|
||
91 | size_t buflen) |
||
92 | { |
||
93 | int mib[3]; |
||
94 | size_t blen = buflen; |
||
95 | |||
96 | mib[0] = mib0;
|
||
97 | mib[1] = mib1;
|
||
98 | mib[2] = mib2;
|
||
99 | if (sysctl(mib, miblen, buf, &blen, NULL, 0) < 0) |
||
100 | { |
||
101 | // how can sysctl fail?
|
||
102 | ep_app_abort("Sysctl failed: %s\n",
|
||
103 | strerror(errno)); |
||
104 | } |
||
105 | } |
||
106 | |||
107 | void
|
||
108 | populate_info(json_t *json) |
||
109 | { |
||
110 | //json_object_set(json, "uptime", json_integer(si.uptime));
|
||
111 | |||
112 | // load average
|
||
113 | { |
||
114 | struct loadavg la;
|
||
115 | do_sysctl(CTL_VM, VM_LOADAVG, 0, 2, &la, sizeof la); |
||
116 | json_object_set(json, "load1", json_integer(la.ldavg[0])); |
||
117 | json_object_set(json, "load5", json_integer(la.ldavg[1])); |
||
118 | json_object_set(json, "load15", json_integer(la.ldavg[2])); |
||
119 | } |
||
120 | |||
121 | // should do others here
|
||
122 | //json_object_set(json, "freeram", json_integer(si.freeram));
|
||
123 | //json_object_set(json, "nproc", json_integer(si.procs));
|
||
124 | } |
||
125 | |||
126 | #endif
|
||
127 | |||
128 | |||
129 | 4beeb239 | Eric Allman | void
|
130 | usage(void)
|
||
131 | { |
||
132 | fprintf(stderr, |
||
133 | 4c776c9e | Eric Allman | "Usage: %s [-D dbgspec] [-h name] [-s sec] logname\n"
|
134 | 4beeb239 | Eric Allman | " -D turn on debugging\n"
|
135 | 4c776c9e | Eric Allman | " -h hostname (logging tag)\n"
|
136 | 4beeb239 | Eric Allman | " -s sample interval in seconds\n",
|
137 | ep_app_getprogname()); |
||
138 | exit(EX_USAGE); |
||
139 | } |
||
140 | |||
141 | |||
142 | int
|
||
143 | main(int argc, char **argv) |
||
144 | { |
||
145 | EP_STAT estat; |
||
146 | eae1d3ec | Eric Allman | gdp_name_t gdpname; |
147 | char *gdpxname;
|
||
148 | 4beeb239 | Eric Allman | bool show_usage = false; |
149 | int opt;
|
||
150 | 4c776c9e | Eric Allman | char *hostname = NULL; |
151 | char hostbuf[100]; |
||
152 | 4beeb239 | Eric Allman | |
153 | 4c776c9e | Eric Allman | while ((opt = getopt(argc, argv, "D:h:s:")) > 0) |
154 | 4beeb239 | Eric Allman | { |
155 | switch (opt)
|
||
156 | { |
||
157 | case 'D': |
||
158 | ep_dbg_set(optarg); |
||
159 | break;
|
||
160 | |||
161 | 4c776c9e | Eric Allman | case 'h': |
162 | hostname = optarg; |
||
163 | break;
|
||
164 | |||
165 | 4beeb239 | Eric Allman | case 's': |
166 | SampleIntvl = atol(optarg); |
||
167 | break;
|
||
168 | |||
169 | default:
|
||
170 | show_usage = true;
|
||
171 | break;
|
||
172 | } |
||
173 | } |
||
174 | argc -= optind; |
||
175 | argv += optind; |
||
176 | |||
177 | if (show_usage || argc != 1) |
||
178 | usage(); |
||
179 | |||
180 | eae1d3ec | Eric Allman | gdpxname = argv[0];
|
181 | 4beeb239 | Eric Allman | |
182 | 4c776c9e | Eric Allman | if (hostname == NULL) |
183 | { |
||
184 | if (gethostname(hostbuf, sizeof hostbuf) < 0) |
||
185 | { |
||
186 | ep_app_abort("gethostname failed");
|
||
187 | exit(1);
|
||
188 | } |
||
189 | hostname = hostbuf; |
||
190 | } |
||
191 | |||
192 | 4beeb239 | Eric Allman | // initialize the GDP library
|
193 | printf("Initializing GDP library:\n");
|
||
194 | estat = gdp_init(NULL);
|
||
195 | if (!EP_STAT_ISOK(estat))
|
||
196 | { |
||
197 | ep_app_error("GDP Initialization failed");
|
||
198 | exit(EX_UNAVAILABLE); |
||
199 | } |
||
200 | |||
201 | // convert the name to internal form
|
||
202 | eae1d3ec | Eric Allman | printf("Converting name %s to internal form:\n", gdpxname);
|
203 | estat = gdp_parse_name(gdpxname, gdpname); |
||
204 | 4beeb239 | Eric Allman | if (!EP_STAT_ISOK(estat))
|
205 | { |
||
206 | eae1d3ec | Eric Allman | ep_app_error("Illegal log name syntax:\n\t%s",
|
207 | gdpxname); |
||
208 | 4beeb239 | Eric Allman | exit(EX_NOINPUT); |
209 | } |
||
210 | |||
211 | // open the GCL for writing
|
||
212 | eae1d3ec | Eric Allman | printf("Opening log for writing:\n");
|
213 | estat = gdp_gin_open(gdpname, GDP_MODE_AO, NULL, &MonGin);
|
||
214 | 4beeb239 | Eric Allman | if (!EP_STAT_ISOK(estat))
|
215 | { |
||
216 | char sbuf[100]; |
||
217 | |||
218 | eae1d3ec | Eric Allman | ep_app_error("Cannot open log:\n %s",
|
219 | 4beeb239 | Eric Allman | ep_stat_tostr(estat, sbuf, sizeof sbuf));
|
220 | exit(EX_NOINPUT); |
||
221 | } |
||
222 | |||
223 | printf("Starting to write data:\n");
|
||
224 | |||
225 | for (;;)
|
||
226 | { |
||
227 | 59e6b4f9 | Eric Allman | // create the top-level option
|
228 | json_t *json = json_object(); |
||
229 | 4beeb239 | Eric Allman | |
230 | 59e6b4f9 | Eric Allman | // fixed part
|
231 | 4c776c9e | Eric Allman | json_object_set(json, "host", json_string(hostname));
|
232 | 59e6b4f9 | Eric Allman | |
233 | // do the os-dependent part
|
||
234 | populate_info(json); |
||
235 | 4beeb239 | Eric Allman | |
236 | // write it out... get a datum and the I/O buffer...
|
||
237 | 2e65953f | Eric Allman | gdp_datum_t *datum = gdp_datum_new(); |
238 | 4beeb239 | Eric Allman | gdp_buf_t *buf = gdp_datum_getbuf(datum); |
239 | |||
240 | // marshall the JSON to a string
|
||
241 | char *p = json_dumps(json, JSON_INDENT(4)); |
||
242 | |||
243 | // copy that string to the buffer
|
||
244 | gdp_buf_printf(buf, "%s", p);
|
||
245 | |||
246 | // append the datum to the log
|
||
247 | eae1d3ec | Eric Allman | estat = gdp_gin_append(MonGin, datum, NULL);
|
248 | 4beeb239 | Eric Allman | |
249 | // remember to free our resources
|
||
250 | free(p); |
||
251 | gdp_datum_free(datum); |
||
252 | |||
253 | // sleep for a while
|
||
254 | sleep(SampleIntvl); |
||
255 | } |
||
256 | ep_app_abort("Impossible exit");
|
||
257 | } |