Skip to content

Commit

Permalink
Merge branch 'prometheus-community-master' into value-converter
Browse files Browse the repository at this point in the history
  • Loading branch information
yhk-mw committed Aug 29, 2022
2 parents 52a4267 + 4592d12 commit 92f077a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 17 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ $ docker run --rm -it -p 9090:9090 -v $PWD/examples/prometheus.yml:/etc/promethe
```
Then head over to http://localhost:9090/graph?g0.range_input=1h&g0.expr=example_value_active&g0.tab=1 or http://localhost:9090/targets to check the scraped metrics or the targets.

## Using custom timestamps

This exporter allows you to use a field of the metric as the (unix/epoch) timestamp for the data as an int64. However, this may lead to unexpected behaviour, as the prometheus implements a [Staleness](https://prometheus.io/docs/prometheus/latest/querying/basics/#staleness) mechanism. Including timestamps in metrics disabled this staleness handling and can make data visible for longer than expected.

## Exposing metrics through HTTPS

TLS configuration supported by this exporter can be found at [exporter-toolkit/web](https://github.com/prometheus/exporter-toolkit/blob/v0.5.1/docs/web-configuration.md)
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Metric struct {
Labels map[string]string
Type ScrapeType
ValueType ValueType
EpochTimestamp string
Help string
Values map[string]string
ValueConverter ValueConverterType
Expand Down
7 changes: 6 additions & 1 deletion examples/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ modules:
labels:
environment: beta # static label
location: "planet-{.location}" # dynamic label

- name: example_timestamped_value
path: "{ .values[?(@.state == "INACTIVE")] }"
epochTimestamp: "{ .timestamp }"
help: Example of a timestamped value scrape in the json
labels:
environment: beta # static label
- name: example_value
type: object
help: Example of sub-level value scrapes from a json
Expand Down
1 change: 1 addition & 0 deletions examples/data.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"counter": 1234,
"timestamp": 1657568506,
"values": [
{
"id": "id-A",
Expand Down
38 changes: 29 additions & 9 deletions exporter/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"bytes"
"encoding/json"
"strings"
"time"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
Expand All @@ -32,13 +33,14 @@ type JSONMetricCollector struct {
}

type JSONMetric struct {
Desc *prometheus.Desc
Type config.ScrapeType
KeyJSONPath string
ValueJSONPath string
LabelsJSONPaths []string
ValueType prometheus.ValueType
Desc *prometheus.Desc
Type config.ScrapeType
KeyJSONPath string
ValueJSONPath string
LabelsJSONPaths []string
ValueType prometheus.ValueType
ValueConverter config.ValueConverterType
EpochTimestampJSONPath string
}

func (mc JSONMetricCollector) Describe(ch chan<- *prometheus.Desc) {
Expand All @@ -58,13 +60,13 @@ func (mc JSONMetricCollector) Collect(ch chan<- prometheus.Metric) {
}

if floatValue, err := SanitizeValue(value); err == nil {

ch <- prometheus.MustNewConstMetric(
metric := prometheus.MustNewConstMetric(
m.Desc,
m.ValueType,
floatValue,
extractLabels(mc.Logger, mc.Data, m.LabelsJSONPaths)...,
)
ch <- timestampMetric(mc.Logger, m, mc.Data, metric)
} else {
level.Error(mc.Logger).Log("msg", "Failed to convert extracted value to float64", "path", m.KeyJSONPath, "value", value, "err", err, "metric", m.Desc)
continue
Expand Down Expand Up @@ -95,12 +97,13 @@ func (mc JSONMetricCollector) Collect(ch chan<- prometheus.Metric) {
value = convertValueIfNeeded(m, value)

if floatValue, err := SanitizeValue(value); err == nil {
ch <- prometheus.MustNewConstMetric(
metric := prometheus.MustNewConstMetric(
m.Desc,
m.ValueType,
floatValue,
extractLabels(mc.Logger, jdata, m.LabelsJSONPaths)...,
)
ch <- timestampMetric(mc.Logger, m, jdata, metric)
} else {
level.Error(mc.Logger).Log("msg", "Failed to convert extracted value to float64", "path", m.ValueJSONPath, "value", value, "err", err, "metric", m.Desc)
continue
Expand Down Expand Up @@ -176,3 +179,20 @@ func convertValueIfNeeded(m JSONMetric, value string) string {
}
return value
}
func timestampMetric(logger log.Logger, m JSONMetric, data []byte, pm prometheus.Metric) prometheus.Metric {
if m.EpochTimestampJSONPath == "" {
return pm
}
ts, err := extractValue(logger, data, m.EpochTimestampJSONPath, false)
if err != nil {
level.Error(logger).Log("msg", "Failed to extract timestamp for metric", "path", m.KeyJSONPath, "err", err, "metric", m.Desc)
return pm
}
epochTime, err := SanitizeIntValue(ts)
if err != nil {
level.Error(logger).Log("msg", "Failed to parse timestamp for metric", "path", m.KeyJSONPath, "err", err, "metric", m.Desc)
return pm
}
timestamp := time.UnixMilli(epochTime)
return prometheus.NewMetricWithTimestamp(timestamp, pm)
}
29 changes: 22 additions & 7 deletions exporter/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ func SanitizeValue(s string) (float64, error) {
return value, fmt.Errorf(resultErr)
}

func SanitizeIntValue(s string) (int64, error) {
var err error
var value int64
var resultErr string

if value, err = strconv.ParseInt(s, 10, 64); err == nil {
return value, nil
}
resultErr = fmt.Sprintf("%s", err)

return value, fmt.Errorf(resultErr)
}

func CreateMetricsList(c config.Module) ([]JSONMetric, error) {
var (
metrics []JSONMetric
Expand Down Expand Up @@ -91,9 +104,10 @@ func CreateMetricsList(c config.Module) ([]JSONMetric, error) {
variableLabels,
nil,
),
KeyJSONPath: metric.Path,
LabelsJSONPaths: variableLabelsValues,
ValueType: valueType,
KeyJSONPath: metric.Path,
LabelsJSONPaths: variableLabelsValues,
ValueType: valueType,
EpochTimestampJSONPath: metric.EpochTimestamp,
}
metrics = append(metrics, jsonMetric)
case config.ObjectScrape:
Expand All @@ -115,11 +129,12 @@ func CreateMetricsList(c config.Module) ([]JSONMetric, error) {
variableLabels,
nil,
),
KeyJSONPath: metric.Path,
ValueJSONPath: valuePath,
LabelsJSONPaths: variableLabelsValues,
ValueType: valueType,
KeyJSONPath: metric.Path,
ValueJSONPath: valuePath,
LabelsJSONPaths: variableLabelsValues,
ValueType: valueType,
ValueConverter: valueConverters,
EpochTimestampJSONPath: metric.EpochTimestamp,
}
metrics = append(metrics, jsonMetric)
}
Expand Down

0 comments on commit 92f077a

Please sign in to comment.