From: Pavel Rochnyak Date: Wed, 30 May 2018 12:59:32 +0000 (+0700) Subject: Merge pull request #2796 from elfiesmelfie/feat_ipmi_SEL_ignore_list X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=979b210145a48a04db82fe3d3daa3c67c51df28f;hp=-c;p=collectd.git Merge pull request #2796 from elfiesmelfie/feat_ipmi_SEL_ignore_list ipmi plugin: Add SELSensor and SELIgnoreSelected config options. --- 979b210145a48a04db82fe3d3daa3c67c51df28f diff --combined src/collectd.conf.in index 925d7d65,da33dbf1..c2aa9152 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@@ -90,7 -90,6 +90,7 @@@ #@BUILD_PLUGIN_AGGREGATION_TRUE@LoadPlugin aggregation #@BUILD_PLUGIN_AMQP_TRUE@LoadPlugin amqp +#@BUILD_PLUGIN_AMQP1_TRUE@LoadPlugin amqp1 #@BUILD_PLUGIN_APACHE_TRUE@LoadPlugin apache #@BUILD_PLUGIN_APCUPS_TRUE@LoadPlugin apcups #@BUILD_PLUGIN_APPLE_SENSORS_TRUE@LoadPlugin apple_sensors @@@ -270,29 -269,6 +270,29 @@@ # # +# +# +# Host "localhost" +# Port "5672" +# User "guest" +# Password "guest" +# Address "collectd" +# RetryDelay 1 +# +# Format JSON +# PreSettle false +# +# +# Format JSON +# PreSettle true +# +# +# Format JSON +# PreSettle false +# +# +# + # # # URL "http://localhost/status?auto" @@@ -690,7 -666,6 +690,7 @@@ # ReportSoftwareEvents true # EventList "/var/cache/pmu/GenuineIntel-6-2D-core.json" # HardwareEvents "L2_RQSTS.CODE_RD_HIT,L2_RQSTS.CODE_RD_MISS" "L2_RQSTS.ALL_CODE_RD" +# Cores "[0-3]" # # @@@ -714,6 -689,9 +714,9 @@@ # NotifySensorNotPresent false # NotifyIPMIConnectionState false # SELEnabled false + # SELSensor "some_sensor" + # SELSensor "another_one" + # SELIgnoreSelected false # SELClearEvent false # # @@@ -730,6 -708,9 +733,9 @@@ # NotifySensorNotPresent false # NotifyIPMIConnectionState false # SELEnabled false + # SELSensor "some_sensor" + # SELSensor "another_one" + # SELIgnoreSelected false # SELClearEvent false # # @@@ -834,8 -815,6 +840,8 @@@ # RegisterType float # Type gauge # Instance "..." +# #Scale 1.0 +# #Shift 0.0 # # # @@@ -1264,11 -1243,6 +1270,11 @@@ # Host "redis.example.com" # Port "6379" # Timeout 2000 +# +# #Database 0 +# Type "queue_length" +# Instance "myqueue" +# # # @@@ -1640,7 -1614,6 +1646,7 @@@ # PluginInstanceFormat name # Instances 1 # ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin" +# PersistentNotification false # # diff --combined src/collectd.conf.pod index cb18247b,dda3a18e..69a1b1e0 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@@ -530,9 -530,9 +530,9 @@@ are disabled by default =head2 Plugin C The I can be used to communicate with other instances of -I or third party applications using an AMQP message broker. Values -are sent to or received from the broker, which handles routing, queueing and -possibly filtering out messages. +I or third party applications using an AMQP 0.9.1 message broker. +Values are sent to or received from the broker, which handles routing, +queueing and possibly filtering out messages. B @@@ -738,171 -738,6 +738,171 @@@ is preserved, i.e. passed through =back +=head2 Plugin C + +The I can be used to communicate with other instances of +I or third party applications using an AMQP 1.0 message +intermediary. Metric values or notifications are sent to the +messaging intermediary which may handle direct messaging or +queue based transfer. + +B + + + # Send values to an AMQP 1.0 intermediary + + Host "localhost" + Port "5672" + User "guest" + Password "guest" + Address "collectd" +# RetryDelay 1 + + Format "command" + PreSettle false + Notify false + # StoreRates false + # GraphitePrefix "collectd." + # GraphiteEscapeChar "_" + # GraphiteSeparateInstances false + # GraphiteAlwaysAppendDS false + # GraphitePreserveSeparator false + + + + +The plugin's configuration consists of a I that configures +communications to the AMQP 1.0 messaging bus and one or more I +corresponding to metric or event publishers to the messaging system. + +The address in the I block concatenated with the name given in the +I block starting tag will be used as the send-to address for +communications over the messaging link. + +The following options are accepted within each I block: + +=over 4 + +=item B I + +Hostname or IP-address of the AMQP 1.0 intermediary. Defaults to the +default behavior of the underlying communications library, +I, which is "localhost". + +=item B I + +Service name or port number on which the AMQP 1.0 intermediary accepts +connections. This argument must be a string, even if the numeric form +is used. Defaults to "5672". + +=item B I + +=item B I + +Credentials used to authenticate to the AMQP 1.0 intermediary. By +default "guest"/"guest" is used. + +=item B
I
+ +This option specifies the prefix for the send-to value in the message. +By default, "collectd" will be used. + +=item B I + +When the AMQP1 connection is lost, defines the time in seconds to wait +before attempting to reconnect. Defaults to 1, which implies attempt +to reconnect at 1 second intervals. + +=back + +The following options are accepted within each I block: + +=over 4 + +=item B B|B|B + +Selects the format in which messages are sent to the intermediary. If set to +B (the default), values are sent as C commands which are +identical to the syntax used by the I and I. In this +case, the C header field will be set to C. + +If set to B, the values are encoded in the I, +an easy and straight forward exchange format. The C header field +will be set to C. + +If set to B, values are encoded in the I format, which is +" \n". The C header field will be set to +C. + +A subscribing client I use the C header field to +determine how to decode the values. + +=item B B|B + +If set to B (the default), the plugin will wait for a message +acknowledgement from the messaging bus before sending the next +message. This indicates transfer of ownership to the messaging +system. If set to B, the plugin will not wait for a message +acknowledgement and the message may be dropped prior to transfer of +ownership. + +=item B B|B + +If set to B (the default), the plugin will service the +instance write call back as a value list. If set to B the +plugin will service the instance as a write notification callback +for alert formatting. + +=item B B|B + +Determines whether or not C, C and C data sources +are converted to a I (i.e. a C value). If set to B (the +default), no conversion is performed. Otherwise the conversion is performed +using the internal value cache. + +Please note that currently this option is only used if the B option has +been set to B. + +=item B + +A prefix can be added in the metric name when outputting in the I format. +It's added before the I name. +Metric name will be "" + +=item B + +A postfix can be added in the metric name when outputting in the I format. +It's added after the I name. +Metric name will be "" + +=item B + +Specify a character to replace dots (.) in the host part of the metric name. +In I metric name, dots are used as separators between different +metric parts (host, plugin, type). +Default is "_" (I). + +=item B B|B + +If set to B, the plugin instance and type instance will be in their own +path component, for example C. If set to B (the +default), the plugin and plugin instance (and likewise the type and type +instance) are put into one component, for example C. + +=item B B|B + +If set to B, append the name of the I (DS) to the "metric" +identifier. If set to B (the default), this is only done when there is +more than one DS. + +=item B B|B + +If set to B (the default) the C<.> (dot) character is replaced with +I. Otherwise, if set to B, the C<.> (dot) character +is preserved, i.e. passed through. + +=back + =head2 Plugin C To configure the C-plugin you first need to configure the Apache @@@ -3347,7 -3182,6 +3347,7 @@@ B B @@@ -3419,23 -3253,6 +3419,23 @@@ event_download.py script to download ev This field is a list of event names or groups of comma separated event names. This option requires B option to be configured. +=item B I + +All events are reported on a per core basis. Monitoring of the events can be +configured for a group of cores (aggregated statistics). This field defines +groups of cores on which to monitor supported events. The field is represented +as list of strings with core group values. Each string represents a list of +cores in a group. If a group is enclosed in square brackets each core is added +individually to a separate group (that is statistics are not aggregated). +Allowed formats are: + 0,1,2,3 + 0-10,20-18 + 1,3,5-8,10,0x10-12 + [4-15,32-63] + +If an empty string is provided as value for this field default cores +configuration is applied - that is separate group is created for each core. + =back =head2 Plugin C @@@ -3636,8 -3453,23 +3636,23 @@@ a notification is sent. Defaults to B and B + config options. Defaults to B. + =item B I + + Selects sensors to get events from or to ignore, depending on B. + + See F for details. + + =item B I|I + + If no configuration is given, the B plugin will pass events from all + sensors. This option enables you to do that: By setting B + to I the effect of B is inverted: All events from selected + sensors are ignored and all events from other sensors are passed. + =item B I|I If SEL clear event is enabled, plugin will delete event from SEL list after @@@ -4242,9 -4074,8 +4257,9 @@@ which the sizes of physical memory vary The B connects to a Modbus "slave" via Modbus/TCP or Modbus/RTU and reads register values. It supports reading single registers (unsigned 16Ebit -values), large integer values (unsigned 32Ebit values) and floating point -values (two registers interpreted as IEEE floats in big endian notation). +values), large integer values (unsigned 32Ebit and 64Ebit values) and +floating point values (two registers interpreted as IEEE floats in big endian +notation). B @@@ -4254,8 -4085,6 +4269,8 @@@ RegisterCmd ReadHolding Type voltage Instance "input-1" + #Scale 1.0 + #Shift 0.0 @@@ -4314,7 -4143,7 +4329,7 @@@ Configures the base register to read fr B has been set to B or B, this and the next register will be read (the register number is increased by one). -=item B B|B|B|B|B|B|B|B +=item B B|B|B|B|B|B|B|B|B|B Specifies what kind of data is returned by the device. This defaults to B. If the type is B, B, B, B, @@@ -4326,10 -4155,7 +4341,10 @@@ significant 16Ebits are in the re For B, B, or B, the high and low order registers are swapped with the most significant 16Ebits in the B and the least significant 16Ebits in -B. +B. If the type is B or B, four 16Ebit +registers at B, B, B and +B will be read and the data combined into one +64Evalue. =item B B|B @@@ -4344,19 -4170,9 +4359,19 @@@ supported =item B I -Sets the type instance to use when dispatching the value to I. If +Sets the type instance to use when dispatching the value to I. If unset, an empty string (no type instance) is used. +=item B I + +The values taken from device are multiplied by I. The field is optional +and the default is B<1.0>. + +=item B I + +I is added to values from device after they have been multiplied by +B value. The field is optional and the default value is B<0.0>. + =back =item EB IE blocks @@@ -7276,7 -7092,6 +7291,7 @@@ which configures the connection paramet Port "6379" Timeout 2000 + #Database 0 Type "queue_length" Instance "myqueue" @@@ -7322,11 -7137,6 +7337,11 @@@ than B defined globally The B block identifies a query to execute against the redis server. There may be an arbitrary number of queries to execute. +=item B I + +This index selects the Redis logical database to use for query. Defaults +to C<0>. + =item B I Within a query definition, a valid collectd type to use as when submitting @@@ -9128,12 -8938,6 +9143,12 @@@ B: I metrics can't be colle =back +=item B B|B +Override default configuration to only send notifications when there is a change +in the lifecycle state of a domain. When set to true notifications will be sent +for every read cycle. Default is false. Does not affect the stats being +dispatched. + =back =head2 Plugin C diff --combined src/ipmi.c index 3037beb7,2642f64e..fb99bad1 --- a/src/ipmi.c +++ b/src/ipmi.c @@@ -49,6 -49,7 +49,7 @@@ typedef struct c_ipmi_sensor_list_s c_i struct c_ipmi_instance_s { char *name; ignorelist_t *ignorelist; + ignorelist_t *sel_ignorelist; bool notify_add; bool notify_remove; bool notify_notpresent; @@@ -357,7 -358,7 +358,7 @@@ static const char *sensor_unit_to_type( /* find the db type by using sensor base unit type */ enum ipmi_unit_type_e ipmi_type = ipmi_sensor_get_base_unit(sensor); - for (int i = 0; i < STATIC_ARRAY_SIZE(ipmi_db_type_map); i++) + for (size_t i = 0; i < STATIC_ARRAY_SIZE(ipmi_db_type_map); i++) if (ipmi_db_type_map[i].type == ipmi_type) return ipmi_db_type_map[i].type_name; @@@ -770,6 -771,40 +771,40 @@@ static int sensor_discrete_event_handle return IPMI_EVENT_NOT_HANDLED; } /* int sensor_discrete_event_handler */ + static int sel_list_add(c_ipmi_instance_t *st, ipmi_sensor_t *sensor) { + char sensor_name[DATA_MAX_NAME_LEN] = {0}; + int status = 0; + + /* Check if sensor on sel_ignorelist */ + sensor_get_name(sensor, sensor_name, sizeof(sensor_name)); + if (ignorelist_match(st->sel_ignorelist, sensor_name) != 0) + return 0; + + /* register threshold event if threshold sensor support events */ + if (ipmi_sensor_get_event_reading_type(sensor) == + IPMI_EVENT_READING_TYPE_THRESHOLD) + status = ipmi_sensor_add_threshold_event_handler( + sensor, sensor_threshold_event_handler, st); + /* register discrete handler if discrete/specific sensor support events */ + else if (ipmi_sensor_get_event_support(sensor) != IPMI_EVENT_SUPPORT_NONE) + status = ipmi_sensor_add_discrete_event_handler( + sensor, sensor_discrete_event_handler, st); + + if (status) + ERROR("Unable to add sensor %s event handler, status: %d", sensor_name, + status); + return status; + } + + static void sel_list_remove(c_ipmi_instance_t *st, ipmi_sensor_t *sensor) { + if (ipmi_sensor_get_event_reading_type(sensor) == + IPMI_EVENT_READING_TYPE_THRESHOLD) + ipmi_sensor_remove_threshold_event_handler( + sensor, sensor_threshold_event_handler, st); + else + ipmi_sensor_remove_discrete_event_handler( + sensor, sensor_discrete_event_handler, st); + } /* * Entity handlers */ @@@ -782,37 -817,12 +817,12 @@@ entity_sensor_update_handler(enum ipmi_ if ((op == IPMI_ADDED) || (op == IPMI_CHANGED)) { /* Will check for duplicate entries.. */ sensor_list_add(st, sensor); - - if (st->sel_enabled) { - int status = 0; - /* register threshold event handler */ - if (ipmi_sensor_get_event_reading_type(sensor) == - IPMI_EVENT_READING_TYPE_THRESHOLD) - status = ipmi_sensor_add_threshold_event_handler( - sensor, sensor_threshold_event_handler, st); - /* register discrete handler if discrete/specific sensor support events */ - else if (ipmi_sensor_get_event_support(sensor) != IPMI_EVENT_SUPPORT_NONE) - status = ipmi_sensor_add_discrete_event_handler( - sensor, sensor_discrete_event_handler, st); - - if (status) { - char buf[DATA_MAX_NAME_LEN] = {0}; - sensor_get_name(sensor, buf, sizeof(buf)); - ERROR("Unable to add sensor %s event handler, status: %d", buf, status); - } - } + if (st->sel_enabled) + sel_list_add(st, sensor); } else if (op == IPMI_DELETED) { sensor_list_remove(st, sensor); - - if (st->sel_enabled) { - if (ipmi_sensor_get_event_reading_type(sensor) == - IPMI_EVENT_READING_TYPE_THRESHOLD) - ipmi_sensor_remove_threshold_event_handler( - sensor, sensor_threshold_event_handler, st); - else - ipmi_sensor_remove_discrete_event_handler( - sensor, sensor_discrete_event_handler, st); - } + if (st->sel_enabled) + sel_list_remove(st, sensor); } } /* void entity_sensor_update_handler */ @@@ -1000,6 -1010,15 +1010,15 @@@ static c_ipmi_instance_t *c_ipmi_init_i return NULL; } + st->sel_ignorelist = ignorelist_create(/* invert = */ 1); + if (st->sel_ignorelist == NULL) { + ignorelist_free(st->ignorelist); + sfree(st->name); + sfree(st); + ERROR("ipmi plugin: SEL ignorelist_create() failed."); + return NULL; + } + st->sensor_list = NULL; pthread_mutex_init(&st->sensor_list_lock, /* attr = */ NULL); @@@ -1026,6 -1045,7 +1045,7 @@@ static void c_ipmi_free_instance(c_ipmi sfree(st->username); sfree(st->password); + ignorelist_free(st->sel_ignorelist); ignorelist_free(st->ignorelist); pthread_mutex_destroy(&st->sensor_list_lock); sfree(st); @@@ -1083,6 -1103,19 +1103,19 @@@ static int c_ipmi_config_add_instance(o status = cf_util_get_boolean(child, &st->notify_remove); } else if (strcasecmp("NotifySensorNotPresent", child->key) == 0) { status = cf_util_get_boolean(child, &st->notify_notpresent); + } else if (strcasecmp("SELSensor", child->key) == 0) { + char *value = NULL; + status = cf_util_get_string(child, &value); + if (status != 0) + break; + ignorelist_add(st->sel_ignorelist, value); + sfree(value); + } else if (strcasecmp("SELIgnoreSelected", child->key) == 0) { + bool t; + status = cf_util_get_boolean(child, &t); + if (status != 0) + break; + ignorelist_set_invert(st->sel_ignorelist, /* invert = */ !t); } else if (strcasecmp("SELEnabled", child->key) == 0) { status = cf_util_get_boolean(child, &st->sel_enabled); } else if (strcasecmp("SELClearEvent", child->key) == 0) {