rrdproc.c
来自「监控软件rrdtools」· C语言 代码 · 共 250 行
C
250 行
/*** rrdproc.c Copyright 1999 Damien Miller <djm@mindrot.org>****** This program is a very lightweight collecter for rrdtool. It reads** and parses /proc/net/dev and sends a rrdtool remote control update** command to stdout.**** rrdproc will sleep a user-defined amount of time between reads from** /proc/net/dev. This time should match the sample rate you created your** RRD files with.**** Example:**** rrdproc --interface=ppp0 \** --wait 30 \** --filename=/home/djm/traffic-ppp0.rrd | rrdtool -**** This will update the RRD file /home/djm/traffic-eth0.rrd with bytes** received and sent on eth0 every 30 seconds.**** rrdproc --interface=eth0 \** --wait 300 \** --frame \** --filename=/home/djm/traffic-eth0.rrd | rrdtool -**** Will update /home/djm/traffic-eth0.rrd with counts of framing errors and** collisions every 5 minutes**** rrdproc is licensed under the GNU GPL version 2. Please refer to** http://www.fsf.org/copyleft/gpl.html for details.***/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <syslog.h>#include <getopt.h>#include <unistd.h>#include <time.h>#define PROC_DEV "/proc/net/dev"#define DEFAULT_SLEEP_TIME 3#define DEFAULT_INTERFACE "eth0"#define DEFAULT_FILENAME "traffic"#define COLUMN_BYTES 0#define COLUMN_PACKETS 1#define COLUMN_ERRORS 2#define COLUMN_DROPPED 3#define COLUMN_FIFO 4#define COLUMN_FRAME 5void get_stats(FILE *devstats, const char *interface, int start_column);const char *skip_columns(const char *p, int num_columns);void help(void);void version(void);static struct option long_options[] ={ { "wait", 1, NULL, 'w'}, { "interface", 1, NULL, 'i'}, { "filename", 1, NULL, 'f'}, { "help", 0, NULL, 'h'}, { "version", 0, NULL, 'v'}, { "bytes", 0, NULL, 'B'}, { "packets", 0, NULL, 'P'}, { "errors", 0, NULL, 'E'}, { "dropped", 0, NULL, 'D'}, { "fifo", 0, NULL, 'F'}, { "frame", 0, NULL, 'R'},};int main(int argc, char **argv){ int sleep_time = DEFAULT_SLEEP_TIME; char *interface = DEFAULT_INTERFACE; char *filename = DEFAULT_FILENAME; int start_column = COLUMN_BYTES; int c; FILE *devstats; extern char *optarg; openlog("if-update", LOG_PERROR|LOG_PID, LOG_DAEMON); while(1) { c = getopt_long(argc, argv, "w:i:f:hvBPEDFRCM", long_options, NULL); if (c == -1) break; switch(c) { case 'w': sleep_time = atoi(optarg); break; case 'i': interface = strdup(optarg); break; case 'f': filename = strdup(optarg); break; case 'h': help(); exit(0); case 'v': version(); exit(0); case 'B': start_column = COLUMN_BYTES; break; case 'P': start_column = COLUMN_PACKETS; break; case 'E': start_column = COLUMN_ERRORS; break; case 'D': start_column = COLUMN_DROPPED; break; case 'F': start_column = COLUMN_FIFO; break; case 'R': start_column = COLUMN_FRAME; break; default: fprintf(stderr, "Invalid commandline options.\n"); help(); exit(1); } } setlinebuf(stdout); while(1) { devstats = fopen(PROC_DEV, "r"); if (devstats == NULL) { syslog(LOG_ERR, "Couldn't open proc file \"%s\" for reading: %m", PROC_DEV); exit(1); } printf("update %s N:", filename); get_stats(devstats, interface, start_column); sleep(sleep_time); fclose(devstats); } exit(0);}void get_stats(FILE *devstats, const char *interface, int start_column){ char buffer[2048]; const char *p; int if_len; unsigned long long in; unsigned long long out; if_len = strlen(interface); while(fgets(buffer, sizeof(buffer), devstats) != NULL) { p = buffer; /* skip space at start of line */ while(*p && (*p == ' ')) p++; if (strncmp(p, interface, if_len) == 0) { /* Skip to the statistic we wnt to report */ p = skip_columns(p + if_len + 1, start_column); in = strtoull(p, NULL, 10); /* Skip from received column to transmit column */ p = skip_columns(p, 8); out = strtoull(p, NULL, 10); printf("%Lu:%Lu\n", in, out); return; } } /* Non-fatal error if interface not found */ syslog(LOG_WARNING, "Couldn't find statistics for interface \"%s\"", interface); printf("U:U\n"); return;}void help(void){ fprintf(stderr, "\rrdproc - Update rrd file using statistics in /proc\n\\n\rrdproc will periodically read /proc/net/dev and update an RRD database\n\with the numbers that it finds there.\n\\n\Options:\n\ --wait, -w [time] Time to wait between statistics updates\n\ --interface, -i [name] Name of network interface to report on\n\ --filename, -f [filename] Path of RRD file to update\n\ --help, -h Display this help\n\ --version, -v Display version information\n\ --bytes, -B Report bytes in / out\n\ --packets, -P Report packets in / out\n\ --errors, -E Report errors in / out\n\ --dropped, -D Report dropped packets in / out\n\ --fifo, -F Report fifo in / out\n\ --frame, -R Report framing errors / collisions\n\");}void version(void){ fprintf(stderr, "rrdproc v0.0\n");}const char *skip_columns(const char *p, int num_columns){ int c; for(c = 0; c < num_columns; c++) { /* Skip numbers */ while(*p && (*p != ' ')) p++; /* Skip space */ while(*p && (*p == ' ')) p++; if (!*p) { /* Line finished early */ printf("U:U\n"); syslog(LOG_WARNING, "Couldn't parse interface statistics"); return; } } return(p);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?