2 * netdata freeipmi.plugin
3 * Copyright (C) 2017 Costa Tsaousis
7 * ipmimonitoring-sensors.c,v 1.51 2016/11/02 23:46:24 chu11 Exp
8 * ipmimonitoring-sel.c,v 1.51 2016/11/02 23:46:24 chu11 Exp
10 * Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
11 * Copyright (C) 2006-2007 The Regents of the University of California.
12 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
13 * Written by Albert Chu <chu11@llnl.gov>
30 #include <ipmi_monitoring.h>
31 #include <ipmi_monitoring_bitmasks.h>
33 /* Communication Configuration - Initialize accordingly */
35 /* Hostname, NULL for In-band communication, non-null for a hostname */
36 char *hostname = NULL;
38 /* In-band Communication Configuration */
39 int driver_type = IPMI_MONITORING_DRIVER_TYPE_KCS; /* or -1 for default */
40 int disable_auto_probe = 0; /* probe for in-band device */
41 unsigned int driver_address = 0; /* not used if probing */
42 unsigned int register_spacing = 0; /* not used if probing */
43 char *driver_device = NULL; /* not used if probing */
45 /* Out-of-band Communication Configuration */
46 int protocol_version = IPMI_MONITORING_PROTOCOL_VERSION_1_5; /* or -1 for default */
47 char *username = "foousername";
48 char *password = "foopassword";
49 unsigned char *k_g = NULL;
50 unsigned int k_g_len = 0;
51 int privilege_level = IPMI_MONITORING_PRIVILEGE_LEVEL_USER; /* or -1 for default */
52 int authentication_type = IPMI_MONITORING_AUTHENTICATION_TYPE_MD5; /* or -1 for default */
53 int cipher_suite_id = 0; /* or -1 for default */
54 int session_timeout = 0; /* 0 for default */
55 int retransmission_timeout = 0; /* 0 for default */
57 /* Workarounds - specify workaround flags if necessary */
58 unsigned int workaround_flags = 0;
60 /* Initialize w/ record id numbers to only monitor specific record ids */
61 unsigned int record_ids[] = {0};
62 unsigned int record_ids_length = 0;
64 /* Initialize w/ sensor types to only monitor specific sensor types
65 * see ipmi_monitoring.h sensor types list.
67 unsigned int sensor_types[] = {0};
68 unsigned int sensor_types_length = 0;
70 /* Set to an appropriate alternate if desired */
71 char *sdr_cache_directory = "/tmp";
72 char *sensor_config_file = NULL;
74 /* Set to 1 or 0 to enable these sensor reading flags
75 * - See ipmi_monitoring.h for descriptions of these flags.
77 int reread_sdr_cache = 0;
78 int ignore_non_interpretable_sensors = 1;
79 int bridge_sensors = 0;
80 int interpret_oem_data = 0;
81 int shared_sensors = 0;
82 int discrete_reading = 0;
83 int ignore_scanning_disabled = 0;
84 int assume_bmc_owner = 0;
85 int entity_sensor_names = 0;
87 /* Initialization flags
89 * Most commonly bitwise OR IPMI_MONITORING_FLAGS_DEBUG and/or
90 * IPMI_MONITORING_FLAGS_DEBUG_IPMI_PACKETS for extra debugging
93 unsigned int ipmimonitoring_init_flags = 0;
97 // ----------------------------------------------------------------------------
100 /* Initialize w/ date range to only monitoring specific date range */
101 char *date_begin = NULL; /* use MM/DD/YYYY format */
102 char *date_end = NULL; /* use MM/DD/YYYY format */
104 int assume_system_event_record = 0;
106 char *sel_config_file = NULL;
109 // ----------------------------------------------------------------------------
110 // functions common to sensors and SEL
113 _init_ipmi_config (struct ipmi_monitoring_ipmi_config *ipmi_config)
115 assert (ipmi_config);
117 ipmi_config->driver_type = driver_type;
118 ipmi_config->disable_auto_probe = disable_auto_probe;
119 ipmi_config->driver_address = driver_address;
120 ipmi_config->register_spacing = register_spacing;
121 ipmi_config->driver_device = driver_device;
123 ipmi_config->protocol_version = protocol_version;
124 ipmi_config->username = username;
125 ipmi_config->password = password;
126 ipmi_config->k_g = k_g;
127 ipmi_config->k_g_len = k_g_len;
128 ipmi_config->privilege_level = privilege_level;
129 ipmi_config->authentication_type = authentication_type;
130 ipmi_config->cipher_suite_id = cipher_suite_id;
131 ipmi_config->session_timeout_len = session_timeout;
132 ipmi_config->retransmission_timeout_len = retransmission_timeout;
134 ipmi_config->workaround_flags = workaround_flags;
137 #ifdef NETDATA_COMMENTED
139 _get_sensor_type_string (int sensor_type)
143 case IPMI_MONITORING_SENSOR_TYPE_RESERVED:
145 case IPMI_MONITORING_SENSOR_TYPE_TEMPERATURE:
146 return ("Temperature");
147 case IPMI_MONITORING_SENSOR_TYPE_VOLTAGE:
149 case IPMI_MONITORING_SENSOR_TYPE_CURRENT:
151 case IPMI_MONITORING_SENSOR_TYPE_FAN:
153 case IPMI_MONITORING_SENSOR_TYPE_PHYSICAL_SECURITY:
154 return ("Physical Security");
155 case IPMI_MONITORING_SENSOR_TYPE_PLATFORM_SECURITY_VIOLATION_ATTEMPT:
156 return ("Platform Security Violation Attempt");
157 case IPMI_MONITORING_SENSOR_TYPE_PROCESSOR:
158 return ("Processor");
159 case IPMI_MONITORING_SENSOR_TYPE_POWER_SUPPLY:
160 return ("Power Supply");
161 case IPMI_MONITORING_SENSOR_TYPE_POWER_UNIT:
162 return ("Power Unit");
163 case IPMI_MONITORING_SENSOR_TYPE_COOLING_DEVICE:
164 return ("Cooling Device");
165 case IPMI_MONITORING_SENSOR_TYPE_OTHER_UNITS_BASED_SENSOR:
166 return ("Other Units Based Sensor");
167 case IPMI_MONITORING_SENSOR_TYPE_MEMORY:
169 case IPMI_MONITORING_SENSOR_TYPE_DRIVE_SLOT:
170 return ("Drive Slot");
171 case IPMI_MONITORING_SENSOR_TYPE_POST_MEMORY_RESIZE:
172 return ("POST Memory Resize");
173 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS:
174 return ("System Firmware Progress");
175 case IPMI_MONITORING_SENSOR_TYPE_EVENT_LOGGING_DISABLED:
176 return ("Event Logging Disabled");
177 case IPMI_MONITORING_SENSOR_TYPE_WATCHDOG1:
178 return ("Watchdog 1");
179 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_EVENT:
180 return ("System Event");
181 case IPMI_MONITORING_SENSOR_TYPE_CRITICAL_INTERRUPT:
182 return ("Critical Interrupt");
183 case IPMI_MONITORING_SENSOR_TYPE_BUTTON_SWITCH:
184 return ("Button/Switch");
185 case IPMI_MONITORING_SENSOR_TYPE_MODULE_BOARD:
186 return ("Module/Board");
187 case IPMI_MONITORING_SENSOR_TYPE_MICROCONTROLLER_COPROCESSOR:
188 return ("Microcontroller/Coprocessor");
189 case IPMI_MONITORING_SENSOR_TYPE_ADD_IN_CARD:
190 return ("Add In Card");
191 case IPMI_MONITORING_SENSOR_TYPE_CHASSIS:
193 case IPMI_MONITORING_SENSOR_TYPE_CHIP_SET:
195 case IPMI_MONITORING_SENSOR_TYPE_OTHER_FRU:
196 return ("Other Fru");
197 case IPMI_MONITORING_SENSOR_TYPE_CABLE_INTERCONNECT:
198 return ("Cable/Interconnect");
199 case IPMI_MONITORING_SENSOR_TYPE_TERMINATOR:
200 return ("Terminator");
201 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_BOOT_INITIATED:
202 return ("System Boot Initiated");
203 case IPMI_MONITORING_SENSOR_TYPE_BOOT_ERROR:
204 return ("Boot Error");
205 case IPMI_MONITORING_SENSOR_TYPE_OS_BOOT:
207 case IPMI_MONITORING_SENSOR_TYPE_OS_CRITICAL_STOP:
208 return ("OS Critical Stop");
209 case IPMI_MONITORING_SENSOR_TYPE_SLOT_CONNECTOR:
210 return ("Slot/Connector");
211 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE:
212 return ("System ACPI Power State");
213 case IPMI_MONITORING_SENSOR_TYPE_WATCHDOG2:
214 return ("Watchdog 2");
215 case IPMI_MONITORING_SENSOR_TYPE_PLATFORM_ALERT:
216 return ("Platform Alert");
217 case IPMI_MONITORING_SENSOR_TYPE_ENTITY_PRESENCE:
218 return ("Entity Presence");
219 case IPMI_MONITORING_SENSOR_TYPE_MONITOR_ASIC_IC:
220 return ("Monitor ASIC/IC");
221 case IPMI_MONITORING_SENSOR_TYPE_LAN:
223 case IPMI_MONITORING_SENSOR_TYPE_MANAGEMENT_SUBSYSTEM_HEALTH:
224 return ("Management Subsystem Health");
225 case IPMI_MONITORING_SENSOR_TYPE_BATTERY:
227 case IPMI_MONITORING_SENSOR_TYPE_SESSION_AUDIT:
228 return ("Session Audit");
229 case IPMI_MONITORING_SENSOR_TYPE_VERSION_CHANGE:
230 return ("Version Change");
231 case IPMI_MONITORING_SENSOR_TYPE_FRU_STATE:
232 return ("FRU State");
235 return ("Unrecognized");
237 #endif // NETDATA_COMMENTED
240 // ----------------------------------------------------------------------------
241 // BEGIN NETDATA CODE
243 static int debug = 0;
245 static int netdata_update_every = 5;
246 static int netdata_priority = 90000;
248 static size_t netdata_sensors_updated = 0;
249 static size_t netdata_sensors_collected = 0;
250 static size_t netdata_sel_events = 0;
260 int sensor_reading_type;
263 uint32_t uint32_value;
272 } *sensors_root = NULL;
274 static void netdata_mark_as_not_updated() {
276 for(sn = sensors_root; sn ;sn = sn->next)
277 sn->updated = sn->sent = 0;
279 netdata_sensors_updated = 0;
280 netdata_sensors_collected = 0;
281 netdata_sel_events = 0;
284 static void send_chart_to_netdata_for_units(int units) {
288 case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
289 printf("CHART ipmi.temperatures_c '' 'System Celcius Temperatures read by IPMI' 'Celcius' 'temperatures' 'ipmi.temperatures_c' 'line' %d %d\n"
291 , netdata_update_every
295 case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
296 printf("CHART ipmi.temperatures_f '' 'System Fahrenheit Temperatures read by IPMI' 'Fahrenheit' 'temperatures' 'ipmi.temperatures_f' 'line' %d %d\n"
298 , netdata_update_every
302 case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
303 printf("CHART ipmi.volts '' 'System Voltages read by IPMI' 'Volts' 'voltages' 'ipmi.voltages' 'line' %d %d\n"
305 , netdata_update_every
309 case IPMI_MONITORING_SENSOR_UNITS_AMPS:
310 printf("CHART ipmi.amps '' 'System Current read by IPMI' 'Amps' 'current' 'ipmi.amps' 'line' %d %d\n"
312 , netdata_update_every
316 case IPMI_MONITORING_SENSOR_UNITS_RPM:
317 printf("CHART ipmi.rpm '' 'System Fans read by IPMI' 'RPM' 'fans' 'ipmi.rpm' 'line' %d %d\n"
319 , netdata_update_every
323 case IPMI_MONITORING_SENSOR_UNITS_WATTS:
324 printf("CHART ipmi.watts '' 'System Power read by IPMI' 'Watts' 'power' 'ipmi.watts' 'line' %d %d\n"
326 , netdata_update_every
330 case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
331 printf("CHART ipmi.percent '' 'System Metrics read by IPMI' '%%' 'other' 'ipmi.percent' 'line' %d %d\n"
333 , netdata_update_every
338 for(sn = sensors_root; sn; sn = sn->next)
339 if(sn->sensor_units == units)
344 for(sn = sensors_root; sn; sn = sn->next) {
345 if(sn->sensor_units == units && sn->updated && !sn->ignore) {
348 switch(sn->sensor_reading_type) {
349 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
350 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
351 printf("DIMENSION i%d_n%d_r%d '%s i%d' absolute 1 1\n"
354 , sn->sensor_reading_type
360 case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
361 printf("DIMENSION i%d_n%d_r%d '%s i%d' absolute 1 1000\n"
364 , sn->sensor_reading_type
378 static void send_metrics_to_netdata_for_units(int units) {
382 case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
383 printf("BEGIN ipmi.temperatures_c\n");
386 case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
387 printf("BEGIN ipmi.temperatures_f\n");
390 case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
391 printf("BEGIN ipmi.volts\n");
394 case IPMI_MONITORING_SENSOR_UNITS_AMPS:
395 printf("BEGIN ipmi.amps\n");
398 case IPMI_MONITORING_SENSOR_UNITS_RPM:
399 printf("BEGIN ipmi.rpm\n");
402 case IPMI_MONITORING_SENSOR_UNITS_WATTS:
403 printf("BEGIN ipmi.watts\n");
406 case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
407 printf("BEGIN ipmi.percent\n");
411 for(sn = sensors_root; sn; sn = sn->next)
412 if(sn->sensor_units == units)
417 for(sn = sensors_root; sn; sn = sn->next) {
418 if(sn->sensor_units == units && sn->updated && !sn->sent && !sn->ignore) {
419 netdata_sensors_updated++;
423 switch(sn->sensor_reading_type) {
424 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
425 printf("SET i%d_n%d_r%d = %u\n"
428 , sn->sensor_reading_type
429 , sn->sensor_reading.bool_value
433 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
434 printf("SET i%d_n%d_r%d = %u\n"
437 , sn->sensor_reading_type
438 , sn->sensor_reading.uint32_value
442 case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
443 printf("SET i%d_n%d_r%d = %lld\n"
446 , sn->sensor_reading_type
447 , (long long int)(sn->sensor_reading.double_value * 1000)
461 static void send_metrics_to_netdata() {
462 static int sel_chart_generated = 0;
465 if(!sel_chart_generated) {
466 printf("CHART ipmi.events '' 'IPMI Events' 'events' 'events' 'ipmi.sel' 'area' %d %d\n"
468 , netdata_update_every
470 printf("DIMENSION events '' absolute 1 1\n");
473 // generate the CHART/DIMENSION lines, if we have to
474 for(sn = sensors_root; sn; sn = sn->next)
475 if(sn->updated && !sn->exposed && !sn->ignore)
476 send_chart_to_netdata_for_units(sn->sensor_units);
478 printf("BEGIN ipmi.events\nSET events = %zu\nEND\n", netdata_sel_events);
480 // send metrics to netdata
481 for(sn = sensors_root; sn; sn = sn->next)
482 if(sn->updated && sn->exposed && !sn->sent && !sn->ignore)
483 send_metrics_to_netdata_for_units(sn->sensor_units);
487 static void netdata_get_sensor(
493 , int sensor_reading_type
495 , void *sensor_reading
497 // find the sensor record
499 for(sn = sensors_root; sn ;sn = sn->next)
500 if( sn->record_id == record_id &&
501 sn->sensor_number == sensor_number &&
502 sn->sensor_reading_type == sensor_reading_type &&
503 sn->sensor_units == sensor_units &&
504 !strcmp(sn->sensor_name, sensor_name)
509 // not found, create it
511 sn = calloc(1, sizeof(struct sensor));
513 fatal("cannot allocate %zu bytes of memory.", sizeof(struct sensor));
516 sn->record_id = record_id;
517 sn->sensor_number = sensor_number;
518 sn->sensor_type = sensor_type;
519 sn->sensor_state = sensor_state;
520 sn->sensor_units = sensor_units;
521 sn->sensor_reading_type = sensor_reading_type;
522 sn->sensor_name = strdup(sensor_name);
523 if(!sn->sensor_name) {
524 fatal("cannot allocate %zu bytes of memory.", strlen(sensor_name));
527 sn->next = sensors_root;
531 switch(sensor_reading_type) {
532 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
533 sn->sensor_reading.bool_value = *((uint8_t *)sensor_reading);
535 netdata_sensors_collected++;
538 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
539 sn->sensor_reading.uint32_value = *((uint32_t *)sensor_reading);
541 netdata_sensors_collected++;
544 case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
545 sn->sensor_reading.double_value = *((double *)sensor_reading);
547 netdata_sensors_collected++;
555 /* switch(sensor_state) {
556 case IPMI_MONITORING_STATE_NOMINAL:
557 case IPMI_MONITORING_STATE_WARNING:
558 case IPMI_MONITORING_STATE_CRITICAL:
565 static void netdata_get_sel(
567 , int record_type_class
571 (void)record_type_class;
574 netdata_sel_events++;
578 void netdata_cleanup_and_exit(int ret) {
583 // ----------------------------------------------------------------------------
587 _ipmimonitoring_sensors (struct ipmi_monitoring_ipmi_config *ipmi_config)
589 ipmi_monitoring_ctx_t ctx = NULL;
590 unsigned int sensor_reading_flags = 0;
595 if (!(ctx = ipmi_monitoring_ctx_create ())) {
596 error("ipmi_monitoring_ctx_create()");
600 if (sdr_cache_directory)
602 if (ipmi_monitoring_ctx_sdr_cache_directory (ctx,
603 sdr_cache_directory) < 0)
605 error("ipmi_monitoring_ctx_sdr_cache_directory(): %s\n",
606 ipmi_monitoring_ctx_errormsg (ctx));
611 /* Must call otherwise only default interpretations ever used */
612 if (sensor_config_file)
614 if (ipmi_monitoring_ctx_sensor_config_file (ctx,
615 sensor_config_file) < 0)
617 error( "ipmi_monitoring_ctx_sensor_config_file(): %s\n",
618 ipmi_monitoring_ctx_errormsg (ctx));
624 if (ipmi_monitoring_ctx_sensor_config_file (ctx, NULL) < 0)
626 error( "ipmi_monitoring_ctx_sensor_config_file(): %s\n",
627 ipmi_monitoring_ctx_errormsg (ctx));
632 if (reread_sdr_cache)
633 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_REREAD_SDR_CACHE;
635 if (ignore_non_interpretable_sensors)
636 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_NON_INTERPRETABLE_SENSORS;
639 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_BRIDGE_SENSORS;
641 if (interpret_oem_data)
642 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_INTERPRET_OEM_DATA;
645 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_SHARED_SENSORS;
647 if (discrete_reading)
648 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_DISCRETE_READING;
650 if (ignore_scanning_disabled)
651 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_SCANNING_DISABLED;
653 if (assume_bmc_owner)
654 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_ASSUME_BMC_OWNER;
656 #ifdef IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES
657 if (entity_sensor_names)
658 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES;
659 #endif // IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES
661 if (!record_ids_length && !sensor_types_length)
663 if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (ctx,
666 sensor_reading_flags,
672 error( "ipmi_monitoring_sensor_readings_by_record_id(): %s",
673 ipmi_monitoring_ctx_errormsg (ctx));
677 else if (record_ids_length)
679 if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (ctx,
682 sensor_reading_flags,
688 error( "ipmi_monitoring_sensor_readings_by_record_id(): %s",
689 ipmi_monitoring_ctx_errormsg (ctx));
695 if ((sensor_count = ipmi_monitoring_sensor_readings_by_sensor_type (ctx,
698 sensor_reading_flags,
704 error( "ipmi_monitoring_sensor_readings_by_sensor_type(): %s",
705 ipmi_monitoring_ctx_errormsg (ctx));
710 #ifdef NETDATA_COMMENTED
711 printf ("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
719 "Sensor Event/Reading Type Code",
720 "Sensor Event Bitmask",
721 "Sensor Event String");
722 #endif // NETDATA_COMMENTED
724 for (i = 0; i < sensor_count; i++, ipmi_monitoring_sensor_iterator_next (ctx))
726 int record_id, sensor_number, sensor_type, sensor_state, sensor_units,
729 #ifdef NETDATA_COMMENTED
730 int sensor_bitmask_type, sensor_bitmask, event_reading_type_code;
731 char **sensor_bitmask_strings = NULL;
732 const char *sensor_type_str;
733 const char *sensor_state_str;
734 #endif // NETDATA_COMMENTED
736 char *sensor_name = NULL;
737 void *sensor_reading;
739 if ((record_id = ipmi_monitoring_sensor_read_record_id (ctx)) < 0)
741 error( "ipmi_monitoring_sensor_read_record_id(): %s",
742 ipmi_monitoring_ctx_errormsg (ctx));
746 if ((sensor_number = ipmi_monitoring_sensor_read_sensor_number (ctx)) < 0)
748 error( "ipmi_monitoring_sensor_read_sensor_number(): %s",
749 ipmi_monitoring_ctx_errormsg (ctx));
753 if ((sensor_type = ipmi_monitoring_sensor_read_sensor_type (ctx)) < 0)
755 error( "ipmi_monitoring_sensor_read_sensor_type(): %s",
756 ipmi_monitoring_ctx_errormsg (ctx));
760 if (!(sensor_name = ipmi_monitoring_sensor_read_sensor_name (ctx)))
762 error( "ipmi_monitoring_sensor_read_sensor_name(): %s",
763 ipmi_monitoring_ctx_errormsg (ctx));
767 if ((sensor_state = ipmi_monitoring_sensor_read_sensor_state (ctx)) < 0)
769 error( "ipmi_monitoring_sensor_read_sensor_state(): %s",
770 ipmi_monitoring_ctx_errormsg (ctx));
774 if ((sensor_units = ipmi_monitoring_sensor_read_sensor_units (ctx)) < 0)
776 error( "ipmi_monitoring_sensor_read_sensor_units(): %s",
777 ipmi_monitoring_ctx_errormsg (ctx));
781 #ifdef NETDATA_COMMENTED
782 if ((sensor_bitmask_type = ipmi_monitoring_sensor_read_sensor_bitmask_type (ctx)) < 0)
784 error( "ipmi_monitoring_sensor_read_sensor_bitmask_type(): %s",
785 ipmi_monitoring_ctx_errormsg (ctx));
788 if ((sensor_bitmask = ipmi_monitoring_sensor_read_sensor_bitmask (ctx)) < 0)
791 "ipmi_monitoring_sensor_read_sensor_bitmask(): %s",
792 ipmi_monitoring_ctx_errormsg (ctx));
796 if (!(sensor_bitmask_strings = ipmi_monitoring_sensor_read_sensor_bitmask_strings (ctx)))
798 error( "ipmi_monitoring_sensor_read_sensor_bitmask_strings(): %s",
799 ipmi_monitoring_ctx_errormsg (ctx));
802 #endif // NETDATA_COMMENTED
804 if ((sensor_reading_type = ipmi_monitoring_sensor_read_sensor_reading_type (ctx)) < 0)
806 error( "ipmi_monitoring_sensor_read_sensor_reading_type(): %s",
807 ipmi_monitoring_ctx_errormsg (ctx));
811 sensor_reading = ipmi_monitoring_sensor_read_sensor_reading (ctx);
813 #ifdef NETDATA_COMMENTED
814 if ((event_reading_type_code = ipmi_monitoring_sensor_read_event_reading_type_code (ctx)) < 0)
816 error( "ipmi_monitoring_sensor_read_event_reading_type_code(): %s",
817 ipmi_monitoring_ctx_errormsg (ctx));
820 #endif // NETDATA_COMMENTED
828 , sensor_reading_type
833 #ifdef NETDATA_COMMENTED
834 if (!strlen (sensor_name))
837 sensor_type_str = _get_sensor_type_string (sensor_type);
839 printf ("%d, %s, %d, %s",
845 if (sensor_state == IPMI_MONITORING_STATE_NOMINAL)
846 sensor_state_str = "Nominal";
847 else if (sensor_state == IPMI_MONITORING_STATE_WARNING)
848 sensor_state_str = "Warning";
849 else if (sensor_state == IPMI_MONITORING_STATE_CRITICAL)
850 sensor_state_str = "Critical";
852 sensor_state_str = "N/A";
854 printf (", %s", sensor_state_str);
858 const char *sensor_units_str;
860 if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL)
862 (*((uint8_t *)sensor_reading) ? "true" : "false"));
863 else if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32)
865 *((uint32_t *)sensor_reading));
866 else if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE)
868 *((double *)sensor_reading));
872 if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_CELSIUS)
873 sensor_units_str = "C";
874 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT)
875 sensor_units_str = "F";
876 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_VOLTS)
877 sensor_units_str = "V";
878 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_AMPS)
879 sensor_units_str = "A";
880 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_RPM)
881 sensor_units_str = "RPM";
882 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_WATTS)
883 sensor_units_str = "W";
884 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_PERCENT)
885 sensor_units_str = "%";
887 sensor_units_str = "N/A";
889 printf (", %s", sensor_units_str);
892 printf (", N/A, N/A");
894 printf (", %Xh", event_reading_type_code);
896 /* It is possible you may want to monitor specific event
897 * conditions that may occur. If that is the case, you may want
898 * to check out what specific bitmask type and bitmask events
899 * occurred. See ipmi_monitoring_bitmasks.h for a list of
900 * bitmasks and types.
903 if (sensor_bitmask_type != IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN)
904 printf (", %Xh", sensor_bitmask);
908 if (sensor_bitmask_type != IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN)
914 while (sensor_bitmask_strings[i])
919 sensor_bitmask_strings[i]);
928 #endif // NETDATA_COMMENTED
934 ipmi_monitoring_ctx_destroy (ctx);
940 _ipmimonitoring_sel (struct ipmi_monitoring_ipmi_config *ipmi_config)
942 ipmi_monitoring_ctx_t ctx = NULL;
943 unsigned int sel_flags = 0;
948 if (!(ctx = ipmi_monitoring_ctx_create ()))
950 error("ipmi_monitoring_ctx_create()");
954 if (sdr_cache_directory)
956 if (ipmi_monitoring_ctx_sdr_cache_directory (ctx,
957 sdr_cache_directory) < 0)
959 error( "ipmi_monitoring_ctx_sdr_cache_directory(): %s",
960 ipmi_monitoring_ctx_errormsg (ctx));
965 /* Must call otherwise only default interpretations ever used */
968 if (ipmi_monitoring_ctx_sel_config_file (ctx,
969 sel_config_file) < 0)
971 error( "ipmi_monitoring_ctx_sel_config_file(): %s",
972 ipmi_monitoring_ctx_errormsg (ctx));
978 if (ipmi_monitoring_ctx_sel_config_file (ctx, NULL) < 0)
980 error( "ipmi_monitoring_ctx_sel_config_file(): %s",
981 ipmi_monitoring_ctx_errormsg (ctx));
986 if (reread_sdr_cache)
987 sel_flags |= IPMI_MONITORING_SEL_FLAGS_REREAD_SDR_CACHE;
989 if (interpret_oem_data)
990 sel_flags |= IPMI_MONITORING_SEL_FLAGS_INTERPRET_OEM_DATA;
992 if (assume_system_event_record)
993 sel_flags |= IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD;
995 #ifdef IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES
996 if (entity_sensor_names)
997 sel_flags |= IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES;
998 #endif // IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES
1000 if (record_ids_length)
1002 if ((sel_count = ipmi_monitoring_sel_by_record_id (ctx,
1011 error( "ipmi_monitoring_sel_by_record_id(): %s",
1012 ipmi_monitoring_ctx_errormsg (ctx));
1016 else if (sensor_types_length)
1018 if ((sel_count = ipmi_monitoring_sel_by_sensor_type (ctx,
1023 sensor_types_length,
1027 error( "ipmi_monitoring_sel_by_sensor_type(): %s",
1028 ipmi_monitoring_ctx_errormsg (ctx));
1035 if ((sel_count = ipmi_monitoring_sel_by_date_range (ctx,
1044 error( "ipmi_monitoring_sel_by_sensor_type(): %s",
1045 ipmi_monitoring_ctx_errormsg (ctx));
1051 if ((sel_count = ipmi_monitoring_sel_by_record_id (ctx,
1060 error( "ipmi_monitoring_sel_by_record_id(): %s",
1061 ipmi_monitoring_ctx_errormsg (ctx));
1066 #ifdef NETDATA_COMMENTED
1067 printf ("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
1078 "Event Offset String");
1079 #endif // NETDATA_COMMENTED
1081 for (i = 0; i < sel_count; i++, ipmi_monitoring_sel_iterator_next (ctx))
1083 int record_id, record_type, sel_state, record_type_class;
1084 #ifdef NETDATA_COMMENTED
1085 int sensor_type, sensor_number, event_direction,
1086 event_offset_type, event_offset, event_type_code, manufacturer_id;
1087 unsigned int timestamp, event_data1, event_data2, event_data3;
1088 char *event_offset_string = NULL;
1089 const char *sensor_type_str;
1090 const char *event_direction_str;
1091 const char *sel_state_str;
1092 char *sensor_name = NULL;
1093 unsigned char oem_data[64];
1096 #endif // NETDATA_COMMENTED
1098 if ((record_id = ipmi_monitoring_sel_read_record_id (ctx)) < 0)
1100 error( "ipmi_monitoring_sel_read_record_id(): %s",
1101 ipmi_monitoring_ctx_errormsg (ctx));
1105 if ((record_type = ipmi_monitoring_sel_read_record_type (ctx)) < 0)
1107 error( "ipmi_monitoring_sel_read_record_type(): %s",
1108 ipmi_monitoring_ctx_errormsg (ctx));
1112 if ((record_type_class = ipmi_monitoring_sel_read_record_type_class (ctx)) < 0)
1114 error( "ipmi_monitoring_sel_read_record_type_class(): %s",
1115 ipmi_monitoring_ctx_errormsg (ctx));
1119 if ((sel_state = ipmi_monitoring_sel_read_sel_state (ctx)) < 0)
1121 error( "ipmi_monitoring_sel_read_sel_state(): %s",
1122 ipmi_monitoring_ctx_errormsg (ctx));
1132 #ifdef NETDATA_COMMENTED
1133 if (sel_state == IPMI_MONITORING_STATE_NOMINAL)
1134 sel_state_str = "Nominal";
1135 else if (sel_state == IPMI_MONITORING_STATE_WARNING)
1136 sel_state_str = "Warning";
1137 else if (sel_state == IPMI_MONITORING_STATE_CRITICAL)
1138 sel_state_str = "Critical";
1140 sel_state_str = "N/A";
1142 printf ("%d, %d, %s",
1147 if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD
1148 || record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
1151 if (ipmi_monitoring_sel_read_timestamp (ctx, ×tamp) < 0)
1153 error( "ipmi_monitoring_sel_read_timestamp(): %s",
1154 ipmi_monitoring_ctx_errormsg (ctx));
1158 /* XXX: This should be converted to a nice date output using
1159 * your favorite timestamp -> string conversion functions.
1161 printf (", %u", timestamp);
1166 if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD)
1168 /* If you are integrating ipmimonitoring SEL into a monitoring application,
1169 * you may wish to count the number of times a specific error occurred
1170 * and report that to the monitoring application.
1172 * In this particular case, you'll probably want to check out
1173 * what sensor type each SEL event is reporting, the
1174 * event offset type, and the specific event offset that occurred.
1176 * See ipmi_monitoring_offsets.h for a list of event offsets
1180 if (!(sensor_name = ipmi_monitoring_sel_read_sensor_name (ctx)))
1182 error( "ipmi_monitoring_sel_read_sensor_name(): %s",
1183 ipmi_monitoring_ctx_errormsg (ctx));
1187 if ((sensor_type = ipmi_monitoring_sel_read_sensor_type (ctx)) < 0)
1189 error( "ipmi_monitoring_sel_read_sensor_type(): %s",
1190 ipmi_monitoring_ctx_errormsg (ctx));
1194 if ((sensor_number = ipmi_monitoring_sel_read_sensor_number (ctx)) < 0)
1196 error( "ipmi_monitoring_sel_read_sensor_number(): %s",
1197 ipmi_monitoring_ctx_errormsg (ctx));
1201 if ((event_direction = ipmi_monitoring_sel_read_event_direction (ctx)) < 0)
1203 error( "ipmi_monitoring_sel_read_event_direction(): %s",
1204 ipmi_monitoring_ctx_errormsg (ctx));
1208 if ((event_type_code = ipmi_monitoring_sel_read_event_type_code (ctx)) < 0)
1210 error( "ipmi_monitoring_sel_read_event_type_code(): %s",
1211 ipmi_monitoring_ctx_errormsg (ctx));
1215 if (ipmi_monitoring_sel_read_event_data (ctx,
1220 error( "ipmi_monitoring_sel_read_event_data(): %s",
1221 ipmi_monitoring_ctx_errormsg (ctx));
1225 if ((event_offset_type = ipmi_monitoring_sel_read_event_offset_type (ctx)) < 0)
1227 error( "ipmi_monitoring_sel_read_event_offset_type(): %s",
1228 ipmi_monitoring_ctx_errormsg (ctx));
1232 if ((event_offset = ipmi_monitoring_sel_read_event_offset (ctx)) < 0)
1234 error( "ipmi_monitoring_sel_read_event_offset(): %s",
1235 ipmi_monitoring_ctx_errormsg (ctx));
1239 if (!(event_offset_string = ipmi_monitoring_sel_read_event_offset_string (ctx)))
1241 error( "ipmi_monitoring_sel_read_event_offset_string(): %s",
1242 ipmi_monitoring_ctx_errormsg (ctx));
1246 if (!strlen (sensor_name))
1247 sensor_name = "N/A";
1249 sensor_type_str = _get_sensor_type_string (sensor_type);
1251 if (event_direction == IPMI_MONITORING_SEL_EVENT_DIRECTION_ASSERTION)
1252 event_direction_str = "Assertion";
1254 event_direction_str = "Deassertion";
1256 printf (", %s, %s, %d, %s, %Xh, %Xh-%Xh-%Xh",
1260 event_direction_str,
1266 if (event_offset_type != IPMI_MONITORING_EVENT_OFFSET_TYPE_UNKNOWN)
1267 printf (", %Xh", event_offset);
1271 if (event_offset_type != IPMI_MONITORING_EVENT_OFFSET_TYPE_UNKNOWN)
1272 printf (", %s", event_offset_string);
1276 else if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD
1277 || record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD)
1279 if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
1281 if ((manufacturer_id = ipmi_monitoring_sel_read_manufacturer_id (ctx)) < 0)
1283 error( "ipmi_monitoring_sel_read_manufacturer_id(): %s",
1284 ipmi_monitoring_ctx_errormsg (ctx));
1288 printf (", Manufacturer ID = %Xh", manufacturer_id);
1291 if ((oem_data_len = ipmi_monitoring_sel_read_oem_data (ctx, oem_data, 1024)) < 0)
1293 error( "ipmi_monitoring_sel_read_oem_data(): %s",
1294 ipmi_monitoring_ctx_errormsg (ctx));
1298 printf (", OEM Data = ");
1300 for (j = 0; j < oem_data_len; j++)
1301 printf ("%02Xh ", oem_data[j]);
1304 printf (", N/A, N/A, N/A, N/A, N/A, N/A, N/A");
1307 #endif // NETDATA_COMMENTED
1313 ipmi_monitoring_ctx_destroy (ctx);
1317 // ----------------------------------------------------------------------------
1318 // MAIN PROGRAM FOR NETDATA PLUGIN
1320 int ipmi_collect_data(struct ipmi_monitoring_ipmi_config *ipmi_config) {
1323 if (_ipmimonitoring_sensors(ipmi_config) < 0) return -1;
1324 if (_ipmimonitoring_sel (ipmi_config) < 0) return -2;
1329 int ipmi_detect_speed_secs(struct ipmi_monitoring_ipmi_config *ipmi_config) {
1331 unsigned long long total = 0;
1333 for(i = 0 ; i < checks ; i++) {
1334 if(debug) fprintf(stderr, "freeipmi.plugin: checking data collection speed iteration %d of %d\n", i+1, checks);
1336 // measure the time a data collection needs
1337 unsigned long long start = now_realtime_usec();
1338 if(ipmi_collect_data(ipmi_config) < 0)
1339 fatal("freeipmi.plugin: data collection failed.");
1341 unsigned long long end = now_realtime_usec();
1343 if(debug) fprintf(stderr, "freeipmi.plugin: data collection speed was %llu usec\n", end - start);
1345 // add it to our total
1346 total += end - start;
1348 // wait the same time
1349 // to avoid flooding the IPMI processor with requests
1350 sleep_usec(end - start);
1353 // so, we assume it needed 3x the time
1354 // we find the average in microseconds
1355 // and we round-up to the closest second
1357 return (( total * 3 / checks / 1000000 ) + 1);
1360 int main (int argc, char **argv) {
1362 // ------------------------------------------------------------------------
1363 // initialization of netdata plugin
1365 program_name = "freeipmi.plugin";
1368 error_log_syslog = 0;
1370 // set errors flood protection to 100 logs per hour
1371 error_log_errors_per_period = 100;
1372 error_log_throttle_period = 3600;
1375 // ------------------------------------------------------------------------
1376 // parse command line parameters
1379 for(i = 1; i < argc ; i++) {
1381 int n = atoi(argv[i]);
1388 if(strcmp("debug", argv[i]) == 0) {
1392 else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
1395 "netdata freeipmi.plugin " VERSION "\n"
1398 " freeipmi.plugin [OPTIONS]\n"
1400 "Available options:\n"
1401 " NUMBER, sets the data collection frequency\n"
1402 " debug, enables verbose output\n"
1403 " hostname X, sets the remote host to connect to\n"
1404 " username X, sets the username to authenticate at the remote host\n"
1405 " password X, sets the password to authenticate at the remote host\n"
1406 " sdr-cache-dir X, sets the directory to save SDR cache files\n"
1407 " sensor-config-file X, set the filename to read sensor configuration\n"
1411 else if(i < argc && strcmp("hostname", argv[i]) == 0) {
1412 hostname = argv[++i];
1413 if(debug) fprintf(stderr, "freeipmi.plugin: hostname set to '%s'\n", hostname);
1416 else if(i < argc && strcmp("username", argv[i]) == 0) {
1417 username = argv[++i];
1418 if(debug) fprintf(stderr, "freeipmi.plugin: username set to '%s'\n", username);
1421 else if(i < argc && strcmp("password", argv[i]) == 0) {
1422 password = argv[++i];
1423 if(debug) fprintf(stderr, "freeipmi.plugin: password set to '%s'\n", password);
1426 else if(i < argc && strcmp("sdr-cache-dir", argv[i]) == 0) {
1427 sdr_cache_directory = argv[++i];
1428 if(debug) fprintf(stderr, "freeipmi.plugin: SDR cache directory set to '%s'\n", sdr_cache_directory);
1431 else if(i < argc && strcmp("sensor-config-file", argv[i]) == 0) {
1432 sensor_config_file = argv[++i];
1433 if(debug) fprintf(stderr, "freeipmi.plugin: sensor config file set to '%s'\n", sensor_config_file);
1437 error("freeipmi.plugin: ignoring parameter '%s'", argv[i]);
1440 if(freq > 0 && freq < netdata_update_every)
1441 netdata_update_every = freq;
1444 error("update frequency %d seconds is too small for IPMI. Using %d.", freq, netdata_update_every);
1447 // ------------------------------------------------------------------------
1450 struct ipmi_monitoring_ipmi_config ipmi_config;
1452 if(debug) fprintf(stderr, "freeipmi.plugin: calling _init_ipmi_config()\n");
1454 _init_ipmi_config(&ipmi_config);
1456 if(debug) fprintf(stderr, "freeipmi.plugin: calling ipmi_monitoring_init()\n");
1458 if(ipmi_monitoring_init(ipmimonitoring_init_flags, &errnum) < 0)
1459 fatal("ipmi_monitoring_init: %s", ipmi_monitoring_ctx_strerror(errnum));
1461 if(debug) fprintf(stderr, "freeipmi.plugin: detecting IPMI minimum update frequency...\n");
1462 freq = ipmi_detect_speed_secs(&ipmi_config);
1463 if(debug) fprintf(stderr, "freeipmi.plugin: IPMI minimum update frequency was calculated to %d seconds.\n", freq);
1465 if(netdata_update_every < freq) {
1466 info("enforcing minimum data collection frequency, calculated to %d seconds.", freq);
1467 netdata_update_every = freq;
1471 // ------------------------------------------------------------------------
1474 if(debug) fprintf(stderr, "freeipmi.plugin: starting data collection\n");
1476 time_t started_t = now_monotonic_sec();
1478 size_t iteration = 0;
1479 usec_t step = netdata_update_every * USEC_PER_SEC;
1482 heartbeat_init(&hb);
1483 for(iteration = 0; 1 ; iteration++) {
1484 usec_t dt = heartbeat_next(&hb, step);
1486 if(debug && iteration)
1487 fprintf(stderr, "freeipmi.plugin: iteration %zu, dt %llu usec, sensors collected %zu, sensors sent to netdata %zu \n"
1490 , netdata_sensors_collected
1491 , netdata_sensors_updated
1494 netdata_mark_as_not_updated();
1496 if(debug) fprintf(stderr, "freeipmi.plugin: calling ipmi_collect_data()\n");
1497 if(ipmi_collect_data(&ipmi_config) < 0)
1498 fatal("data collection failed.");
1500 if(debug) fprintf(stderr, "freeipmi.plugin: calling send_metrics_to_netdata()\n");
1501 send_metrics_to_netdata();
1504 // restart check (14400 seconds)
1505 if(now_monotonic_sec() - started_t > 14400) exit(0);
1509 #else // !HAVE_FREEIPMI
1511 int main(int argc, char **argv) {
1512 fatal("freeipmi.plugin is not compiled.");
1515 #endif // !HAVE_FREEIPMI