inline int web_client_api_old_graph_request(RRDHOST *host, struct web_client *w, char *url) { // get the name of the data to show char *tok = mystrsep(&url, "/?&"); if(tok && *tok) { debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok); // do we have such a data set? RRDSET *st = rrdset_find_byname(host, tok); if(!st) st = rrdset_find(host, tok); if(!st) { // we don't have it // try to send a file with that name buffer_flush(w->response.data); return mysendfile(w, tok); } st->last_accessed_time = now_realtime_sec(); debug(D_WEB_CLIENT_ACCESS, "%llu: Sending %s.json of RRD_STATS...", w->id, st->name); w->response.data->contenttype = CT_APPLICATION_JSON; buffer_flush(w->response.data); rrd_graph2json_api_old(st, url, w->response.data); return 200; } buffer_flush(w->response.data); buffer_strcat(w->response.data, "Graph name?\r\n"); return 400; }
RRDSET *rrdset_find_bytype(const char *type, const char *id) { debug(D_RRD_CALLS, "rrdset_find_bytype() for chart %s.%s", type, id); char buf[RRD_ID_LENGTH_MAX + 1]; strncpyz(buf, type, RRD_ID_LENGTH_MAX - 1); strcat(buf, "."); int len = (int) strlen(buf); strncpyz(&buf[len], id, (size_t) (RRD_ID_LENGTH_MAX - len)); return(rrdset_find(buf)); }
void *cpuidlejitter_main(void *ptr) { if(ptr) { ; } info("CPU Idle Jitter thread created with task id %d", gettid()); if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) error("Cannot set pthread cancel type to DEFERRED."); if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) error("Cannot set pthread cancel state to ENABLE."); int sleep_ms = (int) config_get_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS); if(sleep_ms <= 0) { config_set_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS); sleep_ms = CPU_IDLEJITTER_SLEEP_TIME_MS; } RRDSET *st = rrdset_find("system.idlejitter"); if(!st) { st = rrdset_create("system", "idlejitter", NULL, "cpu", "CPU Idle Jitter", "microseconds lost/s", 9999, rrd_update_every, RRDSET_TYPE_LINE); rrddim_add(st, "jitter", NULL, 1, 1, RRDDIM_ABSOLUTE); } struct timeval before, after; unsigned long long counter; for(counter = 0; 1 ;counter++) { unsigned long long usec = 0, susec = 0; while(susec < (rrd_update_every * 1000000ULL)) { gettimeofday(&before, NULL); usleep(sleep_ms * 1000); gettimeofday(&after, NULL); // calculate the time it took for a full loop usec = usecdiff(&after, &before); susec += usec; } usec -= (sleep_ms * 1000); if(counter) rrdset_next(st); rrddim_set(st, "jitter", usec); rrdset_done(st); } return NULL; }
inline int web_client_api_request_single_chart(RRDHOST *host, struct web_client *w, char *url, void callback(RRDSET *st, BUFFER *buf)) { int ret = 400; char *chart = NULL; buffer_flush(w->response.data); while(url) { char *value = mystrsep(&url, "?&"); if(!value || !*value) continue; char *name = mystrsep(&value, "="); if(!name || !*name) continue; if(!value || !*value) continue; // name and value are now the parameters // they are not null and not empty if(!strcmp(name, "chart")) chart = value; //else { /// buffer_sprintf(w->response.data, "Unknown parameter '%s' in request.", name); // goto cleanup; //} } if(!chart || !*chart) { buffer_sprintf(w->response.data, "No chart id is given at the request."); goto cleanup; } RRDSET *st = rrdset_find(host, chart); if(!st) st = rrdset_find_byname(host, chart); if(!st) { buffer_strcat(w->response.data, "Chart is not found: "); buffer_strcat_htmlescape(w->response.data, chart); ret = 404; goto cleanup; } w->response.data->contenttype = CT_APPLICATION_JSON; st->last_accessed_time = now_realtime_sec(); callback(st, w->response.data); return 200; cleanup: return ret; }
int web_client_api_old_data_request(RRDHOST *host, struct web_client *w, char *url, int datasource_type) { if(!url || !*url) { buffer_flush(w->response.data); buffer_sprintf(w->response.data, "Incomplete request."); return 400; } RRDSET *st = NULL; char *args = strchr(url, '?'); if(args) { *args='\0'; args = &args[1]; } // get the name of the data to show char *tok = mystrsep(&url, "/"); if(!tok) tok = ""; // do we have such a data set? if(*tok) { debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok); st = rrdset_find_byname(host, tok); if(!st) st = rrdset_find(host, tok); } if(!st) { // we don't have it // try to send a file with that name buffer_flush(w->response.data); return(mysendfile(w, tok)); } // we have it debug(D_WEB_CLIENT, "%llu: Found RRD data with name '%s'.", w->id, tok); // how many entries does the client want? int lines = (int)st->entries; int group_count = 1; time_t after = 0, before = 0; int group_method = GROUP_AVERAGE; int nonzero = 0; if(url) { // parse the lines required tok = mystrsep(&url, "/"); if(tok) lines = str2i(tok); if(lines < 1) lines = 1; } if(url) { // parse the group count required tok = mystrsep(&url, "/"); if(tok && *tok) group_count = str2i(tok); if(group_count < 1) group_count = 1; //if(group_count > save_history / 20) group_count = save_history / 20; } if(url) { // parse the grouping method required tok = mystrsep(&url, "/"); if(tok && *tok) { if(strcmp(tok, "max") == 0) group_method = GROUP_MAX; else if(strcmp(tok, "average") == 0) group_method = GROUP_AVERAGE; else if(strcmp(tok, "sum") == 0) group_method = GROUP_SUM; else debug(D_WEB_CLIENT, "%llu: Unknown group method '%s'", w->id, tok); } } if(url) { // parse after time tok = mystrsep(&url, "/"); if(tok && *tok) after = str2ul(tok); if(after < 0) after = 0; } if(url) { // parse before time tok = mystrsep(&url, "/"); if(tok && *tok) before = str2ul(tok); if(before < 0) before = 0; } if(url) { // parse nonzero tok = mystrsep(&url, "/"); if(tok && *tok && strcmp(tok, "nonzero") == 0) nonzero = 1; } w->response.data->contenttype = CT_APPLICATION_JSON; buffer_flush(w->response.data); char *google_version = "0.6"; char *google_reqId = "0"; char *google_sig = "0"; char *google_out = "json"; char *google_responseHandler = "google.visualization.Query.setResponse"; char *google_outFileName = NULL; time_t last_timestamp_in_data = 0; if(datasource_type == DATASOURCE_DATATABLE_JSON || datasource_type == DATASOURCE_DATATABLE_JSONP) { w->response.data->contenttype = CT_APPLICATION_X_JAVASCRIPT; while(args) { tok = mystrsep(&args, "&"); if(tok && *tok) { char *name = mystrsep(&tok, "="); if(name && *name && strcmp(name, "tqx") == 0) { char *key = mystrsep(&tok, ":"); char *value = mystrsep(&tok, ";"); if(key && value && *key && *value) { if(strcmp(key, "version") == 0) google_version = value; else if(strcmp(key, "reqId") == 0) google_reqId = value; else if(strcmp(key, "sig") == 0) google_sig = value; else if(strcmp(key, "out") == 0) google_out = value; else if(strcmp(key, "responseHandler") == 0) google_responseHandler = value; else if(strcmp(key, "outFileName") == 0) google_outFileName = value; } } } } debug(D_WEB_CLIENT_ACCESS, "%llu: GOOGLE JSONP: version = '%s', reqId = '%s', sig = '%s', out = '%s', responseHandler = '%s', outFileName = '%s'", w->id, google_version, google_reqId, google_sig, google_out, google_responseHandler, google_outFileName ); if(datasource_type == DATASOURCE_DATATABLE_JSONP) { last_timestamp_in_data = strtoul(google_sig, NULL, 0); // check the client wants json if(strcmp(google_out, "json") != 0) { buffer_sprintf(w->response.data, "%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'invalid_query',message:'output format is not supported',detailed_message:'the format %s requested is not supported by netdata.'}]});", google_responseHandler, google_version, google_reqId, google_out); return 200; } } } if(datasource_type == DATASOURCE_DATATABLE_JSONP) { buffer_sprintf(w->response.data, "%s({version:'%s',reqId:'%s',status:'ok',sig:'%ld',table:", google_responseHandler, google_version, google_reqId, st->last_updated.tv_sec); } debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %ld after, %ld before).", w->id, st->name, st->id, lines, group_count, group_method, after, before); time_t timestamp_in_data = rrdset2json_api_old(datasource_type, st, w->response.data, lines, group_count , group_method, (unsigned long) after, (unsigned long) before , nonzero); if(datasource_type == DATASOURCE_DATATABLE_JSONP) { if(timestamp_in_data > last_timestamp_in_data) buffer_strcat(w->response.data, "});"); else { // the client already has the latest data buffer_flush(w->response.data); buffer_sprintf(w->response.data, "%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'not_modified',message:'Data not modified'}]});", google_responseHandler, google_version, google_reqId); } } return 200; }
void *checks_main(void *ptr) { if(ptr) { ; } info("CHECKS thread created with task id %d", gettid()); if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) error("Cannot set pthread cancel type to DEFERRED."); if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) error("Cannot set pthread cancel state to ENABLE."); unsigned long long usec = 0, susec = rrd_update_every * 1000000ULL, loop_usec = 0, total_susec = 0; struct timeval now, last, loop; RRDSET *check1, *check2, *check3, *apps_cpu = NULL; check1 = rrdset_create("netdata", "check1", NULL, "netdata", "Caller gives microseconds", "a million !", 99999, rrd_update_every, RRDSET_TYPE_LINE); rrddim_add(check1, "absolute", NULL, -1, 1, RRDDIM_ABSOLUTE); rrddim_add(check1, "incremental", NULL, 1, 1, RRDDIM_INCREMENTAL); check2 = rrdset_create("netdata", "check2", NULL, "netdata", "Netdata calcs microseconds", "a million !", 99999, rrd_update_every, RRDSET_TYPE_LINE); rrddim_add(check2, "absolute", NULL, -1, 1, RRDDIM_ABSOLUTE); rrddim_add(check2, "incremental", NULL, 1, 1, RRDDIM_INCREMENTAL); check3 = rrdset_create("netdata", "checkdt", NULL, "netdata", "Clock difference", "microseconds diff", 99999, rrd_update_every, RRDSET_TYPE_LINE); rrddim_add(check3, "caller", NULL, 1, 1, RRDDIM_ABSOLUTE); rrddim_add(check3, "netdata", NULL, 1, 1, RRDDIM_ABSOLUTE); rrddim_add(check3, "apps.plugin", NULL, 1, 1, RRDDIM_ABSOLUTE); gettimeofday(&last, NULL); while(1) { usleep(susec); // find the time to sleep in order to wait exactly update_every seconds gettimeofday(&now, NULL); loop_usec = usecdiff(&now, &last); usec = loop_usec - susec; debug(D_PROCNETDEV_LOOP, "CHECK: last loop took %llu usec (worked for %llu, sleeped for %llu).", loop_usec, usec, susec); if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec; else susec = rrd_update_every * 1000000ULL / 2ULL; // -------------------------------------------------------------------- // Calculate loop time last.tv_sec = now.tv_sec; last.tv_usec = now.tv_usec; total_susec += loop_usec; // -------------------------------------------------------------------- // check chart 1 if(check1->counter_done) rrdset_next_usec(check1, loop_usec); rrddim_set(check1, "absolute", 1000000); rrddim_set(check1, "incremental", total_susec); rrdset_done(check1); // -------------------------------------------------------------------- // check chart 2 if(check2->counter_done) rrdset_next(check2); rrddim_set(check2, "absolute", 1000000); rrddim_set(check2, "incremental", total_susec); rrdset_done(check2); // -------------------------------------------------------------------- // check chart 3 if(!apps_cpu) apps_cpu = rrdset_find("apps.cpu"); if(check3->counter_done) rrdset_next_usec(check3, loop_usec); gettimeofday(&loop, NULL); rrddim_set(check3, "caller", (long long)usecdiff(&loop, &check1->last_collected_time)); rrddim_set(check3, "netdata", (long long)usecdiff(&loop, &check2->last_collected_time)); if(apps_cpu) rrddim_set(check3, "apps.plugin", (long long)usecdiff(&loop, &apps_cpu->last_collected_time)); rrdset_done(check3); } return NULL; }
int do_proc_net_ip_vs_stats(int update_every, unsigned long long dt) { static int do_bandwidth = -1, do_sockets = -1, do_packets = -1; static procfile *ff = NULL; if(do_bandwidth == -1) do_bandwidth = config_get_boolean("plugin:proc:/proc/net/ip_vs_stats", "IPVS bandwidth", 1); if(do_sockets == -1) do_sockets = config_get_boolean("plugin:proc:/proc/net/ip_vs_stats", "IPVS connections", 1); if(do_packets == -1) do_packets = config_get_boolean("plugin:proc:/proc/net/ip_vs_stats", "IPVS packets", 1); if(dt) {}; if(!ff) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/ip_vs_stats"); ff = procfile_open(config_get("plugin:proc:/proc/net/ip_vs_stats", "filename to monitor", filename), " \t,:|", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time // make sure we have 3 lines if(procfile_lines(ff) < 3) return 1; // make sure we have 5 words on the 3rd line if(procfile_linewords(ff, 2) < 5) return 1; unsigned long long entries, InPackets, OutPackets, InBytes, OutBytes; entries = strtoull(procfile_lineword(ff, 2, 0), NULL, 16); InPackets = strtoull(procfile_lineword(ff, 2, 1), NULL, 16); OutPackets = strtoull(procfile_lineword(ff, 2, 2), NULL, 16); InBytes = strtoull(procfile_lineword(ff, 2, 3), NULL, 16); OutBytes = strtoull(procfile_lineword(ff, 2, 4), NULL, 16); RRDSET *st; // -------------------------------------------------------------------- if(do_sockets) { st = rrdset_find(RRD_TYPE_NET_IPVS ".sockets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_IPVS, "sockets", NULL, RRD_TYPE_NET_IPVS, NULL, "IPVS New Connections", "connections/s", 1001, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "connections", entries); rrdset_done(st); } // -------------------------------------------------------------------- if(do_packets) { st = rrdset_find(RRD_TYPE_NET_IPVS ".packets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_IPVS, "packets", NULL, RRD_TYPE_NET_IPVS, NULL, "IPVS Packets", "packets/s", 1002, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "received", InPackets); rrddim_set(st, "sent", OutPackets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bandwidth) { st = rrdset_find(RRD_TYPE_NET_IPVS ".net"); if(!st) { st = rrdset_create(RRD_TYPE_NET_IPVS, "net", NULL, RRD_TYPE_NET_IPVS, NULL, "IPVS Bandwidth", "kilobits/s", 1000, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "received", NULL, 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "received", InBytes); rrddim_set(st, "sent", OutBytes); rrdset_done(st); } return 0; }
int do_proc_net_netstat(int update_every, usec_t dt) { (void)dt; static int do_bandwidth = -1, do_inerrors = -1, do_mcast = -1, do_bcast = -1, do_mcast_p = -1, do_bcast_p = -1, do_ecn = -1, \ do_tcpext_reorder = -1, do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1, do_tcpext_memory = -1; static uint32_t hash_ipext = 0, hash_tcpext = 0; static procfile *ff = NULL; static ARL_BASE *arl_tcpext = NULL; static ARL_BASE *arl_ipext = NULL; // -------------------------------------------------------------------- // IPv4 // IPv4 bandwidth static unsigned long long ipext_InOctets = 0; static unsigned long long ipext_OutOctets = 0; // IPv4 input errors static unsigned long long ipext_InNoRoutes = 0; static unsigned long long ipext_InTruncatedPkts = 0; static unsigned long long ipext_InCsumErrors = 0; // IPv4 multicast bandwidth static unsigned long long ipext_InMcastOctets = 0; static unsigned long long ipext_OutMcastOctets = 0; // IPv4 multicast packets static unsigned long long ipext_InMcastPkts = 0; static unsigned long long ipext_OutMcastPkts = 0; // IPv4 broadcast bandwidth static unsigned long long ipext_InBcastOctets = 0; static unsigned long long ipext_OutBcastOctets = 0; // IPv4 broadcast packets static unsigned long long ipext_InBcastPkts = 0; static unsigned long long ipext_OutBcastPkts = 0; // IPv4 ECN static unsigned long long ipext_InNoECTPkts = 0; static unsigned long long ipext_InECT1Pkts = 0; static unsigned long long ipext_InECT0Pkts = 0; static unsigned long long ipext_InCEPkts = 0; // -------------------------------------------------------------------- // IPv4 TCP // IPv4 TCP Reordering static unsigned long long tcpext_TCPRenoReorder = 0; static unsigned long long tcpext_TCPFACKReorder = 0; static unsigned long long tcpext_TCPSACKReorder = 0; static unsigned long long tcpext_TCPTSReorder = 0; // IPv4 TCP SYN Cookies static unsigned long long tcpext_SyncookiesSent = 0; static unsigned long long tcpext_SyncookiesRecv = 0; static unsigned long long tcpext_SyncookiesFailed = 0; // IPv4 TCP Out Of Order Queue // http://www.spinics.net/lists/netdev/msg204696.html static unsigned long long tcpext_TCPOFOQueue = 0; // Number of packets queued in OFO queue static unsigned long long tcpext_TCPOFODrop = 0; // Number of packets meant to be queued in OFO but dropped because socket rcvbuf limit hit. static unsigned long long tcpext_TCPOFOMerge = 0; // Number of packets in OFO that were merged with other packets. static unsigned long long tcpext_OfoPruned = 0; // packets dropped from out-of-order queue because of socket buffer overrun // IPv4 TCP connection resets // https://github.com/ecki/net-tools/blob/bd8bceaed2311651710331a7f8990c3e31be9840/statistics.c static unsigned long long tcpext_TCPAbortOnData = 0; // connections reset due to unexpected data static unsigned long long tcpext_TCPAbortOnClose = 0; // connections reset due to early user close static unsigned long long tcpext_TCPAbortOnMemory = 0; // connections aborted due to memory pressure static unsigned long long tcpext_TCPAbortOnTimeout = 0; // connections aborted due to timeout static unsigned long long tcpext_TCPAbortOnLinger = 0; // connections aborted after user close in linger timeout static unsigned long long tcpext_TCPAbortFailed = 0; // times unable to send RST due to no memory // IPv4 TCP memory pressures static unsigned long long tcpext_TCPMemoryPressures = 0; if(unlikely(!arl_ipext)) { hash_ipext = simple_hash("IpExt"); hash_tcpext = simple_hash("TcpExt"); do_bandwidth = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "bandwidth", CONFIG_ONDEMAND_ONDEMAND); do_inerrors = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "input errors", CONFIG_ONDEMAND_ONDEMAND); do_mcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast bandwidth", CONFIG_ONDEMAND_ONDEMAND); do_bcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast bandwidth", CONFIG_ONDEMAND_ONDEMAND); do_mcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast packets", CONFIG_ONDEMAND_ONDEMAND); do_bcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast packets", CONFIG_ONDEMAND_ONDEMAND); do_ecn = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "ECN packets", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_reorder = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP reorders", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_syscookies = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP SYN cookies", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_ofo = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP out-of-order queue", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_memory = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_ONDEMAND_ONDEMAND); arl_ipext = arl_create("netstat/ipext", NULL, 60); arl_tcpext = arl_create("netstat/tcpext", NULL, 60); // -------------------------------------------------------------------- // IPv4 if(do_bandwidth != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InOctets", &ipext_InOctets); arl_expect(arl_ipext, "OutOctets", &ipext_OutOctets); } if(do_inerrors != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InNoRoutes", &ipext_InNoRoutes); arl_expect(arl_ipext, "InTruncatedPkts", &ipext_InTruncatedPkts); arl_expect(arl_ipext, "InCsumErrors", &ipext_InCsumErrors); } if(do_mcast != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InMcastOctets", &ipext_InMcastOctets); arl_expect(arl_ipext, "OutMcastOctets", &ipext_OutMcastOctets); } if(do_mcast_p != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InMcastPkts", &ipext_InMcastPkts); arl_expect(arl_ipext, "OutMcastPkts", &ipext_OutMcastPkts); } if(do_bcast != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InBcastPkts", &ipext_InBcastPkts); arl_expect(arl_ipext, "OutBcastPkts", &ipext_OutBcastPkts); } if(do_bcast_p != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InBcastOctets", &ipext_InBcastOctets); arl_expect(arl_ipext, "OutBcastOctets", &ipext_OutBcastOctets); } if(do_ecn != CONFIG_ONDEMAND_NO) { arl_expect(arl_ipext, "InNoECTPkts", &ipext_InNoECTPkts); arl_expect(arl_ipext, "InECT1Pkts", &ipext_InECT1Pkts); arl_expect(arl_ipext, "InECT0Pkts", &ipext_InECT0Pkts); arl_expect(arl_ipext, "InCEPkts", &ipext_InCEPkts); } // -------------------------------------------------------------------- // IPv4 TCP if(do_tcpext_reorder != CONFIG_ONDEMAND_NO) { arl_expect(arl_tcpext, "TCPFACKReorder", &tcpext_TCPFACKReorder); arl_expect(arl_tcpext, "TCPSACKReorder", &tcpext_TCPSACKReorder); arl_expect(arl_tcpext, "TCPRenoReorder", &tcpext_TCPRenoReorder); arl_expect(arl_tcpext, "TCPTSReorder", &tcpext_TCPTSReorder); } if(do_tcpext_syscookies != CONFIG_ONDEMAND_NO) { arl_expect(arl_tcpext, "SyncookiesSent", &tcpext_SyncookiesSent); arl_expect(arl_tcpext, "SyncookiesRecv", &tcpext_SyncookiesRecv); arl_expect(arl_tcpext, "SyncookiesFailed", &tcpext_SyncookiesFailed); } if(do_tcpext_ofo != CONFIG_ONDEMAND_NO) { arl_expect(arl_tcpext, "TCPOFOQueue", &tcpext_TCPOFOQueue); arl_expect(arl_tcpext, "TCPOFODrop", &tcpext_TCPOFODrop); arl_expect(arl_tcpext, "TCPOFOMerge", &tcpext_TCPOFOMerge); arl_expect(arl_tcpext, "OfoPruned", &tcpext_OfoPruned); } if(do_tcpext_connaborts != CONFIG_ONDEMAND_NO) { arl_expect(arl_tcpext, "TCPAbortOnData", &tcpext_TCPAbortOnData); arl_expect(arl_tcpext, "TCPAbortOnClose", &tcpext_TCPAbortOnClose); arl_expect(arl_tcpext, "TCPAbortOnMemory", &tcpext_TCPAbortOnMemory); arl_expect(arl_tcpext, "TCPAbortOnTimeout", &tcpext_TCPAbortOnTimeout); arl_expect(arl_tcpext, "TCPAbortOnLinger", &tcpext_TCPAbortOnLinger); arl_expect(arl_tcpext, "TCPAbortFailed", &tcpext_TCPAbortFailed); } if(do_tcpext_memory != CONFIG_ONDEMAND_NO) { arl_expect(arl_tcpext, "TCPMemoryPressures", &tcpext_TCPMemoryPressures); } } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/net/netstat"); ff = procfile_open(config_get("plugin:proc:/proc/net/netstat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); if(unlikely(!ff)) return 1; } ff = procfile_readall(ff); if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time size_t lines = procfile_lines(ff), l; size_t words; arl_begin(arl_ipext); arl_begin(arl_tcpext); for(l = 0; l < lines ;l++) { char *key = procfile_lineword(ff, l, 0); uint32_t hash = simple_hash(key); if(unlikely(hash == hash_ipext && strcmp(key, "IpExt") == 0)) { size_t h = l++; words = procfile_linewords(ff, l); if(unlikely(words < 2)) { error("Cannot read /proc/net/netstat IpExt line. Expected 2+ params, read %zu.", words); continue; } parse_line_pair(ff, arl_ipext, h, l); RRDSET *st; // -------------------------------------------------------------------- if(do_bandwidth == CONFIG_ONDEMAND_YES || (do_bandwidth == CONFIG_ONDEMAND_ONDEMAND && (ipext_InOctets || ipext_OutOctets))) { do_bandwidth = CONFIG_ONDEMAND_YES; st = rrdset_find("system.ipv4"); if(unlikely(!st)) { st = rrdset_create("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "InOctets", "received", 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "OutOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InOctets", ipext_InOctets); rrddim_set(st, "OutOctets", ipext_OutOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_inerrors == CONFIG_ONDEMAND_YES || (do_inerrors == CONFIG_ONDEMAND_ONDEMAND && (ipext_InNoRoutes || ipext_InTruncatedPkts))) { do_inerrors = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.inerrors"); if(unlikely(!st)) { st = rrdset_create("ipv4", "inerrors", NULL, "errors", NULL, "IPv4 Input Errors", "packets/s", 4000, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InNoRoutes", "noroutes", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InTruncatedPkts", "truncated", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InCsumErrors", "checksum", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InNoRoutes", ipext_InNoRoutes); rrddim_set(st, "InTruncatedPkts", ipext_InTruncatedPkts); rrddim_set(st, "InCsumErrors", ipext_InCsumErrors); rrdset_done(st); } // -------------------------------------------------------------------- if(do_mcast == CONFIG_ONDEMAND_YES || (do_mcast == CONFIG_ONDEMAND_ONDEMAND && (ipext_InMcastOctets || ipext_OutMcastOctets))) { do_mcast = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.mcast"); if(unlikely(!st)) { st = rrdset_create("ipv4", "mcast", NULL, "multicast", NULL, "IPv4 Multicast Bandwidth", "kilobits/s", 9000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "InMcastOctets", "received", 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "OutMcastOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InMcastOctets", ipext_InMcastOctets); rrddim_set(st, "OutMcastOctets", ipext_OutMcastOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bcast == CONFIG_ONDEMAND_YES || (do_bcast == CONFIG_ONDEMAND_ONDEMAND && (ipext_InBcastOctets || ipext_OutBcastOctets))) { do_bcast = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.bcast"); if(unlikely(!st)) { st = rrdset_create("ipv4", "bcast", NULL, "broadcast", NULL, "IPv4 Broadcast Bandwidth", "kilobits/s", 8000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "InBcastOctets", "received", 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "OutBcastOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InBcastOctets", ipext_InBcastOctets); rrddim_set(st, "OutBcastOctets", ipext_OutBcastOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_mcast_p == CONFIG_ONDEMAND_YES || (do_mcast_p == CONFIG_ONDEMAND_ONDEMAND && (ipext_InMcastPkts || ipext_OutMcastPkts))) { do_mcast_p = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.mcastpkts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "mcastpkts", NULL, "multicast", NULL, "IPv4 Multicast Packets", "packets/s", 8600, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InMcastPkts", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutMcastPkts", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InMcastPkts", ipext_InMcastPkts); rrddim_set(st, "OutMcastPkts", ipext_OutMcastPkts); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bcast_p == CONFIG_ONDEMAND_YES || (do_bcast_p == CONFIG_ONDEMAND_ONDEMAND && (ipext_InBcastPkts || ipext_OutBcastPkts))) { do_bcast_p = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.bcastpkts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "bcastpkts", NULL, "broadcast", NULL, "IPv4 Broadcast Packets", "packets/s", 8500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InBcastPkts", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutBcastPkts", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InBcastPkts", ipext_InBcastPkts); rrddim_set(st, "OutBcastPkts", ipext_OutBcastPkts); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ecn == CONFIG_ONDEMAND_YES || (do_ecn == CONFIG_ONDEMAND_ONDEMAND && (ipext_InCEPkts || ipext_InECT0Pkts || ipext_InECT1Pkts || ipext_InNoECTPkts))) { do_ecn = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.ecnpkts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics", "packets/s", 8700, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InNoECTPkts", "NoECTP", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InECT0Pkts", "ECTP0", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InECT1Pkts", "ECTP1", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InCEPkts", ipext_InCEPkts); rrddim_set(st, "InNoECTPkts", ipext_InNoECTPkts); rrddim_set(st, "InECT0Pkts", ipext_InECT0Pkts); rrddim_set(st, "InECT1Pkts", ipext_InECT1Pkts); rrdset_done(st); } } else if(unlikely(hash == hash_tcpext && strcmp(key, "TcpExt") == 0)) { size_t h = l++; words = procfile_linewords(ff, l); if(unlikely(words < 2)) { error("Cannot read /proc/net/netstat TcpExt line. Expected 2+ params, read %zu.", words); continue; } parse_line_pair(ff, arl_tcpext, h, l); RRDSET *st; // -------------------------------------------------------------------- if(do_tcpext_memory == CONFIG_ONDEMAND_YES || (do_tcpext_memory == CONFIG_ONDEMAND_ONDEMAND && (tcpext_TCPMemoryPressures))) { do_tcpext_memory = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpmemorypressures"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpmemorypressures", NULL, "tcp", NULL, "TCP Memory Pressures", "events/s", 3000, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPMemoryPressures", "pressures", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPMemoryPressures", tcpext_TCPMemoryPressures); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_connaborts == CONFIG_ONDEMAND_YES || (do_tcpext_connaborts == CONFIG_ONDEMAND_ONDEMAND && (tcpext_TCPAbortOnData || tcpext_TCPAbortOnClose || tcpext_TCPAbortOnMemory || tcpext_TCPAbortOnTimeout || tcpext_TCPAbortOnLinger || tcpext_TCPAbortFailed))) { do_tcpext_connaborts = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpconnaborts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts", "connections/s", 3010, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPAbortOnData", "baddata", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnClose", "userclosed", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnMemory", "nomemory", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnTimeout", "timeout", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnLinger", "linger", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortFailed", "failed", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPAbortOnData", tcpext_TCPAbortOnData); rrddim_set(st, "TCPAbortOnClose", tcpext_TCPAbortOnClose); rrddim_set(st, "TCPAbortOnMemory", tcpext_TCPAbortOnMemory); rrddim_set(st, "TCPAbortOnTimeout", tcpext_TCPAbortOnTimeout); rrddim_set(st, "TCPAbortOnLinger", tcpext_TCPAbortOnLinger); rrddim_set(st, "TCPAbortFailed", tcpext_TCPAbortFailed); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_reorder == CONFIG_ONDEMAND_YES || (do_tcpext_reorder == CONFIG_ONDEMAND_ONDEMAND && (tcpext_TCPRenoReorder || tcpext_TCPFACKReorder || tcpext_TCPSACKReorder || tcpext_TCPTSReorder))) { do_tcpext_reorder = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpreorders"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpreorders", NULL, "tcp", NULL, "TCP Reordered Packets by Detection Method", "packets/s", 3020, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPTSReorder", "timestamp", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPSACKReorder", "sack", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPFACKReorder", "fack", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPRenoReorder", "reno", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPTSReorder", tcpext_TCPTSReorder); rrddim_set(st, "TCPSACKReorder", tcpext_TCPSACKReorder); rrddim_set(st, "TCPFACKReorder", tcpext_TCPFACKReorder); rrddim_set(st, "TCPRenoReorder", tcpext_TCPRenoReorder); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_ofo == CONFIG_ONDEMAND_YES || (do_tcpext_ofo == CONFIG_ONDEMAND_ONDEMAND && (tcpext_TCPOFOQueue || tcpext_TCPOFODrop || tcpext_TCPOFOMerge))) { do_tcpext_ofo = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpofo"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue", "packets/s", 3050, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPOFOQueue", "inqueue", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPOFODrop", "dropped", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPOFOMerge", "merged", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OfoPruned", "pruned", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPOFOQueue", tcpext_TCPOFOQueue); rrddim_set(st, "TCPOFODrop", tcpext_TCPOFODrop); rrddim_set(st, "TCPOFOMerge", tcpext_TCPOFOMerge); rrddim_set(st, "OfoPruned", tcpext_OfoPruned); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_syscookies == CONFIG_ONDEMAND_YES || (do_tcpext_syscookies == CONFIG_ONDEMAND_ONDEMAND && (tcpext_SyncookiesSent || tcpext_SyncookiesRecv || tcpext_SyncookiesFailed))) { do_tcpext_syscookies = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpsyncookies"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies", "packets/s", 3100, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "SyncookiesRecv", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SyncookiesSent", "sent", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SyncookiesFailed", "failed", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "SyncookiesRecv", tcpext_SyncookiesRecv); rrddim_set(st, "SyncookiesSent", tcpext_SyncookiesSent); rrddim_set(st, "SyncookiesFailed", tcpext_SyncookiesFailed); rrdset_done(st); } } } return 0; }
RRDSET *rrdset_create(const char *type, const char *id, const char *name, const char *family, const char *context, const char *title, const char *units, long priority, int update_every, int chart_type) { if(!type || !type[0]) { fatal("Cannot create rrd stats without a type."); return NULL; } if(!id || !id[0]) { fatal("Cannot create rrd stats without an id."); return NULL; } char fullid[RRD_ID_LENGTH_MAX + 1]; char fullfilename[FILENAME_MAX + 1]; RRDSET *st = NULL; snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id); st = rrdset_find(fullid); if(st) { error("Cannot create rrd stats for '%s', it already exists.", fullid); return st; } long entries = config_get_number(fullid, "history", rrd_default_history_entries); if(entries < 5) entries = config_set_number(fullid, "history", 5); if(entries > RRD_HISTORY_ENTRIES_MAX) entries = config_set_number(fullid, "history", RRD_HISTORY_ENTRIES_MAX); int enabled = config_get_boolean(fullid, "enabled", 1); if(!enabled) entries = 5; unsigned long size = sizeof(RRDSET); char *cache_dir = rrdset_cache_dir(fullid); debug(D_RRD_CALLS, "Creating RRD_STATS for '%s.%s'.", type, id); snprintfz(fullfilename, FILENAME_MAX, "%s/main.db", cache_dir); if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) st = (RRDSET *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE), 0); if(st) { if(strcmp(st->magic, RRDSET_MAGIC) != 0) { errno = 0; info("Initializing file %s.", fullfilename); bzero(st, size); } else if(strcmp(st->id, fullid) != 0) { errno = 0; error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid); // munmap(st, size); // st = NULL; bzero(st, size); } else if(st->memsize != size || st->entries != entries) { errno = 0; error("File %s does not have the desired size. Clearing it.", fullfilename); bzero(st, size); } else if(st->update_every != update_every) { errno = 0; error("File %s does not have the desired update frequency. Clearing it.", fullfilename); bzero(st, size); } else if((time(NULL) - st->last_updated.tv_sec) > update_every * entries) { errno = 0; error("File %s is too old. Clearing it.", fullfilename); bzero(st, size); } } if(st) { st->name = NULL; st->type = NULL; st->family = NULL; st->context = NULL; st->title = NULL; st->units = NULL; st->dimensions = NULL; st->next = NULL; st->mapped = rrd_memory_mode; } else { st = calloc(1, size); if(!st) { fatal("Cannot allocate memory for RRD_STATS %s.%s", type, id); return NULL; } st->mapped = RRD_MEMORY_MODE_RAM; } st->memsize = size; st->entries = entries; st->update_every = update_every; if(st->current_entry >= st->entries) st->current_entry = 0; strcpy(st->cache_filename, fullfilename); strcpy(st->magic, RRDSET_MAGIC); strcpy(st->id, fullid); st->hash = simple_hash(st->id); st->cache_dir = cache_dir; st->chart_type = rrdset_type_id(config_get(st->id, "chart type", rrdset_type_name(chart_type))); st->type = config_get(st->id, "type", type); st->family = config_get(st->id, "family", family?family:st->type); st->context = config_get(st->id, "context", context?context:st->id); st->units = config_get(st->id, "units", units?units:""); st->priority = config_get_number(st->id, "priority", priority); st->enabled = enabled; st->isdetail = 0; st->debug = 0; st->last_collected_time.tv_sec = 0; st->last_collected_time.tv_usec = 0; st->counter_done = 0; st->gap_when_lost_iterations_above = (int) ( config_get_number(st->id, "gap when lost iterations above", RRD_DEFAULT_GAP_INTERPOLATIONS) + 2); avl_init_lock(&st->dimensions_index, rrddim_compare); pthread_rwlock_init(&st->rwlock, NULL); pthread_rwlock_wrlock(&rrdset_root_rwlock); if(name && *name) rrdset_set_name(st, name); else rrdset_set_name(st, id); { char varvalue[CONFIG_MAX_VALUE + 1]; snprintfz(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name); st->title = config_get(st->id, "title", varvalue); } st->next = rrdset_root; rrdset_root = st; rrdset_index_add(st); pthread_rwlock_unlock(&rrdset_root_rwlock); return(st); }
int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *url) { int ret = 400; buffer_flush(w->response.data); BUFFER *dimensions = NULL; const char *chart = NULL , *before_str = NULL , *after_str = NULL , *points_str = NULL , *multiply_str = NULL , *divide_str = NULL , *label = NULL , *units = NULL , *label_color = NULL , *value_color = NULL , *refresh_str = NULL , *precision_str = NULL , *scale_str = NULL , *alarm = NULL; int group = GROUP_AVERAGE; uint32_t options = 0x00000000; while(url) { char *value = mystrsep(&url, "/?&"); if(!value || !*value) continue; char *name = mystrsep(&value, "="); if(!name || !*name) continue; if(!value || !*value) continue; debug(D_WEB_CLIENT, "%llu: API v1 badge.svg query param '%s' with value '%s'", w->id, name, value); // name and value are now the parameters // they are not null and not empty if(!strcmp(name, "chart")) chart = value; else if(!strcmp(name, "dimension") || !strcmp(name, "dim") || !strcmp(name, "dimensions") || !strcmp(name, "dims")) { if(!dimensions) dimensions = buffer_create(100); buffer_strcat(dimensions, "|"); buffer_strcat(dimensions, value); } else if(!strcmp(name, "after")) after_str = value; else if(!strcmp(name, "before")) before_str = value; else if(!strcmp(name, "points")) points_str = value; else if(!strcmp(name, "group")) { group = web_client_api_request_v1_data_group(value, GROUP_AVERAGE); } else if(!strcmp(name, "options")) { options |= web_client_api_request_v1_data_options(value); } else if(!strcmp(name, "label")) label = value; else if(!strcmp(name, "units")) units = value; else if(!strcmp(name, "label_color")) label_color = value; else if(!strcmp(name, "value_color")) value_color = value; else if(!strcmp(name, "multiply")) multiply_str = value; else if(!strcmp(name, "divide")) divide_str = value; else if(!strcmp(name, "refresh")) refresh_str = value; else if(!strcmp(name, "precision")) precision_str = value; else if(!strcmp(name, "scale")) scale_str = value; else if(!strcmp(name, "alarm")) alarm = value; } if(!chart || !*chart) { buffer_no_cacheable(w->response.data); buffer_sprintf(w->response.data, "No chart id is given at the request."); goto cleanup; } int scale = (scale_str && *scale_str)?str2i(scale_str):100; RRDSET *st = rrdset_find(host, chart); if(!st) st = rrdset_find_byname(host, chart); if(!st) { buffer_no_cacheable(w->response.data); buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1, scale, 0); ret = 200; goto cleanup; } st->last_accessed_time = now_realtime_sec(); RRDCALC *rc = NULL; if(alarm) { rc = rrdcalc_find(st, alarm); if (!rc) { buffer_no_cacheable(w->response.data); buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1, scale, 0); ret = 200; goto cleanup; } } long long multiply = (multiply_str && *multiply_str )?str2l(multiply_str):1; long long divide = (divide_str && *divide_str )?str2l(divide_str):1; long long before = (before_str && *before_str )?str2l(before_str):0; long long after = (after_str && *after_str )?str2l(after_str):-st->update_every; int points = (points_str && *points_str )?str2i(points_str):1; int precision = (precision_str && *precision_str)?str2i(precision_str):-1; if(!multiply) multiply = 1; if(!divide) divide = 1; int refresh = 0; if(refresh_str && *refresh_str) { if(!strcmp(refresh_str, "auto")) { if(rc) refresh = rc->update_every; else if(options & RRDR_OPTION_NOT_ALIGNED) refresh = st->update_every; else { refresh = (int)(before - after); if(refresh < 0) refresh = -refresh; } } else { refresh = str2i(refresh_str); if(refresh < 0) refresh = -refresh; } } if(!label) { if(alarm) { char *s = (char *)alarm; while(*s) { if(*s == '_') *s = ' '; s++; } label = alarm; } else if(dimensions) { const char *dim = buffer_tostring(dimensions); if(*dim == '|') dim++; label = dim; } else label = st->name; } if(!units) { if(alarm) { if(rc->units) units = rc->units; else units = ""; } else if(options & RRDR_OPTION_PERCENTAGE) units = "%"; else units = st->units; } debug(D_WEB_CLIENT, "%llu: API command 'badge.svg' for chart '%s', alarm '%s', dimensions '%s', after '%lld', before '%lld', points '%d', group '%d', options '0x%08x'" , w->id , chart , alarm?alarm:"" , (dimensions)?buffer_tostring(dimensions):"" , after , before , points , group , options ); if(rc) { if (refresh > 0) { buffer_sprintf(w->response.header, "Refresh: %d\r\n", refresh); w->response.data->expires = now_realtime_sec() + refresh; } else buffer_no_cacheable(w->response.data); if(!value_color) { switch(rc->status) { case RRDCALC_STATUS_CRITICAL: value_color = "red"; break; case RRDCALC_STATUS_WARNING: value_color = "orange"; break; case RRDCALC_STATUS_CLEAR: value_color = "brightgreen"; break; case RRDCALC_STATUS_UNDEFINED: value_color = "lightgrey"; break; case RRDCALC_STATUS_UNINITIALIZED: value_color = "#000"; break; default: value_color = "grey"; break; } } buffer_svg(w->response.data, label, (isnan(rc->value)||isinf(rc->value)) ? rc->value : rc->value * multiply / divide, units, label_color, value_color, precision, scale, options ); ret = 200; } else { time_t latest_timestamp = 0; int value_is_null = 1; calculated_number n = NAN; ret = 500; // if the collected value is too old, don't calculate its value if (rrdset_last_entry_t(st) >= (now_realtime_sec() - (st->update_every * st->gap_when_lost_iterations_above))) ret = rrdset2value_api_v1(st, w->response.data, &n, (dimensions) ? buffer_tostring(dimensions) : NULL , points, after, before, group, 0, options, NULL, &latest_timestamp, &value_is_null); // if the value cannot be calculated, show empty badge if (ret != 200) { buffer_no_cacheable(w->response.data); value_is_null = 1; n = 0; ret = 200; } else if (refresh > 0) { buffer_sprintf(w->response.header, "Refresh: %d\r\n", refresh); w->response.data->expires = now_realtime_sec() + refresh; } else buffer_no_cacheable(w->response.data); // render the badge buffer_svg(w->response.data, label, (value_is_null)?NAN:(n * multiply / divide), units, label_color, value_color, precision, scale, options ); } cleanup: buffer_free(dimensions); return ret; }
void *proc_main(void *ptr) { if(ptr) { ; } if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) error("Cannot set pthread cancel type to DEFERRED."); if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) error("Cannot set pthread cancel state to ENABLE."); struct rusage me, me_last; struct timeval last, now; gettimeofday(&last, NULL); last.tv_sec -= rrd_update_every; // disable (by default) various interface that are not needed config_get_boolean("plugin:proc:/proc/net/dev", "interface lo", 0); config_get_boolean("plugin:proc:/proc/net/dev", "interface fireqos_monitor", 0); // when ZERO, attempt to do it int vdo_proc_net_dev = !config_get_boolean("plugin:proc", "/proc/net/dev", 1); int vdo_proc_diskstats = !config_get_boolean("plugin:proc", "/proc/diskstats", 1); int vdo_proc_net_snmp = !config_get_boolean("plugin:proc", "/proc/net/snmp", 1); int vdo_proc_net_netstat = !config_get_boolean("plugin:proc", "/proc/net/netstat", 1); int vdo_proc_net_stat_conntrack = !config_get_boolean("plugin:proc", "/proc/net/stat/conntrack", 1); int vdo_proc_net_ip_vs_stats = !config_get_boolean("plugin:proc", "/proc/net/ip_vs/stats", 1); int vdo_proc_stat = !config_get_boolean("plugin:proc", "/proc/stat", 1); int vdo_proc_meminfo = !config_get_boolean("plugin:proc", "/proc/meminfo", 1); int vdo_proc_vmstat = !config_get_boolean("plugin:proc", "/proc/vmstat", 1); int vdo_proc_net_rpc_nfsd = !config_get_boolean("plugin:proc", "/proc/net/rpc/nfsd", 1); int vdo_proc_sys_kernel_random_entropy_avail = !config_get_boolean("plugin:proc", "/proc/sys/kernel/random/entropy_avail", 1); int vdo_proc_interrupts = !config_get_boolean("plugin:proc", "/proc/interrupts", 1); int vdo_cpu_netdata = !config_get_boolean("plugin:proc", "netdata server resources", 1); RRDSET *stcpu = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL; gettimeofday(&last, NULL); getrusage(RUSAGE_SELF, &me_last); unsigned long long usec = 0, susec = 0; for(;1;) { // BEGIN -- the job to be done if(!vdo_proc_interrupts) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_interrupts()."); vdo_proc_interrupts = do_proc_interrupts(rrd_update_every, usec+susec); } if(!vdo_proc_sys_kernel_random_entropy_avail) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_sys_kernel_random_entropy_avail()."); vdo_proc_sys_kernel_random_entropy_avail = do_proc_sys_kernel_random_entropy_avail(rrd_update_every, usec+susec); } if(!vdo_proc_net_dev) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_dev()."); vdo_proc_net_dev = do_proc_net_dev(rrd_update_every, usec+susec); } if(!vdo_proc_diskstats) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_diskstats()."); vdo_proc_diskstats = do_proc_diskstats(rrd_update_every, usec+susec); } if(!vdo_proc_net_snmp) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_snmp()."); vdo_proc_net_snmp = do_proc_net_snmp(rrd_update_every, usec+susec); } if(!vdo_proc_net_netstat) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_netstat()."); vdo_proc_net_netstat = do_proc_net_netstat(rrd_update_every, usec+susec); } if(!vdo_proc_net_stat_conntrack) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_stat_conntrack()."); vdo_proc_net_stat_conntrack = do_proc_net_stat_conntrack(rrd_update_every, usec+susec); } if(!vdo_proc_net_ip_vs_stats) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_net_ip_vs_stats()."); vdo_proc_net_ip_vs_stats = do_proc_net_ip_vs_stats(rrd_update_every, usec+susec); } if(!vdo_proc_stat) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_stat()."); vdo_proc_stat = do_proc_stat(rrd_update_every, usec+susec); } if(!vdo_proc_meminfo) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_meminfo()."); vdo_proc_meminfo = do_proc_meminfo(rrd_update_every, usec+susec); } if(!vdo_proc_vmstat) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_vmstat()."); vdo_proc_vmstat = do_proc_vmstat(rrd_update_every, usec+susec); } if(!vdo_proc_net_rpc_nfsd) { debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_rpc_nfsd()."); vdo_proc_net_rpc_nfsd = do_proc_net_rpc_nfsd(rrd_update_every, usec+susec); } // END -- the job is done // find the time to sleep in order to wait exactly update_every seconds gettimeofday(&now, NULL); usec = usecdiff(&now, &last) - susec; debug(D_PROCNETDEV_LOOP, "PROCNETDEV: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec); if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec; else susec = rrd_update_every * 1000000ULL / 2ULL; // -------------------------------------------------------------------- if(!vdo_cpu_netdata && getrusage(RUSAGE_SELF, &me) == 0) { unsigned long long cpuuser = me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec; unsigned long long cpusyst = me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec; if(!stcpu) stcpu = rrdset_find("netdata.server_cpu"); if(!stcpu) { stcpu = rrdset_create("netdata", "server_cpu", NULL, "netdata", "NetData CPU usage", "milliseconds/s", 9999, rrd_update_every, RRDSET_TYPE_STACKED); rrddim_add(stcpu, "user", NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); rrddim_add(stcpu, "system", NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); } else rrdset_next(stcpu); rrddim_set(stcpu, "user", cpuuser); rrddim_set(stcpu, "system", cpusyst); rrdset_done(stcpu); bcopy(&me, &me_last, sizeof(struct rusage)); // ---------------------------------------------------------------- if(!stclients) stclients = rrdset_find("netdata.clients"); if(!stclients) { stclients = rrdset_create("netdata", "clients", NULL, "netdata", "NetData Web Clients", "connected clients", 11000, rrd_update_every, RRDSET_TYPE_LINE); rrddim_add(stclients, "clients", NULL, 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next(stclients); rrddim_set(stclients, "clients", global_statistics.connected_clients); rrdset_done(stclients); // ---------------------------------------------------------------- if(!streqs) streqs = rrdset_find("netdata.requests"); if(!streqs) { streqs = rrdset_create("netdata", "requests", NULL, "netdata", "NetData Web Requests", "requests/s", 12000, rrd_update_every, RRDSET_TYPE_LINE); rrddim_add(streqs, "requests", NULL, 1, 1 * rrd_update_every, RRDDIM_INCREMENTAL); } else rrdset_next(streqs); rrddim_set(streqs, "requests", global_statistics.web_requests); rrdset_done(streqs); // ---------------------------------------------------------------- if(!stbytes) stbytes = rrdset_find("netdata.net"); if(!stbytes) { stbytes = rrdset_create("netdata", "net", NULL, "netdata", "NetData Network Traffic", "kilobits/s", 13000, rrd_update_every, RRDSET_TYPE_AREA); rrddim_add(stbytes, "in", NULL, 8, 1024 * rrd_update_every, RRDDIM_INCREMENTAL); rrddim_add(stbytes, "out", NULL, -8, 1024 * rrd_update_every, RRDDIM_INCREMENTAL); } else rrdset_next(stbytes); rrddim_set(stbytes, "in", global_statistics.bytes_received); rrddim_set(stbytes, "out", global_statistics.bytes_sent); rrdset_done(stbytes); } usleep(susec); // copy current to last bcopy(&now, &last, sizeof(struct timeval)); } return NULL; }
int do_proc_net_netstat(int update_every, usec_t dt) { (void)dt; static int do_bandwidth = -1, do_inerrors = -1, do_mcast = -1, do_bcast = -1, do_mcast_p = -1, do_bcast_p = -1, do_ecn = -1, \ do_tcpext_reorder = -1, do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1, do_tcpext_memory = -1; static uint32_t hash_ipext = 0, hash_tcpext = 0; static procfile *ff = NULL; static unsigned long long *tcpext_TCPRenoReorder = NULL; static unsigned long long *tcpext_TCPFACKReorder = NULL; static unsigned long long *tcpext_TCPSACKReorder = NULL; static unsigned long long *tcpext_TCPTSReorder = NULL; static unsigned long long *tcpext_SyncookiesSent = NULL; static unsigned long long *tcpext_SyncookiesRecv = NULL; static unsigned long long *tcpext_SyncookiesFailed = NULL; static unsigned long long *tcpext_TCPOFOQueue = NULL; // Number of packets queued in OFO queue static unsigned long long *tcpext_TCPOFODrop = NULL; // Number of packets meant to be queued in OFO but dropped because socket rcvbuf limit hit. static unsigned long long *tcpext_TCPOFOMerge = NULL; // Number of packets in OFO that were merged with other packets. static unsigned long long *tcpext_OfoPruned = NULL; // packets dropped from out-of-order queue because of socket buffer overrun static unsigned long long *tcpext_TCPAbortOnData = NULL; // connections reset due to unexpected data static unsigned long long *tcpext_TCPAbortOnClose = NULL; // connections reset due to early user close static unsigned long long *tcpext_TCPAbortOnMemory = NULL; // connections aborted due to memory pressure static unsigned long long *tcpext_TCPAbortOnTimeout = NULL; // connections aborted due to timeout static unsigned long long *tcpext_TCPAbortOnLinger = NULL; // connections aborted after user close in linger timeout static unsigned long long *tcpext_TCPAbortFailed = NULL; // times unable to send RST due to no memory static unsigned long long *tcpext_TCPMemoryPressures = NULL; /* // connection rejects static unsigned long long *tcpext_PAWSActive = NULL; // active connections rejected because of time stamp static unsigned long long *tcpext_PAWSPassive = NULL; // passive connections rejected because of time stamp static unsigned long long *tcpext_TCPTimeouts = NULL; static unsigned long long *tcpext_TCPDSACKUndo = NULL; static unsigned long long *tcpext_TCPDSACKOldSent = NULL; static unsigned long long *tcpext_TCPDSACKOfoSent = NULL; static unsigned long long *tcpext_TCPDSACKRecv = NULL; static unsigned long long *tcpext_TCPDSACKOfoRecv = NULL; static unsigned long long *tcpext_TCPDSACKIgnoredOld = NULL; static unsigned long long *tcpext_TCPDSACKIgnoredNoUndo = NULL; static unsigned long long *tcpext_EmbryonicRsts = NULL; static unsigned long long *tcpext_PruneCalled = NULL; static unsigned long long *tcpext_RcvPruned = NULL; static unsigned long long *tcpext_OutOfWindowIcmps = NULL; static unsigned long long *tcpext_LockDroppedIcmps = NULL; static unsigned long long *tcpext_ArpFilter = NULL; static unsigned long long *tcpext_TW = NULL; static unsigned long long *tcpext_TWRecycled = NULL; static unsigned long long *tcpext_TWKilled = NULL; static unsigned long long *tcpext_PAWSEstab = NULL; static unsigned long long *tcpext_DelayedACKs = NULL; static unsigned long long *tcpext_DelayedACKLocked = NULL; static unsigned long long *tcpext_DelayedACKLost = NULL; static unsigned long long *tcpext_ListenOverflows = NULL; static unsigned long long *tcpext_ListenDrops = NULL; static unsigned long long *tcpext_TCPPrequeued = NULL; static unsigned long long *tcpext_TCPDirectCopyFromBacklog = NULL; static unsigned long long *tcpext_TCPDirectCopyFromPrequeue = NULL; static unsigned long long *tcpext_TCPPrequeueDropped = NULL; static unsigned long long *tcpext_TCPHPHits = NULL; static unsigned long long *tcpext_TCPHPHitsToUser = NULL; static unsigned long long *tcpext_TCPHPAcks = NULL; static unsigned long long *tcpext_TCPPureAcks = NULL; static unsigned long long *tcpext_TCPRenoRecovery = NULL; static unsigned long long *tcpext_TCPSackRecovery = NULL; static unsigned long long *tcpext_TCPSackFailures = NULL; static unsigned long long *tcpext_TCPSACKReneging = NULL; static unsigned long long *tcpext_TCPSackRecoveryFail = NULL; static unsigned long long *tcpext_TCPSACKDiscard = NULL; static unsigned long long *tcpext_TCPSackShifted = NULL; static unsigned long long *tcpext_TCPSackMerged = NULL; static unsigned long long *tcpext_TCPSackShiftFallback = NULL; static unsigned long long *tcpext_TCPFullUndo = NULL; static unsigned long long *tcpext_TCPPartialUndo = NULL; static unsigned long long *tcpext_TCPLossUndo = NULL; static unsigned long long *tcpext_TCPLostRetransmit = NULL; static unsigned long long *tcpext_TCPRenoFailures = NULL; static unsigned long long *tcpext_TCPLossFailures = NULL; static unsigned long long *tcpext_TCPFastRetrans = NULL; static unsigned long long *tcpext_TCPForwardRetrans = NULL; static unsigned long long *tcpext_TCPSlowStartRetrans = NULL; static unsigned long long *tcpext_TCPLossProbes = NULL; static unsigned long long *tcpext_TCPLossProbeRecovery = NULL; static unsigned long long *tcpext_TCPRenoRecoveryFail = NULL; static unsigned long long *tcpext_TCPSchedulerFailed = NULL; static unsigned long long *tcpext_TCPRcvCollapsed = NULL; static unsigned long long *tcpext_TCPSpuriousRTOs = NULL; static unsigned long long *tcpext_TCPMD5NotFound = NULL; static unsigned long long *tcpext_TCPMD5Unexpected = NULL; static unsigned long long *tcpext_TCPBacklogDrop = NULL; static unsigned long long *tcpext_TCPMinTTLDrop = NULL; static unsigned long long *tcpext_TCPDeferAcceptDrop = NULL; static unsigned long long *tcpext_IPReversePathFilter = NULL; static unsigned long long *tcpext_TCPTimeWaitOverflow = NULL; static unsigned long long *tcpext_TCPReqQFullDoCookies = NULL; static unsigned long long *tcpext_TCPReqQFullDrop = NULL; static unsigned long long *tcpext_TCPRetransFail = NULL; static unsigned long long *tcpext_TCPRcvCoalesce = NULL; static unsigned long long *tcpext_TCPChallengeACK = NULL; static unsigned long long *tcpext_TCPSYNChallenge = NULL; static unsigned long long *tcpext_TCPFastOpenActive = NULL; static unsigned long long *tcpext_TCPFastOpenActiveFail = NULL; static unsigned long long *tcpext_TCPFastOpenPassive = NULL; static unsigned long long *tcpext_TCPFastOpenPassiveFail = NULL; static unsigned long long *tcpext_TCPFastOpenListenOverflow = NULL; static unsigned long long *tcpext_TCPFastOpenCookieReqd = NULL; static unsigned long long *tcpext_TCPSpuriousRtxHostQueues = NULL; static unsigned long long *tcpext_BusyPollRxPackets = NULL; static unsigned long long *tcpext_TCPAutoCorking = NULL; static unsigned long long *tcpext_TCPFromZeroWindowAdv = NULL; static unsigned long long *tcpext_TCPToZeroWindowAdv = NULL; static unsigned long long *tcpext_TCPWantZeroWindowAdv = NULL; static unsigned long long *tcpext_TCPSynRetrans = NULL; static unsigned long long *tcpext_TCPOrigDataSent = NULL; static unsigned long long *tcpext_TCPHystartTrainDetect = NULL; static unsigned long long *tcpext_TCPHystartTrainCwnd = NULL; static unsigned long long *tcpext_TCPHystartDelayDetect = NULL; static unsigned long long *tcpext_TCPHystartDelayCwnd = NULL; static unsigned long long *tcpext_TCPACKSkippedSynRecv = NULL; static unsigned long long *tcpext_TCPACKSkippedPAWS = NULL; static unsigned long long *tcpext_TCPACKSkippedSeq = NULL; static unsigned long long *tcpext_TCPACKSkippedFinWait2 = NULL; static unsigned long long *tcpext_TCPACKSkippedTimeWait = NULL; static unsigned long long *tcpext_TCPACKSkippedChallenge = NULL; static unsigned long long *tcpext_TCPWinProbe = NULL; static unsigned long long *tcpext_TCPKeepAlive = NULL; static unsigned long long *tcpext_TCPMTUPFail = NULL; static unsigned long long *tcpext_TCPMTUPSuccess = NULL; */ static unsigned long long *ipext_InNoRoutes = NULL; static unsigned long long *ipext_InTruncatedPkts = NULL; static unsigned long long *ipext_InMcastPkts = NULL; static unsigned long long *ipext_OutMcastPkts = NULL; static unsigned long long *ipext_InBcastPkts = NULL; static unsigned long long *ipext_OutBcastPkts = NULL; static unsigned long long *ipext_InOctets = NULL; static unsigned long long *ipext_OutOctets = NULL; static unsigned long long *ipext_InMcastOctets = NULL; static unsigned long long *ipext_OutMcastOctets = NULL; static unsigned long long *ipext_InBcastOctets = NULL; static unsigned long long *ipext_OutBcastOctets = NULL; static unsigned long long *ipext_InCsumErrors = NULL; static unsigned long long *ipext_InNoECTPkts = NULL; static unsigned long long *ipext_InECT1Pkts = NULL; static unsigned long long *ipext_InECT0Pkts = NULL; static unsigned long long *ipext_InCEPkts = NULL; if(unlikely(do_bandwidth == -1)) { do_bandwidth = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "bandwidth", CONFIG_ONDEMAND_ONDEMAND); do_inerrors = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "input errors", CONFIG_ONDEMAND_ONDEMAND); do_mcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast bandwidth", CONFIG_ONDEMAND_ONDEMAND); do_bcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast bandwidth", CONFIG_ONDEMAND_ONDEMAND); do_mcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast packets", CONFIG_ONDEMAND_ONDEMAND); do_bcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast packets", CONFIG_ONDEMAND_ONDEMAND); do_ecn = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "ECN packets", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_reorder = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP reorders", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_syscookies = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP SYN cookies", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_ofo = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP out-of-order queue", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_memory = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_ONDEMAND_ONDEMAND); hash_ipext = simple_hash("IpExt"); hash_tcpext = simple_hash("TcpExt"); hash_array(ipext_data); hash_array(tcpext_data); // Reordering tcpext_TCPFACKReorder = netstat_columns_find(tcpext_data, "TCPFACKReorder"); tcpext_TCPSACKReorder = netstat_columns_find(tcpext_data, "TCPSACKReorder"); tcpext_TCPRenoReorder = netstat_columns_find(tcpext_data, "TCPRenoReorder"); tcpext_TCPTSReorder = netstat_columns_find(tcpext_data, "TCPTSReorder"); // SYN Cookies tcpext_SyncookiesSent = netstat_columns_find(tcpext_data, "SyncookiesSent"); tcpext_SyncookiesRecv = netstat_columns_find(tcpext_data, "SyncookiesRecv"); tcpext_SyncookiesFailed = netstat_columns_find(tcpext_data, "SyncookiesFailed"); // Out Of Order Queue // http://www.spinics.net/lists/netdev/msg204696.html tcpext_TCPOFOQueue = netstat_columns_find(tcpext_data, "TCPOFOQueue"); // Number of packets queued in OFO queue tcpext_TCPOFODrop = netstat_columns_find(tcpext_data, "TCPOFODrop"); // Number of packets meant to be queued in OFO but dropped because socket rcvbuf limit hit. tcpext_TCPOFOMerge = netstat_columns_find(tcpext_data, "TCPOFOMerge"); // Number of packets in OFO that were merged with other packets. tcpext_OfoPruned = netstat_columns_find(tcpext_data, "OfoPruned"); // packets dropped from out-of-order queue because of socket buffer overrun // connection resets // https://github.com/ecki/net-tools/blob/bd8bceaed2311651710331a7f8990c3e31be9840/statistics.c tcpext_TCPAbortOnData = netstat_columns_find(tcpext_data, "TCPAbortOnData"); // connections reset due to unexpected data tcpext_TCPAbortOnClose = netstat_columns_find(tcpext_data, "TCPAbortOnClose"); // connections reset due to early user close tcpext_TCPAbortOnMemory = netstat_columns_find(tcpext_data, "TCPAbortOnMemory"); // connections aborted due to memory pressure tcpext_TCPAbortOnTimeout = netstat_columns_find(tcpext_data, "TCPAbortOnTimeout"); // connections aborted due to timeout tcpext_TCPAbortOnLinger = netstat_columns_find(tcpext_data, "TCPAbortOnLinger"); // connections aborted after user close in linger timeout tcpext_TCPAbortFailed = netstat_columns_find(tcpext_data, "TCPAbortFailed"); // times unable to send RST due to no memory tcpext_TCPMemoryPressures = netstat_columns_find(tcpext_data, "TCPMemoryPressures"); /* tcpext_EmbryonicRsts = netstat_columns_find(tcpext_data, "EmbryonicRsts"); tcpext_PruneCalled = netstat_columns_find(tcpext_data, "PruneCalled"); tcpext_RcvPruned = netstat_columns_find(tcpext_data, "RcvPruned"); tcpext_OutOfWindowIcmps = netstat_columns_find(tcpext_data, "OutOfWindowIcmps"); tcpext_LockDroppedIcmps = netstat_columns_find(tcpext_data, "LockDroppedIcmps"); tcpext_ArpFilter = netstat_columns_find(tcpext_data, "ArpFilter"); tcpext_TW = netstat_columns_find(tcpext_data, "TW"); tcpext_TWRecycled = netstat_columns_find(tcpext_data, "TWRecycled"); tcpext_TWKilled = netstat_columns_find(tcpext_data, "TWKilled"); tcpext_PAWSPassive = netstat_columns_find(tcpext_data, "PAWSPassive"); tcpext_PAWSActive = netstat_columns_find(tcpext_data, "PAWSActive"); tcpext_PAWSEstab = netstat_columns_find(tcpext_data, "PAWSEstab"); tcpext_DelayedACKs = netstat_columns_find(tcpext_data, "DelayedACKs"); tcpext_DelayedACKLocked = netstat_columns_find(tcpext_data, "DelayedACKLocked"); tcpext_DelayedACKLost = netstat_columns_find(tcpext_data, "DelayedACKLost"); tcpext_ListenOverflows = netstat_columns_find(tcpext_data, "ListenOverflows"); tcpext_ListenDrops = netstat_columns_find(tcpext_data, "ListenDrops"); tcpext_TCPPrequeued = netstat_columns_find(tcpext_data, "TCPPrequeued"); tcpext_TCPDirectCopyFromBacklog = netstat_columns_find(tcpext_data, "TCPDirectCopyFromBacklog"); tcpext_TCPDirectCopyFromPrequeue = netstat_columns_find(tcpext_data, "TCPDirectCopyFromPrequeue"); tcpext_TCPPrequeueDropped = netstat_columns_find(tcpext_data, "TCPPrequeueDropped"); tcpext_TCPHPHits = netstat_columns_find(tcpext_data, "TCPHPHits"); tcpext_TCPHPHitsToUser = netstat_columns_find(tcpext_data, "TCPHPHitsToUser"); tcpext_TCPPureAcks = netstat_columns_find(tcpext_data, "TCPPureAcks"); tcpext_TCPHPAcks = netstat_columns_find(tcpext_data, "TCPHPAcks"); tcpext_TCPRenoRecovery = netstat_columns_find(tcpext_data, "TCPRenoRecovery"); tcpext_TCPSackRecovery = netstat_columns_find(tcpext_data, "TCPSackRecovery"); tcpext_TCPSACKReneging = netstat_columns_find(tcpext_data, "TCPSACKReneging"); tcpext_TCPFullUndo = netstat_columns_find(tcpext_data, "TCPFullUndo"); tcpext_TCPPartialUndo = netstat_columns_find(tcpext_data, "TCPPartialUndo"); tcpext_TCPDSACKUndo = netstat_columns_find(tcpext_data, "TCPDSACKUndo"); tcpext_TCPLossUndo = netstat_columns_find(tcpext_data, "TCPLossUndo"); tcpext_TCPLostRetransmit = netstat_columns_find(tcpext_data, "TCPLostRetransmit"); tcpext_TCPRenoFailures = netstat_columns_find(tcpext_data, "TCPRenoFailures"); tcpext_TCPSackFailures = netstat_columns_find(tcpext_data, "TCPSackFailures"); tcpext_TCPLossFailures = netstat_columns_find(tcpext_data, "TCPLossFailures"); tcpext_TCPFastRetrans = netstat_columns_find(tcpext_data, "TCPFastRetrans"); tcpext_TCPForwardRetrans = netstat_columns_find(tcpext_data, "TCPForwardRetrans"); tcpext_TCPSlowStartRetrans = netstat_columns_find(tcpext_data, "TCPSlowStartRetrans"); tcpext_TCPTimeouts = netstat_columns_find(tcpext_data, "TCPTimeouts"); tcpext_TCPLossProbes = netstat_columns_find(tcpext_data, "TCPLossProbes"); tcpext_TCPLossProbeRecovery = netstat_columns_find(tcpext_data, "TCPLossProbeRecovery"); tcpext_TCPRenoRecoveryFail = netstat_columns_find(tcpext_data, "TCPRenoRecoveryFail"); tcpext_TCPSackRecoveryFail = netstat_columns_find(tcpext_data, "TCPSackRecoveryFail"); tcpext_TCPSchedulerFailed = netstat_columns_find(tcpext_data, "TCPSchedulerFailed"); tcpext_TCPRcvCollapsed = netstat_columns_find(tcpext_data, "TCPRcvCollapsed"); tcpext_TCPDSACKOldSent = netstat_columns_find(tcpext_data, "TCPDSACKOldSent"); tcpext_TCPDSACKOfoSent = netstat_columns_find(tcpext_data, "TCPDSACKOfoSent"); tcpext_TCPDSACKRecv = netstat_columns_find(tcpext_data, "TCPDSACKRecv"); tcpext_TCPDSACKOfoRecv = netstat_columns_find(tcpext_data, "TCPDSACKOfoRecv"); tcpext_TCPSACKDiscard = netstat_columns_find(tcpext_data, "TCPSACKDiscard"); tcpext_TCPDSACKIgnoredOld = netstat_columns_find(tcpext_data, "TCPDSACKIgnoredOld"); tcpext_TCPDSACKIgnoredNoUndo = netstat_columns_find(tcpext_data, "TCPDSACKIgnoredNoUndo"); tcpext_TCPSpuriousRTOs = netstat_columns_find(tcpext_data, "TCPSpuriousRTOs"); tcpext_TCPMD5NotFound = netstat_columns_find(tcpext_data, "TCPMD5NotFound"); tcpext_TCPMD5Unexpected = netstat_columns_find(tcpext_data, "TCPMD5Unexpected"); tcpext_TCPSackShifted = netstat_columns_find(tcpext_data, "TCPSackShifted"); tcpext_TCPSackMerged = netstat_columns_find(tcpext_data, "TCPSackMerged"); tcpext_TCPSackShiftFallback = netstat_columns_find(tcpext_data, "TCPSackShiftFallback"); tcpext_TCPBacklogDrop = netstat_columns_find(tcpext_data, "TCPBacklogDrop"); tcpext_TCPMinTTLDrop = netstat_columns_find(tcpext_data, "TCPMinTTLDrop"); tcpext_TCPDeferAcceptDrop = netstat_columns_find(tcpext_data, "TCPDeferAcceptDrop"); tcpext_IPReversePathFilter = netstat_columns_find(tcpext_data, "IPReversePathFilter"); tcpext_TCPTimeWaitOverflow = netstat_columns_find(tcpext_data, "TCPTimeWaitOverflow"); tcpext_TCPReqQFullDoCookies = netstat_columns_find(tcpext_data, "TCPReqQFullDoCookies"); tcpext_TCPReqQFullDrop = netstat_columns_find(tcpext_data, "TCPReqQFullDrop"); tcpext_TCPRetransFail = netstat_columns_find(tcpext_data, "TCPRetransFail"); tcpext_TCPRcvCoalesce = netstat_columns_find(tcpext_data, "TCPRcvCoalesce"); tcpext_TCPChallengeACK = netstat_columns_find(tcpext_data, "TCPChallengeACK"); tcpext_TCPSYNChallenge = netstat_columns_find(tcpext_data, "TCPSYNChallenge"); tcpext_TCPFastOpenActive = netstat_columns_find(tcpext_data, "TCPFastOpenActive"); tcpext_TCPFastOpenActiveFail = netstat_columns_find(tcpext_data, "TCPFastOpenActiveFail"); tcpext_TCPFastOpenPassive = netstat_columns_find(tcpext_data, "TCPFastOpenPassive"); tcpext_TCPFastOpenPassiveFail = netstat_columns_find(tcpext_data, "TCPFastOpenPassiveFail"); tcpext_TCPFastOpenListenOverflow = netstat_columns_find(tcpext_data, "TCPFastOpenListenOverflow"); tcpext_TCPFastOpenCookieReqd = netstat_columns_find(tcpext_data, "TCPFastOpenCookieReqd"); tcpext_TCPSpuriousRtxHostQueues = netstat_columns_find(tcpext_data, "TCPSpuriousRtxHostQueues"); tcpext_BusyPollRxPackets = netstat_columns_find(tcpext_data, "BusyPollRxPackets"); tcpext_TCPAutoCorking = netstat_columns_find(tcpext_data, "TCPAutoCorking"); tcpext_TCPFromZeroWindowAdv = netstat_columns_find(tcpext_data, "TCPFromZeroWindowAdv"); tcpext_TCPToZeroWindowAdv = netstat_columns_find(tcpext_data, "TCPToZeroWindowAdv"); tcpext_TCPWantZeroWindowAdv = netstat_columns_find(tcpext_data, "TCPWantZeroWindowAdv"); tcpext_TCPSynRetrans = netstat_columns_find(tcpext_data, "TCPSynRetrans"); tcpext_TCPOrigDataSent = netstat_columns_find(tcpext_data, "TCPOrigDataSent"); tcpext_TCPHystartTrainDetect = netstat_columns_find(tcpext_data, "TCPHystartTrainDetect"); tcpext_TCPHystartTrainCwnd = netstat_columns_find(tcpext_data, "TCPHystartTrainCwnd"); tcpext_TCPHystartDelayDetect = netstat_columns_find(tcpext_data, "TCPHystartDelayDetect"); tcpext_TCPHystartDelayCwnd = netstat_columns_find(tcpext_data, "TCPHystartDelayCwnd"); tcpext_TCPACKSkippedSynRecv = netstat_columns_find(tcpext_data, "TCPACKSkippedSynRecv"); tcpext_TCPACKSkippedPAWS = netstat_columns_find(tcpext_data, "TCPACKSkippedPAWS"); tcpext_TCPACKSkippedSeq = netstat_columns_find(tcpext_data, "TCPACKSkippedSeq"); tcpext_TCPACKSkippedFinWait2 = netstat_columns_find(tcpext_data, "TCPACKSkippedFinWait2"); tcpext_TCPACKSkippedTimeWait = netstat_columns_find(tcpext_data, "TCPACKSkippedTimeWait"); tcpext_TCPACKSkippedChallenge = netstat_columns_find(tcpext_data, "TCPACKSkippedChallenge"); tcpext_TCPWinProbe = netstat_columns_find(tcpext_data, "TCPWinProbe"); tcpext_TCPKeepAlive = netstat_columns_find(tcpext_data, "TCPKeepAlive"); tcpext_TCPMTUPFail = netstat_columns_find(tcpext_data, "TCPMTUPFail"); tcpext_TCPMTUPSuccess = netstat_columns_find(tcpext_data, "TCPMTUPSuccess"); */ ipext_InNoRoutes = netstat_columns_find(ipext_data, "InNoRoutes"); ipext_InTruncatedPkts = netstat_columns_find(ipext_data, "InTruncatedPkts"); ipext_InMcastPkts = netstat_columns_find(ipext_data, "InMcastPkts"); ipext_OutMcastPkts = netstat_columns_find(ipext_data, "OutMcastPkts"); ipext_InBcastPkts = netstat_columns_find(ipext_data, "InBcastPkts"); ipext_OutBcastPkts = netstat_columns_find(ipext_data, "OutBcastPkts"); ipext_InOctets = netstat_columns_find(ipext_data, "InOctets"); ipext_OutOctets = netstat_columns_find(ipext_data, "OutOctets"); ipext_InMcastOctets = netstat_columns_find(ipext_data, "InMcastOctets"); ipext_OutMcastOctets = netstat_columns_find(ipext_data, "OutMcastOctets"); ipext_InBcastOctets = netstat_columns_find(ipext_data, "InBcastOctets"); ipext_OutBcastOctets = netstat_columns_find(ipext_data, "OutBcastOctets"); ipext_InCsumErrors = netstat_columns_find(ipext_data, "InCsumErrors"); ipext_InNoECTPkts = netstat_columns_find(ipext_data, "InNoECTPkts"); ipext_InECT1Pkts = netstat_columns_find(ipext_data, "InECT1Pkts"); ipext_InECT0Pkts = netstat_columns_find(ipext_data, "InECT0Pkts"); ipext_InCEPkts = netstat_columns_find(ipext_data, "InCEPkts"); } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/netstat"); ff = procfile_open(config_get("plugin:proc:/proc/net/netstat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); if(unlikely(!ff)) return 1; } ff = procfile_readall(ff); if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; for(l = 0; l < lines ;l++) { char *key = procfile_lineword(ff, l, 0); uint32_t hash = simple_hash(key); if(unlikely(hash == hash_ipext && strcmp(key, "IpExt") == 0)) { uint32_t h = l++; if(unlikely(strcmp(procfile_lineword(ff, l, 0), "IpExt") != 0)) { error("Cannot read IpExt line from /proc/net/netstat."); break; } words = procfile_linewords(ff, l); if(unlikely(words < 2)) { error("Cannot read /proc/net/netstat IpExt line. Expected 2+ params, read %u.", words); continue; } parse_line_pair(ff, ipext_data, h, l); RRDSET *st; // -------------------------------------------------------------------- if(do_bandwidth == CONFIG_ONDEMAND_YES || (do_bandwidth == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InOctets || *ipext_OutOctets))) { do_bandwidth = CONFIG_ONDEMAND_YES; st = rrdset_find("system.ipv4"); if(unlikely(!st)) { st = rrdset_create("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "InOctets", "received", 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "OutOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InOctets", *ipext_InOctets); rrddim_set(st, "OutOctets", *ipext_OutOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_inerrors == CONFIG_ONDEMAND_YES || (do_inerrors == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InNoRoutes || *ipext_InTruncatedPkts))) { do_inerrors = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.inerrors"); if(unlikely(!st)) { st = rrdset_create("ipv4", "inerrors", NULL, "errors", NULL, "IPv4 Input Errors", "packets/s", 4000, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InNoRoutes", "noroutes", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InTruncatedPkts", "truncated", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InCsumErrors", "checksum", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InNoRoutes", *ipext_InNoRoutes); rrddim_set(st, "InTruncatedPkts", *ipext_InTruncatedPkts); rrddim_set(st, "InCsumErrors", *ipext_InCsumErrors); rrdset_done(st); } // -------------------------------------------------------------------- if(do_mcast == CONFIG_ONDEMAND_YES || (do_mcast == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InMcastOctets || *ipext_OutMcastOctets))) { do_mcast = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.mcast"); if(unlikely(!st)) { st = rrdset_create("ipv4", "mcast", NULL, "multicast", NULL, "IPv4 Multicast Bandwidth", "kilobits/s", 9000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "InMcastOctets", "received", 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "OutMcastOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InMcastOctets", *ipext_InMcastOctets); rrddim_set(st, "OutMcastOctets", *ipext_OutMcastOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bcast == CONFIG_ONDEMAND_YES || (do_bcast == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InBcastOctets || *ipext_OutBcastOctets))) { do_bcast = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.bcast"); if(unlikely(!st)) { st = rrdset_create("ipv4", "bcast", NULL, "broadcast", NULL, "IPv4 Broadcast Bandwidth", "kilobits/s", 8000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "InBcastOctets", "received", 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "OutBcastOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InBcastOctets", *ipext_InBcastOctets); rrddim_set(st, "OutBcastOctets", *ipext_OutBcastOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_mcast_p == CONFIG_ONDEMAND_YES || (do_mcast_p == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InMcastPkts || *ipext_OutMcastPkts))) { do_mcast_p = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.mcastpkts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "mcastpkts", NULL, "multicast", NULL, "IPv4 Multicast Packets", "packets/s", 8600, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InMcastPkts", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutMcastPkts", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InMcastPkts", *ipext_InMcastPkts); rrddim_set(st, "OutMcastPkts", *ipext_OutMcastPkts); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bcast_p == CONFIG_ONDEMAND_YES || (do_bcast_p == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InBcastPkts || *ipext_OutBcastPkts))) { do_bcast_p = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.bcastpkts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "bcastpkts", NULL, "broadcast", NULL, "IPv4 Broadcast Packets", "packets/s", 8500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InBcastPkts", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutBcastPkts", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InBcastPkts", *ipext_InBcastPkts); rrddim_set(st, "OutBcastPkts", *ipext_OutBcastPkts); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ecn == CONFIG_ONDEMAND_YES || (do_ecn == CONFIG_ONDEMAND_ONDEMAND && (*ipext_InCEPkts || *ipext_InECT0Pkts || *ipext_InECT1Pkts || *ipext_InNoECTPkts))) { do_ecn = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.ecnpkts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics", "packets/s", 8700, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InNoECTPkts", "NoECTP", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InECT0Pkts", "ECTP0", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InECT1Pkts", "ECTP1", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InCEPkts", *ipext_InCEPkts); rrddim_set(st, "InNoECTPkts", *ipext_InNoECTPkts); rrddim_set(st, "InECT0Pkts", *ipext_InECT0Pkts); rrddim_set(st, "InECT1Pkts", *ipext_InECT1Pkts); rrdset_done(st); } } else if(unlikely(hash == hash_tcpext && strcmp(key, "TcpExt") == 0)) { uint32_t h = l++; if(unlikely(strcmp(procfile_lineword(ff, l, 0), "TcpExt") != 0)) { error("Cannot read TcpExt line from /proc/net/netstat."); break; } words = procfile_linewords(ff, l); if(unlikely(words < 2)) { error("Cannot read /proc/net/netstat TcpExt line. Expected 2+ params, read %u.", words); continue; } parse_line_pair(ff, tcpext_data, h, l); RRDSET *st; // -------------------------------------------------------------------- if(do_tcpext_memory == CONFIG_ONDEMAND_YES || (do_tcpext_memory == CONFIG_ONDEMAND_ONDEMAND && (*tcpext_TCPMemoryPressures))) { do_tcpext_memory = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpmemorypressures"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpmemorypressures", NULL, "tcp", NULL, "TCP Memory Pressures", "events/s", 3000, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPMemoryPressures", "pressures", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPMemoryPressures", *tcpext_TCPMemoryPressures); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_connaborts == CONFIG_ONDEMAND_YES || (do_tcpext_connaborts == CONFIG_ONDEMAND_ONDEMAND && (*tcpext_TCPAbortOnData || *tcpext_TCPAbortOnClose || *tcpext_TCPAbortOnMemory || *tcpext_TCPAbortOnTimeout || *tcpext_TCPAbortOnLinger || *tcpext_TCPAbortFailed))) { do_tcpext_connaborts = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpconnaborts"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts", "connections/s", 3010, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPAbortOnData", "baddata", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnClose", "userclosed", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnMemory", "nomemory", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnTimeout", "timeout", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortOnLinger", "linger", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPAbortFailed", "failed", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPAbortOnData", *tcpext_TCPAbortOnData); rrddim_set(st, "TCPAbortOnClose", *tcpext_TCPAbortOnClose); rrddim_set(st, "TCPAbortOnMemory", *tcpext_TCPAbortOnMemory); rrddim_set(st, "TCPAbortOnTimeout", *tcpext_TCPAbortOnTimeout); rrddim_set(st, "TCPAbortOnLinger", *tcpext_TCPAbortOnLinger); rrddim_set(st, "TCPAbortFailed", *tcpext_TCPAbortFailed); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_reorder == CONFIG_ONDEMAND_YES || (do_tcpext_reorder == CONFIG_ONDEMAND_ONDEMAND && (*tcpext_TCPRenoReorder || *tcpext_TCPFACKReorder || *tcpext_TCPSACKReorder || *tcpext_TCPTSReorder))) { do_tcpext_reorder = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpreorders"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpreorders", NULL, "tcp", NULL, "TCP Reordered Packets by Detection Method", "packets/s", 3020, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPTSReorder", "timestamp", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPSACKReorder", "sack", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPFACKReorder", "fack", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPRenoReorder", "reno", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPTSReorder", *tcpext_TCPTSReorder); rrddim_set(st, "TCPSACKReorder", *tcpext_TCPSACKReorder); rrddim_set(st, "TCPFACKReorder", *tcpext_TCPFACKReorder); rrddim_set(st, "TCPRenoReorder", *tcpext_TCPRenoReorder); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_ofo == CONFIG_ONDEMAND_YES || (do_tcpext_ofo == CONFIG_ONDEMAND_ONDEMAND && (*tcpext_TCPOFOQueue || *tcpext_TCPOFODrop || *tcpext_TCPOFOMerge))) { do_tcpext_ofo = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpofo"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue", "packets/s", 3050, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "TCPOFOQueue", "inqueue", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPOFODrop", "dropped", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "TCPOFOMerge", "merged", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OfoPruned", "pruned", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "TCPOFOQueue", *tcpext_TCPOFOQueue); rrddim_set(st, "TCPOFODrop", *tcpext_TCPOFODrop); rrddim_set(st, "TCPOFOMerge", *tcpext_TCPOFOMerge); rrddim_set(st, "OfoPruned", *tcpext_OfoPruned); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcpext_syscookies == CONFIG_ONDEMAND_YES || (do_tcpext_syscookies == CONFIG_ONDEMAND_ONDEMAND && (*tcpext_SyncookiesSent || *tcpext_SyncookiesRecv || *tcpext_SyncookiesFailed))) { do_tcpext_syscookies = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.tcpsyncookies"); if(unlikely(!st)) { st = rrdset_create("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies", "packets/s", 3100, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "SyncookiesRecv", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SyncookiesSent", "sent", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SyncookiesFailed", "failed", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "SyncookiesRecv", *tcpext_SyncookiesRecv); rrddim_set(st, "SyncookiesSent", *tcpext_SyncookiesSent); rrddim_set(st, "SyncookiesFailed", *tcpext_SyncookiesFailed); rrdset_done(st); } } } return 0; }
// returns the HTTP code inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, char *url) { debug(D_WEB_CLIENT, "%llu: API v1 data with URL '%s'", w->id, url); int ret = 400; BUFFER *dimensions = NULL; buffer_flush(w->response.data); char *google_version = "0.6", *google_reqId = "0", *google_sig = "0", *google_out = "json", *responseHandler = NULL, *outFileName = NULL; time_t last_timestamp_in_data = 0, google_timestamp = 0; char *chart = NULL , *before_str = NULL , *after_str = NULL , *group_time_str = NULL , *points_str = NULL; int group = RRDR_GROUPING_AVERAGE; uint32_t format = DATASOURCE_JSON; uint32_t options = 0x00000000; while(url) { char *value = mystrsep(&url, "?&"); if(!value || !*value) continue; char *name = mystrsep(&value, "="); if(!name || !*name) continue; if(!value || !*value) continue; debug(D_WEB_CLIENT, "%llu: API v1 data query param '%s' with value '%s'", w->id, name, value); // name and value are now the parameters // they are not null and not empty if(!strcmp(name, "chart")) chart = value; else if(!strcmp(name, "dimension") || !strcmp(name, "dim") || !strcmp(name, "dimensions") || !strcmp(name, "dims")) { if(!dimensions) dimensions = buffer_create(100); buffer_strcat(dimensions, "|"); buffer_strcat(dimensions, value); } else if(!strcmp(name, "after")) after_str = value; else if(!strcmp(name, "before")) before_str = value; else if(!strcmp(name, "points")) points_str = value; else if(!strcmp(name, "gtime")) group_time_str = value; else if(!strcmp(name, "group")) { group = web_client_api_request_v1_data_group(value, RRDR_GROUPING_AVERAGE); } else if(!strcmp(name, "format")) { format = web_client_api_request_v1_data_format(value); } else if(!strcmp(name, "options")) { options |= web_client_api_request_v1_data_options(value); } else if(!strcmp(name, "callback")) { responseHandler = value; } else if(!strcmp(name, "filename")) { outFileName = value; } else if(!strcmp(name, "tqx")) { // parse Google Visualization API options // https://developers.google.com/chart/interactive/docs/dev/implementing_data_source char *tqx_name, *tqx_value; while(value) { tqx_value = mystrsep(&value, ";"); if(!tqx_value || !*tqx_value) continue; tqx_name = mystrsep(&tqx_value, ":"); if(!tqx_name || !*tqx_name) continue; if(!tqx_value || !*tqx_value) continue; if(!strcmp(tqx_name, "version")) google_version = tqx_value; else if(!strcmp(tqx_name, "reqId")) google_reqId = tqx_value; else if(!strcmp(tqx_name, "sig")) { google_sig = tqx_value; google_timestamp = strtoul(google_sig, NULL, 0); } else if(!strcmp(tqx_name, "out")) { google_out = tqx_value; format = web_client_api_request_v1_data_google_format(google_out); } else if(!strcmp(tqx_name, "responseHandler")) responseHandler = tqx_value; else if(!strcmp(tqx_name, "outFileName")) outFileName = tqx_value; } } } if(!chart || !*chart) { buffer_sprintf(w->response.data, "No chart id is given at the request."); goto cleanup; } RRDSET *st = rrdset_find(host, chart); if(!st) st = rrdset_find_byname(host, chart); if(!st) { buffer_strcat(w->response.data, "Chart is not found: "); buffer_strcat_htmlescape(w->response.data, chart); ret = 404; goto cleanup; } st->last_accessed_time = now_realtime_sec(); long long before = (before_str && *before_str)?str2l(before_str):0; long long after = (after_str && *after_str) ?str2l(after_str):0; int points = (points_str && *points_str)?str2i(points_str):0; long group_time = (group_time_str && *group_time_str)?str2l(group_time_str):0; debug(D_WEB_CLIENT, "%llu: API command 'data' for chart '%s', dimensions '%s', after '%lld', before '%lld', points '%d', group '%d', format '%u', options '0x%08x'" , w->id , chart , (dimensions)?buffer_tostring(dimensions):"" , after , before , points , group , format , options ); if(outFileName && *outFileName) { buffer_sprintf(w->response.header, "Content-Disposition: attachment; filename=\"%s\"\r\n", outFileName); debug(D_WEB_CLIENT, "%llu: generating outfilename header: '%s'", w->id, outFileName); } if(format == DATASOURCE_DATATABLE_JSONP) { if(responseHandler == NULL) responseHandler = "google.visualization.Query.setResponse"; debug(D_WEB_CLIENT_ACCESS, "%llu: GOOGLE JSON/JSONP: version = '%s', reqId = '%s', sig = '%s', out = '%s', responseHandler = '%s', outFileName = '%s'", w->id, google_version, google_reqId, google_sig, google_out, responseHandler, outFileName ); buffer_sprintf(w->response.data, "%s({version:'%s',reqId:'%s',status:'ok',sig:'%ld',table:", responseHandler, google_version, google_reqId, st->last_updated.tv_sec); } else if(format == DATASOURCE_JSONP) { if(responseHandler == NULL) responseHandler = "callback"; buffer_strcat(w->response.data, responseHandler); buffer_strcat(w->response.data, "("); } ret = rrdset2anything_api_v1(st, w->response.data, dimensions, format, points, after, before, group, group_time , options, &last_timestamp_in_data); if(format == DATASOURCE_DATATABLE_JSONP) { if(google_timestamp < last_timestamp_in_data) buffer_strcat(w->response.data, "});"); else { // the client already has the latest data buffer_flush(w->response.data); buffer_sprintf(w->response.data, "%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'not_modified',message:'Data not modified'}]});", responseHandler, google_version, google_reqId); } } else if(format == DATASOURCE_JSONP) buffer_strcat(w->response.data, ");"); cleanup: buffer_free(dimensions); return ret; }
int do_proc_vmstat(int update_every, unsigned long long dt) { static procfile *ff = NULL; static int do_swapio = -1, do_io = -1, do_pgfaults = -1; if(do_swapio == -1) do_swapio = config_get_boolean("plugin:proc:/proc/vmstat", "swap i/o", 1); if(do_io == -1) do_io = config_get_boolean("plugin:proc:/proc/vmstat", "disk i/o", 1); if(do_pgfaults == -1) do_pgfaults = config_get_boolean("plugin:proc:/proc/vmstat", "memory page faults", 1); if(dt) {}; if(!ff) { char filename[FILENAME_MAX + 1]; snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/vmstat"); ff = procfile_open(config_get("plugin:proc:/proc/vmstat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; unsigned long long nr_free_pages = 0, nr_inactive_anon = 0, nr_active_anon = 0, nr_inactive_file = 0, nr_active_file = 0, nr_unevictable = 0, nr_mlock = 0, nr_anon_pages = 0, nr_mapped = 0, nr_file_pages = 0, nr_dirty = 0, nr_writeback = 0, nr_slab_reclaimable = 0, nr_slab_unreclaimable = 0, nr_page_table_pages = 0, nr_kernel_stack = 0, nr_unstable = 0, nr_bounce = 0, nr_vmscan_write = 0, nr_vmscan_immediate_reclaim = 0, nr_writeback_temp = 0, nr_isolated_anon = 0, nr_isolated_file = 0, nr_shmem = 0, nr_dirtied = 0, nr_written = 0, nr_anon_transparent_hugepages = 0, nr_dirty_threshold = 0, nr_dirty_background_threshold = 0, pgpgin = 0, pgpgout = 0, pswpin = 0, pswpout = 0, pgalloc_dma = 0, pgalloc_dma32 = 0, pgalloc_normal = 0, pgalloc_movable = 0, pgfree = 0, pgactivate = 0, pgdeactivate = 0, pgfault = 0, pgmajfault = 0, pgrefill_dma = 0, pgrefill_dma32 = 0, pgrefill_normal = 0, pgrefill_movable = 0, pgsteal_kswapd_dma = 0, pgsteal_kswapd_dma32 = 0, pgsteal_kswapd_normal = 0, pgsteal_kswapd_movable = 0, pgsteal_direct_dma = 0, pgsteal_direct_dma32 = 0, pgsteal_direct_normal = 0, pgsteal_direct_movable = 0, pgscan_kswapd_dma = 0, pgscan_kswapd_dma32 = 0, pgscan_kswapd_normal = 0, pgscan_kswapd_movable = 0, pgscan_direct_dma = 0, pgscan_direct_dma32 = 0, pgscan_direct_normal = 0, pgscan_direct_movable = 0, pginodesteal = 0, slabs_scanned = 0, kswapd_inodesteal = 0, kswapd_low_wmark_hit_quickly = 0, kswapd_high_wmark_hit_quickly = 0, kswapd_skip_congestion_wait = 0, pageoutrun = 0, allocstall = 0, pgrotated = 0, compact_blocks_moved = 0, compact_pages_moved = 0, compact_pagemigrate_failed = 0, compact_stall = 0, compact_fail = 0, compact_success = 0, htlb_buddy_alloc_success = 0, htlb_buddy_alloc_fail = 0, unevictable_pgs_culled = 0, unevictable_pgs_scanned = 0, unevictable_pgs_rescued = 0, unevictable_pgs_mlocked = 0, unevictable_pgs_munlocked = 0, unevictable_pgs_cleared = 0, unevictable_pgs_stranded = 0, unevictable_pgs_mlockfreed = 0, thp_fault_alloc = 0, thp_fault_fallback = 0, thp_collapse_alloc = 0, thp_collapse_alloc_failed = 0, thp_split = 0; for(l = 0; l < lines ;l++) { words = procfile_linewords(ff, l); if(words < 2) { if(words) error("Cannot read /proc/vmstat line %d. Expected 2 params, read %d.", l, words); continue; } char *name = procfile_lineword(ff, l, 0); unsigned long long value = strtoull(procfile_lineword(ff, l, 1), NULL, 10); if(!nr_free_pages && strcmp(name, "nr_free_pages") == 0) nr_free_pages = value; else if(!nr_inactive_anon && strcmp(name, "nr_inactive_anon") == 0) nr_inactive_anon = value; else if(!nr_active_anon && strcmp(name, "nr_active_anon") == 0) nr_active_anon = value; else if(!nr_inactive_file && strcmp(name, "nr_inactive_file") == 0) nr_inactive_file = value; else if(!nr_active_file && strcmp(name, "nr_active_file") == 0) nr_active_file = value; else if(!nr_unevictable && strcmp(name, "nr_unevictable") == 0) nr_unevictable = value; else if(!nr_mlock && strcmp(name, "nr_mlock") == 0) nr_mlock = value; else if(!nr_anon_pages && strcmp(name, "nr_anon_pages") == 0) nr_anon_pages = value; else if(!nr_mapped && strcmp(name, "nr_mapped") == 0) nr_mapped = value; else if(!nr_file_pages && strcmp(name, "nr_file_pages") == 0) nr_file_pages = value; else if(!nr_dirty && strcmp(name, "nr_dirty") == 0) nr_dirty = value; else if(!nr_writeback && strcmp(name, "nr_writeback") == 0) nr_writeback = value; else if(!nr_slab_reclaimable && strcmp(name, "nr_slab_reclaimable") == 0) nr_slab_reclaimable = value; else if(!nr_slab_unreclaimable && strcmp(name, "nr_slab_unreclaimable") == 0) nr_slab_unreclaimable = value; else if(!nr_page_table_pages && strcmp(name, "nr_page_table_pages") == 0) nr_page_table_pages = value; else if(!nr_kernel_stack && strcmp(name, "nr_kernel_stack") == 0) nr_kernel_stack = value; else if(!nr_unstable && strcmp(name, "nr_unstable") == 0) nr_unstable = value; else if(!nr_bounce && strcmp(name, "nr_bounce") == 0) nr_bounce = value; else if(!nr_vmscan_write && strcmp(name, "nr_vmscan_write") == 0) nr_vmscan_write = value; else if(!nr_vmscan_immediate_reclaim && strcmp(name, "nr_vmscan_immediate_reclaim") == 0) nr_vmscan_immediate_reclaim = value; else if(!nr_writeback_temp && strcmp(name, "nr_writeback_temp") == 0) nr_writeback_temp = value; else if(!nr_isolated_anon && strcmp(name, "nr_isolated_anon") == 0) nr_isolated_anon = value; else if(!nr_isolated_file && strcmp(name, "nr_isolated_file") == 0) nr_isolated_file = value; else if(!nr_shmem && strcmp(name, "nr_shmem") == 0) nr_shmem = value; else if(!nr_dirtied && strcmp(name, "nr_dirtied") == 0) nr_dirtied = value; else if(!nr_written && strcmp(name, "nr_written") == 0) nr_written = value; else if(!nr_anon_transparent_hugepages && strcmp(name, "nr_anon_transparent_hugepages") == 0) nr_anon_transparent_hugepages = value; else if(!nr_dirty_threshold && strcmp(name, "nr_dirty_threshold") == 0) nr_dirty_threshold = value; else if(!nr_dirty_background_threshold && strcmp(name, "nr_dirty_background_threshold") == 0) nr_dirty_background_threshold = value; else if(!pgpgin && strcmp(name, "pgpgin") == 0) pgpgin = value; else if(!pgpgout && strcmp(name, "pgpgout") == 0) pgpgout = value; else if(!pswpin && strcmp(name, "pswpin") == 0) pswpin = value; else if(!pswpout && strcmp(name, "pswpout") == 0) pswpout = value; else if(!pgalloc_dma && strcmp(name, "pgalloc_dma") == 0) pgalloc_dma = value; else if(!pgalloc_dma32 && strcmp(name, "pgalloc_dma32") == 0) pgalloc_dma32 = value; else if(!pgalloc_normal && strcmp(name, "pgalloc_normal") == 0) pgalloc_normal = value; else if(!pgalloc_movable && strcmp(name, "pgalloc_movable") == 0) pgalloc_movable = value; else if(!pgfree && strcmp(name, "pgfree") == 0) pgfree = value; else if(!pgactivate && strcmp(name, "pgactivate") == 0) pgactivate = value; else if(!pgdeactivate && strcmp(name, "pgdeactivate") == 0) pgdeactivate = value; else if(!pgfault && strcmp(name, "pgfault") == 0) pgfault = value; else if(!pgmajfault && strcmp(name, "pgmajfault") == 0) pgmajfault = value; else if(!pgrefill_dma && strcmp(name, "pgrefill_dma") == 0) pgrefill_dma = value; else if(!pgrefill_dma32 && strcmp(name, "pgrefill_dma32") == 0) pgrefill_dma32 = value; else if(!pgrefill_normal && strcmp(name, "pgrefill_normal") == 0) pgrefill_normal = value; else if(!pgrefill_movable && strcmp(name, "pgrefill_movable") == 0) pgrefill_movable = value; else if(!pgsteal_kswapd_dma && strcmp(name, "pgsteal_kswapd_dma") == 0) pgsteal_kswapd_dma = value; else if(!pgsteal_kswapd_dma32 && strcmp(name, "pgsteal_kswapd_dma32") == 0) pgsteal_kswapd_dma32 = value; else if(!pgsteal_kswapd_normal && strcmp(name, "pgsteal_kswapd_normal") == 0) pgsteal_kswapd_normal = value; else if(!pgsteal_kswapd_movable && strcmp(name, "pgsteal_kswapd_movable") == 0) pgsteal_kswapd_movable = value; else if(!pgsteal_direct_dma && strcmp(name, "pgsteal_direct_dma") == 0) pgsteal_direct_dma = value; else if(!pgsteal_direct_dma32 && strcmp(name, "pgsteal_direct_dma32") == 0) pgsteal_direct_dma32 = value; else if(!pgsteal_direct_normal && strcmp(name, "pgsteal_direct_normal") == 0) pgsteal_direct_normal = value; else if(!pgsteal_direct_movable && strcmp(name, "pgsteal_direct_movable") == 0) pgsteal_direct_movable = value; else if(!pgscan_kswapd_dma && strcmp(name, "pgscan_kswapd_dma") == 0) pgscan_kswapd_dma = value; else if(!pgscan_kswapd_dma32 && strcmp(name, "pgscan_kswapd_dma32") == 0) pgscan_kswapd_dma32 = value; else if(!pgscan_kswapd_normal && strcmp(name, "pgscan_kswapd_normal") == 0) pgscan_kswapd_normal = value; else if(!pgscan_kswapd_movable && strcmp(name, "pgscan_kswapd_movable") == 0) pgscan_kswapd_movable = value; else if(!pgscan_direct_dma && strcmp(name, "pgscan_direct_dma") == 0) pgscan_direct_dma = value; else if(!pgscan_direct_dma32 && strcmp(name, "pgscan_direct_dma32") == 0) pgscan_direct_dma32 = value; else if(!pgscan_direct_normal && strcmp(name, "pgscan_direct_normal") == 0) pgscan_direct_normal = value; else if(!pgscan_direct_movable && strcmp(name, "pgscan_direct_movable") == 0) pgscan_direct_movable = value; else if(!pginodesteal && strcmp(name, "pginodesteal") == 0) pginodesteal = value; else if(!slabs_scanned && strcmp(name, "slabs_scanned") == 0) slabs_scanned = value; else if(!kswapd_inodesteal && strcmp(name, "kswapd_inodesteal") == 0) kswapd_inodesteal = value; else if(!kswapd_low_wmark_hit_quickly && strcmp(name, "kswapd_low_wmark_hit_quickly") == 0) kswapd_low_wmark_hit_quickly = value; else if(!kswapd_high_wmark_hit_quickly && strcmp(name, "kswapd_high_wmark_hit_quickly") == 0) kswapd_high_wmark_hit_quickly = value; else if(!kswapd_skip_congestion_wait && strcmp(name, "kswapd_skip_congestion_wait") == 0) kswapd_skip_congestion_wait = value; else if(!pageoutrun && strcmp(name, "pageoutrun") == 0) pageoutrun = value; else if(!allocstall && strcmp(name, "allocstall") == 0) allocstall = value; else if(!pgrotated && strcmp(name, "pgrotated") == 0) pgrotated = value; else if(!compact_blocks_moved && strcmp(name, "compact_blocks_moved") == 0) compact_blocks_moved = value; else if(!compact_pages_moved && strcmp(name, "compact_pages_moved") == 0) compact_pages_moved = value; else if(!compact_pagemigrate_failed && strcmp(name, "compact_pagemigrate_failed") == 0) compact_pagemigrate_failed = value; else if(!compact_stall && strcmp(name, "compact_stall") == 0) compact_stall = value; else if(!compact_fail && strcmp(name, "compact_fail") == 0) compact_fail = value; else if(!compact_success && strcmp(name, "compact_success") == 0) compact_success = value; else if(!htlb_buddy_alloc_success && strcmp(name, "htlb_buddy_alloc_success") == 0) htlb_buddy_alloc_success = value; else if(!htlb_buddy_alloc_fail && strcmp(name, "htlb_buddy_alloc_fail") == 0) htlb_buddy_alloc_fail = value; else if(!unevictable_pgs_culled && strcmp(name, "unevictable_pgs_culled") == 0) unevictable_pgs_culled = value; else if(!unevictable_pgs_scanned && strcmp(name, "unevictable_pgs_scanned") == 0) unevictable_pgs_scanned = value; else if(!unevictable_pgs_rescued && strcmp(name, "unevictable_pgs_rescued") == 0) unevictable_pgs_rescued = value; else if(!unevictable_pgs_mlocked && strcmp(name, "unevictable_pgs_mlocked") == 0) unevictable_pgs_mlocked = value; else if(!unevictable_pgs_munlocked && strcmp(name, "unevictable_pgs_munlocked") == 0) unevictable_pgs_munlocked = value; else if(!unevictable_pgs_cleared && strcmp(name, "unevictable_pgs_cleared") == 0) unevictable_pgs_cleared = value; else if(!unevictable_pgs_stranded && strcmp(name, "unevictable_pgs_stranded") == 0) unevictable_pgs_stranded = value; else if(!unevictable_pgs_mlockfreed && strcmp(name, "unevictable_pgs_mlockfreed") == 0) unevictable_pgs_mlockfreed = value; else if(!thp_fault_alloc && strcmp(name, "thp_fault_alloc") == 0) thp_fault_alloc = value; else if(!thp_fault_fallback && strcmp(name, "thp_fault_fallback") == 0) thp_fault_fallback = value; else if(!thp_collapse_alloc && strcmp(name, "thp_collapse_alloc") == 0) thp_collapse_alloc = value; else if(!thp_collapse_alloc_failed && strcmp(name, "thp_collapse_alloc_failed") == 0) thp_collapse_alloc_failed = value; else if(!thp_split && strcmp(name, "thp_split") == 0) thp_split = value; } RRDSET *st; // -------------------------------------------------------------------- if(do_swapio) { st = rrdset_find("system.swapio"); if(!st) { st = rrdset_create("system", "swapio", NULL, "mem", "Swap I/O", "kilobytes/s", 250, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "in", NULL, sysconf(_SC_PAGESIZE), 1024 * update_every, RRDDIM_INCREMENTAL); rrddim_add(st, "out", NULL, -sysconf(_SC_PAGESIZE), 1024 * update_every, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "in", pswpin); rrddim_set(st, "out", pswpout); rrdset_done(st); } // -------------------------------------------------------------------- if(do_io) { st = rrdset_find("system.io"); if(!st) { st = rrdset_create("system", "io", NULL, "disk", "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "in", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL); rrddim_add(st, "out", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "in", pgpgin); rrddim_set(st, "out", pgpgout); rrdset_done(st); } // -------------------------------------------------------------------- if(do_pgfaults) { st = rrdset_find("system.pgfaults"); if(!st) { st = rrdset_create("system", "pgfaults", NULL, "mem", "Memory Page Faults", "page faults/s", 500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "minor", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL); rrddim_add(st, "major", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "minor", pgfault); rrddim_set(st, "major", pgmajfault); rrdset_done(st); } return 0; }
int do_proc_net_snmp(int update_every, usec_t dt) { (void)dt; static procfile *ff = NULL; static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1, do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, do_udp_packets = -1, do_udp_errors = -1, do_icmp_packets = -1, do_icmpmsg = -1, do_udplite_packets = -1; static uint32_t hash_ip = 0, hash_icmp = 0, hash_tcp = 0, hash_udp = 0, hash_icmpmsg = 0, hash_udplite = 0; //static unsigned long long *ip_Forwarding = NULL; //static unsigned long long *ip_DefaultTTL = NULL; static unsigned long long *ip_InReceives = NULL; static unsigned long long *ip_InHdrErrors = NULL; static unsigned long long *ip_InAddrErrors = NULL; static unsigned long long *ip_ForwDatagrams = NULL; static unsigned long long *ip_InUnknownProtos = NULL; static unsigned long long *ip_InDiscards = NULL; static unsigned long long *ip_InDelivers = NULL; static unsigned long long *ip_OutRequests = NULL; static unsigned long long *ip_OutDiscards = NULL; static unsigned long long *ip_OutNoRoutes = NULL; //static unsigned long long *ip_ReasmTimeout = NULL; static unsigned long long *ip_ReasmReqds = NULL; static unsigned long long *ip_ReasmOKs = NULL; static unsigned long long *ip_ReasmFails = NULL; static unsigned long long *ip_FragOKs = NULL; static unsigned long long *ip_FragFails = NULL; static unsigned long long *ip_FragCreates = NULL; static unsigned long long *icmp_InMsgs = NULL; static unsigned long long *icmp_OutMsgs = NULL; static unsigned long long *icmp_InErrors = NULL; static unsigned long long *icmp_OutErrors = NULL; static unsigned long long *icmp_InCsumErrors = NULL; //static unsigned long long *tcp_RtoAlgorithm = NULL; //static unsigned long long *tcp_RtoMin = NULL; //static unsigned long long *tcp_RtoMax = NULL; //static unsigned long long *tcp_MaxConn = NULL; static unsigned long long *tcp_ActiveOpens = NULL; static unsigned long long *tcp_PassiveOpens = NULL; static unsigned long long *tcp_AttemptFails = NULL; static unsigned long long *tcp_EstabResets = NULL; static unsigned long long *tcp_CurrEstab = NULL; static unsigned long long *tcp_InSegs = NULL; static unsigned long long *tcp_OutSegs = NULL; static unsigned long long *tcp_RetransSegs = NULL; static unsigned long long *tcp_InErrs = NULL; static unsigned long long *tcp_OutRsts = NULL; static unsigned long long *tcp_InCsumErrors = NULL; static unsigned long long *udp_InDatagrams = NULL; static unsigned long long *udp_NoPorts = NULL; static unsigned long long *udp_InErrors = NULL; static unsigned long long *udp_OutDatagrams = NULL; static unsigned long long *udp_RcvbufErrors = NULL; static unsigned long long *udp_SndbufErrors = NULL; static unsigned long long *udp_InCsumErrors = NULL; static unsigned long long *udp_IgnoredMulti = NULL; static unsigned long long *udplite_InDatagrams = NULL; static unsigned long long *udplite_NoPorts = NULL; static unsigned long long *udplite_InErrors = NULL; static unsigned long long *udplite_OutDatagrams = NULL; static unsigned long long *udplite_RcvbufErrors = NULL; static unsigned long long *udplite_SndbufErrors = NULL; static unsigned long long *udplite_InCsumErrors = NULL; static unsigned long long *udplite_IgnoredMulti = NULL; if(unlikely(do_ip_packets == -1)) { do_ip_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1); do_ip_fragsout = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments sent", 1); do_ip_fragsin = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1); do_ip_errors = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 errors", 1); do_tcp_sockets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP connections", 1); do_tcp_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP packets", 1); do_tcp_errors = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP errors", 1); do_tcp_handshake = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP handshake issues", 1); do_udp_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP packets", 1); do_udp_errors = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP errors", 1); do_icmp_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 ICMP packets", 1); do_icmpmsg = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 ICMP messages", 1); do_udplite_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDPLite packets", 1); hash_ip = simple_hash("Ip"); hash_tcp = simple_hash("Tcp"); hash_udp = simple_hash("Udp"); hash_icmp = simple_hash("Icmp"); hash_icmpmsg = simple_hash("IcmpMsg"); hash_udplite = simple_hash("UdpLite"); hash_array(ip_data); hash_array(tcp_data); hash_array(udp_data); hash_array(icmp_data); hash_array(icmpmsg_data); hash_array(udplite_data); //ip_Forwarding = netstat_columns_find(ip_data, "Forwarding"); //ip_DefaultTTL = netstat_columns_find(ip_data, "DefaultTTL"); ip_InReceives = netstat_columns_find(ip_data, "InReceives"); ip_InHdrErrors = netstat_columns_find(ip_data, "InHdrErrors"); ip_InAddrErrors = netstat_columns_find(ip_data, "InAddrErrors"); ip_ForwDatagrams = netstat_columns_find(ip_data, "ForwDatagrams"); ip_InUnknownProtos = netstat_columns_find(ip_data, "InUnknownProtos"); ip_InDiscards = netstat_columns_find(ip_data, "InDiscards"); ip_InDelivers = netstat_columns_find(ip_data, "InDelivers"); ip_OutRequests = netstat_columns_find(ip_data, "OutRequests"); ip_OutDiscards = netstat_columns_find(ip_data, "OutDiscards"); ip_OutNoRoutes = netstat_columns_find(ip_data, "OutNoRoutes"); //ip_ReasmTimeout = netstat_columns_find(ip_data, "ReasmTimeout"); ip_ReasmReqds = netstat_columns_find(ip_data, "ReasmReqds"); ip_ReasmOKs = netstat_columns_find(ip_data, "ReasmOKs"); ip_ReasmFails = netstat_columns_find(ip_data, "ReasmFails"); ip_FragOKs = netstat_columns_find(ip_data, "FragOKs"); ip_FragFails = netstat_columns_find(ip_data, "FragFails"); ip_FragCreates = netstat_columns_find(ip_data, "FragCreates"); icmp_InMsgs = netstat_columns_find(icmp_data, "InMsgs"); icmp_OutMsgs = netstat_columns_find(icmp_data, "OutMsgs"); icmp_InErrors = netstat_columns_find(icmp_data, "InErrors"); icmp_OutErrors = netstat_columns_find(icmp_data, "OutErrors"); icmp_InCsumErrors = netstat_columns_find(icmp_data, "InCsumErrors"); //tcp_RtoAlgorithm = netstat_columns_find(tcp_data, "RtoAlgorithm"); //tcp_RtoMin = netstat_columns_find(tcp_data, "RtoMin"); //tcp_RtoMax = netstat_columns_find(tcp_data, "RtoMax"); //tcp_MaxConn = netstat_columns_find(tcp_data, "MaxConn"); tcp_ActiveOpens = netstat_columns_find(tcp_data, "ActiveOpens"); tcp_PassiveOpens = netstat_columns_find(tcp_data, "PassiveOpens"); tcp_AttemptFails = netstat_columns_find(tcp_data, "AttemptFails"); tcp_EstabResets = netstat_columns_find(tcp_data, "EstabResets"); tcp_CurrEstab = netstat_columns_find(tcp_data, "CurrEstab"); tcp_InSegs = netstat_columns_find(tcp_data, "InSegs"); tcp_OutSegs = netstat_columns_find(tcp_data, "OutSegs"); tcp_RetransSegs = netstat_columns_find(tcp_data, "RetransSegs"); tcp_InErrs = netstat_columns_find(tcp_data, "InErrs"); tcp_OutRsts = netstat_columns_find(tcp_data, "OutRsts"); tcp_InCsumErrors = netstat_columns_find(tcp_data, "InCsumErrors"); udp_InDatagrams = netstat_columns_find(udp_data, "InDatagrams"); udp_NoPorts = netstat_columns_find(udp_data, "NoPorts"); udp_InErrors = netstat_columns_find(udp_data, "InErrors"); udp_OutDatagrams = netstat_columns_find(udp_data, "OutDatagrams"); udp_RcvbufErrors = netstat_columns_find(udp_data, "RcvbufErrors"); udp_SndbufErrors = netstat_columns_find(udp_data, "SndbufErrors"); udp_InCsumErrors = netstat_columns_find(udp_data, "InCsumErrors"); udp_IgnoredMulti = netstat_columns_find(udp_data, "IgnoredMulti"); udplite_InDatagrams = netstat_columns_find(udplite_data, "InDatagrams"); udplite_NoPorts = netstat_columns_find(udplite_data, "NoPorts"); udplite_InErrors = netstat_columns_find(udplite_data, "InErrors"); udplite_OutDatagrams = netstat_columns_find(udplite_data, "OutDatagrams"); udplite_RcvbufErrors = netstat_columns_find(udplite_data, "RcvbufErrors"); udplite_SndbufErrors = netstat_columns_find(udplite_data, "SndbufErrors"); udplite_InCsumErrors = netstat_columns_find(udplite_data, "InCsumErrors"); udplite_IgnoredMulti = netstat_columns_find(udplite_data, "IgnoredMulti"); } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/snmp"); ff = procfile_open(config_get("plugin:proc:/proc/net/snmp", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); if(unlikely(!ff)) return 1; } ff = procfile_readall(ff); if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; RRDSET *st; for(l = 0; l < lines ;l++) { char *key = procfile_lineword(ff, l, 0); uint32_t hash = simple_hash(key); if(unlikely(hash == hash_ip && strcmp(key, "Ip") == 0)) { uint32_t h = l++; if(strcmp(procfile_lineword(ff, l, 0), "Ip") != 0) { error("Cannot read Ip line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 3) { error("Cannot read /proc/net/snmp Ip line. Expected 3+ params, read %u.", words); continue; } // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html parse_line_pair(ff, ip_data, h, l); // -------------------------------------------------------------------- if(do_ip_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".packets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s", 3000, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "InReceives", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutRequests", "sent", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "ForwDatagrams", "forwarded", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InDelivers", "delivered", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "OutRequests", *ip_OutRequests); rrddim_set(st, "InReceives", *ip_InReceives); rrddim_set(st, "ForwDatagrams", *ip_ForwDatagrams); rrddim_set(st, "InDelivers", *ip_InDelivers); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ip_fragsout) { st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsout"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent", "packets/s", 3010, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "FragOKs", "ok", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "FragFails", "failed", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "FragCreates", "created", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "FragOKs", *ip_FragOKs); rrddim_set(st, "FragFails", *ip_FragFails); rrddim_set(st, "FragCreates", *ip_FragCreates); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ip_fragsin) { st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsin"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsin", NULL, "fragments", NULL, "IPv4 Fragments Reassembly", "packets/s", 3011, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "ReasmFails", "failed", -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "ReasmReqds", "all", 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "ReasmOKs", *ip_ReasmOKs); rrddim_set(st, "ReasmFails", *ip_ReasmFails); rrddim_set(st, "ReasmReqds", *ip_ReasmReqds); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ip_errors) { st = rrdset_find(RRD_TYPE_NET_SNMP ".errors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s", 3002, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InDiscards", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutDiscards", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InDiscards", *ip_InDiscards); rrddim_set(st, "OutDiscards", *ip_OutDiscards); rrddim_set(st, "InHdrErrors", *ip_InHdrErrors); rrddim_set(st, "InAddrErrors", *ip_InAddrErrors); rrddim_set(st, "InUnknownProtos", *ip_InUnknownProtos); rrddim_set(st, "OutNoRoutes", *ip_OutNoRoutes); rrdset_done(st); } } else if(unlikely(hash == hash_icmp && strcmp(key, "Icmp") == 0)) { uint32_t h = l++; if(strcmp(procfile_lineword(ff, l, 0), "Icmp") != 0) { error("Cannot read Icmp line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 3) { error("Cannot read /proc/net/snmp Icmp line. Expected 3+ params, read %u.", words); continue; } parse_line_pair(ff, icmp_data, h, l); // -------------------------------------------------------------------- if(do_icmp_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".icmp"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets", "packets/s", 2602, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "InMsgs", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutMsgs", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InMsgs", *icmp_InMsgs); rrddim_set(st, "OutMsgs", *icmp_OutMsgs); rrdset_done(st); st = rrdset_find(RRD_TYPE_NET_SNMP ".icmp_errors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "icmp_errors", NULL, "icmp", NULL, "IPv4 ICMP Errors", "packets/s", 2603, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "InErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutErrors", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InErrors", *icmp_InErrors); rrddim_set(st, "OutErrors", *icmp_OutErrors); rrddim_set(st, "InCsumErrors", *icmp_InCsumErrors); rrdset_done(st); } } else if(unlikely(hash == hash_icmpmsg && strcmp(key, "IcmpMsg") == 0)) { uint32_t h = l++; if(strcmp(procfile_lineword(ff, l, 0), "IcmpMsg") != 0) { error("Cannot read IcmpMsg line from /proc/net/snmp."); break; } parse_line_pair(ff, icmpmsg_data, h, l); // -------------------------------------------------------------------- if(do_icmpmsg) { int i; st = rrdset_find(RRD_TYPE_NET_SNMP ".icmpmsg"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messsages", "packets/s", 2604, update_every, RRDSET_TYPE_LINE); for(i = 0; icmpmsg_data[i].name ;i++) rrddim_add(st, icmpmsg_data[i].name, icmpmsg_data[i].label, icmpmsg_data[i].multiplier, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); for(i = 0; icmpmsg_data[i].name ;i++) rrddim_set(st, icmpmsg_data[i].name, icmpmsg_data[i].value); rrdset_done(st); } } else if(unlikely(hash == hash_tcp && strcmp(key, "Tcp") == 0)) { uint32_t h = l++; if(strcmp(procfile_lineword(ff, l, 0), "Tcp") != 0) { error("Cannot read Tcp line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 3) { error("Cannot read /proc/net/snmp Tcp line. Expected 3+ params, read %u.", words); continue; } parse_line_pair(ff, tcp_data, h, l); // -------------------------------------------------------------------- // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html if(do_tcp_sockets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", NULL, "IPv4 TCP Connections", "active connections", 2500, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "CurrEstab", "connections", 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "CurrEstab", *tcp_CurrEstab); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcp_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets", "packets/s", 2600, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "InSegs", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutSegs", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InSegs", *tcp_InSegs); rrddim_set(st, "OutSegs", *tcp_OutSegs); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcp_errors) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors", "packets/s", 2700, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InErrs", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "RetransSegs", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InErrs", *tcp_InErrs); rrddim_set(st, "InCsumErrors", *tcp_InCsumErrors); rrddim_set(st, "RetransSegs", *tcp_RetransSegs); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcp_handshake) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcphandshake", NULL, "tcp", NULL, "IPv4 TCP Handshake Issues", "events/s", 2900, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "EstabResets", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutRsts", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "AttemptFails", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "EstabResets", *tcp_EstabResets); rrddim_set(st, "OutRsts", *tcp_OutRsts); rrddim_set(st, "ActiveOpens", *tcp_ActiveOpens); rrddim_set(st, "PassiveOpens", *tcp_PassiveOpens); rrddim_set(st, "AttemptFails", *tcp_AttemptFails); rrdset_done(st); } } else if(unlikely(hash == hash_udp && strcmp(key, "Udp") == 0)) { uint32_t h = l++; if(strcmp(procfile_lineword(ff, l, 0), "Udp") != 0) { error("Cannot read Udp line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 3) { error("Cannot read /proc/net/snmp Udp line. Expected 3+ params, read %u.", words); continue; } parse_line_pair(ff, udp_data, h, l); // -------------------------------------------------------------------- // see http://net-snmp.sourceforge.net/docs/mibs/udp.html if(do_udp_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets", "packets/s", 2601, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "InDatagrams", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InDatagrams", *udp_InDatagrams); rrddim_set(st, "OutDatagrams", *udp_OutDatagrams); rrdset_done(st); } // -------------------------------------------------------------------- if(do_udp_errors) { st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s", 2701, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "NoPorts", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InErrors", *udp_InErrors); rrddim_set(st, "NoPorts", *udp_NoPorts); rrddim_set(st, "RcvbufErrors", *udp_RcvbufErrors); rrddim_set(st, "SndbufErrors", *udp_SndbufErrors); rrddim_set(st, "InCsumErrors", *udp_InCsumErrors); rrddim_set(st, "IgnoredMulti", *udp_IgnoredMulti); rrdset_done(st); } } else if(unlikely(hash == hash_udplite && strcmp(key, "UdpLite") == 0)) { uint32_t h = l++; if(strcmp(procfile_lineword(ff, l, 0), "UdpLite") != 0) { error("Cannot read UdpLite line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 3) { error("Cannot read /proc/net/snmp UdpLite line. Expected 3+ params, read %u.", words); continue; } parse_line_pair(ff, udplite_data, h, l); // -------------------------------------------------------------------- if(do_udplite_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".udplite"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "udplite", NULL, "udplite", NULL, "IPv4 UDPLite Packets", "packets/s", 2603, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "InDatagrams", "received", 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InDatagrams", *udplite_InDatagrams); rrddim_set(st, "OutDatagrams", *udplite_OutDatagrams); rrdset_done(st); st = rrdset_find(RRD_TYPE_NET_SNMP ".udplite_errors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "udplite_errors", NULL, "udplite", NULL, "IPv4 UDPLite Errors", "packets/s", 2604, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "NoPorts", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "NoPorts", *udplite_NoPorts); rrddim_set(st, "InErrors", *udplite_InErrors); rrddim_set(st, "InCsumErrors", *udplite_InCsumErrors); rrddim_set(st, "RcvbufErrors", *udplite_RcvbufErrors); rrddim_set(st, "SndbufErrors", *udplite_SndbufErrors); rrddim_set(st, "IgnoredMulti", *udplite_IgnoredMulti); rrdset_done(st); } } } return 0; }
int do_proc_net_stat_conntrack(int update_every, unsigned long long dt) { static procfile *ff = NULL; static int do_sockets = -1, do_new = -1, do_changes = -1, do_expect = -1, do_search = -1, do_errors = -1; if(do_sockets == -1) do_sockets = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connections", 1); if(do_new == -1) do_new = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter new connections", 1); if(do_changes == -1) do_changes = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection changes", 1); if(do_expect == -1) do_expect = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection expectations", 1); if(do_search == -1) do_search = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection searches", 1); if(do_errors == -1) do_errors = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter errors", 1); if(dt) {}; if(!ff) { char filename[FILENAME_MAX + 1]; snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/stat/nf_conntrack"); ff = procfile_open(config_get("plugin:proc:/proc/net/stat/nf_conntrack", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; unsigned long long aentries = 0, asearched = 0, afound = 0, anew = 0, ainvalid = 0, aignore = 0, adelete = 0, adelete_list = 0, ainsert = 0, ainsert_failed = 0, adrop = 0, aearly_drop = 0, aicmp_error = 0, aexpect_new = 0, aexpect_create = 0, aexpect_delete = 0, asearch_restart = 0; for(l = 1; l < lines ;l++) { words = procfile_linewords(ff, l); if(words < 17) { if(words) error("Cannot read /proc/net/stat/nf_conntrack line. Expected 17 params, read %d.", words); continue; } unsigned long long tentries = 0, tsearched = 0, tfound = 0, tnew = 0, tinvalid = 0, tignore = 0, tdelete = 0, tdelete_list = 0, tinsert = 0, tinsert_failed = 0, tdrop = 0, tearly_drop = 0, ticmp_error = 0, texpect_new = 0, texpect_create = 0, texpect_delete = 0, tsearch_restart = 0; tentries = strtoull(procfile_lineword(ff, l, 0), NULL, 16); tsearched = strtoull(procfile_lineword(ff, l, 1), NULL, 16); tfound = strtoull(procfile_lineword(ff, l, 2), NULL, 16); tnew = strtoull(procfile_lineword(ff, l, 3), NULL, 16); tinvalid = strtoull(procfile_lineword(ff, l, 4), NULL, 16); tignore = strtoull(procfile_lineword(ff, l, 5), NULL, 16); tdelete = strtoull(procfile_lineword(ff, l, 6), NULL, 16); tdelete_list = strtoull(procfile_lineword(ff, l, 7), NULL, 16); tinsert = strtoull(procfile_lineword(ff, l, 8), NULL, 16); tinsert_failed = strtoull(procfile_lineword(ff, l, 9), NULL, 16); tdrop = strtoull(procfile_lineword(ff, l, 10), NULL, 16); tearly_drop = strtoull(procfile_lineword(ff, l, 11), NULL, 16); ticmp_error = strtoull(procfile_lineword(ff, l, 12), NULL, 16); texpect_new = strtoull(procfile_lineword(ff, l, 13), NULL, 16); texpect_create = strtoull(procfile_lineword(ff, l, 14), NULL, 16); texpect_delete = strtoull(procfile_lineword(ff, l, 15), NULL, 16); tsearch_restart = strtoull(procfile_lineword(ff, l, 16), NULL, 16); if(!aentries) aentries = tentries; // sum all the cpus together asearched += tsearched; // conntrack.search afound += tfound; // conntrack.search anew += tnew; // conntrack.new ainvalid += tinvalid; // conntrack.new aignore += tignore; // conntrack.new adelete += tdelete; // conntrack.changes adelete_list += tdelete_list; // conntrack.changes ainsert += tinsert; // conntrack.changes ainsert_failed += tinsert_failed; // conntrack.errors adrop += tdrop; // conntrack.errors aearly_drop += tearly_drop; // conntrack.errors aicmp_error += ticmp_error; // conntrack.errors aexpect_new += texpect_new; // conntrack.expect aexpect_create += texpect_create; // conntrack.expect aexpect_delete += texpect_delete; // conntrack.expect asearch_restart += tsearch_restart; // conntrack.search } RRDSET *st; // -------------------------------------------------------------------- if(do_sockets) { st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_sockets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_sockets", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Connections", "active connections", 1000, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "connections", aentries); rrdset_done(st); } // -------------------------------------------------------------------- if(do_new) { st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_new"); if(!st) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_new", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker New Connections", "connections/s", 1001, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "new", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "ignore", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "invalid", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "new", anew); rrddim_set(st, "ignore", aignore); rrddim_set(st, "invalid", ainvalid); rrdset_done(st); } // -------------------------------------------------------------------- if(do_changes) { st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_changes"); if(!st) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_changes", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Changes", "changes/s", 1002, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "inserted", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "deleted", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "delete_list", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "inserted", ainsert); rrddim_set(st, "deleted", adelete); rrddim_set(st, "delete_list", adelete_list); rrdset_done(st); } // -------------------------------------------------------------------- if(do_expect) { st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_expect"); if(!st) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_expect", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Expectations", "expectations/s", 1003, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "created", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "deleted", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "new", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "created", aexpect_create); rrddim_set(st, "deleted", aexpect_delete); rrddim_set(st, "new", aexpect_new); rrdset_done(st); } // -------------------------------------------------------------------- if(do_search) { st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_search"); if(!st) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_search", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Searches", "searches/s", 1010, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "searched", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "restarted", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "found", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "searched", asearched); rrddim_set(st, "restarted", asearch_restart); rrddim_set(st, "found", afound); rrdset_done(st); } // -------------------------------------------------------------------- if(do_errors) { st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_errors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_errors", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Errors", "events/s", 1005, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "icmp_error", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "insert_failed", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "drop", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "early_drop", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "icmp_error", aicmp_error); rrddim_set(st, "insert_failed", ainsert_failed); rrddim_set(st, "drop", adrop); rrddim_set(st, "early_drop", aearly_drop); rrdset_done(st); } return 0; }
void *pluginsd_worker_thread(void *arg) { struct plugind *cd = (struct plugind *)arg; char line[PLUGINSD_LINE_MAX + 1]; #ifdef DETACH_PLUGINS_FROM_NETDATA unsigned long long usec = 0, susec = 0; struct timeval last = {0, 0} , now = {0, 0}; #endif char *words[MAX_WORDS] = { NULL }; uint32_t SET_HASH = simple_hash("SET"); uint32_t BEGIN_HASH = simple_hash("BEGIN"); uint32_t END_HASH = simple_hash("END"); uint32_t FLUSH_HASH = simple_hash("FLUSH"); uint32_t CHART_HASH = simple_hash("CHART"); uint32_t DIMENSION_HASH = simple_hash("DIMENSION"); uint32_t DISABLE_HASH = simple_hash("DISABLE"); #ifdef DETACH_PLUGINS_FROM_NETDATA uint32_t MYPID_HASH = simple_hash("MYPID"); uint32_t STOPPING_WAKE_ME_UP_PLEASE_HASH = simple_hash("STOPPING_WAKE_ME_UP_PLEASE"); #endif while(likely(1)) { if(unlikely(netdata_exit)) break; FILE *fp = mypopen(cd->cmd, &cd->pid); if(unlikely(!fp)) { error("Cannot popen(\"%s\", \"r\").", cd->cmd); break; } info("PLUGINSD: '%s' running on pid %d", cd->fullfilename, cd->pid); RRDSET *st = NULL; unsigned long long count = 0; char *s; uint32_t hash; while(likely(fgets(line, PLUGINSD_LINE_MAX, fp) != NULL)) { if(unlikely(netdata_exit)) break; line[PLUGINSD_LINE_MAX] = '\0'; // debug(D_PLUGINSD, "PLUGINSD: %s: %s", cd->filename, line); int w = pluginsd_split_words(line, words, MAX_WORDS); s = words[0]; if(unlikely(!s || !*s || !w)) { // debug(D_PLUGINSD, "PLUGINSD: empty line"); continue; } // debug(D_PLUGINSD, "PLUGINSD: words 0='%s' 1='%s' 2='%s' 3='%s' 4='%s' 5='%s' 6='%s' 7='%s' 8='%s' 9='%s'", words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]); hash = simple_hash(s); if(likely(hash == SET_HASH && !strcmp(s, "SET"))) { char *dimension = words[1]; char *value = words[2]; if(unlikely(!dimension || !*dimension)) { error("PLUGINSD: '%s' is requesting a SET on chart '%s', without a dimension. Disabling it.", cd->fullfilename, st->id); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } if(unlikely(!value || !*value)) value = NULL; if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value?value:"<nothing>"); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value?value:"<nothing>"); if(value) rrddim_set(st, dimension, atoll(value)); count++; } else if(likely(hash == BEGIN_HASH && !strcmp(s, "BEGIN"))) { char *id = words[1]; char *microseconds_txt = words[2]; if(unlikely(!id)) { error("PLUGINSD: '%s' is requesting a BEGIN without a chart id. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } st = rrdset_find(id); if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting a BEGIN on chart '%s', which does not exist. Disabling it.", cd->fullfilename, id); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } if(likely(st->counter_done)) { unsigned long long microseconds = 0; if(microseconds_txt && *microseconds_txt) microseconds = strtoull(microseconds_txt, NULL, 10); if(microseconds) rrdset_next_usec(st, microseconds); else rrdset_next_plugins(st); } } else if(likely(hash == END_HASH && !strcmp(s, "END"))) { if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting an END, without a BEGIN. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a END on chart %s", cd->fullfilename, st->id); rrdset_done(st); st = NULL; } else if(likely(hash == FLUSH_HASH && !strcmp(s, "FLUSH"))) { debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a FLUSH", cd->fullfilename); st = NULL; } else if(likely(hash == CHART_HASH && !strcmp(s, "CHART"))) { st = NULL; char *type = words[1]; char *id = NULL; if(likely(type)) { id = strchr(type, '.'); if(likely(id)) { *id = '\0'; id++; } } char *name = words[2]; char *title = words[3]; char *units = words[4]; char *family = words[5]; char *category = words[6]; char *chart = words[7]; char *priority_s = words[8]; char *update_every_s = words[9]; if(unlikely(!type || !*type || !id || !*id)) { error("PLUGINSD: '%s' is requesting a CHART, without a type.id. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } int priority = 1000; if(likely(priority_s)) priority = atoi(priority_s); int update_every = cd->update_every; if(likely(update_every_s)) update_every = atoi(update_every_s); if(unlikely(!update_every)) update_every = cd->update_every; int chart_type = RRDSET_TYPE_LINE; if(unlikely(chart)) chart_type = rrdset_type_id(chart); if(unlikely(!name || !*name)) name = NULL; if(unlikely(!family || !*family)) family = id; if(unlikely(!category || !*category)) category = type; st = rrdset_find_bytype(type, id); if(unlikely(!st)) { debug(D_PLUGINSD, "PLUGINSD: Creating chart type='%s', id='%s', name='%s', family='%s', category='%s', chart='%s', priority=%d, update_every=%d" , type, id , name?name:"" , family?family:"" , category?category:"" , rrdset_type_name(chart_type) , priority , update_every ); st = rrdset_create(type, id, name, family, title, units, priority, update_every, chart_type); cd->update_every = update_every; if(unlikely(strcmp(category, "none") == 0)) st->isdetail = 1; } else debug(D_PLUGINSD, "PLUGINSD: Chart '%s' already exists. Not adding it again.", st->id); } else if(likely(hash == DIMENSION_HASH && !strcmp(s, "DIMENSION"))) { char *id = words[1]; char *name = words[2]; char *algorithm = words[3]; char *multiplier_s = words[4]; char *divisor_s = words[5]; char *options = words[6]; if(unlikely(!id || !*id)) { error("PLUGINSD: '%s' is requesting a DIMENSION, without an id. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting a DIMENSION, without a CHART. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } long multiplier = 1; if(multiplier_s && *multiplier_s) multiplier = atol(multiplier_s); if(unlikely(!multiplier)) multiplier = 1; long divisor = 1; if(likely(divisor_s && *divisor_s)) divisor = atol(divisor_s); if(unlikely(!divisor)) divisor = 1; if(unlikely(!algorithm || !*algorithm)) algorithm = "absolute"; if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: Creating dimension in chart %s, id='%s', name='%s', algorithm='%s', multiplier=%ld, divisor=%ld, hidden='%s'" , st->id , id , name?name:"" , rrddim_algorithm_name(rrddim_algorithm_id(algorithm)) , multiplier , divisor , options?options:"" ); RRDDIM *rd = rrddim_find(st, id); if(unlikely(!rd)) { rd = rrddim_add(st, id, name, multiplier, divisor, rrddim_algorithm_id(algorithm)); rd->flags = 0x00000000; if(options && *options) { if(strstr(options, "hidden") != NULL) rd->flags |= RRDDIM_FLAG_HIDDEN; if(strstr(options, "noreset") != NULL) rd->flags |= RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS; if(strstr(options, "nooverflow") != NULL) rd->flags |= RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS; } } else if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: dimension %s/%s already exists. Not adding it again.", st->id, id); } else if(unlikely(hash == DISABLE_HASH && !strcmp(s, "DISABLE"))) { error("PLUGINSD: '%s' called DISABLE. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } #ifdef DETACH_PLUGINS_FROM_NETDATA else if(likely(hash == MYPID_HASH && !strcmp(s, "MYPID"))) { char *pid_s = words[1]; pid_t pid = atol(pid_s); if(likely(pid)) cd->pid = pid; debug(D_PLUGINSD, "PLUGINSD: %s is on pid %d", cd->id, cd->pid); } else if(likely(hash == STOPPING_WAKE_ME_UP_PLEASE_HASH && !strcmp(s, "STOPPING_WAKE_ME_UP_PLEASE"))) { error("PLUGINSD: '%s' (pid %d) called STOPPING_WAKE_ME_UP_PLEASE.", cd->fullfilename, cd->pid); gettimeofday(&now, NULL); if(unlikely(!usec && !susec)) { // our first run susec = cd->rrd_update_every * 1000000ULL; } else { // second+ run usec = usecdiff(&now, &last) - susec; error("PLUGINSD: %s last loop took %llu usec (worked for %llu, sleeped for %llu).\n", cd->fullfilename, usec + susec, usec, susec); if(unlikely(usec < (rrd_update_every * 1000000ULL / 2ULL))) susec = (rrd_update_every * 1000000ULL) - usec; else susec = rrd_update_every * 1000000ULL / 2ULL; } error("PLUGINSD: %s sleeping for %llu. Will kill with SIGCONT pid %d to wake it up.\n", cd->fullfilename, susec, cd->pid); usleep(susec); killpid(cd->pid, SIGCONT); bcopy(&now, &last, sizeof(struct timeval)); break; } #endif else { error("PLUGINSD: '%s' is sending command '%s' which is not known by netdata. Disabling it.", cd->fullfilename, s); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } } info("PLUGINSD: '%s' on pid %d stopped.", cd->fullfilename, cd->pid); // fgets() failed or loop broke int code = mypclose(fp, cd->pid); if(code == 1 || code == 127) { // 1 = DISABLE // 127 = cannot even run it error("PLUGINSD: '%s' (pid %d) exited with code %d. Disabling it.", cd->fullfilename, cd->pid, code); cd->enabled = 0; } if(netdata_exit) { cd->pid = 0; cd->enabled = 0; cd->obsolete = 1; return NULL; } if(unlikely(!count && cd->enabled)) { error("PLUGINSD: '%s' (pid %d) does not generate usefull output. Waiting a bit before starting it again.", cd->fullfilename, cd->pid); sleep((unsigned int) (cd->update_every * 10)); } cd->pid = 0; if(likely(cd->enabled)) sleep((unsigned int) cd->update_every); else break; } cd->obsolete = 1; return NULL; }
int do_proc_net_stat_synproxy(int update_every, unsigned long long dt) { (void)dt; static int do_entries = -1, do_cookies = -1, do_syns = -1, do_reopened = -1; static procfile *ff = NULL; if(unlikely(do_entries == -1)) { do_entries = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY entries", CONFIG_ONDEMAND_ONDEMAND); do_cookies = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY cookies", CONFIG_ONDEMAND_ONDEMAND); do_syns = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY SYN received", CONFIG_ONDEMAND_ONDEMAND); do_reopened = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY connections reopened", CONFIG_ONDEMAND_ONDEMAND); } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/stat/synproxy"); ff = procfile_open(config_get("plugin:proc:/proc/net/stat/synproxy", "filename to monitor", filename), " \t,:|", PROCFILE_FLAG_DEFAULT); if(unlikely(!ff)) return 1; } ff = procfile_readall(ff); if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time // make sure we have 3 lines size_t lines = procfile_lines(ff), l; if(unlikely(lines < 2)) { error("/proc/net/stat/synproxy has %zu lines, expected no less than 2. Disabling it.", lines); return 1; } unsigned long long entries = 0, syn_received = 0, cookie_invalid = 0, cookie_valid = 0, cookie_retrans = 0, conn_reopened = 0; // synproxy gives its values per CPU for(l = 1; l < lines ;l++) { int words = procfile_linewords(ff, l); if(unlikely(words < 6)) continue; entries += strtoull(procfile_lineword(ff, l, 0), NULL, 16); syn_received += strtoull(procfile_lineword(ff, l, 1), NULL, 16); cookie_invalid += strtoull(procfile_lineword(ff, l, 2), NULL, 16); cookie_valid += strtoull(procfile_lineword(ff, l, 3), NULL, 16); cookie_retrans += strtoull(procfile_lineword(ff, l, 4), NULL, 16); conn_reopened += strtoull(procfile_lineword(ff, l, 5), NULL, 16); } unsigned long long events = entries + syn_received + cookie_invalid + cookie_valid + cookie_retrans + conn_reopened; RRDSET *st; // -------------------------------------------------------------------- if((do_entries == CONFIG_ONDEMAND_ONDEMAND && events) || do_entries == CONFIG_ONDEMAND_YES) { do_entries = CONFIG_ONDEMAND_YES; st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_entries"); if(unlikely(!st)) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_entries", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY Entries Used", "entries", 3304, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "entries", NULL, 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "entries", entries); rrdset_done(st); } // -------------------------------------------------------------------- if((do_syns == CONFIG_ONDEMAND_ONDEMAND && events) || do_syns == CONFIG_ONDEMAND_YES) { do_syns = CONFIG_ONDEMAND_YES; st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_syn_received"); if(unlikely(!st)) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_syn_received", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY SYN Packets received", "SYN/s", 3301, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "received", syn_received); rrdset_done(st); } // -------------------------------------------------------------------- if((do_reopened == CONFIG_ONDEMAND_ONDEMAND && events) || do_reopened == CONFIG_ONDEMAND_YES) { do_reopened = CONFIG_ONDEMAND_YES; st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened"); if(unlikely(!st)) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY Connections Reopened", "connections/s", 3303, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "reopened", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "reopened", conn_reopened); rrdset_done(st); } // -------------------------------------------------------------------- if((do_cookies == CONFIG_ONDEMAND_ONDEMAND && events) || do_cookies == CONFIG_ONDEMAND_YES) { do_cookies = CONFIG_ONDEMAND_YES; st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_cookies"); if(unlikely(!st)) { st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_cookies", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY TCP Cookies", "cookies/s", 3302, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "valid", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "invalid", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "retransmits", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "valid", cookie_valid); rrddim_set(st, "invalid", cookie_invalid); rrddim_set(st, "retransmits", cookie_retrans); rrdset_done(st); } return 0; }
int do_proc_net_netstat(int update_every, unsigned long long dt) { static int do_bandwidth = -1, do_inerrors = -1, do_mcast = -1, do_bcast = -1, do_mcast_p = -1, do_bcast_p = -1; static procfile *ff = NULL; if(do_bandwidth == -1) do_bandwidth = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "bandwidth", CONFIG_ONDEMAND_ONDEMAND); if(do_inerrors == -1) do_inerrors = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "input errors", CONFIG_ONDEMAND_ONDEMAND); if(do_mcast == -1) do_mcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast bandwidth", CONFIG_ONDEMAND_ONDEMAND); if(do_bcast == -1) do_bcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast bandwidth", CONFIG_ONDEMAND_ONDEMAND); if(do_mcast_p == -1) do_mcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast packets", CONFIG_ONDEMAND_ONDEMAND); if(do_bcast_p == -1) do_bcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast packets", CONFIG_ONDEMAND_ONDEMAND); if(dt) {}; if(!ff) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/netstat"); ff = procfile_open(config_get("plugin:proc:/proc/net/netstat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; for(l = 0; l < lines ;l++) { if(strcmp(procfile_lineword(ff, l, 0), "IpExt") == 0) { l++; // we need the next line if(strcmp(procfile_lineword(ff, l, 0), "IpExt") != 0) { error("Cannot read IpExt line from /proc/net/netstat."); break; } words = procfile_linewords(ff, l); if(words < 12) { error("Cannot read /proc/net/netstat IpExt line. Expected 12 params, read %d.", words); continue; } unsigned long long InNoRoutes = 0, InTruncatedPkts = 0, InOctets = 0, InMcastPkts = 0, InBcastPkts = 0, InMcastOctets = 0, InBcastOctets = 0, OutOctets = 0, OutMcastPkts = 0, OutBcastPkts = 0, OutMcastOctets = 0, OutBcastOctets = 0; InNoRoutes = strtoull(procfile_lineword(ff, l, 1), NULL, 10); InTruncatedPkts = strtoull(procfile_lineword(ff, l, 2), NULL, 10); InMcastPkts = strtoull(procfile_lineword(ff, l, 3), NULL, 10); OutMcastPkts = strtoull(procfile_lineword(ff, l, 4), NULL, 10); InBcastPkts = strtoull(procfile_lineword(ff, l, 5), NULL, 10); OutBcastPkts = strtoull(procfile_lineword(ff, l, 6), NULL, 10); InOctets = strtoull(procfile_lineword(ff, l, 7), NULL, 10); OutOctets = strtoull(procfile_lineword(ff, l, 8), NULL, 10); InMcastOctets = strtoull(procfile_lineword(ff, l, 9), NULL, 10); OutMcastOctets = strtoull(procfile_lineword(ff, l, 10), NULL, 10); InBcastOctets = strtoull(procfile_lineword(ff, l, 11), NULL, 10); OutBcastOctets = strtoull(procfile_lineword(ff, l, 12), NULL, 10); RRDSET *st; // -------------------------------------------------------------------- if(do_bandwidth == CONFIG_ONDEMAND_YES || (do_bandwidth == CONFIG_ONDEMAND_ONDEMAND && (InOctets || OutOctets))) { do_bandwidth = CONFIG_ONDEMAND_YES; st = rrdset_find("system.ipv4"); if(!st) { st = rrdset_create("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "received", NULL, 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "sent", OutOctets); rrddim_set(st, "received", InOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_inerrors == CONFIG_ONDEMAND_YES || (do_inerrors == CONFIG_ONDEMAND_ONDEMAND && (InNoRoutes || InTruncatedPkts))) { do_inerrors = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.inerrors"); if(!st) { st = rrdset_create("ipv4", "inerrors", NULL, "errors", NULL, "IPv4 Input Errors", "packets/s", 4000, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "noroutes", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "truncated", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "noroutes", InNoRoutes); rrddim_set(st, "truncated", InTruncatedPkts); rrdset_done(st); } // -------------------------------------------------------------------- if(do_mcast == CONFIG_ONDEMAND_YES || (do_mcast == CONFIG_ONDEMAND_ONDEMAND && (InMcastOctets || OutMcastOctets))) { do_mcast = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.mcast"); if(!st) { st = rrdset_create("ipv4", "mcast", NULL, "multicast", NULL, "IPv4 Multicast Bandwidth", "kilobits/s", 9000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "received", NULL, 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "sent", OutMcastOctets); rrddim_set(st, "received", InMcastOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bcast == CONFIG_ONDEMAND_YES || (do_bcast == CONFIG_ONDEMAND_ONDEMAND && (InBcastOctets || OutBcastOctets))) { do_bcast = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.bcast"); if(!st) { st = rrdset_create("ipv4", "bcast", NULL, "broadcast", NULL, "IPv4 Broadcast Bandwidth", "kilobits/s", 8000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "received", NULL, 8, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -8, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "sent", OutBcastOctets); rrddim_set(st, "received", InBcastOctets); rrdset_done(st); } // -------------------------------------------------------------------- if(do_mcast_p == CONFIG_ONDEMAND_YES || (do_mcast_p == CONFIG_ONDEMAND_ONDEMAND && (InMcastPkts || OutMcastPkts))) { do_mcast_p = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.mcastpkts"); if(!st) { st = rrdset_create("ipv4", "mcastpkts", NULL, "multicast", NULL, "IPv4 Multicast Packets", "packets/s", 9500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "sent", OutMcastPkts); rrddim_set(st, "received", InMcastPkts); rrdset_done(st); } // -------------------------------------------------------------------- if(do_bcast_p == CONFIG_ONDEMAND_YES || (do_bcast_p == CONFIG_ONDEMAND_ONDEMAND && (InBcastPkts || OutBcastPkts))) { do_bcast_p = CONFIG_ONDEMAND_YES; st = rrdset_find("ipv4.bcastpkts"); if(!st) { st = rrdset_create("ipv4", "bcastpkts", NULL, "broadcast", NULL, "IPv4 Broadcast Packets", "packets/s", 8500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "sent", OutBcastPkts); rrddim_set(st, "received", InBcastPkts); rrdset_done(st); } } } return 0; }
int do_proc_meminfo(int update_every, unsigned long long dt) { static procfile *ff = NULL; static int do_ram = -1, do_swap = -1, do_hwcorrupt = -1, do_committed = -1, do_writeback = -1, do_kernel = -1, do_slab = -1; if(do_ram == -1) do_ram = config_get_boolean("plugin:proc:/proc/meminfo", "system ram", 1); if(do_swap == -1) do_swap = config_get_boolean("plugin:proc:/proc/meminfo", "system swap", 1); if(do_hwcorrupt == -1) do_hwcorrupt = config_get_boolean_ondemand("plugin:proc:/proc/meminfo", "hardware corrupted ECC", CONFIG_ONDEMAND_ONDEMAND); if(do_committed == -1) do_committed = config_get_boolean("plugin:proc:/proc/meminfo", "committed memory", 1); if(do_writeback == -1) do_writeback = config_get_boolean("plugin:proc:/proc/meminfo", "writeback memory", 1); if(do_kernel == -1) do_kernel = config_get_boolean("plugin:proc:/proc/meminfo", "kernel memory", 1); if(do_slab == -1) do_slab = config_get_boolean("plugin:proc:/proc/meminfo", "slab memory", 1); if(dt) {}; if(!ff) { char filename[FILENAME_MAX + 1]; snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/meminfo"); ff = procfile_open(config_get("plugin:proc:/proc/meminfo", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; int hwcorrupted = 0; unsigned long long MemTotal = 0, MemFree = 0, Buffers = 0, Cached = 0, SwapCached = 0, Active = 0, Inactive = 0, ActiveAnon = 0, InactiveAnon = 0, ActiveFile = 0, InactiveFile = 0, Unevictable = 0, Mlocked = 0, SwapTotal = 0, SwapFree = 0, Dirty = 0, Writeback = 0, AnonPages = 0, Mapped = 0, Shmem = 0, Slab = 0, SReclaimable = 0, SUnreclaim = 0, KernelStack = 0, PageTables = 0, NFS_Unstable = 0, Bounce = 0, WritebackTmp = 0, CommitLimit = 0, Committed_AS = 0, VmallocTotal = 0, VmallocUsed = 0, VmallocChunk = 0, AnonHugePages = 0, HugePages_Total = 0, HugePages_Free = 0, HugePages_Rsvd = 0, HugePages_Surp = 0, Hugepagesize = 0, DirectMap4k = 0, DirectMap2M = 0, HardwareCorrupted = 0; for(l = 0; l < lines ;l++) { words = procfile_linewords(ff, l); if(words < 2) continue; char *name = procfile_lineword(ff, l, 0); unsigned long long value = strtoull(procfile_lineword(ff, l, 1), NULL, 10); if(!MemTotal && strcmp(name, "MemTotal") == 0) MemTotal = value; else if(!MemFree && strcmp(name, "MemFree") == 0) MemFree = value; else if(!Buffers && strcmp(name, "Buffers") == 0) Buffers = value; else if(!Cached && strcmp(name, "Cached") == 0) Cached = value; else if(!SwapCached && strcmp(name, "SwapCached") == 0) SwapCached = value; else if(!Active && strcmp(name, "Active") == 0) Active = value; else if(!Inactive && strcmp(name, "Inactive") == 0) Inactive = value; else if(!ActiveAnon && strcmp(name, "ActiveAnon") == 0) ActiveAnon = value; else if(!InactiveAnon && strcmp(name, "InactiveAnon") == 0) InactiveAnon = value; else if(!ActiveFile && strcmp(name, "ActiveFile") == 0) ActiveFile = value; else if(!InactiveFile && strcmp(name, "InactiveFile") == 0) InactiveFile = value; else if(!Unevictable && strcmp(name, "Unevictable") == 0) Unevictable = value; else if(!Mlocked && strcmp(name, "Mlocked") == 0) Mlocked = value; else if(!SwapTotal && strcmp(name, "SwapTotal") == 0) SwapTotal = value; else if(!SwapFree && strcmp(name, "SwapFree") == 0) SwapFree = value; else if(!Dirty && strcmp(name, "Dirty") == 0) Dirty = value; else if(!Writeback && strcmp(name, "Writeback") == 0) Writeback = value; else if(!AnonPages && strcmp(name, "AnonPages") == 0) AnonPages = value; else if(!Mapped && strcmp(name, "Mapped") == 0) Mapped = value; else if(!Shmem && strcmp(name, "Shmem") == 0) Shmem = value; else if(!Slab && strcmp(name, "Slab") == 0) Slab = value; else if(!SReclaimable && strcmp(name, "SReclaimable") == 0) SReclaimable = value; else if(!SUnreclaim && strcmp(name, "SUnreclaim") == 0) SUnreclaim = value; else if(!KernelStack && strcmp(name, "KernelStack") == 0) KernelStack = value; else if(!PageTables && strcmp(name, "PageTables") == 0) PageTables = value; else if(!NFS_Unstable && strcmp(name, "NFS_Unstable") == 0) NFS_Unstable = value; else if(!Bounce && strcmp(name, "Bounce") == 0) Bounce = value; else if(!WritebackTmp && strcmp(name, "WritebackTmp") == 0) WritebackTmp = value; else if(!CommitLimit && strcmp(name, "CommitLimit") == 0) CommitLimit = value; else if(!Committed_AS && strcmp(name, "Committed_AS") == 0) Committed_AS = value; else if(!VmallocTotal && strcmp(name, "VmallocTotal") == 0) VmallocTotal = value; else if(!VmallocUsed && strcmp(name, "VmallocUsed") == 0) VmallocUsed = value; else if(!VmallocChunk && strcmp(name, "VmallocChunk") == 0) VmallocChunk = value; else if(!HardwareCorrupted && strcmp(name, "HardwareCorrupted") == 0) { HardwareCorrupted = value; hwcorrupted = 1; } else if(!AnonHugePages && strcmp(name, "AnonHugePages") == 0) AnonHugePages = value; else if(!HugePages_Total && strcmp(name, "HugePages_Total") == 0) HugePages_Total = value; else if(!HugePages_Free && strcmp(name, "HugePages_Free") == 0) HugePages_Free = value; else if(!HugePages_Rsvd && strcmp(name, "HugePages_Rsvd") == 0) HugePages_Rsvd = value; else if(!HugePages_Surp && strcmp(name, "HugePages_Surp") == 0) HugePages_Surp = value; else if(!Hugepagesize && strcmp(name, "Hugepagesize") == 0) Hugepagesize = value; else if(!DirectMap4k && strcmp(name, "DirectMap4k") == 0) DirectMap4k = value; else if(!DirectMap2M && strcmp(name, "DirectMap2M") == 0) DirectMap2M = value; } RRDSET *st; // -------------------------------------------------------------------- // http://stackoverflow.com/questions/3019748/how-to-reliably-measure-available-memory-in-linux unsigned long long MemUsed = MemTotal - MemFree - Cached - Buffers; if(do_ram) { st = rrdset_find("system.ram"); if(!st) { st = rrdset_create("system", "ram", NULL, "ram", NULL, "System RAM", "MB", 200, update_every, RRDSET_TYPE_STACKED); rrddim_add(st, "buffers", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "used", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "cached", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "free", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "used", MemUsed); rrddim_set(st, "free", MemFree); rrddim_set(st, "cached", Cached); rrddim_set(st, "buffers", Buffers); rrdset_done(st); } // -------------------------------------------------------------------- unsigned long long SwapUsed = SwapTotal - SwapFree; if(do_swap) { st = rrdset_find("system.swap"); if(!st) { st = rrdset_create("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201, update_every, RRDSET_TYPE_STACKED); st->isdetail = 1; rrddim_add(st, "free", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "used", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "used", SwapUsed); rrddim_set(st, "free", SwapFree); rrdset_done(st); } // -------------------------------------------------------------------- if(hwcorrupted && do_hwcorrupt && HardwareCorrupted > 0) { do_hwcorrupt = CONFIG_ONDEMAND_YES; st = rrdset_find("mem.hwcorrupt"); if(!st) { st = rrdset_create("mem", "hwcorrupt", NULL, "errors", NULL, "Hardware Corrupted ECC", "MB", 9000, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "HardwareCorrupted", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "HardwareCorrupted", HardwareCorrupted); rrdset_done(st); } // -------------------------------------------------------------------- if(do_committed) { st = rrdset_find("mem.committed"); if(!st) { st = rrdset_create("mem", "committed", NULL, "system", NULL, "Committed (Allocated) Memory", "MB", 5000, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "Committed_AS", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "Committed_AS", Committed_AS); rrdset_done(st); } // -------------------------------------------------------------------- if(do_writeback) { st = rrdset_find("mem.writeback"); if(!st) { st = rrdset_create("mem", "writeback", NULL, "kernel", NULL, "Writeback Memory", "MB", 4000, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "Dirty", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "Writeback", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "FuseWriteback", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "NfsWriteback", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "Bounce", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "Dirty", Dirty); rrddim_set(st, "Writeback", Writeback); rrddim_set(st, "FuseWriteback", WritebackTmp); rrddim_set(st, "NfsWriteback", NFS_Unstable); rrddim_set(st, "Bounce", Bounce); rrdset_done(st); } // -------------------------------------------------------------------- if(do_kernel) { st = rrdset_find("mem.kernel"); if(!st) { st = rrdset_create("mem", "kernel", NULL, "kernel", NULL, "Memory Used by Kernel", "MB", 6000, update_every, RRDSET_TYPE_STACKED); st->isdetail = 1; rrddim_add(st, "Slab", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "KernelStack", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "PageTables", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "VmallocUsed", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "KernelStack", KernelStack); rrddim_set(st, "Slab", Slab); rrddim_set(st, "PageTables", PageTables); rrddim_set(st, "VmallocUsed", VmallocUsed); rrdset_done(st); } // -------------------------------------------------------------------- if(do_slab) { st = rrdset_find("mem.slab"); if(!st) { st = rrdset_create("mem", "slab", NULL, "slab", NULL, "Reclaimable Kernel Memory", "MB", 6500, update_every, RRDSET_TYPE_STACKED); st->isdetail = 1; rrddim_add(st, "reclaimable", NULL, 1, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "unreclaimable", NULL, 1, 1024, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "reclaimable", SReclaimable); rrddim_set(st, "unreclaimable", SUnreclaim); rrdset_done(st); } return 0; }
int do_macos_mach_smi(int update_every, usec_t dt) { (void)dt; static int do_cpu = -1, do_ram = - 1, do_swapio = -1, do_pgfaults = -1; if (unlikely(do_cpu == -1)) { do_cpu = config_get_boolean("plugin:macos:mach_smi", "cpu utilization", 1); do_ram = config_get_boolean("plugin:macos:mach_smi", "system ram", 1); do_swapio = config_get_boolean("plugin:macos:mach_smi", "swap i/o", 1); do_pgfaults = config_get_boolean("plugin:macos:mach_smi", "memory page faults", 1); } RRDSET *st; kern_return_t kr; mach_msg_type_number_t count; host_t host; vm_size_t system_pagesize; // NEEDED BY: do_cpu natural_t cp_time[CPU_STATE_MAX]; // NEEDED BY: do_ram, do_swapio, do_pgfaults vm_statistics64_data_t vm_statistics; host = mach_host_self(); kr = host_page_size(host, &system_pagesize); if (unlikely(kr != KERN_SUCCESS)) return -1; // -------------------------------------------------------------------- if (likely(do_cpu)) { if (unlikely(HOST_CPU_LOAD_INFO_COUNT != 4)) { error("MACOS: There are %d CPU states (4 was expected)", HOST_CPU_LOAD_INFO_COUNT); do_cpu = 0; error("DISABLED: system.cpu"); } else { count = HOST_CPU_LOAD_INFO_COUNT; kr = host_statistics(host, HOST_CPU_LOAD_INFO, (host_info_t)cp_time, &count); if (unlikely(kr != KERN_SUCCESS)) { error("MACOS: host_statistics() failed: %s", mach_error_string(kr)); do_cpu = 0; error("DISABLED: system.cpu"); } else { st = rrdset_find_bytype("system", "cpu"); if (unlikely(!st)) { st = rrdset_create("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED); rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_hide(st, "idle"); } else rrdset_next(st); rrddim_set(st, "user", cp_time[CPU_STATE_USER]); rrddim_set(st, "nice", cp_time[CPU_STATE_NICE]); rrddim_set(st, "system", cp_time[CPU_STATE_SYSTEM]); rrddim_set(st, "idle", cp_time[CPU_STATE_IDLE]); rrdset_done(st); } } } // -------------------------------------------------------------------- if (likely(do_ram || do_swapio || do_pgfaults)) { count = sizeof(vm_statistics64_data_t); kr = host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&vm_statistics, &count); if (unlikely(kr != KERN_SUCCESS)) { error("MACOS: host_statistics64() failed: %s", mach_error_string(kr)); do_ram = 0; error("DISABLED: system.ram"); do_swapio = 0; error("DISABLED: system.swapio"); do_pgfaults = 0; error("DISABLED: mem.pgfaults"); } else { if (likely(do_ram)) { st = rrdset_find("system.ram"); if (unlikely(!st)) { st = rrdset_create("system", "ram", NULL, "ram", NULL, "System RAM", "MB", 200, update_every, RRDSET_TYPE_STACKED); rrddim_add(st, "active", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "wired", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "throttled", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "compressor", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "inactive", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "purgeable", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "speculative", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "free", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "active", vm_statistics.active_count); rrddim_set(st, "wired", vm_statistics.wire_count); rrddim_set(st, "throttled", vm_statistics.throttled_count); rrddim_set(st, "compressor", vm_statistics.compressor_page_count); rrddim_set(st, "inactive", vm_statistics.inactive_count); rrddim_set(st, "purgeable", vm_statistics.purgeable_count); rrddim_set(st, "speculative", vm_statistics.speculative_count); rrddim_set(st, "free", (vm_statistics.free_count - vm_statistics.speculative_count)); rrdset_done(st); } // -------------------------------------------------------------------- if (likely(do_swapio)) { st = rrdset_find("system.swapio"); if (unlikely(!st)) { st = rrdset_create("system", "swapio", NULL, "swap", NULL, "Swap I/O", "kilobytes/s", 250, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "in", NULL, system_pagesize, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "out", NULL, -system_pagesize, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "in", vm_statistics.swapins); rrddim_set(st, "out", vm_statistics.swapouts); rrdset_done(st); } // -------------------------------------------------------------------- if (likely(do_pgfaults)) { st = rrdset_find("mem.pgfaults"); if (unlikely(!st)) { st = rrdset_create("mem", "pgfaults", NULL, "system", NULL, "Memory Page Faults", "page faults/s", 500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "memory", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "cow", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "pagein", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "pageout", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "compress", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "decompress", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "zero_fill", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "reactivate", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "purge", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "memory", vm_statistics.faults); rrddim_set(st, "cow", vm_statistics.cow_faults); rrddim_set(st, "pagein", vm_statistics.pageins); rrddim_set(st, "pageout", vm_statistics.pageouts); rrddim_set(st, "compress", vm_statistics.compressions); rrddim_set(st, "decompress", vm_statistics.decompressions); rrddim_set(st, "zero_fill", vm_statistics.zero_fill_count); rrddim_set(st, "reactivate", vm_statistics.reactivations); rrddim_set(st, "purge", vm_statistics.purges); rrdset_done(st); } } } // -------------------------------------------------------------------- return 0; }