Elliptics version update: 2.19.2.7
[elliptics.git] / example / stat.c
blob7c5883d935aecf0a618479b7a96c6d9c575f9d1c
1 /*
2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/socket.h>
19 #include <sys/time.h>
20 #include <sys/syscall.h>
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
31 #include <netinet/in.h>
33 #include "elliptics/packet.h"
34 #include "elliptics/interface.h"
36 #include "common.h"
38 #ifndef __unused
39 #define __unused __attribute__ ((unused))
40 #endif
42 static struct dnet_log stat_logger;
43 static int stat_mem, stat_la, stat_fs;
45 static int stat_complete(struct dnet_net_state *state,
46 struct dnet_cmd *cmd,
47 void *priv)
49 float la[3];
50 struct dnet_stat *st;
51 char str[64];
52 struct tm tm;
53 struct timeval tv;
54 FILE *stream = priv;
56 if (is_trans_destroyed(state, cmd))
57 return 0;
59 if (cmd->size != sizeof(struct dnet_stat))
60 return cmd->status;
62 if (!stat_mem && !stat_la && !stat_fs)
63 return 0;
65 gettimeofday(&tv, NULL);
66 localtime_r((time_t *)&tv.tv_sec, &tm);
67 strftime(str, sizeof(str), "%F %R:%S", &tm);
69 fprintf(stream, "%s.%06lu :", str, (unsigned long)tv.tv_usec);
71 st = (struct dnet_stat *)(cmd + 1);
73 dnet_convert_stat(st);
75 la[0] = (float)st->la[0] / 100.0;
76 la[1] = (float)st->la[1] / 100.0;
77 la[2] = (float)st->la[2] / 100.0;
80 fprintf(stream, "%s: %s: ", dnet_dump_id(&cmd->id), dnet_state_dump_addr(state));
82 if (stat_la)
83 fprintf(stream, "la: %3.2f %3.2f %3.2f ", la[0], la[1], la[2]);
85 if (stat_mem)
86 fprintf(stream, "mem: total: %8llu kB, free: %8llu kB, cache: %8llu kB, buffers: %8llu, active: %8llu, inactive: %8llu ",
87 (unsigned long long)st->vm_total, (unsigned long long)st->vm_free,
88 (unsigned long long)st->vm_cached, (unsigned long long)st->vm_buffers,
89 (unsigned long long)st->vm_active, (unsigned long long)st->vm_inactive);
91 if (stat_fs)
92 fprintf(stream, "fs: total: %8llu mB, avail: %8llu/%8llu mB ",
93 (unsigned long long)(st->frsize * st->blocks / 1024 / 1024),
94 (unsigned long long)(st->bavail * st->bsize / 1024 / 1024),
95 (unsigned long long)(st->bfree * st->bsize / 1024 / 1024));
97 fprintf(stream, "\n");
98 fflush(stream);
100 return 0;
103 static void stat_usage(char *p)
105 fprintf(stderr, "Usage: %s\n"
106 " -r addr:port:family - adds a route to the given node\n"
107 " -l log - log file. Default: disabled\n"
108 " -L log - statistics log. Default: stdout\n"
109 " -w timeout - wait timeout in seconds used to wait for content sync.\n"
110 " -m level - log level\n"
111 " -I id - request statistics from node which handles given id\n"
112 " -t timeout - timeout in seconds to repeatedly request statistics\n"
113 " -M - show memory usage statistics\n"
114 " -F - show filesystem usage statistics\n"
115 " -A - show load average statistics\n"
116 , p);
119 int main(int argc, char *argv[])
121 int ch, err, i, have_remote = 0;
122 struct dnet_node *n = NULL;
123 struct dnet_session *s = NULL;
124 struct dnet_config cfg, rem;
125 int max_id_idx = 1000, id_idx = 0;
126 int timeout;
127 unsigned char id[max_id_idx][DNET_ID_SIZE];
128 char *logfile = "/dev/stderr", *statfile = "/dev/stdout";
129 FILE *log = NULL, *stat;
131 memset(&cfg, 0, sizeof(struct dnet_config));
133 cfg.sock_type = SOCK_STREAM;
134 cfg.proto = IPPROTO_TCP;
135 cfg.wait_timeout = 60*60;
136 stat_logger.log_level = DNET_LOG_ERROR;
138 timeout = 1;
140 memcpy(&rem, &cfg, sizeof(struct dnet_config));
142 while ((ch = getopt(argc, argv, "MFAt:m:w:l:I:r:h")) != -1) {
143 switch (ch) {
144 case 'M':
145 stat_mem = 1;
146 break;
147 case 'F':
148 stat_fs = 1;
149 break;
150 case 'A':
151 stat_la = 1;
152 break;
153 case 't':
154 timeout = atoi(optarg);
155 break;
156 case 'm':
157 stat_logger.log_level = strtoul(optarg, NULL, 0);
158 break;
159 case 'w':
160 cfg.wait_timeout = atoi(optarg);
161 break;
162 case 'L':
163 statfile = optarg;
164 break;
165 case 'l':
166 logfile = optarg;
167 break;
168 case 'I':
169 if (id_idx < max_id_idx) {
170 err = dnet_parse_numeric_id(optarg, id[id_idx]);
171 if (err)
172 return err;
173 id_idx++;
175 break;
176 case 'r':
177 err = dnet_parse_addr(optarg, &rem);
178 if (err)
179 return err;
180 have_remote = 1;
181 break;
182 case 'h':
183 default:
184 stat_usage(argv[0]);
185 return -1;
189 if (!have_remote) {
190 fprintf(stderr, "No remote node specified to route requests.\n");
191 return -ENOENT;
194 log = fopen(logfile, "a");
195 if (!log) {
196 err = -errno;
197 fprintf(stderr, "Failed to open log file %s: %s.\n", logfile, strerror(errno));
198 return err;
201 stat_logger.log_private = log;
202 stat_logger.log = dnet_common_log;
203 cfg.log = &stat_logger;
205 stat = fopen(statfile, "a");
206 if (!stat) {
207 err = -errno;
208 fprintf(stderr, "Failed to open stat file %s: %s.\n", statfile, strerror(errno));
209 return err;
212 n = dnet_node_create(&cfg);
213 if (!n)
214 return -1;
216 s = dnet_session_create(n);
217 if (!s)
218 return -1;
220 err = dnet_add_state(n, &rem);
221 if (err)
222 return err;
224 while (1) {
225 struct dnet_id raw;
227 if (!id_idx) {
228 err = dnet_request_stat(s, NULL, DNET_CMD_STAT, 0, stat_complete, stat);
229 if (err < 0)
230 return err;
233 for (i=0; i<id_idx; ++i) {
234 dnet_setup_id(&raw, 0, id[i]);
235 err = dnet_request_stat(s, &raw, DNET_CMD_STAT, 0, stat_complete, stat);
236 if (err < 0)
237 return err;
240 sleep(timeout);
243 return 0;