Skip to content

Commit 7241817

Browse files
committed
feat add ipmi component
#731
1 parent 7ca16ad commit 7241817

File tree

11 files changed

+1335
-3
lines changed

11 files changed

+1335
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Main (unreleased)
5555

5656
- Add `file_match` block to `loki.source.file` for built-in file discovery using glob patterns. (@kalleep)
5757

58+
- Add `prometheus.exporter.ipmi` component to collect hardware metrics from IPMI-enabled devices. Supports both local IPMI collection and remote IPMI monitoring with authentication. (@parsa97)
59+
5860
### Enhancements
5961

6062
- Add support of `tls` in components `loki.source.(awsfirehose|gcplog|heroku|api)` and `prometheus.receive_http` and `pyroscope.receive_http`. (@fgouteroux)
Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
---
2+
canonical: https://grafana.com/docs/alloy/latest/reference/components/prometheus/prometheus.exporter.ipmi/
3+
aliases:
4+
- ../prometheus.exporter.ipmi/ # /docs/alloy/latest/reference/components/prometheus.exporter.ipmi/
5+
description: Learn about prometheus.exporter.ipmi
6+
labels:
7+
stage: general-availability
8+
products:
9+
- oss
10+
title: prometheus.exporter.ipmi
11+
---
12+
13+
# `prometheus.exporter.ipmi`
14+
15+
The `prometheus.exporter.ipmi` component collects hardware metrics from IPMI-enabled devices.
16+
It supports both local IPMI collection (from the machine running Alloy) and remote IPMI collection from network-accessible devices.
17+
18+
## Usage
19+
20+
```alloy
21+
prometheus.exporter.ipmi "<LABEL>" {
22+
target {
23+
name = "<NAME>"
24+
address = "<IPMI_ADDRESS>"
25+
user = "<USERNAME>"
26+
password = "<PASSWORD>"
27+
}
28+
}
29+
```
30+
31+
## Arguments
32+
33+
You can use the following arguments with `prometheus.exporter.ipmi`:
34+
35+
| Name | Type | Description | Default | Required |
36+
| ------------- | ---------- | ----------------------------------------------------- | ------- | -------- |
37+
| `timeout` | `duration` | Timeout for IPMI requests. | `"30s"` | no |
38+
| `config_file` | `string` | Path to IPMI exporter configuration file. | | no |
39+
| `ipmi_config` | `string` | IPMI exporter configuration as inline YAML string. | | no |
40+
41+
The `timeout` should be set high enough to allow IPMI sensor collection to complete.
42+
IPMI operations can be slow, especially for devices with many sensors.
43+
A timeout of 30 seconds or more is recommended for most hardware.
44+
45+
The `config_file` and `ipmi_config` arguments are mutually exclusive.
46+
They allow advanced configuration of IPMI collection modules and command overrides.
47+
48+
## Blocks
49+
50+
You can use the following blocks with `prometheus.exporter.ipmi`:
51+
52+
| Name | Description | Required |
53+
| ---------------- | ------------------------------------ | -------- |
54+
| [`target`][target] | Configures a remote IPMI target. | no |
55+
| [`local`][local] | Configures local IPMI collection. | no |
56+
57+
At least one `target` block or the `local` block must be configured.
58+
59+
[target]: #target
60+
[local]: #local
61+
62+
### `target`
63+
64+
| Name | Type | Description | Default | Required |
65+
| ----------- | -------- | --------------------------------------------- | ----------- | -------- |
66+
| `name` | `string` | Name of the target (used in job label). | | yes |
67+
| `address` | `string` | IP address or hostname of the IPMI device. | | yes |
68+
| `user` | `string` | IPMI username for authentication. | | no |
69+
| `password` | `secret` | IPMI password for authentication. | | no |
70+
| `driver` | `string` | IPMI driver to use (`LAN_2_0` or `LAN`). | `"LAN_2_0"` | no |
71+
| `privilege` | `string` | IPMI privilege level (`user` or `admin`). | `"admin"` | no |
72+
| `module` | `string` | IPMI collector module to use. | | no |
73+
74+
The `target` block defines a remote IPMI device to monitor.
75+
Multiple `target` blocks can be specified to monitor multiple devices.
76+
77+
The `driver` attribute specifies which IPMI protocol version to use:
78+
- `LAN_2_0`: IPMI 2.0 protocol (recommended for most modern hardware)
79+
- `LAN`: IPMI 1.5 protocol (for older hardware)
80+
81+
The `privilege` attribute sets the privilege level for IPMI operations:
82+
- `admin`: Full administrative access (required for all sensor data on most hardware)
83+
- `user`: User-level access (limited sensor access)
84+
85+
### `local`
86+
87+
| Name | Type | Description | Default | Required |
88+
| --------- | -------- | ---------------------------------------- | ------- | -------- |
89+
| `enabled` | `bool` | Enable local IPMI collection. | `false` | no |
90+
| `module` | `string` | IPMI collector module to use. | | no |
91+
92+
The `local` block enables collection from the local machine's IPMI interface.
93+
This requires the machine to have IPMI hardware and appropriate permissions.
94+
On Linux systems, this typically requires:
95+
- FreeIPMI tools installed
96+
- Kernel modules loaded (`ipmi_devintf`, `ipmi_si`)
97+
- Appropriate device permissions (`/dev/ipmi0`)
98+
99+
## Exported fields
100+
101+
{{< docs/shared lookup="reference/components/exporter-component-exports.md" source="alloy" version="<ALLOY_VERSION>" >}}
102+
103+
## Component health
104+
105+
`prometheus.exporter.ipmi` is only reported as unhealthy if given an invalid configuration.
106+
In those cases, exported fields retain their last healthy values.
107+
108+
IPMI connection failures or timeouts don't affect component health.
109+
Instead, the `ipmi_up` metric is set to 0 for unreachable targets.
110+
111+
## Debug information
112+
113+
`prometheus.exporter.ipmi` doesn't expose any component-specific debug information.
114+
115+
## Debug metrics
116+
117+
`prometheus.exporter.ipmi` doesn't expose any component-specific debug metrics.
118+
119+
## Collected metrics
120+
121+
The IPMI exporter collects the following metrics:
122+
123+
| Metric | Type | Description |
124+
| --------------------------- | ----- | ----------------------------------------------------------------- |
125+
| `ipmi_up` | Gauge | IPMI device reachability (1=up, 0=down) |
126+
| `ipmi_temperature_celsius` | Gauge | Temperature sensor reading in degrees Celsius |
127+
| `ipmi_fan_speed_rpm` | Gauge | Fan speed sensor reading in RPM |
128+
| `ipmi_voltage_volts` | Gauge | Voltage sensor reading in volts |
129+
| `ipmi_power_watts` | Gauge | Power sensor reading in watts |
130+
| `ipmi_current_amperes` | Gauge | Current sensor reading in amperes |
131+
| `ipmi_sensor_state` | Gauge | Sensor state (0=nominal, 1=warning, 2=critical, 3=not available) |
132+
| `ipmi_collector_info` | Gauge | Information about the IPMI collector configuration |
133+
134+
All sensor metrics include labels:
135+
- `target`: IP address or "localhost" for local collection
136+
- `sensor`: Sensor name from IPMI hardware
137+
- `id`: Sensor ID number
138+
139+
## Examples
140+
141+
### Monitor remote IPMI devices
142+
143+
This example monitors two remote servers via IPMI and forwards metrics to Prometheus:
144+
145+
```alloy
146+
prometheus.exporter.ipmi "servers" {
147+
target {
148+
name = "server-01"
149+
address = "192.168.1.10"
150+
user = "monitoring"
151+
password = env("IPMI_PASSWORD")
152+
driver = "LAN_2_0"
153+
privilege = "admin"
154+
}
155+
156+
target {
157+
name = "server-02"
158+
address = "192.168.1.11"
159+
user = "monitoring"
160+
password = env("IPMI_PASSWORD")
161+
driver = "LAN_2_0"
162+
privilege = "admin"
163+
}
164+
165+
timeout = "30s"
166+
}
167+
168+
prometheus.scrape "ipmi" {
169+
targets = prometheus.exporter.ipmi.servers.targets
170+
forward_to = [prometheus.remote_write.default.receiver]
171+
scrape_interval = "60s"
172+
scrape_timeout = "45s"
173+
}
174+
175+
prometheus.remote_write "default" {
176+
endpoint {
177+
url = "http://prometheus:9090/api/v1/write"
178+
}
179+
}
180+
```
181+
182+
### Monitor local IPMI device
183+
184+
This example monitors the local server's IPMI interface:
185+
186+
```alloy
187+
prometheus.exporter.ipmi "local_server" {
188+
local {
189+
enabled = true
190+
module = "default"
191+
}
192+
}
193+
194+
prometheus.scrape "ipmi_local" {
195+
targets = prometheus.exporter.ipmi.local_server.targets
196+
forward_to = [prometheus.remote_write.default.receiver]
197+
}
198+
199+
prometheus.remote_write "default" {
200+
endpoint {
201+
url = "http://prometheus:9090/api/v1/write"
202+
}
203+
}
204+
```
205+
206+
### Monitor both local and remote devices
207+
208+
This example combines local and remote IPMI monitoring:
209+
210+
```alloy
211+
prometheus.exporter.ipmi "infrastructure" {
212+
// Monitor local machine
213+
local {
214+
enabled = true
215+
}
216+
217+
// Monitor remote servers
218+
target {
219+
name = "compute-01"
220+
address = "10.0.1.10"
221+
user = "admin"
222+
password = env("IPMI_PASSWORD")
223+
}
224+
225+
target {
226+
name = "compute-02"
227+
address = "10.0.1.11"
228+
user = "admin"
229+
password = env("IPMI_PASSWORD")
230+
}
231+
232+
timeout = "30s"
233+
}
234+
235+
prometheus.scrape "all_ipmi" {
236+
targets = prometheus.exporter.ipmi.infrastructure.targets
237+
forward_to = [prometheus.remote_write.default.receiver]
238+
scrape_interval = "60s"
239+
scrape_timeout = "45s"
240+
}
241+
242+
prometheus.remote_write "default" {
243+
endpoint {
244+
url = env("PROMETHEUS_URL")
245+
}
246+
}
247+
```
248+
249+
### Access metrics directly without scraping
250+
251+
For testing or debugging, you can access IPMI metrics directly via HTTP:
252+
253+
```alloy
254+
prometheus.exporter.ipmi "test" {
255+
target {
256+
name = "test-server"
257+
address = "192.168.1.100"
258+
user = "monitoring"
259+
password = env("IPMI_PASSWORD")
260+
}
261+
}
262+
```
263+
264+
Metrics are available at:
265+
```
266+
http://localhost:12345/api/v0/component/prometheus.exporter.ipmi.test/metrics
267+
```
268+
269+
## Technical notes
270+
271+
### IPMI timeout configuration
272+
273+
IPMI sensor collection can be slow, especially for servers with many sensors.
274+
Configure timeouts appropriately:
275+
276+
- **Component timeout**: Set to 30-60 seconds to allow sensor collection to complete
277+
- **Scrape timeout**: Must be longer than the component timeout
278+
- **Scrape interval**: Recommended 60 seconds or more to avoid overlapping collections
279+
280+
Example configuration:
281+
```alloy
282+
prometheus.exporter.ipmi "servers" {
283+
timeout = "30s" // Allow 30 seconds for IPMI operations
284+
// ... targets ...
285+
}
286+
287+
prometheus.scrape "ipmi" {
288+
scrape_interval = "60s" // Scrape every minute
289+
scrape_timeout = "45s" // Allow 45 seconds (> component timeout)
290+
targets = prometheus.exporter.ipmi.servers.targets
291+
// ... forward_to ...
292+
}
293+
```
294+
295+
### IPMI driver selection
296+
297+
Choose the appropriate IPMI driver based on your hardware:
298+
299+
- **LAN_2_0** (IPMI 2.0): Recommended for modern servers (Dell, HP, Supermicro from ~2010+)
300+
- **LAN** (IPMI 1.5): For older hardware that doesn't support IPMI 2.0
301+
302+
If unsure, try `LAN_2_0` first. Connection failures may indicate the need to use `LAN`.
303+
304+
### Local IPMI requirements
305+
306+
For local IPMI collection, ensure:
307+
308+
1. **Hardware support**: Server has BMC/IPMI hardware
309+
2. **Kernel modules** (Linux):
310+
```bash
311+
modprobe ipmi_devintf
312+
modprobe ipmi_si
313+
```
314+
3. **Device permissions**:
315+
```bash
316+
ls -l /dev/ipmi* /dev/ipmi0
317+
# Should be accessible by the user running Alloy
318+
```
319+
4. **FreeIPMI tools** (optional but recommended):
320+
```bash
321+
# Debian/Ubuntu
322+
apt-get install freeipmi-tools
323+
324+
# RHEL/CentOS
325+
yum install freeipmi
326+
```
327+
328+
### Security considerations
329+
330+
IPMI credentials provide low-level hardware access:
331+
332+
- **Use dedicated monitoring users** with minimal required privileges
333+
- **Store passwords securely** using `env()` or secrets management
334+
- **Never commit passwords** to version control
335+
- **Consider network isolation** for IPMI interfaces (dedicated management network)
336+
- **Use IPMI 2.0** (`LAN_2_0`) when possible for better security
337+
338+
Example with environment variables:
339+
```alloy
340+
prometheus.exporter.ipmi "secure" {
341+
target {
342+
name = "production-server"
343+
address = env("IPMI_HOST")
344+
user = env("IPMI_USER")
345+
password = env("IPMI_PASSWORD")
346+
}
347+
}
348+
```
349+
350+
<!-- START GENERATED COMPATIBLE COMPONENTS -->
351+
352+
## Compatible components
353+
354+
`prometheus.exporter.ipmi` has exports that can be consumed by the following components:
355+
356+
- Components that consume [Targets](../../../compatibility/#targets-consumers)
357+
358+
{{< admonition type="note" >}}
359+
Connecting some components may not be sensible or components may require further configuration to make the connection work correctly.
360+
Refer to the linked documentation for more details.
361+
{{< /admonition >}}
362+
363+
<!-- END GENERATED COMPATIBLE COMPONENTS -->

go.mod

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ require (
115115
github.com/natefinch/atomic v1.0.1
116116
github.com/ncabatoff/process-exporter v0.8.7
117117
github.com/oklog/run v1.2.0
118-
github.com/olekukonko/tablewriter v0.0.5
118+
github.com/olekukonko/tablewriter v1.0.9
119119
github.com/oliver006/redis_exporter v1.74.0
120120
github.com/open-telemetry/opentelemetry-collector-contrib/connector/servicegraphconnector v0.134.0
121121
github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.134.0
@@ -998,7 +998,16 @@ require (
998998
github.com/go-openapi/swag/stringutils v0.25.1 // indirect
999999
github.com/go-openapi/swag/typeutils v0.25.1 // indirect
10001000
github.com/go-openapi/swag/yamlutils v0.25.1 // indirect
1001-
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/cloudflarereceiver v0.138.0 // indirect
1001+
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/cloudflarereceiver v0.138.0
1002+
)
1003+
1004+
require github.com/bougou/go-ipmi v0.7.8 // indirect
1005+
1006+
require (
1007+
github.com/kr/pretty v0.3.1 // indirect
1008+
github.com/kr/text v0.2.0 // indirect
1009+
github.com/olekukonko/errors v1.1.0 // indirect
1010+
github.com/olekukonko/ll v0.0.9 // indirect
10021011
)
10031012

10041013
// NOTE: replace directives below must always be *temporary*.

0 commit comments

Comments
 (0)