Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / examples / machine-mon.c @ master

History | View | Annotate | Download (5.17 KB)

1
#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
#include <unistd.h>
12
#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
**        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
**        (4) start up gdp-reader specifying a text subscription
28
**            to the same log:
29
**                    gdp-reader -s -t logname
30
**        (5) you should see the gdp-reader window spit out JSON
31
**            records every 30 seconds showing a bunch of information
32
**            about the machine being monitored.
33
**
34
**        The -h flag is because on the beaglebone the name is always
35
**        "beaglebone".
36
*/
37

    
38

    
39
gdp_gin_t        *MonGin;
40
unsigned int        SampleIntvl        = 60;
41

    
42

    
43
#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
#include <sys/resource.h>
79
#include <sys/sysctl.h>
80

    
81
#if !__APPLE__
82
#include <vm/vm_param.h>
83
#endif
84

    
85
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
void
130
usage(void)
131
{
132
        fprintf(stderr,
133
                "Usage: %s [-D dbgspec] [-h name] [-s sec] logname\n"
134
                "    -D  turn on debugging\n"
135
                "    -h  hostname (logging tag)\n"
136
                "    -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
        gdp_name_t gdpname;
147
        char *gdpxname;
148
        bool show_usage = false;
149
        int opt;
150
        char *hostname = NULL;
151
        char hostbuf[100];
152

    
153
        while ((opt = getopt(argc, argv, "D:h:s:")) > 0)
154
        {
155
                switch (opt)
156
                {
157
                  case 'D':
158
                        ep_dbg_set(optarg);
159
                        break;
160

    
161
                  case 'h':
162
                        hostname = optarg;
163
                        break;
164

    
165
                  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
        gdpxname = argv[0];
181

    
182
        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
        // 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
        printf("Converting name %s to internal form:\n", gdpxname);
203
        estat = gdp_parse_name(gdpxname, gdpname);
204
        if (!EP_STAT_ISOK(estat))
205
        {
206
                ep_app_error("Illegal log name syntax:\n\t%s",
207
                        gdpxname);
208
                exit(EX_NOINPUT);
209
        }
210

    
211
        // open the GCL for writing
212
        printf("Opening log for writing:\n");
213
        estat = gdp_gin_open(gdpname, GDP_MODE_AO, NULL, &MonGin);
214
        if (!EP_STAT_ISOK(estat))
215
        {
216
                char sbuf[100];
217

    
218
                ep_app_error("Cannot open log:\n    %s",
219
                        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
                // create the top-level option
228
                json_t *json = json_object();
229

    
230
                // fixed part
231
                json_object_set(json, "host", json_string(hostname));
232

    
233
                // do the os-dependent part
234
                populate_info(json);
235

    
236
                // write it out... get a datum and the I/O buffer...
237
                gdp_datum_t *datum = gdp_datum_new();
238
                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
                estat = gdp_gin_append(MonGin, datum, NULL);
248

    
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
}