int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt) { (void)dt; static procfile *ff = NULL; static ARL_BASE *arl_base = NULL; arcstats.l2exist = -1; if(unlikely(!arl_base)) { arl_base = arl_create("arcstats", NULL, 60); arl_expect(arl_base, "hits", &arcstats.hits); arl_expect(arl_base, "misses", &arcstats.misses); arl_expect(arl_base, "demand_data_hits", &arcstats.demand_data_hits); arl_expect(arl_base, "demand_data_misses", &arcstats.demand_data_misses); arl_expect(arl_base, "demand_metadata_hits", &arcstats.demand_metadata_hits); arl_expect(arl_base, "demand_metadata_misses", &arcstats.demand_metadata_misses); arl_expect(arl_base, "prefetch_data_hits", &arcstats.prefetch_data_hits); arl_expect(arl_base, "prefetch_data_misses", &arcstats.prefetch_data_misses); arl_expect(arl_base, "prefetch_metadata_hits", &arcstats.prefetch_metadata_hits); arl_expect(arl_base, "prefetch_metadata_misses", &arcstats.prefetch_metadata_misses); arl_expect(arl_base, "mru_hits", &arcstats.mru_hits); arl_expect(arl_base, "mru_ghost_hits", &arcstats.mru_ghost_hits); arl_expect(arl_base, "mfu_hits", &arcstats.mfu_hits); arl_expect(arl_base, "mfu_ghost_hits", &arcstats.mfu_ghost_hits); arl_expect(arl_base, "deleted", &arcstats.deleted); arl_expect(arl_base, "mutex_miss", &arcstats.mutex_miss); arl_expect(arl_base, "evict_skip", &arcstats.evict_skip); arl_expect(arl_base, "evict_not_enough", &arcstats.evict_not_enough); arl_expect(arl_base, "evict_l2_cached", &arcstats.evict_l2_cached); arl_expect(arl_base, "evict_l2_eligible", &arcstats.evict_l2_eligible); arl_expect(arl_base, "evict_l2_ineligible", &arcstats.evict_l2_ineligible); arl_expect(arl_base, "evict_l2_skip", &arcstats.evict_l2_skip); arl_expect(arl_base, "hash_elements", &arcstats.hash_elements); arl_expect(arl_base, "hash_elements_max", &arcstats.hash_elements_max); arl_expect(arl_base, "hash_collisions", &arcstats.hash_collisions); arl_expect(arl_base, "hash_chains", &arcstats.hash_chains); arl_expect(arl_base, "hash_chain_max", &arcstats.hash_chain_max); arl_expect(arl_base, "p", &arcstats.p); arl_expect(arl_base, "c", &arcstats.c); arl_expect(arl_base, "c_min", &arcstats.c_min); arl_expect(arl_base, "c_max", &arcstats.c_max); arl_expect(arl_base, "size", &arcstats.size); arl_expect(arl_base, "hdr_size", &arcstats.hdr_size); arl_expect(arl_base, "data_size", &arcstats.data_size); arl_expect(arl_base, "metadata_size", &arcstats.metadata_size); arl_expect(arl_base, "other_size", &arcstats.other_size); arl_expect(arl_base, "anon_size", &arcstats.anon_size); arl_expect(arl_base, "anon_evictable_data", &arcstats.anon_evictable_data); arl_expect(arl_base, "anon_evictable_metadata", &arcstats.anon_evictable_metadata); arl_expect(arl_base, "mru_size", &arcstats.mru_size); arl_expect(arl_base, "mru_evictable_data", &arcstats.mru_evictable_data); arl_expect(arl_base, "mru_evictable_metadata", &arcstats.mru_evictable_metadata); arl_expect(arl_base, "mru_ghost_size", &arcstats.mru_ghost_size); arl_expect(arl_base, "mru_ghost_evictable_data", &arcstats.mru_ghost_evictable_data); arl_expect(arl_base, "mru_ghost_evictable_metadata", &arcstats.mru_ghost_evictable_metadata); arl_expect(arl_base, "mfu_size", &arcstats.mfu_size); arl_expect(arl_base, "mfu_evictable_data", &arcstats.mfu_evictable_data); arl_expect(arl_base, "mfu_evictable_metadata", &arcstats.mfu_evictable_metadata); arl_expect(arl_base, "mfu_ghost_size", &arcstats.mfu_ghost_size); arl_expect(arl_base, "mfu_ghost_evictable_data", &arcstats.mfu_ghost_evictable_data); arl_expect(arl_base, "mfu_ghost_evictable_metadata", &arcstats.mfu_ghost_evictable_metadata); arl_expect(arl_base, "l2_hits", &arcstats.l2_hits); arl_expect(arl_base, "l2_misses", &arcstats.l2_misses); arl_expect(arl_base, "l2_feeds", &arcstats.l2_feeds); arl_expect(arl_base, "l2_rw_clash", &arcstats.l2_rw_clash); arl_expect(arl_base, "l2_read_bytes", &arcstats.l2_read_bytes); arl_expect(arl_base, "l2_write_bytes", &arcstats.l2_write_bytes); arl_expect(arl_base, "l2_writes_sent", &arcstats.l2_writes_sent); arl_expect(arl_base, "l2_writes_done", &arcstats.l2_writes_done); arl_expect(arl_base, "l2_writes_error", &arcstats.l2_writes_error); arl_expect(arl_base, "l2_writes_lock_retry", &arcstats.l2_writes_lock_retry); arl_expect(arl_base, "l2_evict_lock_retry", &arcstats.l2_evict_lock_retry); arl_expect(arl_base, "l2_evict_reading", &arcstats.l2_evict_reading); arl_expect(arl_base, "l2_evict_l1cached", &arcstats.l2_evict_l1cached); arl_expect(arl_base, "l2_free_on_write", &arcstats.l2_free_on_write); arl_expect(arl_base, "l2_cdata_free_on_write", &arcstats.l2_cdata_free_on_write); arl_expect(arl_base, "l2_abort_lowmem", &arcstats.l2_abort_lowmem); arl_expect(arl_base, "l2_cksum_bad", &arcstats.l2_cksum_bad); arl_expect(arl_base, "l2_io_error", &arcstats.l2_io_error); arl_expect(arl_base, "l2_size", &arcstats.l2_size); arl_expect(arl_base, "l2_asize", &arcstats.l2_asize); arl_expect(arl_base, "l2_hdr_size", &arcstats.l2_hdr_size); arl_expect(arl_base, "l2_compress_successes", &arcstats.l2_compress_successes); arl_expect(arl_base, "l2_compress_zeros", &arcstats.l2_compress_zeros); arl_expect(arl_base, "l2_compress_failures", &arcstats.l2_compress_failures); arl_expect(arl_base, "memory_throttle_count", &arcstats.memory_throttle_count); arl_expect(arl_base, "duplicate_buffers", &arcstats.duplicate_buffers); arl_expect(arl_base, "duplicate_buffers_size", &arcstats.duplicate_buffers_size); arl_expect(arl_base, "duplicate_reads", &arcstats.duplicate_reads); arl_expect(arl_base, "memory_direct_count", &arcstats.memory_direct_count); arl_expect(arl_base, "memory_indirect_count", &arcstats.memory_indirect_count); arl_expect(arl_base, "arc_no_grow", &arcstats.arc_no_grow); arl_expect(arl_base, "arc_tempreserve", &arcstats.arc_tempreserve); arl_expect(arl_base, "arc_loaned_bytes", &arcstats.arc_loaned_bytes); arl_expect(arl_base, "arc_prune", &arcstats.arc_prune); arl_expect(arl_base, "arc_meta_used", &arcstats.arc_meta_used); arl_expect(arl_base, "arc_meta_limit", &arcstats.arc_meta_limit); arl_expect(arl_base, "arc_meta_max", &arcstats.arc_meta_max); arl_expect(arl_base, "arc_meta_min", &arcstats.arc_meta_min); arl_expect(arl_base, "arc_need_free", &arcstats.arc_need_free); arl_expect(arl_base, "arc_sys_free", &arcstats.arc_sys_free); } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, ZFS_PROC_ARCSTATS); ff = procfile_open(config_get("plugin:proc:" ZFS_PROC_ARCSTATS, "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; arl_begin(arl_base); for(l = 0; l < lines ;l++) { size_t words = procfile_linewords(ff, l); if(unlikely(words < 3)) { if(unlikely(words)) error("Cannot read " ZFS_PROC_ARCSTATS " line %zu. Expected 3 params, read %zu.", l, words); continue; } const char *key = procfile_lineword(ff, l, 0); const char *value = procfile_lineword(ff, l, 2); if(unlikely(arcstats.l2exist == -1)) { if(key[0] == 'l' && key[1] == '2' && key[2] == '_') arcstats.l2exist = 1; } if(unlikely(arl_check(arl_base, key, value))) break; } if(unlikely(arcstats.l2exist == -1)) arcstats.l2exist = 0; generate_charts_arcstats("proc", update_every); generate_charts_arc_summary("proc", update_every); return 0; }
int do_proc_vmstat(int update_every, usec_t dt) { (void)dt; static procfile *ff = NULL; static int do_swapio = -1, do_io = -1, do_pgfaults = -1, do_numa = -1; static int has_numa = -1; static ARL_BASE *arl_base = NULL; static unsigned long long numa_foreign = 0ULL; static unsigned long long numa_hint_faults = 0ULL; static unsigned long long numa_hint_faults_local = 0ULL; static unsigned long long numa_huge_pte_updates = 0ULL; static unsigned long long numa_interleave = 0ULL; static unsigned long long numa_local = 0ULL; static unsigned long long numa_other = 0ULL; static unsigned long long numa_pages_migrated = 0ULL; static unsigned long long numa_pte_updates = 0ULL; static unsigned long long pgfault = 0ULL; static unsigned long long pgmajfault = 0ULL; static unsigned long long pgpgin = 0ULL; static unsigned long long pgpgout = 0ULL; static unsigned long long pswpin = 0ULL; static unsigned long long pswpout = 0ULL; if(unlikely(!arl_base)) { do_swapio = config_get_boolean_ondemand("plugin:proc:/proc/vmstat", "swap i/o", CONFIG_BOOLEAN_AUTO); do_io = config_get_boolean("plugin:proc:/proc/vmstat", "disk i/o", 1); do_pgfaults = config_get_boolean("plugin:proc:/proc/vmstat", "memory page faults", 1); do_numa = config_get_boolean_ondemand("plugin:proc:/proc/vmstat", "system-wide numa metric summary", CONFIG_BOOLEAN_AUTO); arl_base = arl_create("vmstat", NULL, 60); arl_expect(arl_base, "pgfault", &pgfault); arl_expect(arl_base, "pgmajfault", &pgmajfault); arl_expect(arl_base, "pgpgin", &pgpgin); arl_expect(arl_base, "pgpgout", &pgpgout); arl_expect(arl_base, "pswpin", &pswpin); arl_expect(arl_base, "pswpout", &pswpout); if(do_numa == CONFIG_BOOLEAN_YES || (do_numa == CONFIG_BOOLEAN_AUTO && get_numa_node_count() >= 2)) { arl_expect(arl_base, "numa_foreign", &numa_foreign); arl_expect(arl_base, "numa_hint_faults_local", &numa_hint_faults_local); arl_expect(arl_base, "numa_hint_faults", &numa_hint_faults); arl_expect(arl_base, "numa_huge_pte_updates", &numa_huge_pte_updates); arl_expect(arl_base, "numa_interleave", &numa_interleave); arl_expect(arl_base, "numa_local", &numa_local); arl_expect(arl_base, "numa_other", &numa_other); arl_expect(arl_base, "numa_pages_migrated", &numa_pages_migrated); arl_expect(arl_base, "numa_pte_updates", &numa_pte_updates); } else { // Do not expect numa metrics when they are not needed. // By not adding them, the ARL will stop processing the file // when all the expected metrics are collected. // Also ARL will not parse their values. has_numa = 0; do_numa = CONFIG_BOOLEAN_NO; } } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/vmstat"); ff = procfile_open(config_get("plugin:proc:/proc/vmstat", "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; arl_begin(arl_base); for(l = 0; l < lines ;l++) { size_t words = procfile_linewords(ff, l); if(unlikely(words < 2)) { if(unlikely(words)) error("Cannot read /proc/vmstat line %zu. Expected 2 params, read %zu.", l, words); continue; } if(unlikely(arl_check(arl_base, procfile_lineword(ff, l, 0), procfile_lineword(ff, l, 1)))) break; } // -------------------------------------------------------------------- if(pswpin || pswpout || do_swapio == CONFIG_BOOLEAN_YES) { do_swapio = CONFIG_BOOLEAN_YES; static RRDSET *st_swapio = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_swapio)) { st_swapio = rrdset_create_localhost( "system" , "swapio" , NULL , "swap" , NULL , "Swap I/O" , "kilobytes/s" , 250 , update_every , RRDSET_TYPE_AREA ); rd_in = rrddim_add(st_swapio, "in", NULL, sysconf(_SC_PAGESIZE), 1024, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_swapio, "out", NULL, -sysconf(_SC_PAGESIZE), 1024, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_swapio); rrddim_set_by_pointer(st_swapio, rd_in, pswpin); rrddim_set_by_pointer(st_swapio, rd_out, pswpout); rrdset_done(st_swapio); } // -------------------------------------------------------------------- if(do_io) { static RRDSET *st_io = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_io)) { st_io = rrdset_create_localhost( "system" , "io" , NULL , "disk" , NULL , "Disk I/O" , "kilobytes/s" , 150 , update_every , RRDSET_TYPE_AREA ); rd_in = rrddim_add(st_io, "in", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_io, "out", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_io); rrddim_set_by_pointer(st_io, rd_in, pgpgin); rrddim_set_by_pointer(st_io, rd_out, pgpgout); rrdset_done(st_io); } // -------------------------------------------------------------------- if(do_pgfaults) { static RRDSET *st_pgfaults = NULL; static RRDDIM *rd_minor = NULL, *rd_major = NULL; if(unlikely(!st_pgfaults)) { st_pgfaults = rrdset_create_localhost( "mem" , "pgfaults" , NULL , "system" , NULL , "Memory Page Faults" , "page faults/s" , 500 , update_every , RRDSET_TYPE_LINE ); rrdset_flag_set(st_pgfaults, RRDSET_FLAG_DETAIL); rd_minor = rrddim_add(st_pgfaults, "minor", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_major = rrddim_add(st_pgfaults, "major", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_pgfaults); rrddim_set_by_pointer(st_pgfaults, rd_minor, pgfault); rrddim_set_by_pointer(st_pgfaults, rd_major, pgmajfault); rrdset_done(st_pgfaults); } // -------------------------------------------------------------------- // Ondemand criteria for NUMA. Since this won't change at run time, we // check it only once. We check whether the node count is >= 2 because // single-node systems have uninteresting statistics (since all accesses // are local). if(unlikely(has_numa == -1)) has_numa = (numa_local || numa_foreign || numa_interleave || numa_other || numa_pte_updates || numa_huge_pte_updates || numa_hint_faults || numa_hint_faults_local || numa_pages_migrated) ? 1 : 0; if(do_numa == CONFIG_BOOLEAN_YES || (do_numa == CONFIG_BOOLEAN_AUTO && has_numa)) { do_numa = CONFIG_BOOLEAN_YES; static RRDSET *st_numa = NULL; static RRDDIM *rd_local = NULL, *rd_foreign = NULL, *rd_interleave = NULL, *rd_other = NULL, *rd_pte_updates = NULL, *rd_huge_pte_updates = NULL, *rd_hint_faults = NULL, *rd_hint_faults_local = NULL, *rd_pages_migrated = NULL; if(unlikely(!st_numa)) { st_numa = rrdset_create_localhost( "mem" , "numa" , NULL , "numa" , NULL , "NUMA events" , "events/s" , 800 , update_every , RRDSET_TYPE_LINE ); rrdset_flag_set(st_numa, RRDSET_FLAG_DETAIL); // These depend on CONFIG_NUMA in the kernel. rd_local = rrddim_add(st_numa, "local", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_foreign = rrddim_add(st_numa, "foreign", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_interleave = rrddim_add(st_numa, "interleave", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_other = rrddim_add(st_numa, "other", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); // The following stats depend on CONFIG_NUMA_BALANCING in the // kernel. rd_pte_updates = rrddim_add(st_numa, "pte_updates", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_huge_pte_updates = rrddim_add(st_numa, "huge_pte_updates", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_hint_faults = rrddim_add(st_numa, "hint_faults", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_hint_faults_local = rrddim_add(st_numa, "hint_faults_local", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_pages_migrated = rrddim_add(st_numa, "pages_migrated", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_numa); rrddim_set_by_pointer(st_numa, rd_local, numa_local); rrddim_set_by_pointer(st_numa, rd_foreign, numa_foreign); rrddim_set_by_pointer(st_numa, rd_interleave, numa_interleave); rrddim_set_by_pointer(st_numa, rd_other, numa_other); rrddim_set_by_pointer(st_numa, rd_pte_updates, numa_pte_updates); rrddim_set_by_pointer(st_numa, rd_huge_pte_updates, numa_huge_pte_updates); rrddim_set_by_pointer(st_numa, rd_hint_faults, numa_hint_faults); rrddim_set_by_pointer(st_numa, rd_hint_faults_local, numa_hint_faults_local); rrddim_set_by_pointer(st_numa, rd_pages_migrated, numa_pages_migrated); rrdset_done(st_numa); } 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, do_tcpext_listen = -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 // https://perfchron.com/2015/12/26/investigating-linux-network-issues-with-netstat-and-nstat/ static unsigned long long tcpext_ListenOverflows = 0; // times the listen queue of a socket overflowed static unsigned long long tcpext_ListenDrops = 0; // SYNs to LISTEN sockets ignored // IPv4 TCP memory pressures static unsigned long long tcpext_TCPMemoryPressures = 0; // shared: tcpext_TCPSynRetrans 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_BOOLEAN_AUTO); do_inerrors = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "input errors", CONFIG_BOOLEAN_AUTO); do_mcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast bandwidth", CONFIG_BOOLEAN_AUTO); do_bcast = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast bandwidth", CONFIG_BOOLEAN_AUTO); do_mcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast packets", CONFIG_BOOLEAN_AUTO); do_bcast_p = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast packets", CONFIG_BOOLEAN_AUTO); do_ecn = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "ECN packets", CONFIG_BOOLEAN_AUTO); do_tcpext_reorder = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP reorders", CONFIG_BOOLEAN_AUTO); do_tcpext_syscookies = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP SYN cookies", CONFIG_BOOLEAN_AUTO); do_tcpext_ofo = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP out-of-order queue", CONFIG_BOOLEAN_AUTO); do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_BOOLEAN_AUTO); do_tcpext_memory = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_BOOLEAN_AUTO); do_tcpext_listen = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP listen issues", CONFIG_BOOLEAN_AUTO); arl_ipext = arl_create("netstat/ipext", NULL, 60); arl_tcpext = arl_create("netstat/tcpext", NULL, 60); // -------------------------------------------------------------------- // IPv4 if(do_bandwidth != CONFIG_BOOLEAN_NO) { arl_expect(arl_ipext, "InOctets", &ipext_InOctets); arl_expect(arl_ipext, "OutOctets", &ipext_OutOctets); } if(do_inerrors != CONFIG_BOOLEAN_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_BOOLEAN_NO) { arl_expect(arl_ipext, "InMcastOctets", &ipext_InMcastOctets); arl_expect(arl_ipext, "OutMcastOctets", &ipext_OutMcastOctets); } if(do_mcast_p != CONFIG_BOOLEAN_NO) { arl_expect(arl_ipext, "InMcastPkts", &ipext_InMcastPkts); arl_expect(arl_ipext, "OutMcastPkts", &ipext_OutMcastPkts); } if(do_bcast != CONFIG_BOOLEAN_NO) { arl_expect(arl_ipext, "InBcastPkts", &ipext_InBcastPkts); arl_expect(arl_ipext, "OutBcastPkts", &ipext_OutBcastPkts); } if(do_bcast_p != CONFIG_BOOLEAN_NO) { arl_expect(arl_ipext, "InBcastOctets", &ipext_InBcastOctets); arl_expect(arl_ipext, "OutBcastOctets", &ipext_OutBcastOctets); } if(do_ecn != CONFIG_BOOLEAN_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_BOOLEAN_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_BOOLEAN_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_BOOLEAN_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_BOOLEAN_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_BOOLEAN_NO) { arl_expect(arl_tcpext, "TCPMemoryPressures", &tcpext_TCPMemoryPressures); } if(do_tcpext_listen != CONFIG_BOOLEAN_NO) { arl_expect(arl_tcpext, "ListenOverflows", &tcpext_ListenOverflows); arl_expect(arl_tcpext, "ListenDrops", &tcpext_ListenDrops); } // shared metrics arl_expect(arl_tcpext, "TCPSynRetrans", &tcpext_TCPSynRetrans); } 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); // -------------------------------------------------------------------- if(do_bandwidth == CONFIG_BOOLEAN_YES || (do_bandwidth == CONFIG_BOOLEAN_AUTO && (ipext_InOctets || ipext_OutOctets))) { do_bandwidth = CONFIG_BOOLEAN_YES; static RRDSET *st_system_ipv4 = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_system_ipv4)) { st_system_ipv4 = rrdset_create_localhost( "system" , "ipv4" , NULL , "network" , NULL , "IPv4 Bandwidth" , "kilobits/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_SYSTEM_IPV4 , update_every , RRDSET_TYPE_AREA ); rd_in = rrddim_add(st_system_ipv4, "InOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_system_ipv4, "OutOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_system_ipv4); rrddim_set_by_pointer(st_system_ipv4, rd_in, ipext_InOctets); rrddim_set_by_pointer(st_system_ipv4, rd_out, ipext_OutOctets); rrdset_done(st_system_ipv4); } // -------------------------------------------------------------------- if(do_inerrors == CONFIG_BOOLEAN_YES || (do_inerrors == CONFIG_BOOLEAN_AUTO && (ipext_InNoRoutes || ipext_InTruncatedPkts))) { do_inerrors = CONFIG_BOOLEAN_YES; static RRDSET *st_ipv4_inerrors = NULL; static RRDDIM *rd_noroutes = NULL, *rd_truncated = NULL, *rd_checksum = NULL; if(unlikely(!st_ipv4_inerrors)) { st_ipv4_inerrors = rrdset_create_localhost( "ipv4" , "inerrors" , NULL , "errors" , NULL , "IPv4 Input Errors" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_ERRORS , update_every , RRDSET_TYPE_LINE ); rrdset_flag_set(st_ipv4_inerrors, RRDSET_FLAG_DETAIL); rd_noroutes = rrddim_add(st_ipv4_inerrors, "InNoRoutes", "noroutes", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_truncated = rrddim_add(st_ipv4_inerrors, "InTruncatedPkts", "truncated", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_checksum = rrddim_add(st_ipv4_inerrors, "InCsumErrors", "checksum", 1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ipv4_inerrors); rrddim_set_by_pointer(st_ipv4_inerrors, rd_noroutes, ipext_InNoRoutes); rrddim_set_by_pointer(st_ipv4_inerrors, rd_truncated, ipext_InTruncatedPkts); rrddim_set_by_pointer(st_ipv4_inerrors, rd_checksum, ipext_InCsumErrors); rrdset_done(st_ipv4_inerrors); } // -------------------------------------------------------------------- if(do_mcast == CONFIG_BOOLEAN_YES || (do_mcast == CONFIG_BOOLEAN_AUTO && (ipext_InMcastOctets || ipext_OutMcastOctets))) { do_mcast = CONFIG_BOOLEAN_YES; static RRDSET *st_ipv4_mcast = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_ipv4_mcast)) { st_ipv4_mcast = rrdset_create_localhost( "ipv4" , "mcast" , NULL , "multicast" , NULL , "IPv4 Multicast Bandwidth" , "kilobits/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_MCAST , update_every , RRDSET_TYPE_AREA ); rrdset_flag_set(st_ipv4_mcast, RRDSET_FLAG_DETAIL); rd_in = rrddim_add(st_ipv4_mcast, "InMcastOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_ipv4_mcast, "OutMcastOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ipv4_mcast); rrddim_set_by_pointer(st_ipv4_mcast, rd_in, ipext_InMcastOctets); rrddim_set_by_pointer(st_ipv4_mcast, rd_out, ipext_OutMcastOctets); rrdset_done(st_ipv4_mcast); } // -------------------------------------------------------------------- if(do_bcast == CONFIG_BOOLEAN_YES || (do_bcast == CONFIG_BOOLEAN_AUTO && (ipext_InBcastOctets || ipext_OutBcastOctets))) { do_bcast = CONFIG_BOOLEAN_YES; static RRDSET *st_ipv4_bcast = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_ipv4_bcast)) { st_ipv4_bcast = rrdset_create_localhost( "ipv4" , "bcast" , NULL , "broadcast" , NULL , "IPv4 Broadcast Bandwidth" , "kilobits/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_BCAST , update_every , RRDSET_TYPE_AREA ); rrdset_flag_set(st_ipv4_bcast, RRDSET_FLAG_DETAIL); rd_in = rrddim_add(st_ipv4_bcast, "InBcastOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_ipv4_bcast, "OutBcastOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ipv4_bcast); rrddim_set_by_pointer(st_ipv4_bcast, rd_in, ipext_InBcastOctets); rrddim_set_by_pointer(st_ipv4_bcast, rd_out, ipext_OutBcastOctets); rrdset_done(st_ipv4_bcast); } // -------------------------------------------------------------------- if(do_mcast_p == CONFIG_BOOLEAN_YES || (do_mcast_p == CONFIG_BOOLEAN_AUTO && (ipext_InMcastPkts || ipext_OutMcastPkts))) { do_mcast_p = CONFIG_BOOLEAN_YES; static RRDSET *st_ipv4_mcastpkts = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_ipv4_mcastpkts)) { st_ipv4_mcastpkts = rrdset_create_localhost( "ipv4" , "mcastpkts" , NULL , "multicast" , NULL , "IPv4 Multicast Packets" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_MCAST + 10 , update_every , RRDSET_TYPE_LINE ); rrdset_flag_set(st_ipv4_mcastpkts, RRDSET_FLAG_DETAIL); rd_in = rrddim_add(st_ipv4_mcastpkts, "InMcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_ipv4_mcastpkts, "OutMcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ipv4_mcastpkts); rrddim_set_by_pointer(st_ipv4_mcastpkts, rd_in, ipext_InMcastPkts); rrddim_set_by_pointer(st_ipv4_mcastpkts, rd_out, ipext_OutMcastPkts); rrdset_done(st_ipv4_mcastpkts); } // -------------------------------------------------------------------- if(do_bcast_p == CONFIG_BOOLEAN_YES || (do_bcast_p == CONFIG_BOOLEAN_AUTO && (ipext_InBcastPkts || ipext_OutBcastPkts))) { do_bcast_p = CONFIG_BOOLEAN_YES; static RRDSET *st_ipv4_bcastpkts = NULL; static RRDDIM *rd_in = NULL, *rd_out = NULL; if(unlikely(!st_ipv4_bcastpkts)) { st_ipv4_bcastpkts = rrdset_create_localhost( "ipv4" , "bcastpkts" , NULL , "broadcast" , NULL , "IPv4 Broadcast Packets" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_BCAST + 10 , update_every , RRDSET_TYPE_LINE ); rrdset_flag_set(st_ipv4_bcastpkts, RRDSET_FLAG_DETAIL); rd_in = rrddim_add(st_ipv4_bcastpkts, "InBcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_out = rrddim_add(st_ipv4_bcastpkts, "OutBcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ipv4_bcastpkts); rrddim_set_by_pointer(st_ipv4_bcastpkts, rd_in, ipext_InBcastPkts); rrddim_set_by_pointer(st_ipv4_bcastpkts, rd_out, ipext_OutBcastPkts); rrdset_done(st_ipv4_bcastpkts); } // -------------------------------------------------------------------- if(do_ecn == CONFIG_BOOLEAN_YES || (do_ecn == CONFIG_BOOLEAN_AUTO && (ipext_InCEPkts || ipext_InECT0Pkts || ipext_InECT1Pkts || ipext_InNoECTPkts))) { do_ecn = CONFIG_BOOLEAN_YES; static RRDSET *st_ecnpkts = NULL; static RRDDIM *rd_cep = NULL, *rd_noectp = NULL, *rd_ectp0 = NULL, *rd_ectp1 = NULL; if(unlikely(!st_ecnpkts)) { st_ecnpkts = rrdset_create_localhost( "ipv4" , "ecnpkts" , NULL , "ecn" , NULL , "IPv4 ECN Statistics" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_ECN , update_every , RRDSET_TYPE_LINE ); rrdset_flag_set(st_ecnpkts, RRDSET_FLAG_DETAIL); rd_cep = rrddim_add(st_ecnpkts, "InCEPkts", "CEP", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_noectp = rrddim_add(st_ecnpkts, "InNoECTPkts", "NoECTP", -1, 1, RRD_ALGORITHM_INCREMENTAL); rd_ectp0 = rrddim_add(st_ecnpkts, "InECT0Pkts", "ECTP0", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_ectp1 = rrddim_add(st_ecnpkts, "InECT1Pkts", "ECTP1", 1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ecnpkts); rrddim_set_by_pointer(st_ecnpkts, rd_cep, ipext_InCEPkts); rrddim_set_by_pointer(st_ecnpkts, rd_noectp, ipext_InNoECTPkts); rrddim_set_by_pointer(st_ecnpkts, rd_ectp0, ipext_InECT0Pkts); rrddim_set_by_pointer(st_ecnpkts, rd_ectp1, ipext_InECT1Pkts); rrdset_done(st_ecnpkts); } } 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); // -------------------------------------------------------------------- if(do_tcpext_memory == CONFIG_BOOLEAN_YES || (do_tcpext_memory == CONFIG_BOOLEAN_AUTO && (tcpext_TCPMemoryPressures))) { do_tcpext_memory = CONFIG_BOOLEAN_YES; static RRDSET *st_tcpmemorypressures = NULL; static RRDDIM *rd_pressures = NULL; if(unlikely(!st_tcpmemorypressures)) { st_tcpmemorypressures = rrdset_create_localhost( "ipv4" , "tcpmemorypressures" , NULL , "tcp" , NULL , "TCP Memory Pressures" , "events/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_TCP_MEM , update_every , RRDSET_TYPE_LINE ); rd_pressures = rrddim_add(st_tcpmemorypressures, "TCPMemoryPressures", "pressures", 1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_tcpmemorypressures); rrddim_set_by_pointer(st_tcpmemorypressures, rd_pressures, tcpext_TCPMemoryPressures); rrdset_done(st_tcpmemorypressures); } // -------------------------------------------------------------------- if(do_tcpext_connaborts == CONFIG_BOOLEAN_YES || (do_tcpext_connaborts == CONFIG_BOOLEAN_AUTO && (tcpext_TCPAbortOnData || tcpext_TCPAbortOnClose || tcpext_TCPAbortOnMemory || tcpext_TCPAbortOnTimeout || tcpext_TCPAbortOnLinger || tcpext_TCPAbortFailed))) { do_tcpext_connaborts = CONFIG_BOOLEAN_YES; static RRDSET *st_tcpconnaborts = NULL; static RRDDIM *rd_baddata = NULL, *rd_userclosed = NULL, *rd_nomemory = NULL, *rd_timeout = NULL, *rd_linger = NULL, *rd_failed = NULL; if(unlikely(!st_tcpconnaborts)) { st_tcpconnaborts = rrdset_create_localhost( "ipv4" , "tcpconnaborts" , NULL , "tcp" , NULL , "TCP Connection Aborts" , "connections/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_TCP + 10 , update_every , RRDSET_TYPE_LINE ); rd_baddata = rrddim_add(st_tcpconnaborts, "TCPAbortOnData", "baddata", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_userclosed = rrddim_add(st_tcpconnaborts, "TCPAbortOnClose", "userclosed", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_nomemory = rrddim_add(st_tcpconnaborts, "TCPAbortOnMemory", "nomemory", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_timeout = rrddim_add(st_tcpconnaborts, "TCPAbortOnTimeout", "timeout", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_linger = rrddim_add(st_tcpconnaborts, "TCPAbortOnLinger", "linger", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_failed = rrddim_add(st_tcpconnaborts, "TCPAbortFailed", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_tcpconnaborts); rrddim_set_by_pointer(st_tcpconnaborts, rd_baddata, tcpext_TCPAbortOnData); rrddim_set_by_pointer(st_tcpconnaborts, rd_userclosed, tcpext_TCPAbortOnClose); rrddim_set_by_pointer(st_tcpconnaborts, rd_nomemory, tcpext_TCPAbortOnMemory); rrddim_set_by_pointer(st_tcpconnaborts, rd_timeout, tcpext_TCPAbortOnTimeout); rrddim_set_by_pointer(st_tcpconnaborts, rd_linger, tcpext_TCPAbortOnLinger); rrddim_set_by_pointer(st_tcpconnaborts, rd_failed, tcpext_TCPAbortFailed); rrdset_done(st_tcpconnaborts); } // -------------------------------------------------------------------- if(do_tcpext_reorder == CONFIG_BOOLEAN_YES || (do_tcpext_reorder == CONFIG_BOOLEAN_AUTO && (tcpext_TCPRenoReorder || tcpext_TCPFACKReorder || tcpext_TCPSACKReorder || tcpext_TCPTSReorder))) { do_tcpext_reorder = CONFIG_BOOLEAN_YES; static RRDSET *st_tcpreorders = NULL; static RRDDIM *rd_timestamp = NULL, *rd_sack = NULL, *rd_fack = NULL, *rd_reno = NULL; if(unlikely(!st_tcpreorders)) { st_tcpreorders = rrdset_create_localhost( "ipv4" , "tcpreorders" , NULL , "tcp" , NULL , "TCP Reordered Packets by Detection Method" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_TCP + 20 , update_every , RRDSET_TYPE_LINE ); rd_timestamp = rrddim_add(st_tcpreorders, "TCPTSReorder", "timestamp", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_sack = rrddim_add(st_tcpreorders, "TCPSACKReorder", "sack", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_fack = rrddim_add(st_tcpreorders, "TCPFACKReorder", "fack", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_reno = rrddim_add(st_tcpreorders, "TCPRenoReorder", "reno", 1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_tcpreorders); rrddim_set_by_pointer(st_tcpreorders, rd_timestamp, tcpext_TCPTSReorder); rrddim_set_by_pointer(st_tcpreorders, rd_sack, tcpext_TCPSACKReorder); rrddim_set_by_pointer(st_tcpreorders, rd_fack, tcpext_TCPFACKReorder); rrddim_set_by_pointer(st_tcpreorders, rd_reno, tcpext_TCPRenoReorder); rrdset_done(st_tcpreorders); } // -------------------------------------------------------------------- if(do_tcpext_ofo == CONFIG_BOOLEAN_YES || (do_tcpext_ofo == CONFIG_BOOLEAN_AUTO && (tcpext_TCPOFOQueue || tcpext_TCPOFODrop || tcpext_TCPOFOMerge))) { do_tcpext_ofo = CONFIG_BOOLEAN_YES; static RRDSET *st_ipv4_tcpofo = NULL; static RRDDIM *rd_inqueue = NULL, *rd_dropped = NULL, *rd_merged = NULL, *rd_pruned = NULL; if(unlikely(!st_ipv4_tcpofo)) { st_ipv4_tcpofo = rrdset_create_localhost( "ipv4" , "tcpofo" , NULL , "tcp" , NULL , "TCP Out-Of-Order Queue" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_TCP + 50 , update_every , RRDSET_TYPE_LINE ); rd_inqueue = rrddim_add(st_ipv4_tcpofo, "TCPOFOQueue", "inqueue", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_dropped = rrddim_add(st_ipv4_tcpofo, "TCPOFODrop", "dropped", -1, 1, RRD_ALGORITHM_INCREMENTAL); rd_merged = rrddim_add(st_ipv4_tcpofo, "TCPOFOMerge", "merged", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_pruned = rrddim_add(st_ipv4_tcpofo, "OfoPruned", "pruned", -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_ipv4_tcpofo); rrddim_set_by_pointer(st_ipv4_tcpofo, rd_inqueue, tcpext_TCPOFOQueue); rrddim_set_by_pointer(st_ipv4_tcpofo, rd_dropped, tcpext_TCPOFODrop); rrddim_set_by_pointer(st_ipv4_tcpofo, rd_merged, tcpext_TCPOFOMerge); rrddim_set_by_pointer(st_ipv4_tcpofo, rd_pruned, tcpext_OfoPruned); rrdset_done(st_ipv4_tcpofo); } // -------------------------------------------------------------------- if(do_tcpext_syscookies == CONFIG_BOOLEAN_YES || (do_tcpext_syscookies == CONFIG_BOOLEAN_AUTO && (tcpext_SyncookiesSent || tcpext_SyncookiesRecv || tcpext_SyncookiesFailed))) { do_tcpext_syscookies = CONFIG_BOOLEAN_YES; static RRDSET *st_syncookies = NULL; static RRDDIM *rd_received = NULL, *rd_sent = NULL, *rd_failed = NULL; if(unlikely(!st_syncookies)) { st_syncookies = rrdset_create_localhost( "ipv4" , "tcpsyncookies" , NULL , "tcp" , NULL , "TCP SYN Cookies" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_TCP + 60 , update_every , RRDSET_TYPE_LINE ); rd_received = rrddim_add(st_syncookies, "SyncookiesRecv", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_sent = rrddim_add(st_syncookies, "SyncookiesSent", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL); rd_failed = rrddim_add(st_syncookies, "SyncookiesFailed", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_syncookies); rrddim_set_by_pointer(st_syncookies, rd_received, tcpext_SyncookiesRecv); rrddim_set_by_pointer(st_syncookies, rd_sent, tcpext_SyncookiesSent); rrddim_set_by_pointer(st_syncookies, rd_failed, tcpext_SyncookiesFailed); rrdset_done(st_syncookies); } // -------------------------------------------------------------------- if(do_tcpext_listen == CONFIG_BOOLEAN_YES || (do_tcpext_listen == CONFIG_BOOLEAN_AUTO && (tcpext_ListenOverflows || tcpext_ListenDrops))) { do_tcpext_listen = CONFIG_BOOLEAN_YES; static RRDSET *st_listen = NULL; static RRDDIM *rd_overflows = NULL, *rd_drops = NULL; if(unlikely(!st_listen)) { st_listen = rrdset_create_localhost( "ipv4" , "tcplistenissues" , NULL , "tcp" , NULL , "TCP Listen Socket Issues" , "packets/s" , "proc" , "net/netstat" , NETDATA_CHART_PRIO_IPV4_TCP + 15 , update_every , RRDSET_TYPE_LINE ); rd_overflows = rrddim_add(st_listen, "ListenOverflows", "overflows", 1, 1, RRD_ALGORITHM_INCREMENTAL); rd_drops = rrddim_add(st_listen, "ListenDrops", "drops", 1, 1, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(st_listen); rrddim_set_by_pointer(st_listen, rd_overflows, tcpext_ListenOverflows); rrddim_set_by_pointer(st_listen, rd_drops, tcpext_ListenDrops); rrdset_done(st_listen); } } } 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; }
int do_proc_net_sockstat6(int update_every, usec_t dt) { (void)dt; static procfile *ff = NULL; static uint32_t hash_raw = 0, hash_frag = 0, hash_tcp = 0, hash_udp = 0, hash_udplite = 0; static ARL_BASE *arl_tcp = NULL; static ARL_BASE *arl_udp = NULL; static ARL_BASE *arl_udplite = NULL; static ARL_BASE *arl_raw = NULL; static ARL_BASE *arl_frag = NULL; static int do_tcp_sockets = -1, do_udp_sockets = -1, do_udplite_sockets = -1, do_raw_sockets = -1, do_frag_sockets = -1; static char *keys[6] = { NULL }; static uint32_t hashes[6] = { 0 }; static ARL_BASE *bases[6] = { NULL }; if(unlikely(!arl_tcp)) { do_tcp_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 TCP sockets", CONFIG_BOOLEAN_AUTO); do_udp_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 UDP sockets", CONFIG_BOOLEAN_AUTO); do_udplite_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 UDPLITE sockets", CONFIG_BOOLEAN_AUTO); do_raw_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 RAW sockets", CONFIG_BOOLEAN_AUTO); do_frag_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 FRAG sockets", CONFIG_BOOLEAN_AUTO); arl_tcp = arl_create("sockstat6/TCP6", arl_callback_str2kernel_uint_t, 60); arl_expect(arl_tcp, "inuse", &sockstat6_root.tcp6_inuse); arl_udp = arl_create("sockstat6/UDP6", arl_callback_str2kernel_uint_t, 60); arl_expect(arl_udp, "inuse", &sockstat6_root.udp6_inuse); arl_udplite = arl_create("sockstat6/UDPLITE6", arl_callback_str2kernel_uint_t, 60); arl_expect(arl_udplite, "inuse", &sockstat6_root.udplite6_inuse); arl_raw = arl_create("sockstat6/RAW6", arl_callback_str2kernel_uint_t, 60); arl_expect(arl_raw, "inuse", &sockstat6_root.raw6_inuse); arl_frag = arl_create("sockstat6/FRAG6", arl_callback_str2kernel_uint_t, 60); arl_expect(arl_frag, "inuse", &sockstat6_root.frag6_inuse); hash_tcp = simple_hash("TCP6"); hash_udp = simple_hash("UDP6"); hash_udplite = simple_hash("UDPLITE6"); hash_raw = simple_hash("RAW6"); hash_frag = simple_hash("FRAG6"); keys[0] = "TCP6"; hashes[0] = hash_tcp; bases[0] = arl_tcp; keys[1] = "UDP6"; hashes[1] = hash_udp; bases[1] = arl_udp; keys[2] = "UDPLITE6"; hashes[2] = hash_udplite; bases[2] = arl_udplite; keys[3] = "RAW6"; hashes[3] = hash_raw; bases[3] = arl_raw; keys[4] = "FRAG6"; hashes[4] = hash_frag; bases[4] = arl_frag; keys[5] = NULL; // terminator } if(unlikely(!ff)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/net/sockstat6"); ff = procfile_open(config_get("plugin:proc:/proc/net/sockstat6", "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; for(l = 0; l < lines ;l++) { size_t words = procfile_linewords(ff, l); char *key = procfile_lineword(ff, l, 0); uint32_t hash = simple_hash(key); int k; for(k = 0; keys[k] ; k++) { if(unlikely(hash == hashes[k] && strcmp(key, keys[k]) == 0)) { // fprintf(stderr, "KEY: '%s', l=%zu, w=1, words=%zu\n", key, l, words); ARL_BASE *arl = bases[k]; arl_begin(arl); size_t w = 1; while(w + 1 < words) { char *name = procfile_lineword(ff, l, w); w++; char *value = procfile_lineword(ff, l, w); w++; // fprintf(stderr, " > NAME '%s', VALUE '%s', l=%zu, w=%zu, words=%zu\n", name, value, l, w, words); if(unlikely(arl_check(arl, name, value) != 0)) break; } break; } } } // ------------------------------------------------------------------------ if(do_tcp_sockets == CONFIG_BOOLEAN_YES || (do_tcp_sockets == CONFIG_BOOLEAN_AUTO && (sockstat6_root.tcp6_inuse))) { do_tcp_sockets = CONFIG_BOOLEAN_YES; static RRDSET *st = NULL; static RRDDIM *rd_inuse = NULL; if(unlikely(!st)) { st = rrdset_create_localhost( "ipv6" , "sockstat6_tcp_sockets" , NULL , "tcp6" , NULL , "IPv6 TCP Sockets" , "sockets" , PLUGIN_PROC_NAME , PLUGIN_PROC_MODULE_NET_SOCKSTAT6_NAME , NETDATA_CHART_PRIO_IPV6_TCP , update_every , RRDSET_TYPE_LINE ); rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); } else rrdset_next(st); rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.tcp6_inuse); rrdset_done(st); } // ------------------------------------------------------------------------ if(do_udp_sockets == CONFIG_BOOLEAN_YES || (do_udp_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.udp6_inuse)) { do_udp_sockets = CONFIG_BOOLEAN_YES; static RRDSET *st = NULL; static RRDDIM *rd_inuse = NULL; if(unlikely(!st)) { st = rrdset_create_localhost( "ipv6" , "sockstat6_udp_sockets" , NULL , "udp6" , NULL , "IPv6 UDP Sockets" , "sockets" , PLUGIN_PROC_NAME , PLUGIN_PROC_MODULE_NET_SOCKSTAT6_NAME , NETDATA_CHART_PRIO_IPV6_UDP , update_every , RRDSET_TYPE_LINE ); rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); } else rrdset_next(st); rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.udp6_inuse); rrdset_done(st); } // ------------------------------------------------------------------------ if(do_udplite_sockets == CONFIG_BOOLEAN_YES || (do_udplite_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.udplite6_inuse)) { do_udplite_sockets = CONFIG_BOOLEAN_YES; static RRDSET *st = NULL; static RRDDIM *rd_inuse = NULL; if(unlikely(!st)) { st = rrdset_create_localhost( "ipv6" , "sockstat6_udplite_sockets" , NULL , "udplite6" , NULL , "IPv6 UDPLITE Sockets" , "sockets" , PLUGIN_PROC_NAME , PLUGIN_PROC_MODULE_NET_SOCKSTAT6_NAME , NETDATA_CHART_PRIO_IPV6_UDPLITE , update_every , RRDSET_TYPE_LINE ); rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); } else rrdset_next(st); rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.udplite6_inuse); rrdset_done(st); } // ------------------------------------------------------------------------ if(do_raw_sockets == CONFIG_BOOLEAN_YES || (do_raw_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.raw6_inuse)) { do_raw_sockets = CONFIG_BOOLEAN_YES; static RRDSET *st = NULL; static RRDDIM *rd_inuse = NULL; if(unlikely(!st)) { st = rrdset_create_localhost( "ipv6" , "sockstat6_raw_sockets" , NULL , "raw6" , NULL , "IPv6 RAW Sockets" , "sockets" , PLUGIN_PROC_NAME , PLUGIN_PROC_MODULE_NET_SOCKSTAT6_NAME , NETDATA_CHART_PRIO_IPV6_RAW , update_every , RRDSET_TYPE_LINE ); rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); } else rrdset_next(st); rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.raw6_inuse); rrdset_done(st); } // ------------------------------------------------------------------------ if(do_frag_sockets == CONFIG_BOOLEAN_YES || (do_frag_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.frag6_inuse)) { do_frag_sockets = CONFIG_BOOLEAN_YES; static RRDSET *st = NULL; static RRDDIM *rd_inuse = NULL; if(unlikely(!st)) { st = rrdset_create_localhost( "ipv6" , "sockstat6_frag_sockets" , NULL , "fragments6" , NULL , "IPv6 FRAG Sockets" , "fragments" , PLUGIN_PROC_NAME , PLUGIN_PROC_MODULE_NET_SOCKSTAT6_NAME , NETDATA_CHART_PRIO_IPV6_FRAGMENTS , update_every , RRDSET_TYPE_LINE ); rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); } else rrdset_next(st); rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.frag6_inuse); rrdset_done(st); } return 0; }