Skip to content

Commit 732ffc0

Browse files
pmalek-sumopmalek
authored andcommitted
Introduce telegrafreceiver (#935)
1 parent 5053494 commit 732ffc0

File tree

12 files changed

+2621
-1
lines changed

12 files changed

+2621
-1
lines changed

cmd/otelcontribcol/unstable_components_enabled.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ package main
1818

1919
import (
2020
"go.opentelemetry.io/collector/component"
21+
22+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/telegrafreceiver"
2123
)
2224

2325
func extraReceivers() []component.ReceiverFactory {
24-
return []component.ReceiverFactory{}
26+
return []component.ReceiverFactory{
27+
telegrafreceiver.NewFactory(),
28+
}
2529
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ require (
6363
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/splunkhecreceiver v0.0.0-00010101000000-000000000000
6464
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/statsdreceiver v0.0.0-00010101000000-000000000000
6565
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/syslogreceiver v0.0.0-00010101000000-000000000000
66+
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/telegrafreceiver v0.0.0-00010101000000-000000000000
6667
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/wavefrontreceiver v0.0.0-00010101000000-000000000000
6768
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/windowsperfcountersreceiver v0.0.0-00010101000000-000000000000
6869
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zookeeperreceiver v0.0.0-00010101000000-000000000000
@@ -73,6 +74,8 @@ require (
7374

7475
replace go.opentelemetry.io/collector => github.com/SumoLogic/opentelemetry-collector v0.21.0-sumo
7576

77+
replace github.com/influxdata/telegraf => github.com/sumologic/telegraf v1.17.3-sumo
78+
7679
// Replace references to modules that are in this repository with their relateive paths
7780
// so that we always build with current (latest) version of the source code.
7881

@@ -206,6 +209,8 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kafka
206209

207210
replace github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbyattrsprocessor => ./processor/groupbyattrsprocessor
208211

212+
replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/telegrafreceiver => ./receiver/telegrafreceiver
213+
209214
replace github.com/open-telemetry/opentelemetry-collector-contrib/processor/cascadingfilterprocessor => ./processor/cascadingfilterprocessor
210215

211216
replace github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbytraceprocessor => ./processor/groupbytraceprocessor

receiver/telegrafreceiver/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include ../../Makefile.Common
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Telegraf Receiver
2+
3+
Telegraf receiver for ingesting metrics from various [input plugins][input_plugins]
4+
into otc pipeline.
5+
6+
Supported pipeline types: metrics
7+
8+
Use case: user configures telegraf input plugins in config for ingestion and otc
9+
processors and exporters for data processing and export.
10+
11+
> :construction: This receiver is currently in **BETA** and is considered **unstable**.
12+
13+
[input_plugins]: https://github.com/influxdata/telegraf/tree/master/plugins/inputs
14+
15+
## Configuration
16+
17+
The following settings are required:
18+
19+
- `agent_config`: Telegraf config. For now it allows to provide agent and input
20+
plugins configuration. One can refer to
21+
[telegraf configuration docs][telegraf_config_docs] for full list of
22+
configuration options.
23+
24+
The Following settings are optional:
25+
26+
- `separate_field` (default value is `false`): Specify whether metric field
27+
should be added separately as data point label.
28+
29+
Example:
30+
31+
```yaml
32+
receivers:
33+
telegraf:
34+
separate_field: false
35+
agent_config: |
36+
[agent]
37+
interval = "2s"
38+
flush_interval = "3s"
39+
[[inputs.mem]]
40+
```
41+
42+
The full list of settings exposed for this receiver are documented in
43+
[config.go](./config.go).
44+
45+
[telegraf_config_docs]: https://github.com/influxdata/telegraf/blob/master/docs/CONFIGURATION.md
46+
47+
## Limitations
48+
49+
With its current implementation Telegraf receiver has the following limitations:
50+
51+
- only input plugins can be configured in telegraf agent confugration section
52+
(apart from agent's configuration itself). That means that metrics go straight
53+
from input plugin to the receiver for translation (into otc data model) without
54+
any processing
55+
- ony `telegraf.Gauge` metric data is supported, which translated (loosly) into
56+
`pdata.MetricDataTypeDoubleGauge` and `pdata.MetricDataTypeIntGauge` depending
57+
on the underlying data type

receiver/telegrafreceiver/all.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2021, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package telegrafreceiver
16+
17+
import (
18+
// _ "github.com/influxdata/telegraf/plugins/aggregators/all"
19+
_ "github.com/influxdata/telegraf/plugins/inputs/all"
20+
// _ "github.com/influxdata/telegraf/plugins/outputs/all"
21+
// _ "github.com/influxdata/telegraf/plugins/processors/all"
22+
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2021, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package telegrafreceiver
16+
17+
import (
18+
"go.opentelemetry.io/collector/config/configmodels"
19+
)
20+
21+
// Config defines configuration for the telegraf receiver.
22+
type Config struct {
23+
configmodels.ReceiverSettings `mapstructure:",squash"`
24+
25+
// AgentConfig is the yaml config used as telegraf configuration.
26+
// Please note that only inputs should be configured as all metrics gathered
27+
// by them will be passed through to otc pipeline for processing and export.
28+
AgentConfig string `mapstructure:"agent_config"`
29+
30+
// SeparateField controls whether the ingested metrics should have a field
31+
// concatenated with metric name like e.g. metric=mem_available or maybe rather
32+
// have it as a separate label like e.g. metric=mem field=available
33+
SeparateField bool `mapstructure:"separate_field"`
34+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2021, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package telegrafreceiver
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/influxdata/telegraf"
21+
"go.opentelemetry.io/collector/consumer/pdata"
22+
)
23+
24+
const (
25+
fieldLabel = "field"
26+
)
27+
28+
type MetricConverter interface {
29+
Convert(telegraf.Metric) (pdata.Metrics, error)
30+
}
31+
32+
type metricConverter struct {
33+
separateField bool
34+
}
35+
36+
func newConverter(separateField bool) MetricConverter {
37+
return metricConverter{
38+
separateField: separateField,
39+
}
40+
}
41+
42+
// Convert converts telegraf.Metric to pdata.Metrics.
43+
func (mc metricConverter) Convert(m telegraf.Metric) (pdata.Metrics, error) {
44+
ms := pdata.NewMetrics()
45+
rms := ms.ResourceMetrics()
46+
rms.Resize(1)
47+
rm := rms.At(0)
48+
49+
// Attach tags as attributes - pipe through the metadata
50+
for _, t := range m.TagList() {
51+
rm.Resource().Attributes().InsertString(t.Key, t.Value)
52+
}
53+
54+
rm.InstrumentationLibraryMetrics().Resize(1)
55+
ilm := rm.InstrumentationLibraryMetrics().At(0)
56+
57+
il := ilm.InstrumentationLibrary()
58+
il.SetName(typeStr)
59+
il.SetVersion(versionStr)
60+
61+
tim := m.Time().UnixNano()
62+
63+
metrics := ilm.Metrics()
64+
65+
switch t := m.Type(); t {
66+
case telegraf.Gauge:
67+
for _, f := range m.FieldList() {
68+
pm := pdata.NewMetric()
69+
70+
if mc.separateField {
71+
pm.SetName(m.Name())
72+
} else {
73+
pm.SetName(m.Name() + "_" + f.Key)
74+
}
75+
76+
switch v := f.Value.(type) {
77+
case float64:
78+
pm.SetDataType(pdata.MetricDataTypeDoubleGauge)
79+
dps := pm.DoubleGauge().DataPoints()
80+
dps.Resize(1)
81+
dp := dps.At(0)
82+
dp.SetValue(v)
83+
dp.SetTimestamp(pdata.TimestampUnixNano(tim))
84+
if mc.separateField {
85+
dp.LabelsMap().Insert(fieldLabel, f.Key)
86+
}
87+
88+
case int64, uint64:
89+
pm.SetDataType(pdata.MetricDataTypeIntGauge)
90+
dps := pm.IntGauge().DataPoints()
91+
dps.Resize(1)
92+
dp := dps.At(0)
93+
switch vv := v.(type) {
94+
case int64:
95+
dp.SetValue(vv)
96+
case uint64:
97+
dp.SetValue(int64(vv))
98+
}
99+
100+
dp.SetTimestamp(pdata.TimestampUnixNano(tim))
101+
if mc.separateField {
102+
dp.LabelsMap().Insert(fieldLabel, f.Key)
103+
}
104+
105+
default:
106+
return pdata.Metrics{},
107+
fmt.Errorf("unknown data type in telegraf.Gauge metric: %T", v)
108+
}
109+
metrics.Append(pm)
110+
}
111+
112+
case telegraf.Counter:
113+
return pdata.Metrics{}, fmt.Errorf("unsupported metric type: telegraf.Counter")
114+
case telegraf.Untyped:
115+
return pdata.Metrics{}, fmt.Errorf("unsupported metric type: telegraf.Untyped")
116+
case telegraf.Summary:
117+
return pdata.Metrics{}, fmt.Errorf("unsupported metric type: telegraf.Summary")
118+
case telegraf.Histogram:
119+
return pdata.Metrics{}, fmt.Errorf("unsupported metric type: telegraf.Histogram")
120+
121+
default:
122+
return pdata.Metrics{}, fmt.Errorf("unknown metric type: %T", t)
123+
}
124+
125+
return ms, nil
126+
}

0 commit comments

Comments
 (0)