Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add apcupsd_ups_status and apcupsd_ups_info metrics #8

Closed
wants to merge 7 commits into from

Conversation

jangrewe
Copy link

@jangrewe jangrewe commented May 24, 2019

This adds multiple apcupsd_ups_status metrics, each containing the label status with all possible values the STATUS: line can contain. (Label values taken from https://www.systutorials.com/docs/linux/man/8-apcaccess/)

This also add the apcupsd_ups_info metric and moves all the redundant info labels from the other metrics to this one (as suggested by you in #6).

And lastly this PR adds an example Grafana dashboard and the respective screenhot.

Added bonus: a Dockerfile (image size: 8MB), with the image available at https://hub.docker.com/r/jangrewe/apcupsd-exporter

@jangrewe jangrewe changed the title Add apcupsd_ups_status metric Add apcupsd_ups_status and apcupsd_ups_info metrics May 24, 2019
@jangrewe
Copy link
Author

@mdlayher Any chance you could have a look at this PR? I'm sorry that it got a bit out of hand, but i think it's worth it! 😄

@mdlayher
Copy link
Owner

Thank you for the PR and I appreciate the effort you've put in, but this PR has a lot of unrelated changes that make it difficult to review quickly.

My free time is rather limited this week. I'll try to get to this early next week.

@@ -0,0 +1,2 @@
.idea
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add these to your global gitignore instead.


You can find the dashboard JSON in the `grafana` folder.

![sample](https://raw.githubusercontent.com/jangrewe/apcupsd_exporter/master/grafana/screenshot.png)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would need to reflect the path of the upstream repository.

@@ -1,19 +1,55 @@
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a lot of churn, did you go mod tidy too?

@@ -41,105 +44,119 @@ var _ prometheus.Collector = &UPSCollector{}
// NewUPSCollector creates a new UPSCollector.
func NewUPSCollector(ss StatusSource) *UPSCollector {
var (
labels = []string{"hostname", "ups_name", "model"}
infoLabels = []string{"hostname", "ups_name", "model"}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move these to package level so they can be deduplicated at this point.


UPSInfo: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "ups_info"),
"Hostname, UPS Model and Name.",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Metadata about a UPS."

More flexible for the future.

nil,
),

UPSStatus: prometheus.NewDesc(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it would make more sense to include the status label in UPSInfo rather than in its own metric.

@candlerb
Copy link

Just a note to say that I have tested from the @jangrewe repo, and it works for me:

apcupsd_apcupsd_nominal_power_watts 390
apcupsd_battery_charge_percent 100
apcupsd_battery_cumulative_time_on_seconds_total 0
apcupsd_battery_nominal_volts 12
apcupsd_battery_number_transfers_total 0
apcupsd_battery_time_left_seconds 4602
apcupsd_battery_time_on_seconds 0
apcupsd_battery_volts 13.4
apcupsd_line_nominal_volts 230
apcupsd_line_volts 240
apcupsd_ups_info{hostname="nuc2",model="Back-UPS XS 700U",ups_name="bx700"} 1
apcupsd_ups_load_percent 3
apcupsd_ups_status{status="BOOST"} 0
apcupsd_ups_status{status="CAL"} 0
apcupsd_ups_status{status="COMMLOST"} 0
apcupsd_ups_status{status="LOWBATT"} 0
apcupsd_ups_status{status="NOBATT"} 0
apcupsd_ups_status{status="ONBATT"} 0
apcupsd_ups_status{status="ONLINE"} 1
apcupsd_ups_status{status="OVERLOAD"} 0
apcupsd_ups_status{status="REPLACEBATT"} 0
apcupsd_ups_status{status="SHUTTING DOWN"} 0
apcupsd_ups_status{status="SLAVE"} 0
apcupsd_ups_status{status="SLAVEDOWN"} 0
apcupsd_ups_status{status="TRIM"} 0

I am ambivalent, however, about the loss of metadata from the individual metrics.

Including metadata in every metric is how the official snmp_exporter works. Example:

# HELP ifHCInOctets The total number of octets received on the interface, including framing characters - 1.3.6.1.2.1.31.1.1.1.
6
# TYPE ifHCInOctets counter
ifHCInOctets{ifAlias="",ifDescr="bridge",ifIndex="14",ifName="bridge"} 6.343343949e+09
ifHCInOctets{ifAlias="",ifDescr="ether1",ifIndex="16",ifName="ether1"} 2.4808641625e+10
ifHCInOctets{ifAlias="",ifDescr="ether2",ifIndex="2",ifName="ether2"} 0
ifHCInOctets{ifAlias="",ifDescr="ether3",ifIndex="3",ifName="ether3"} 6.083273145e+09
ifHCInOctets{ifAlias="",ifDescr="ether4",ifIndex="4",ifName="ether4"} 6.79593826e+08
ifHCInOctets{ifAlias="",ifDescr="ether5",ifIndex="5",ifName="ether5"} 2.91243382e+08
ifHCInOctets{ifAlias="",ifDescr="pppoe-out1",ifIndex="17",ifName="pppoe-out1"} 2.4255138238e+10
...
# HELP ifHCOutOctets The total number of octets transmitted out of the interface, including framing characters - 1.3.6.1.2.1.31.1.1.1.10
# TYPE ifHCOutOctets counter
ifHCOutOctets{ifAlias="",ifDescr="bridge",ifIndex="14",ifName="bridge"} 2.5131203193e+10
ifHCOutOctets{ifAlias="",ifDescr="ether1",ifIndex="16",ifName="ether1"} 5.096503509e+09
ifHCOutOctets{ifAlias="",ifDescr="ether2",ifIndex="2",ifName="ether2"} 0
ifHCOutOctets{ifAlias="",ifDescr="ether3",ifIndex="3",ifName="ether3"} 1.0343428154e+10
ifHCOutOctets{ifAlias="",ifDescr="ether4",ifIndex="4",ifName="ether4"} 1.4271999034e+10
ifHCOutOctets{ifAlias="",ifDescr="ether5",ifIndex="5",ifName="ether5"} 4.11163912e+09
ifHCOutOctets{ifAlias="",ifDescr="pppoe-out1",ifIndex="17",ifName="pppoe-out1"} 4.764235347e+09

This in turn makes it very easy to use in grafana dashboards, with all of the graph lines labelled with the available metadata, and easy to filter on any particular piece of metadata.

If they changed it to work the way proposed here, then it would look more like this:

ifIndex{ifAlias="",ifDescr="bridge",ifIndex="14",ifName="bridge"} 1
ifIndex{ifAlias="",ifDescr="ether1",ifIndex="16",ifName="ether1"} 1
ifIndex{ifAlias="",ifDescr="ether2",ifIndex="2",ifName="ether2"} 1
ifIndex{ifAlias="",ifDescr="ether3",ifIndex="3",ifName="ether3"} 1
ifIndex{ifAlias="",ifDescr="ether4",ifIndex="4",ifName="ether4"} 1
ifIndex{ifAlias="",ifDescr="ether5",ifIndex="5",ifName="ether5"} 1
ifIndex{ifAlias="",ifDescr="pppoe-out1",ifIndex="17",ifName="pppoe-out1"} 1
...
ifHCInOctets{ifIndex="14"} 6.343343949e+09
ifHCInOctets{ifIndex="16"} 2.4808641625e+10
ifHCInOctets{ifIndex="2"} 0
ifHCInOctets{ifIndex="3"} 6.083273145e+09
ifHCInOctets{ifIndex="4"} 6.79593826e+08
ifHCInOctets{ifIndex="5"} 2.91243382e+08
ifHCInOctets{ifIndex="17"} 2.4255138238e+10
...
ifHCOutOctets{ifIndex="14"} 2.5131203193e+10
ifHCOutOctets{ifIndex="16"} 5.096503509e+09
ifHCOutOctets{ifIndex="2"} 0
ifHCOutOctets{ifIndex="3"} 1.0343428154e+10
ifHCOutOctets{ifIndex="4"} 1.4271999034e+10
ifHCOutOctets{ifIndex="5"} 4.11163912e+09
ifHCOutOctets{ifIndex="17",ifName="pppoe-out1"} 4.764235347e+09

This has some advantages with regards to continuity of timeseries if metadata changes, but seems to be a lot harder to work with in grafana.

Let's consider the simpler case of apcupsd with this proposed patch applied. Suppose you have multiple UPSes, and are showing all the "time remaining" in a single graph with a separate line for each UPS. Once prometheus has added its own scraping labels, you would get metrics like this:

apcupsd_ups_info{job="apcupsd",instance="192.0.2.1",hostname="nuc1",model="Back-UPS XS 700U",ups_name="bx700-1"} 1
apcupsd_battery_time_left_seconds{job="apcupsd",instance="192.0.2.1",status="ONLINE"} 4062
...
apcupsd_ups_info{job="apcupsd",instance="192.0.2.2",hostname="nuc2",model="Back-UPS XS 700U",ups_name="bx700-2"} 1
apcupsd_battery_time_left_seconds{job="apcupsd",instance="192.0.2.2",status="ONLINE"} 3950

If you want your graphs labelled with the UPS name or hostname, you need to invoke some prometheus join magic. According to this article I think that adding the ups_name to the apcupsd_battery_time_left_seconds metric might look something like this:

apcupsd_battery_time_left_seconds * on (instance, job) group_left(ups_name) apcupsd_ups_info

I don't pretend to understand this, and it may be wrong. In any case it would have to be copy-pasted into every grafana query in the dashboard.

Similarly: suppose you want a drop-down menu to select between UPSes. If you don't mind just showing the 'instance' value this is straightforward:

  • Dashboard variable 'instance' = label_values(apcupsd_ups_info, instance)
  • Query: apcupsd_battery_time_left_seconds{instance="$instance"}

But if you want the dropdown to select on 'ups_name', it gets tricky.

  • Dashboard variable 'ups_name' = label_values(apcupsd_ups_info, ups_name)
  • Query: apcupsd_battery_time_left_seconds * on (instance, job) group_left(ups_name) apcupsd_ups_info{ups_name="$ups_name"} ???

@candlerb
Copy link

candlerb commented Jul 5, 2019

I am ambivalent, however, about the loss of metadata from the individual metrics.

Including metadata in every metric is how the official snmp_exporter works.

For reference, discussion about it at prometheus/snmp_exporter#180 and prometheus/snmp_exporter#339

@mdlayher
Copy link
Owner

I ended up fixing things up, thanks for your time.

@mdlayher mdlayher closed this May 18, 2020
@crockk
Copy link

crockk commented Jul 22, 2021

Can this be revisited? It would be very useful to have status info in the metrics, or as a label in apcupsd_info. I made an issue pertaining to it:
#19

@candlerb
Copy link

FWIW, I changed to https://github.com/damomurf/apcupsd-exporter a while ago.

@crockk
Copy link

crockk commented Jul 27, 2021

Fair enough, but I need both status metrics and the metrics that this exporter provides... Both exporters use the same command line tool so it seems a bit silly to be installing two exporters for the same tool 😅

@crockk crockk mentioned this pull request Jul 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants