char *hostname = NULL;
/* In-band Communication Configuration */
-int driver_type = IPMI_MONITORING_DRIVER_TYPE_KCS; /* or -1 for default */
+int driver_type = -1; // IPMI_MONITORING_DRIVER_TYPE_KCS; /* or -1 for default */
int disable_auto_probe = 0; /* probe for in-band device */
unsigned int driver_address = 0; /* not used if probing */
unsigned int register_spacing = 0; /* not used if probing */
char *driver_device = NULL; /* not used if probing */
/* Out-of-band Communication Configuration */
-int protocol_version = IPMI_MONITORING_PROTOCOL_VERSION_1_5; /* or -1 for default */
+int protocol_version = -1; //IPMI_MONITORING_PROTOCOL_VERSION_1_5; /* or -1 for default */
char *username = "foousername";
char *password = "foopassword";
unsigned char *k_g = NULL;
unsigned int k_g_len = 0;
-int privilege_level = IPMI_MONITORING_PRIVILEGE_LEVEL_USER; /* or -1 for default */
-int authentication_type = IPMI_MONITORING_AUTHENTICATION_TYPE_MD5; /* or -1 for default */
+int privilege_level = -1; // IPMI_MONITORING_PRIVILEGE_LEVEL_USER; /* or -1 for default */
+int authentication_type = -1; // IPMI_MONITORING_AUTHENTICATION_TYPE_MD5; /* or -1 for default */
int cipher_suite_id = 0; /* or -1 for default */
int session_timeout = 0; /* 0 for default */
int retransmission_timeout = 0; /* 0 for default */
static int netdata_update_every = 5;
static int netdata_priority = 90000;
+static int netdata_do_sel = 1;
static size_t netdata_sensors_updated = 0;
static size_t netdata_sensors_collected = 0;
static size_t netdata_sel_events = 0;
+static size_t netdata_sensors_states_nominal = 0;
+static size_t netdata_sensors_states_warning = 0;
+static size_t netdata_sensors_states_critical = 0;
struct sensor {
int record_id;
netdata_sensors_updated = 0;
netdata_sensors_collected = 0;
netdata_sel_events = 0;
+
+ netdata_sensors_states_nominal = 0;
+ netdata_sensors_states_warning = 0;
+ netdata_sensors_states_critical = 0;
}
static void send_chart_to_netdata_for_units(int units) {
switch(units) {
case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
printf("CHART ipmi.temperatures_c '' 'System Celcius Temperatures read by IPMI' 'Celcius' 'temperatures' 'ipmi.temperatures_c' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 10
, netdata_update_every
);
break;
case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
printf("CHART ipmi.temperatures_f '' 'System Fahrenheit Temperatures read by IPMI' 'Fahrenheit' 'temperatures' 'ipmi.temperatures_f' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 11
, netdata_update_every
);
break;
case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
printf("CHART ipmi.volts '' 'System Voltages read by IPMI' 'Volts' 'voltages' 'ipmi.voltages' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 12
, netdata_update_every
);
break;
case IPMI_MONITORING_SENSOR_UNITS_AMPS:
printf("CHART ipmi.amps '' 'System Current read by IPMI' 'Amps' 'current' 'ipmi.amps' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 13
, netdata_update_every
);
break;
case IPMI_MONITORING_SENSOR_UNITS_RPM:
printf("CHART ipmi.rpm '' 'System Fans read by IPMI' 'RPM' 'fans' 'ipmi.rpm' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 14
, netdata_update_every
);
break;
case IPMI_MONITORING_SENSOR_UNITS_WATTS:
printf("CHART ipmi.watts '' 'System Power read by IPMI' 'Watts' 'power' 'ipmi.watts' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 5
, netdata_update_every
);
break;
case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
printf("CHART ipmi.percent '' 'System Metrics read by IPMI' '%%' 'other' 'ipmi.percent' 'line' %d %d\n"
- , netdata_priority
+ , netdata_priority + 15
, netdata_update_every
);
break;
}
static void send_metrics_to_netdata() {
- static int sel_chart_generated = 0;
+ static int sel_chart_generated = 0, sensors_states_chart_generated = 0;
struct sensor *sn;
- if(!sel_chart_generated) {
- printf("CHART ipmi.events '' 'IPMI Events' 'events' 'events' 'ipmi.sel' 'area' %d %d\n"
- , netdata_priority
+ if(netdata_do_sel && !sel_chart_generated) {
+ sel_chart_generated = 1;
+ printf("CHART ipmi.events '' 'IPMI Events' 'events' 'events' ipmi.sel area %d %d\n"
+ , netdata_priority + 2
, netdata_update_every
);
printf("DIMENSION events '' absolute 1 1\n");
}
+ if(!sensors_states_chart_generated) {
+ sensors_states_chart_generated = 1;
+ printf("CHART ipmi.sensors_states '' 'IPMI Sensors State' 'sensors' 'states' ipmi.sensors_states line %d %d\n"
+ , netdata_priority + 1
+ , netdata_update_every
+ );
+ printf("DIMENSION nominal '' absolute 1 1\n");
+ printf("DIMENSION critical '' absolute 1 1\n");
+ printf("DIMENSION warning '' absolute 1 1\n");
+ }
+
// generate the CHART/DIMENSION lines, if we have to
for(sn = sensors_root; sn; sn = sn->next)
if(sn->updated && !sn->exposed && !sn->ignore)
send_chart_to_netdata_for_units(sn->sensor_units);
- printf("BEGIN ipmi.events\nSET events = %zu\nEND\n", netdata_sel_events);
+ if(netdata_do_sel) {
+ printf(
+ "BEGIN ipmi.events\n"
+ "SET events = %zu\n"
+ "END\n"
+ , netdata_sel_events
+ );
+ }
+
+ printf(
+ "BEGIN ipmi.sensors_states\n"
+ "SET nominal = %zu\n"
+ "SET warning = %zu\n"
+ "SET critical = %zu\n"
+ "END\n"
+ , netdata_sensors_states_nominal
+ , netdata_sensors_states_warning
+ , netdata_sensors_states_critical
+ );
// send metrics to netdata
for(sn = sensors_root; sn; sn = sn->next)
break;
}
-/* switch(sensor_state) {
+ switch(sensor_state) {
case IPMI_MONITORING_STATE_NOMINAL:
+ netdata_sensors_states_nominal++;
+ break;
+
case IPMI_MONITORING_STATE_WARNING:
+ netdata_sensors_states_warning++;
+ break;
+
case IPMI_MONITORING_STATE_CRITICAL:
+ netdata_sensors_states_critical++;
+ break;
+
default:
break;
}
-*/
}
static void netdata_get_sel(
errno = 0;
if (_ipmimonitoring_sensors(ipmi_config) < 0) return -1;
- if (_ipmimonitoring_sel (ipmi_config) < 0) return -2;
+
+ if(netdata_do_sel) {
+ if(_ipmimonitoring_sel(ipmi_config) < 0) return -2;
+ }
return 0;
}
sleep_usec(end - start);
}
- // so, we assume it needed 3x the time
+ // so, we assume it needed 2x the time
// we find the average in microseconds
// and we round-up to the closest second
- return (( total * 3 / checks / 1000000 ) + 1);
+ return (( total * 2 / checks / 1000000 ) + 1);
}
int main (int argc, char **argv) {
}
}
- if(strcmp("debug", argv[i]) == 0) {
+ if(strcmp("version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0 || strcmp("-V", argv[i]) == 0) {
+ printf("freeipmi.plugin %s\n", VERSION);
+ exit(0);
+ }
+ else if(strcmp("debug", argv[i]) == 0) {
debug = 1;
continue;
}
+ else if(strcmp("sel", argv[i]) == 0) {
+ netdata_do_sel = 1;
+ continue;
+ }
+ else if(strcmp("no-sel", argv[i]) == 0) {
+ netdata_do_sel = 0;
+ continue;
+ }
else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
fprintf(stderr,
"\n"
- "netdata freeipmi.plugin " VERSION "\n"
- "Usage:\n"
+ " netdata freeipmi.plugin %s\n"
+ " Copyright (C) 2016-2017 Costa Tsaousis <costa@tsaousis.gr>\n"
+ " Released under GNU General Public License v3 or later.\n"
+ " All rights reserved.\n"
+ "\n"
+ " This program is a data collector plugin for netdata.\n"
+ "\n"
+ " Available command line options:\n"
+ "\n"
+ " SECONDS data collection frequency\n"
+ " minimum: %d\n"
+ "\n"
+ " debug enable verbose output\n"
+ " default: disabled\n"
+ "\n"
+ " sel\n"
+ " no-sel enable/disable SEL collection\n"
+ " default: %s\n"
+ "\n"
+ " hostname HOST\n"
+ " username USER\n"
+ " password PASS connect to remote IPMI host\n"
+ " default: local IPMI processor\n"
+ "\n"
+ " sdr-cache-dir PATH directory for SDR cache files\n"
+ " default: %s\n"
+ "\n"
+ " sensor-config-file FILE filename to read sensor configuration\n"
+ " default: %s\n"
+ "\n"
+ " -v\n"
+ " -V\n"
+ " version print version and exit\n"
+ "\n"
+ " Linux kernel module for IPMI is CPU hungry.\n"
+ " On Linux run this to lower kipmiN CPU utilization:\n"
+ " # echo 10 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us\n"
+ "\n"
+ " or create: /etc/modprobe.d/ipmi.conf with these contents:\n"
+ " options ipmi_si kipmid_max_busy_us=10\n"
"\n"
- " freeipmi.plugin [OPTIONS]\n"
+ " For more information:\n"
+ " https://github.com/firehol/netdata/wiki/monitoring-IPMI\n"
"\n"
- "Available options:\n"
- " NUMBER, sets the data collection frequency\n"
- " debug, enables verbose output\n"
- " hostname X, sets the remote host to connect to\n"
- " username X, sets the username to authenticate at the remote host\n"
- " password X, sets the password to authenticate at the remote host\n"
- " sdr-cache-dir X, sets the directory to save SDR cache files\n"
- " sensor-config-file X, set the filename to read sensor configuration\n"
+ , VERSION
+ , netdata_update_every
+ , netdata_do_sel?"enabled":"disabled"
+ , sdr_cache_directory?sdr_cache_directory:"system default"
+ , sensor_config_file?sensor_config_file:"system default"
);
exit(1);
}
else if(i < argc && strcmp("hostname", argv[i]) == 0) {
- hostname = argv[++i];
+ hostname = strdupz(argv[++i]);
+ char *s = argv[i];
+ // mask it be hidden from the process tree
+ while(*s) *s++ = 'x';
if(debug) fprintf(stderr, "freeipmi.plugin: hostname set to '%s'\n", hostname);
continue;
}
else if(i < argc && strcmp("username", argv[i]) == 0) {
- username = argv[++i];
+ username = strdupz(argv[++i]);
+ char *s = argv[i];
+ // mask it be hidden from the process tree
+ while(*s) *s++ = 'x';
if(debug) fprintf(stderr, "freeipmi.plugin: username set to '%s'\n", username);
continue;
}
else if(i < argc && strcmp("password", argv[i]) == 0) {
- password = argv[++i];
+ password = strdupz(argv[++i]);
+ char *s = argv[i];
+ // mask it be hidden from the process tree
+ while(*s) *s++ = 'x';
if(debug) fprintf(stderr, "freeipmi.plugin: password set to '%s'\n", password);
continue;
}
error("freeipmi.plugin: ignoring parameter '%s'", argv[i]);
}
- if(freq > 0 && freq < netdata_update_every)
+ if(freq > netdata_update_every)
netdata_update_every = freq;
else if(freq)