Skip to content

Commit f6f7c74

Browse files
Support labels for metric.fielddtoappend (#351)
Signed-off-by: Anders Swanson <anders.swanson@oracle.com>
1 parent 017acdd commit f6f7c74

File tree

4 files changed

+58
-65
lines changed

4 files changed

+58
-65
lines changed

collector/collector.go

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var (
3030
exporterName = "exporter"
3131
)
3232

33-
// ScrapResult is container structure for error handling
33+
// ScrapeResult is container structure for error handling
3434
type ScrapeResult struct {
3535
Err error
3636
Metric Metric
@@ -433,7 +433,10 @@ func (e *Exporter) scrapeGenericValues(d *Database, ch chan<- prometheus.Metric,
433433
// Construct labels value
434434
labelsValues := []string{}
435435
for _, label := range m.Labels {
436-
labelsValues = append(labelsValues, row[label])
436+
// Don't include FieldToAppend in the label values
437+
if label != m.FieldToAppend {
438+
labelsValues = append(labelsValues, row[label])
439+
}
437440
}
438441
// Construct Prometheus values to sent back
439442
for metric, metricHelp := range m.MetricsDesc {
@@ -444,75 +447,42 @@ func (e *Exporter) scrapeGenericValues(d *Database, ch chan<- prometheus.Metric,
444447
}
445448
e.logger.Debug("Query result",
446449
"value", value)
447-
// If metric do not use a field content in metric's name
448-
if strings.Compare(m.FieldToAppend, "") == 0 {
449-
desc := prometheus.NewDesc(
450-
prometheus.BuildFQName(namespace, m.Context, metric),
451-
metricHelp,
452-
m.Labels,
453-
constLabels,
454-
)
455-
if m.MetricsType[strings.ToLower(metric)] == "histogram" {
456-
count, err := strconv.ParseUint(strings.TrimSpace(row["count"]), 10, 64)
450+
451+
// Build metric desc
452+
suffix := metricNameSuffix(row, metric, m.FieldToAppend)
453+
desc := prometheus.NewDesc(
454+
prometheus.BuildFQName(namespace, m.Context, suffix),
455+
metricHelp,
456+
m.GetLabels(),
457+
constLabels,
458+
)
459+
// process histogram metric, then cache and send metric through channel
460+
if m.MetricsType[strings.ToLower(metric)] == "histogram" {
461+
count, err := strconv.ParseUint(strings.TrimSpace(row["count"]), 10, 64)
462+
if err != nil {
463+
e.logger.Error("Unable to convert count value to int (metric=" + metric +
464+
",metricHelp=" + metricHelp + ",value=<" + row["count"] + ">)")
465+
continue
466+
}
467+
buckets := make(map[float64]uint64)
468+
for field, le := range m.MetricsBuckets[metric] {
469+
lelimit, err := strconv.ParseFloat(strings.TrimSpace(le), 64)
457470
if err != nil {
458-
e.logger.Error("Unable to convert count value to int (metric=" + metric +
459-
",metricHelp=" + metricHelp + ",value=<" + row["count"] + ">)")
471+
e.logger.Error("Unable to convert bucket limit value to float (metric=" + metric +
472+
",metricHelp=" + metricHelp + ",bucketlimit=<" + le + ">)")
460473
continue
461474
}
462-
buckets := make(map[float64]uint64)
463-
for field, le := range m.MetricsBuckets[metric] {
464-
lelimit, err := strconv.ParseFloat(strings.TrimSpace(le), 64)
465-
if err != nil {
466-
e.logger.Error("Unable to convert bucket limit value to float (metric=" + metric +
467-
",metricHelp=" + metricHelp + ",bucketlimit=<" + le + ">)")
468-
continue
469-
}
470-
counter, err := strconv.ParseUint(strings.TrimSpace(row[field]), 10, 64)
471-
if err != nil {
472-
e.logger.Error("Unable to convert ", field, " value to int (metric="+metric+
473-
",metricHelp="+metricHelp+",value=<"+row[field]+">)")
474-
continue
475-
}
476-
buckets[lelimit] = counter
477-
}
478-
d.MetricsCache.CacheAndSend(ch, m, prometheus.MustNewConstHistogram(desc, count, value, buckets, labelsValues...))
479-
} else {
480-
d.MetricsCache.CacheAndSend(ch, m, prometheus.MustNewConstMetric(desc, getMetricType(metric, m.MetricsType), value, labelsValues...))
481-
}
482-
// If no labels, use metric name
483-
} else {
484-
desc := prometheus.NewDesc(
485-
prometheus.BuildFQName(namespace, m.Context, cleanName(row[m.FieldToAppend])),
486-
metricHelp,
487-
nil, constLabels,
488-
)
489-
if m.MetricsType[strings.ToLower(metric)] == "histogram" {
490-
count, err := strconv.ParseUint(strings.TrimSpace(row["count"]), 10, 64)
475+
counter, err := strconv.ParseUint(strings.TrimSpace(row[field]), 10, 64)
491476
if err != nil {
492-
e.logger.Error("Unable to convert count value to int (metric=" + metric +
493-
",metricHelp=" + metricHelp + ",value=<" + row["count"] + ">)")
477+
e.logger.Error("Unable to convert ", field, " value to int (metric="+metric+
478+
",metricHelp="+metricHelp+",value=<"+row[field]+">)")
494479
continue
495480
}
496-
buckets := make(map[float64]uint64)
497-
for field, le := range m.MetricsBuckets[metric] {
498-
lelimit, err := strconv.ParseFloat(strings.TrimSpace(le), 64)
499-
if err != nil {
500-
e.logger.Error("Unable to convert bucket limit value to float (metric=" + metric +
501-
",metricHelp=" + metricHelp + ",bucketlimit=<" + le + ">)")
502-
continue
503-
}
504-
counter, err := strconv.ParseUint(strings.TrimSpace(row[field]), 10, 64)
505-
if err != nil {
506-
e.logger.Error("Unable to convert ", field, " value to int (metric="+metric+
507-
",metricHelp="+metricHelp+",value=<"+row[field]+">)")
508-
continue
509-
}
510-
buckets[lelimit] = counter
511-
}
512-
d.MetricsCache.CacheAndSend(ch, m, prometheus.MustNewConstHistogram(desc, count, value, buckets))
513-
} else {
514-
d.MetricsCache.CacheAndSend(ch, m, prometheus.MustNewConstMetric(desc, getMetricType(metric, m.MetricsType), value))
481+
buckets[lelimit] = counter
515482
}
483+
d.MetricsCache.CacheAndSend(ch, m, prometheus.MustNewConstHistogram(desc, count, value, buckets, labelsValues...))
484+
} else {
485+
d.MetricsCache.CacheAndSend(ch, m, prometheus.MustNewConstMetric(desc, getMetricType(metric, m.MetricsType), value, labelsValues...))
516486
}
517487
metricsCount++
518488
}
@@ -611,3 +581,10 @@ func cleanName(s string) string {
611581
s = strings.ToLower(s)
612582
return s
613583
}
584+
585+
func metricNameSuffix(row map[string]string, metric, fieldToAppend string) string {
586+
if len(fieldToAppend) == 0 {
587+
return metric
588+
}
589+
return cleanName(row[fieldToAppend])
590+
}

collector/metrics.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,18 @@ func (e *Exporter) parseFloat(metric, metricHelp string, row map[string]string)
7777
}
7878
return valueFloat, true
7979
}
80+
81+
func (m *Metric) GetLabels() []string {
82+
if len(m.FieldToAppend) == 0 {
83+
return m.Labels
84+
}
85+
// Do not include FieldToAppend in metric labels,
86+
// as this field is appended to the metric FQDN.
87+
var labels []string
88+
for _, label := range m.Labels {
89+
if label != m.FieldToAppend {
90+
labels = append(labels, label)
91+
}
92+
}
93+
return labels
94+
}

site/docs/configuration/custom-metrics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Metrics files must contain a series of `[[metric]]` definitions, in TOML, or the
3434
| metricsdesc | Mapping between field(s) in the request and comment(s) | Dictionary of Strings | Yes | |
3535
| metricstype | Mapping between field(s) in the request and [Prometheus metric types](https://prometheus.io/docs/concepts/metric_types/) | Dictionary of Strings | No | |
3636
| metricsbuckets | Split [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) metric types into buckets based on value ([example](https://github.com/oracle/oracle-db-appdev-monitoring/blob/main/custom-metrics-example/metric-histogram-example.toml)) | Dictionary of String dictionaries | No | |
37-
| fieldtoappend | Field from the request to append to the metric FQN | String | No | |
37+
| fieldtoappend | Field from the request to append to the metric FQN. This field will **not** be included in the metric labels. | String | No | |
3838
| request | Oracle database query to run for metrics scraping | String | Yes | |
3939
| ignorezeroresult | Whether or not an error will be printed if the request does not return any results | Boolean | No | false |
4040
| querytimeout | Oracle Database query timeout duration, e.g., 300ms, 0.5h | String duration | No | Value of query.timeout in seconds |

site/docs/releases/changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ List of upcoming and historic changes to the exporter.
1212
Our current priorities are support for Exadata metrics. We expect to address these in an upcoming release.
1313

1414
- Updated project dependencies.
15+
- Added metric label support for metrics using the `fieldtoappend` property. The default `wait_time` and `activity` use the `fieldtoappend` property.
1516
- Fix `wait_time` default metric to work with Oracle Database 19c.
1617

1718
Thank you to the following people for their suggestions and contributions:

0 commit comments

Comments
 (0)