feat(go.d/snmp profile): add sensors to mikrotik-router.yaml (#20507)
Ilya Mashchenko committed
Jun 17, 2025 at 19:13 UTC
d8939dba75a5e94da94f6e29242e432903957088
4 files changed
+94
-46
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collect_table.go
+15
-12
@@ -196,21 +196,23 @@ func (c *Collector) processTableData(cfg ddprofiledefinition.MetricsConfig, pdus
196
rowTags := make(map[string]string)
197
198
// Process tags for this row
199
- for columnOID, tagCfg := range tagColumnOIDs {
199
+ for columnOID, tagCfgs := range tagColumnOIDs {
200
pdu, ok := rowPDUs[columnOID]
201
if !ok {
202
continue
203
}
204
205
- tags, err := processTableMetricTagValue(tagCfg, pdu)
206
- if err != nil {
207
- c.log.Debugf("Error processing tag %s: %v", tagCfg.Tag, err)
208
- continue
209
- }
205
+ for _, tagCfg := range tagCfgs {
206
+ tags, err := processTableMetricTagValue(tagCfg, pdu)
207
+ if err != nil {
208
+ c.log.Debugf("Error processing tag %s: %v", tagCfg.Tag, err)
209
+ continue
210
+ }
211
211
- for k, v := range tags {
212
- rowTags[k] = v
213
- tagCache[index][k] = v
212
+ for k, v := range tags {
213
+ rowTags[k] = v
214
+ tagCache[index][k] = v
215
+ }
216
}
217
}
218
@@ -342,11 +344,12 @@ func buildColumnOIDs(cfg ddprofiledefinition.MetricsConfig) map[string]ddprofile
344
return columnOIDs
345
}
346
345
-func buildTagColumnOIDs(cfg ddprofiledefinition.MetricsConfig) map[string]ddprofiledefinition.MetricTagConfig {
346
- tagColumnOIDs := make(map[string]ddprofiledefinition.MetricTagConfig)
347
+func buildTagColumnOIDs(cfg ddprofiledefinition.MetricsConfig) map[string][]ddprofiledefinition.MetricTagConfig {
348
+ tagColumnOIDs := make(map[string][]ddprofiledefinition.MetricTagConfig)
349
for _, tagCfg := range cfg.MetricTags {
350
if tagCfg.Table == "" || tagCfg.Table == cfg.Table.Name {
349
- tagColumnOIDs[trimOID(tagCfg.Symbol.OID)] = tagCfg
351
+ oid := trimOID(tagCfg.Symbol.OID)
352
+ tagColumnOIDs[oid] = append(tagColumnOIDs[oid], tagCfg)
353
}
354
}
355
return tagColumnOIDs
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collector.go
+30
-4
@@ -98,8 +98,7 @@ func (c *Collector) Collect() ([]*ProfileMetrics, error) {
98
c.log.Debugf("collecting metrics: %v", errors.Join(errs...))
99
}
100
101
- c.updateMetricFamily(metrics)
102
- cleanMetrics(metrics)
101
+ c.updateMetrics(metrics)
102
103
return metrics, nil
104
}
@@ -150,7 +149,7 @@ func (c *Collector) collectProfile(ps *profileState) (*ProfileMetrics, error) {
149
return pm, nil
150
}
151
153
-func (c *Collector) updateMetricFamily(pms []*ProfileMetrics) {
152
+func (c *Collector) updateMetrics(pms []*ProfileMetrics) {
153
// Find device vendor and type from any profile that has them.
154
// Multiple profiles can be loaded for a single device (e.g., base profiles, generic MIB profiles),
155
// but only device-specific profiles contain vendor/type information.
@@ -174,7 +173,27 @@ func (c *Collector) updateMetricFamily(pms []*ProfileMetrics) {
173
m.Family = processMetricFamily(m.Family, dt, dv)
174
}
175
}
177
- return
176
+ break
177
+ }
178
+
179
+ for _, pm := range pms {
180
+ for i := range pm.Metrics {
181
+ m := &pm.Metrics[i]
182
+ m.Description = metricMetaReplacer.Replace(m.Description)
183
+ m.Family = metricMetaReplacer.Replace(m.Family)
184
+ m.Unit = metricMetaReplacer.Replace(m.Unit)
185
+ for k, v := range m.Tags {
186
+ m.Tags[k] = metricMetaReplacer.Replace(v)
187
+ }
188
+ if v, ok := m.Tags["_unit"]; ok && v != "" {
189
+ delete(m.Tags, "_unit")
190
+ m.Unit = metricMetaReplacer.Replace(v)
191
+ }
192
+ if v, ok := m.Tags["_metric_suffix"]; ok && v != "" {
193
+ delete(m.Tags, "_metric_suffix")
194
+ m.Name += "_" + metricMetaReplacer.Replace(v)
195
+ }
196
+ }
197
}
198
}
199
@@ -215,3 +234,10 @@ func processMetricFamily(family, devType, vendor string) string {
234
235
return strings.TrimSuffix(prefix+"/"+strings.Join(parts, "/"), "/")
236
}
237
+
238
+var metricMetaReplacer = strings.NewReplacer(
239
+ "'", "",
240
+ "\n", " ",
241
+ "\r", " ",
242
+ "\x00", "",
243
+)
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/utils.go
-20
@@ -252,23 +252,3 @@ func isMappingKeysNumeric(mapping map[string]string) bool {
252
}
253
return true
254
}
255
-func cleanMetrics(pms []*ProfileMetrics) {
256
- for _, pm := range pms {
257
- for i := range pm.Metrics {
258
- m := &pm.Metrics[i]
259
- m.Description = metricMetaReplacer.Replace(m.Description)
260
- m.Family = metricMetaReplacer.Replace(m.Family)
261
- m.Unit = metricMetaReplacer.Replace(m.Unit)
262
- for k, v := range m.Tags {
263
- m.Tags[k] = metricMetaReplacer.Replace(v)
264
- }
265
- }
266
- }
267
-}
268
-
269
-var metricMetaReplacer = strings.NewReplacer(
270
- "'", "",
271
- "\n", " ",
272
- "\r", " ",
273
- "\x00", "",
274
-)
src/go/plugin/go.d/config/go.d/snmp.profiles/default/mikrotik-router.yaml
+49
-10
@@ -129,16 +129,6 @@ metrics:
129
2: waiting_for_load
130
3: powered_on
131
4: overload
132
- # - MIB: MIKROTIK-MIB
133
- # symbol:
134
- # OID: 1.3.6.1.4.1.14988.1.1.3.17
135
- # name: mtxrHlFanSpeed1
136
- # string metric is not supported yet (keep this metric and this comment in profile until it's fixed)
137
- # - MIB: MIKROTIK-MIB
138
- # symbol:
139
- # OID: 1.3.6.1.4.1.14988.1.1.3.18
140
- # name: mtxrHlFanSpeed2
141
- # string metric is not supported yet (keep this metric and this comment in profile until it's fixed)
132
- MIB: HOST-RESOURCES-MIB
133
symbol:
134
OID: 1.3.6.1.2.1.25.3.3.1.2.1
@@ -174,3 +164,52 @@ metrics:
164
symbol:
165
OID: 1.3.6.1.2.1.25.2.3.1.3
166
name: hrStorageDescr
167
+ # Table metrics - Extended health monitoring (multi-sensor support)
168
+ - MIB: MIKROTIK-MIB
169
+ table:
170
+ OID: 1.3.6.1.4.1.14988.1.1.3.100
171
+ name: mtxrHlTable
172
+ symbols:
173
+ - OID: 1.3.6.1.4.1.14988.1.1.3.100.1.3
174
+ name: mtxrHlSensorValue
175
+ description: Sensor value
176
+ family: Health/Sensors
177
+ metric_tags:
178
+ - tag: sensor_name
179
+ symbol:
180
+ OID: 1.3.6.1.4.1.14988.1.1.3.100.1.2
181
+ name: mtxrHlSensorName
182
+ - tag: "_unit"
183
+ symbol:
184
+ OID: 1.3.6.1.4.1.14988.1.1.3.100.1.4
185
+ name: mtxrHlSensorUnit
186
+ mapping:
187
+ 1: celsius
188
+ 2: rpm
189
+ 3: dV # decivolts
190
+ 4: dA # deciamps
191
+ 5: dW # deciwatts
192
+ 6: status
193
+ 7: boolean
194
+ 8: percentage
195
+ - tag: "_metric_suffix"
196
+ symbol:
197
+ OID: 1.3.6.1.4.1.14988.1.1.3.100.1.4
198
+ name: mtxrHlSensorType
199
+ mapping:
200
+ 1: temperature
201
+ 2: fan_speed
202
+ 3: voltage
203
+ 4: current
204
+ 5: power
205
+ 6: state
206
+ 7: boolean
207
+ 8: percentage
208
+
209
+metric_tags:
210
+ - OID: 1.3.6.1.4.1.14988.1.1.4.1.0
211
+ symbol: mtxrLicSoftwareId
212
+ tag: software_id
213
+ - OID: 1.3.6.1.4.1.14988.1.1.4.4.0
214
+ symbol: mtxrLicVersion
215
+ tag: license_version