From: Marc Fournier Date: Sun, 30 Mar 2014 22:10:44 +0000 (+0200) Subject: Merge pull request #546 from manuelluis/mlsr/tcpconns-aix X-Git-Tag: collectd-5.5.0~311 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=4f4c2dce20d92a61b4cfdee2f1142ad0ca180bdf;hp=bab4f4cddf4aa053ed7b6b632bac3d42cee7d33e;p=collectd.git Merge pull request #546 from manuelluis/mlsr/tcpconns-aix Fix tcp state names in AIX to be like others. --- diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 830add99..7d9dab30 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -1007,6 +1007,7 @@ # # # Instance "exim" +# Interval 60 # # Regex "S=([1-9][0-9]*)" # DSType "CounterAdd" diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 7a3d6a36..a14a8f68 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -9,14 +9,14 @@ collectd.conf - Configuration for the system statistics collection daemon B Interval 3600 - + LoadPlugin ping Host "example.org" @@ -341,10 +341,10 @@ The full example configuration looks like this: Plugin "cpu" Type "cpu" - + GroupBy "Host" GroupBy "TypeInstance" - + CalculateSum true CalculateAverage true @@ -420,13 +420,13 @@ The following example calculates the average usage of all "even" CPUs: Plugin "cpu" PluginInstance "/[0,2,4,6,8]$/" Type "cpu" - + SetPlugin "cpu" SetPluginInstance "even-%{aggregation}" - + GroupBy "Host" GroupBy "TypeInstance" - + CalculateAverage true @@ -495,7 +495,7 @@ possibly filtering or messages. # GraphitePrefix "collectd." # GraphiteEscapeChar "_" - + # Receive values from an AMQP broker Host "localhost" @@ -822,17 +822,17 @@ Synopsis: ParseTime false OpCodes true QTypes true - + ServerStats true ZoneMaintStats true ResolverStats false MemoryStats true - + QTypes true ResolverStats true CacheRRSets true - + Zone "127.in-addr.arpa/IN" @@ -973,6 +973,31 @@ at all, B cgroups are selected. =back +=head2 Plugin C + +The I collects CPU usage metrics. + +The following configuration options are available: + +=over 4 + +=item B B|B + +Reports non-idle CPU usage as the "active" value. Defaults to false. + +=item B B|B + +When true reports usage for all cores. When false, reports cpu usage +aggregated over all cores. Implies ValuesPercentage when false. +Defaults to true. + +=item B B|B + +When true report percentage usage instead of tick values. Defaults to false. + +=back + + =head2 Plugin C This plugin doesn't have any options. It reads @@ -1046,6 +1071,10 @@ Username to use if authorization is required to read the page. Password to use if authorization is required to read the page. +=item B B|B + +Enable HTTP digest authentication. + =item B B|B Enable or disable peer SSL certificate verification. See @@ -1157,11 +1186,19 @@ The following options are valid within B blocks: Sets the plugin instance to I. =item B I + =item B I + +=item B B|B + =item B B|B + =item B B|B + =item B I + =item B
I
+ =item B I These options behave exactly equivalent to the appropriate options of the @@ -1250,6 +1287,8 @@ Examples: =item B I +=item B B|B + =item B B|B =item B B|B @@ -2425,12 +2464,12 @@ B ShowCPU true ShowCPUCores true ShowMemory true - + ShowTemperatures true Temperature vddg Temperature vddq IgnoreSelectedTemperature true - + ShowPower true Power total0 Power total1 @@ -2610,19 +2649,19 @@ B Type voltage Instance "input-1" - + RegisterBase 2 RegisterType float Type voltage Instance "input-2" - + Address "192.168.0.42" Port "502" Interval 60 - + Instance "power-supply" Collect "voltage-input-1" @@ -2855,7 +2894,7 @@ Required capabilities are documented below. User "username" Password "aef4Aebe" Interval 30 - + Interval 30 GetNameCache true @@ -2863,12 +2902,12 @@ Required capabilities are documented below. GetBufferCache true GetInodeCache true - + Interval 30 GetBusy true - + Interval 30 GetIO "volume0" @@ -2878,7 +2917,7 @@ Required capabilities are documented below. GetLatency "volume0" IgnoreSelectedLatency false - + Interval 30 GetCapacity "vol0" @@ -2888,15 +2927,15 @@ Required capabilities are documented below. GetSnapshot "vol3" IgnoreSelectedSnapshot false - + Interval 60 - + Interval 30 - + Interval 30 GetCPULoad true @@ -3457,7 +3496,7 @@ signature): # Export to an internal server # (demonstrates usage without additional options) Server "collectd.internal.tld" - + # Export to an external server # (demonstrates usage with signature options) @@ -5525,6 +5564,7 @@ user using (extended) regular expressions, as described in L. Instance "exim" + Interval 60 Regex "S=([1-9][0-9]*)" DSType "CounterAdd" @@ -5551,6 +5591,9 @@ This plugin instance is for all B blocks that B it, until the next B option. This way you can extract several plugin instances from one logfile, handy when parsing syslog and the like. +The B option allows you to define the length of time between reads. If +this is not set, the default Interval will be used. + Each B block has the following options to describe how the match should be performed: @@ -7061,7 +7104,7 @@ Example: Max 100 Satisfy "All" - + # Match if the value of any data source is outside the range of 0 - 100. Min 0 @@ -7243,7 +7286,7 @@ Example: # Replace "example.net" with "example.com" Host "\\" "example.com" - + # Strip "www." from hostnames Host "\\ diff --git a/src/common.c b/src/common.c index 81142fd0..18b5c432 100644 --- a/src/common.c +++ b/src/common.c @@ -650,7 +650,7 @@ int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name) char ident[128]; *ksp_ptr = NULL; - + if (kc == NULL) return (-1); @@ -1236,7 +1236,7 @@ int walk_directory (const char *dir, dirwalk_callback_f callback, while ((ent = readdir (dh)) != NULL) { int status; - + if (include_hidden) { if ((strcmp (".", ent->d_name) == 0) @@ -1399,6 +1399,69 @@ int rate_to_value (value_t *ret_value, gauge_t rate, /* {{{ */ return (0); } /* }}} value_t rate_to_value */ +int value_to_rate (value_t *ret_rate, derive_t value, /* {{{ */ + value_to_rate_state_t *state, + int ds_type, cdtime_t t) +{ + double interval; + + /* Another invalid state: The time is not increasing. */ + if (t <= state->last_time) + { + memset (state, 0, sizeof (*state)); + return (EINVAL); + } + + interval = CDTIME_T_TO_DOUBLE(t - state->last_time); + + /* Previous value is invalid. */ + if (state->last_time == 0) /* {{{ */ + { + if (ds_type == DS_TYPE_DERIVE) + { + state->last_value.derive = value; + } + else if (ds_type == DS_TYPE_COUNTER) + { + state->last_value.counter = (counter_t) value; + } + else if (ds_type == DS_TYPE_ABSOLUTE) + { + state->last_value.absolute = (absolute_t) value; + } + else + { + assert (23 == 42); + } + + state->last_time = t; + return (EAGAIN); + } /* }}} */ + + if (ds_type == DS_TYPE_DERIVE) + { + ret_rate->gauge = (value - state->last_value.derive) / interval; + state->last_value.derive = value; + } + else if (ds_type == DS_TYPE_COUNTER) + { + ret_rate->gauge = (((counter_t)value) - state->last_value.counter) / interval; + state->last_value.counter = (counter_t) value; + } + else if (ds_type == DS_TYPE_ABSOLUTE) + { + ret_rate->gauge = (((absolute_t)value) - state->last_value.absolute) / interval; + state->last_value.absolute = (absolute_t) value; + } + else + { + assert (23 == 42); + } + + state->last_time = t; + return (0); +} /* }}} value_t rate_to_value */ + int service_name_to_port_number (const char *service_name) { struct addrinfo *ai_list; diff --git a/src/common.h b/src/common.h index 67f307c3..29590ff2 100644 --- a/src/common.h +++ b/src/common.h @@ -55,6 +55,13 @@ struct rate_to_value_state_s }; typedef struct rate_to_value_state_s rate_to_value_state_t; +struct value_to_rate_state_s +{ + value_t last_value; + cdtime_t last_time; +}; +typedef struct value_to_rate_state_s value_to_rate_state_t; + char *sstrncpy (char *dest, const char *src, size_t n); __attribute__ ((format(printf,3,4))) @@ -324,6 +331,9 @@ counter_t counter_diff (counter_t old_value, counter_t new_value); int rate_to_value (value_t *ret_value, gauge_t rate, rate_to_value_state_t *state, int ds_type, cdtime_t t); +int value_to_rate (value_t *ret_rate, derive_t value, + value_to_rate_state_t *state, int ds_type, cdtime_t t); + /* Converts a service name (a string) to a port number * (in the range [1-65535]). Returns less than zero on error. */ int service_name_to_port_number (const char *service_name); diff --git a/src/cpu.c b/src/cpu.c index f1aa4abe..2e225fd1 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1,9 +1,9 @@ /** * collectd - src/cpu.c * Copyright (C) 2005-2010 Florian octo Forster - * Copyright (C) 2008 Oleg King - * Copyright (C) 2009 Simon Kuhnle - * Copyright (C) 2009 Manuel Sanmartin + * Copyright (C) 2008 Oleg King + * Copyright (C) 2009 Simon Kuhnle + * Copyright (C) 2009 Manuel Sanmartin * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -11,7 +11,7 @@ * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along @@ -86,6 +86,18 @@ # define CAN_USE_SYSCTL 0 #endif +#define CPU_SUBMIT_USER 0 +#define CPU_SUBMIT_SYSTEM 1 +#define CPU_SUBMIT_WAIT 2 +#define CPU_SUBMIT_NICE 3 +#define CPU_SUBMIT_SWAP 4 +#define CPU_SUBMIT_INTERRUPT 5 +#define CPU_SUBMIT_SOFTIRQ 6 +#define CPU_SUBMIT_STEAL 7 +#define CPU_SUBMIT_IDLE 8 +#define CPU_SUBMIT_ACTIVE 9 +#define CPU_SUBMIT_MAX 10 + #if HAVE_STATGRAB_H # include #endif @@ -100,6 +112,19 @@ # error "No applicable input method." #endif +static const char *cpu_state_names[] = { + "user", + "system", + "wait", + "nice", + "swap", + "interrupt", + "softirq", + "steal", + "idle", + "active" +}; + #ifdef PROCESSOR_CPU_LOAD_INFO static mach_port_t port_host; static processor_port_array_t cpu_list; @@ -107,8 +132,8 @@ static mach_msg_type_number_t cpu_list_len; #if PROCESSOR_TEMPERATURE static int cpu_temp_retry_counter = 0; -static int cpu_temp_retry_step = 1; -static int cpu_temp_retry_max = 1; +static int cpu_temp_retry_step = 1; +static int cpu_temp_retry_max = 1; #endif /* PROCESSOR_TEMPERATURE */ /* #endif PROCESSOR_CPU_LOAD_INFO */ @@ -145,6 +170,86 @@ static int numcpu; static int pnumcpu; #endif /* HAVE_PERFSTAT */ +static value_to_rate_state_t *percents = NULL; +static gauge_t agg_percents[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + +}; +static int percents_cells = 0; +static int cpu_count = 0; + + +static _Bool report_by_cpu = 1; +static _Bool report_percent = 0; +static _Bool report_active = 0; + +static const char *config_keys[] = +{ + "ReportByCpu", + "ReportActive", + "ValuesPercentage" +}; +static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); + + +static int cpu_config (const char *key, const char *value) +{ + if (strcasecmp (key, "ReportByCpu") == 0) { + report_by_cpu = IS_TRUE (value) ? 1 : 0; + if (!report_by_cpu) + report_percent = 1; + } + if (strcasecmp (key, "ValuesPercentage") == 0) { + report_percent = IS_TRUE (value) ? 1 : 0; + if (!report_percent) + report_by_cpu = 1; + } + if (strcasecmp (key, "ReportActive") == 0) + report_active = IS_TRUE (value) ? 1 : 0; + return (-1); +} + +static int cpu_states_grow (void) +{ + void *tmp; + int size; + int i; + + size = cpu_count * CPU_SUBMIT_MAX; /* always alloc for all states */ + + if (size <= 0) + return 0; + + if (percents_cells >= size) + return 0; + + if (percents == NULL) { + percents = malloc(size * sizeof(*percents)); + if (percents == NULL) + return -1; + for (i = 0; i < size; i++) + memset(&percents[i], 0, sizeof(*percents)); + percents_cells = size; + return 0; + } + + tmp = realloc(percents, size * sizeof(*percents)); + + if (tmp == NULL) { + ERROR ("cpu plugin: could not reserve enough space to hold states"); + percents = NULL; + return -1; + } + + for (i = percents_cells; i < size; i++) + memset(&percents[i], 0, sizeof(*percents)); + + percents = tmp; + percents_cells = size; + return 0; +} /* cpu_states_grow */ + + static int init (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE @@ -241,40 +346,156 @@ static int init (void) return (0); } /* int init */ -static void submit (int cpu_num, const char *type_instance, derive_t value) +static void submit_value (int cpu_num, int cpu_state, const char *type, value_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].derive = value; + memcpy(&values[0], &value, sizeof(value)); vl.values = values; vl.values_len = 1; + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i", cpu_num); - sstrncpy (vl.type, "cpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy (vl.type_instance, cpu_state_names[cpu_state], + sizeof (vl.type_instance)); + if (cpu_num >= 0) { + ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), + "%i", cpu_num); + } plugin_dispatch_values (&vl); } +static void submit_percent(int cpu_num, int cpu_state, gauge_t percent) +{ + value_t value; + + value.gauge = percent; + submit_value (cpu_num, cpu_state, "percent", value); +} + +static void submit_derive(int cpu_num, int cpu_state, derive_t derive) +{ + value_t value; + + value.derive = derive; + submit_value (cpu_num, cpu_state, "cpu", value); +} + +static void submit_flush (void) +{ + int i = 0; + + if (report_by_cpu) { + cpu_count = 0; + return; + } + + for (i = 0; i < CPU_SUBMIT_MAX; i++) { + if (agg_percents[i] == -1) + continue; + + submit_percent(-1, i, agg_percents[i] / cpu_count); + agg_percents[i] = -1; + } + cpu_count = 0; +} + +static void submit (int cpu_num, derive_t *derives) +{ + + int i = 0; + + if (!report_percent && report_by_cpu) { + derive_t cpu_active = 0; + for (i = 0; i < CPU_SUBMIT_ACTIVE; i++) + { + if (derives[i] == -1) + continue; + + if (i != CPU_SUBMIT_IDLE) + cpu_active += derives[i]; + + submit_derive(cpu_num, i, derives[i]); + } + if (report_active) + submit_derive(cpu_num, CPU_SUBMIT_ACTIVE, cpu_active); + } + else /* we are reporting percents */ + { + cdtime_t cdt; + gauge_t percent; + gauge_t cpu_total = 0; + gauge_t cpu_active = 0; + gauge_t local_rates[CPU_SUBMIT_MAX]; + + cpu_count++; + if (cpu_states_grow()) + return; + + memset(local_rates, 0, sizeof(local_rates)); + + cdt = cdtime(); + for (i = 0; i < CPU_SUBMIT_ACTIVE; i++) { + value_t rate; + int index; + + if (derives[i] == -1) + continue; + + index = (cpu_num * CPU_SUBMIT_MAX) + i; + if (value_to_rate(&rate, derives[i], &percents[index], + DS_TYPE_DERIVE, cdt) != 0) { + local_rates[i] = -1; + continue; + } + + local_rates[i] = rate.gauge; + cpu_total += rate.gauge; + if (i != CPU_SUBMIT_IDLE) + cpu_active += rate.gauge; + } + if (cpu_total == 0.0) + return; + + if (report_active) + local_rates[CPU_SUBMIT_ACTIVE] = cpu_active; + + for (i = 0; i < CPU_SUBMIT_MAX; i++) { + if (local_rates[i] == -1) + continue; + + percent = (local_rates[i] / cpu_total) * 100; + if (report_by_cpu) + submit_percent (cpu_num, i, percent); + else { + if (agg_percents[i] == -1) + agg_percents[i] = percent; + else + agg_percents[i] += percent; + } + + } + } +} + static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; - + #if PROCESSOR_CPU_LOAD_INFO - derive_t cpu_active; processor_cpu_load_info_data_t cpu_info; - mach_msg_type_number_t cpu_info_len; + mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE - processor_info_data_t cpu_temp; - mach_msg_type_number_t cpu_temp_len; + processor_info_data_t cpu_temp; + mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; @@ -282,6 +503,10 @@ static int cpu_read (void) for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + memset(derives, -1, sizeof(derives)); cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; @@ -299,15 +524,12 @@ static int cpu_read (void) continue; } - submit (cpu, "user", (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]); - submit (cpu, "nice", (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]); - submit (cpu, "system", (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]); - submit (cpu, "idle", (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]); - cpu_active = (derive_t) (cpu_info.cpu_ticks[CPU_STATE_USER] + - cpu_info.cpu_ticks[CPU_STATE_NICE] + - cpu_info.cpu_ticks[CPU_STATE_SYSTEM]); - submit (cpu, "active", cpu_active); - + derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]; + derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]; + derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]; + derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]; + submit (cpu, derives); + #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* @@ -344,7 +566,7 @@ static int cpu_read (void) if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", - (int) cpu_temp_len); + (int) cpu_temp_len); continue; } @@ -352,13 +574,11 @@ static int cpu_read (void) cpu_temp_retry_step = 1; #endif /* PROCESSOR_TEMPERATURE */ } + submit_flush (); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; - derive_t cpu_active; - derive_t user, nice, syst, idle; - derive_t wait, intr, sitr; /* sitr == soft interrupt */ FILE *fh; char buf[1024]; @@ -375,6 +595,10 @@ static int cpu_read (void) while (fgets (buf, 1024, fh) != NULL) { + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) @@ -385,42 +609,29 @@ static int cpu_read (void) continue; cpu = atoi (fields[0] + 3); - user = atoll (fields[1]); - nice = atoll (fields[2]); - syst = atoll (fields[3]); - idle = atoll (fields[4]); - - submit (cpu, "user", user); - submit (cpu, "nice", nice); - submit (cpu, "system", syst); - submit (cpu, "idle", idle); - cpu_active = user + nice + syst; + derives[CPU_SUBMIT_USER] = atoll(fields[1]); + derives[CPU_SUBMIT_NICE] = atoll(fields[2]); + derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]); + derives[CPU_SUBMIT_IDLE] = atoll(fields[4]); if (numfields >= 8) { - wait = atoll (fields[5]); - intr = atoll (fields[6]); - sitr = atoll (fields[7]); - - submit (cpu, "wait", wait); - submit (cpu, "interrupt", intr); - submit (cpu, "softirq", sitr); - - cpu_active += wait + intr + sitr; + derives[CPU_SUBMIT_WAIT] = atoll(fields[5]); + derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]); + derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]); if (numfields >= 9) - cpu_active += (derive_t) atoll (fields[8]); - submit (cpu, "steal", atoll (fields[8])); + derives[CPU_SUBMIT_STEAL] = atoll(fields[8]); } - submit (cpu, "active", cpu_active); + submit(cpu, derives); } + submit_flush(); fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; - derive_t user, syst, idle, wait; static cpu_stat_t cs; if (kc == NULL) @@ -428,20 +639,21 @@ static int cpu_read (void) for (cpu = 0; cpu < numcpu; cpu++) { + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ - idle = (derive_t) cs.cpu_sysinfo.cpu[CPU_IDLE]; - user = (derive_t) cs.cpu_sysinfo.cpu[CPU_USER]; - syst = (derive_t) cs.cpu_sysinfo.cpu[CPU_KERNEL]; - wait = (derive_t) cs.cpu_sysinfo.cpu[CPU_WAIT]; - - submit (ksp[cpu]->ks_instance, "user", user); - submit (ksp[cpu]->ks_instance, "system", syst); - submit (ksp[cpu]->ks_instance, "idle", idle); - submit (ksp[cpu]->ks_instance, "wait", wait); - submit (ksp[cpu]->ks_instance, "active", user + syst + wait); + memset(derives, -1, sizeof(derives)); + derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE]; + derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER]; + derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL]; + derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT]; + submit (ksp[cpu]->ks_instance, derives); } + submit_flush (); /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL @@ -500,16 +712,18 @@ static int cpu_read (void) } for (i = 0; i < numcpu; i++) { - submit (i, "user", cpuinfo[i][CP_USER]); - submit (i, "nice", cpuinfo[i][CP_NICE]); - submit (i, "system", cpuinfo[i][CP_SYS]); - submit (i, "idle", cpuinfo[i][CP_IDLE]); - submit (i, "interrupt", cpuinfo[i][CP_INTR]); - submit (i, "active", cpuinfo[i][CP_USER] + - cpuinfo[i][CP_NICE] + - cpuinfo[i][CP_SYS] + - cpuinfo[i][CP_INTR]); + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; + derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; + derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; + derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; + derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; + submit(i, derives); } + submit_flush(); /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) long cpuinfo[maxcpu][CPUSTATES]; @@ -528,20 +742,26 @@ static int cpu_read (void) } for (i = 0; i < numcpu; i++) { - submit (i, "user", cpuinfo[i][CP_USER]); - submit (i, "nice", cpuinfo[i][CP_NICE]); - submit (i, "system", cpuinfo[i][CP_SYS]); - submit (i, "idle", cpuinfo[i][CP_IDLE]); - submit (i, "interrupt", cpuinfo[i][CP_INTR]); - submit (i, "active", cpuinfo[i][CP_USER] + - cpuinfo[i][CP_NICE] + - cpuinfo[i][CP_SYS] + - cpuinfo[i][CP_INTR]); + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; + derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; + derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; + derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; + derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; + submit(i, derives); } + submit_flush(); + /* #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; cpuinfo_size = sizeof (cpuinfo); @@ -553,19 +773,21 @@ static int cpu_read (void) return (-1); } - submit (0, "user", cpuinfo[CP_USER]); - submit (0, "nice", cpuinfo[CP_NICE]); - submit (0, "system", cpuinfo[CP_SYS]); - submit (0, "idle", cpuinfo[CP_IDLE]); - submit (0, "interrupt", cpuinfo[CP_INTR]); - submit (0, "active", cpuinfo[CP_USER] + - cpuinfo[CP_NICE] + - cpuinfo[CP_SYS] + - cpuinfo[CP_INTR]); + derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER]; + derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS]; + derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE]; + derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE]; + derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR]; + submit(0, derives); + submit_flush(); + /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; cs = sg_get_cpu_stats (); if (cs == NULL) @@ -574,18 +796,14 @@ static int cpu_read (void) return (-1); } - submit (0, "idle", (derive_t) cs->idle); - submit (0, "nice", (derive_t) cs->nice); - submit (0, "swap", (derive_t) cs->swap); - submit (0, "system", (derive_t) cs->kernel); - submit (0, "user", (derive_t) cs->user); - submit (0, "wait", (derive_t) cs->iowait); - submit (0, "active", (derive_t) cs->nice + - cs->swap + - cs->kernel + - cs->user + - cs->iowait + - cs->nice); + derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle; + derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice; + derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap; + derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel; + derives[CPU_SUBMIT_USER] = (derive_t) cs->user; + derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait; + submit(0, derives); + submit_flush(); /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) @@ -600,10 +818,10 @@ static int cpu_read (void) sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } - - if (pnumcpu != numcpu || perfcpu == NULL) + + if (pnumcpu != numcpu || perfcpu == NULL) { - if (perfcpu != NULL) + if (perfcpu != NULL) free(perfcpu); perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); } @@ -618,16 +836,18 @@ static int cpu_read (void) return (-1); } - for (i = 0; i < cpus; i++) + for (i = 0; i < cpus; i++) { - submit (i, "idle", (derive_t) perfcpu[i].idle); - submit (i, "system", (derive_t) perfcpu[i].sys); - submit (i, "user", (derive_t) perfcpu[i].user); - submit (i, "wait", (derive_t) perfcpu[i].wait); - submit (i, "active", (derive_t) perfcpu[i].sys + - perfcpu[i].user + - perfcpu[i].wait); + derive_t derives[CPU_SUBMIT_MAX] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle; + derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys; + derives[CPU_SUBMIT_USER] = perfcpu[i].user; + derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait; + submit(i, derives); } + submit_flush(); #endif /* HAVE_PERFSTAT */ return (0); @@ -636,5 +856,6 @@ static int cpu_read (void) void module_register (void) { plugin_register_init ("cpu", init); + plugin_register_config ("cpu", cpu_config, config_keys, config_keys_num); plugin_register_read ("cpu", cpu_read); } /* void module_register */ diff --git a/src/curl.c b/src/curl.c index ae238345..e189df6b 100644 --- a/src/curl.c +++ b/src/curl.c @@ -58,6 +58,7 @@ struct web_page_s /* {{{ */ char *user; char *pass; char *credentials; + _Bool digest; _Bool verify_peer; _Bool verify_host; char *cacert; @@ -388,6 +389,13 @@ static int cc_page_init_curl (web_page_t *wp) /* {{{ */ ssnprintf (wp->credentials, credentials_size, "%s:%s", wp->user, (wp->pass == NULL) ? "" : wp->pass); curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials); + + if (wp->digest) + { + curl_easy_setopt (wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt (wp->curl, CURLOPT_USERNAME, wp->user); + curl_easy_setopt (wp->curl, CURLOPT_PASSWORD, wp->pass); + } } curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer); @@ -425,6 +433,7 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ page->url = NULL; page->user = NULL; page->pass = NULL; + page->digest = 0; page->verify_peer = 1; page->verify_host = 1; page->response_time = 0; @@ -450,6 +459,8 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string (child, &page->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &page->pass); + else if (strcasecmp ("Digest", child->key) == 0) + status = cf_util_get_boolean (child, &page->digest); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &page->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) diff --git a/src/curl_json.c b/src/curl_json.c index 36cc468b..a9db9250 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -71,6 +71,7 @@ struct cj_s /* {{{ */ char *user; char *pass; char *credentials; + _Bool digest; _Bool verify_peer; _Bool verify_host; char *cacert; @@ -609,6 +610,13 @@ static int cj_init_curl (cj_t *db) /* {{{ */ ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); + + if (db->digest) + { + curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); + curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass); + } } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (long) db->verify_peer); @@ -675,6 +683,8 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string (child, &db->user); else if (db->url && strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); + else if (strcasecmp ("Digest", child->key) == 0) + status = cf_util_get_boolean (child, &db->digest); else if (db->url && strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_peer); else if (db->url && strcasecmp ("VerifyHost", child->key) == 0) diff --git a/src/curl_xml.c b/src/curl_xml.c index 8d505610..6d36d29d 100644 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@ -76,6 +76,7 @@ struct cx_s /* {{{ */ char *user; char *pass; char *credentials; + _Bool digest; _Bool verify_peer; _Bool verify_host; char *cacert; @@ -860,6 +861,13 @@ static int cx_init_curl (cx_t *db) /* {{{ */ ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); + + if (db->digest) + { + curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); + curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass); + } } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); @@ -926,6 +934,8 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string (child, &db->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); + else if (strcasecmp ("Digest", child->key) == 0) + status = cf_util_get_boolean (child, &db->digest); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) diff --git a/src/memory.c b/src/memory.c index e8ba9348..b33c1f85 100644 --- a/src/memory.c +++ b/src/memory.c @@ -487,6 +487,7 @@ static int memory_read (void) /* {{{ */ vl.values_len = STATIC_ARRAY_SIZE (v); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "memory", sizeof (vl.plugin)); + sstrncpy (vl.type, "memory", sizeof (vl.type)); vl.time = cdtime (); return (memory_read_internal (&vl)); diff --git a/src/tail.c b/src/tail.c index bcb15725..20f2a9b4 100644 --- a/src/tail.c +++ b/src/tail.c @@ -28,6 +28,7 @@ * * * Instance "exim" + * Interval 60 * * Regex "S=([1-9][0-9]*)" * ExcludeRegex "U=root.*S=" @@ -46,11 +47,13 @@ struct ctail_config_match_s int flags; char *type; char *type_instance; + cdtime_t interval; }; typedef struct ctail_config_match_s ctail_config_match_t; cu_tail_match_t **tail_match_list = NULL; size_t tail_match_list_num = 0; +cdtime_t tail_match_list_intervals[255]; static int ctail_config_add_match_dstype (ctail_config_match_t *cm, oconfig_item_t *ci) @@ -123,7 +126,7 @@ static int ctail_config_add_match_dstype (ctail_config_match_t *cm, } /* int ctail_config_add_match_dstype */ static int ctail_config_add_match (cu_tail_match_t *tm, - const char *plugin_instance, oconfig_item_t *ci) + const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval) { ctail_config_match_t cm; int status; @@ -190,7 +193,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm, if (status == 0) { status = tail_match_add_match_simple (tm, cm.regex, cm.excluderegex, - cm.flags, "tail", plugin_instance, cm.type, cm.type_instance); + cm.flags, "tail", plugin_instance, cm.type, cm.type_instance, interval); if (status != 0) { @@ -209,6 +212,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm, static int ctail_config_add_file (oconfig_item_t *ci) { cu_tail_match_t *tm; + cdtime_t interval = 0; char *plugin_instance = NULL; int num_matches = 0; int status; @@ -233,19 +237,20 @@ static int ctail_config_add_file (oconfig_item_t *ci) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Match", option->key) == 0) + if (strcasecmp ("Instance", option->key) == 0) + status = cf_util_get_string (option, &plugin_instance); + else if (strcasecmp ("Interval", option->key) == 0) + cf_util_get_cdtime (option, &interval); + else if (strcasecmp ("Match", option->key) == 0) { - status = ctail_config_add_match (tm, plugin_instance, option); + status = ctail_config_add_match (tm, plugin_instance, option, interval); if (status == 0) num_matches++; /* Be mild with failed matches.. */ status = 0; } - else if (strcasecmp ("Instance", option->key) == 0) - status = cf_util_get_string (option, &plugin_instance); else { - WARNING ("tail plugin: Option `%s' not allowed here.", option->key); status = -1; } @@ -275,6 +280,7 @@ static int ctail_config_add_file (oconfig_item_t *ci) tail_match_list = temp; tail_match_list[tail_match_list_num] = tm; + tail_match_list_intervals[tail_match_list_num] = interval; tail_match_list_num++; } @@ -300,41 +306,43 @@ static int ctail_config (oconfig_item_t *ci) return (0); } /* int ctail_config */ -static int ctail_init (void) +static int ctail_read (user_data_t *ud) { - if (tail_match_list_num == 0) + int status; + + status = tail_match_read ((cu_tail_match_t *)ud->data); + if (status != 0) { - WARNING ("tail plugin: File list is empty. Returning an error."); + ERROR ("tail plugin: tail_match_read failed."); return (-1); } return (0); -} /* int ctail_init */ +} /* int ctail_read */ -static int ctail_read (void) +static int ctail_init (void) { - int success = 0; + struct timespec cb_interval; + char str[255]; + user_data_t ud; size_t i; - for (i = 0; i < tail_match_list_num; i++) + if (tail_match_list_num == 0) { - int status; + WARNING ("tail plugin: File list is empty. Returning an error."); + return (-1); + } - status = tail_match_read (tail_match_list[i]); - if (status != 0) - { - ERROR ("tail plugin: tail_match_read[%zu] failed.", i); - } - else - { - success++; - } + for (i = 0; i < tail_match_list_num; i++) + { + ud.data = (void *)tail_match_list[i]; + ssnprintf(str, sizeof(str), "tail-%zu", i); + CDTIME_T_TO_TIMESPEC (tail_match_list_intervals[i], &cb_interval); + plugin_register_complex_read (NULL, str, ctail_read, &cb_interval, &ud); } - if (success == 0) - return (-1); return (0); -} /* int ctail_read */ +} /* int ctail_init */ static int ctail_shutdown (void) { @@ -355,7 +363,6 @@ void module_register (void) { plugin_register_complex_config ("tail", ctail_config); plugin_register_init ("tail", ctail_init); - plugin_register_read ("tail", ctail_read); plugin_register_shutdown ("tail", ctail_shutdown); } /* void module_register */ diff --git a/src/utils_tail_match.c b/src/utils_tail_match.c index 8ae2208c..13b518b3 100644 --- a/src/utils_tail_match.c +++ b/src/utils_tail_match.c @@ -37,6 +37,7 @@ struct cu_tail_match_simple_s char plugin_instance[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; + cdtime_t interval; }; typedef struct cu_tail_match_simple_s cu_tail_match_simple_t; @@ -54,6 +55,7 @@ struct cu_tail_match_s int flags; cu_tail_t *tail; + cdtime_t interval; cu_tail_match_match_t *matches; size_t matches_num; }; @@ -88,6 +90,7 @@ static int simple_submit_match (cu_match_t *match, void *user_data) sstrncpy (vl.type_instance, data->type_instance, sizeof (vl.type_instance)); + vl.interval = data->interval; plugin_dispatch_values (&vl); if (match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) @@ -180,6 +183,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, obj->matches = temp; obj->matches_num++; + DEBUG ("tail_match_add_match interval %lf", CDTIME_T_TO_DOUBLE(((cu_tail_match_simple_t *)user_data)->interval)); temp = obj->matches + (obj->matches_num - 1); temp->match = match; @@ -193,7 +197,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, int tail_match_add_match_simple (cu_tail_match_t *obj, const char *regex, const char *excluderegex, int ds_type, const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance) + const char *type, const char *type_instance, const cdtime_t interval) { cu_match_t *match; cu_tail_match_simple_t *user_data; @@ -221,6 +225,8 @@ int tail_match_add_match_simple (cu_tail_match_t *obj, sstrncpy (user_data->type_instance, type_instance, sizeof (user_data->type_instance)); + user_data->interval = interval; + status = tail_match_add_match (obj, match, simple_submit_match, user_data, free); diff --git a/src/utils_tail_match.h b/src/utils_tail_match.h index 76597457..abd98b63 100644 --- a/src/utils_tail_match.h +++ b/src/utils_tail_match.h @@ -105,7 +105,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, int tail_match_add_match_simple (cu_tail_match_t *obj, const char *regex, const char *excluderegex, int ds_type, const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance); + const char *type, const char *type_instance, const cdtime_t interval); /* * NAME diff --git a/src/write_riemann.c b/src/write_riemann.c index c890818d..e85e9436 100644 --- a/src/write_riemann.c +++ b/src/write_riemann.c @@ -425,6 +425,9 @@ static Msg *riemann_notification_to_protobuf (struct riemann_host *host, /* {{{ n->type, n->type_instance); event->service = strdup (&service_buffer[1]); + if (n->message[0] != 0) + riemann_event_add_attribute (event, "description", n->message); + /* Pull in values from threshold and add extra attributes */ for (meta = n->meta; meta != NULL; meta = meta->next) {