Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New otelcol.exporter.debug component #5867

Merged
merged 11 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
aliases:
- /docs/grafana-cloud/agent/flow/reference/components/otelcol.exporter.debug/
- /docs/grafana-cloud/monitor-infrastructure/agent/flow/reference/components/otelcol.exporter.debug/
- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/reference/components/otelcol.exporter.debug/
- /docs/grafana-cloud/send-data/agent/flow/reference/components/otelcol.exporter.debug/
canonical: https://grafana.com/docs/agent/latest/flow/reference/components/otelcol.exporter.debug/
description: Learn about otelcol.exporter.debug
labels:
stage: experimental
title: otelcol.exporter.debug
BarunKGP marked this conversation as resolved.
Show resolved Hide resolved
---

# otelcol.exporter.debug

`otelcol.exporter.debug` accepts telemetry data from other `otelcol` components and writes them to the console (stderr).
You can control the verbosity of the logs.

{{< admonition type="note" >}}
`otelcol.exporter.debug` is a wrapper over the upstream OpenTelemetry Collector `debug` exporter.
If necessary, bug reports or feature requests are redirected to the upstream repository.
{{< /admonition >}}

Multiple `otelcol.exporter.debug` components can be specified by giving them different labels.

## Usage

```river
otelcol.exporter.debug "LABEL" { }
```

## Arguments

`otelcol.exporter.debug` supports the following arguments:

Name | Type | Description | Default | Required
---- | ---- | ----------- | ------- | --------
`verbosity` | `string` | Verbosity of the generated logs. | `"normal"` | no
`sampling_initial` | `int` | Number of messages initially logged each second. | `2` | no
`sampling_thereafter` | `int` | Sampling rate after the initial messages are logged. | `500` | no

The `verbosity` argument must be one of `"basic"`, `"normal"`, or `"detailed"`.

## Exported fields

The following fields are exported and can be referenced by other components:

Name | Type | Description
---- | ---- | -----------
`input` | `otelcol.Consumer` | A value that other components can use to send telemetry data to.

`input` accepts `otelcol.Consumer` data for any telemetry signal (metrics,
logs, or traces).

## Component health

`otelcol.exporter.debug` is only reported as unhealthy if given an invalid
configuration.

## Debug information

`otelcol.exporter.debug` does not expose any component-specific debug
information.

## Example

This example scrapes Prometheus UNIX metrics and writes them to the console:

```river
prometheus.exporter.unix "default" { }

prometheus.scrape "default" {
targets = prometheus.exporter.unix.default.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

otelcol.receiver.prometheus "default" {
output {
metrics = [otelcol.exporter.debug.default.input]
}
}

otelcol.exporter.debug "default" {
verbosity = "detailed"
sampling_initial = 1
sampling_thereafter = 1
}
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ require (
github.com/open-telemetry/opentelemetry-collector-contrib/processor/filterprocessor v0.87.0
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.87.0
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/vcenterreceiver v0.87.0
github.com/prometheus/tsdb v0.10.0
go.opentelemetry.io/collector/exporter/debugexporter v0.87.0
BarunKGP marked this conversation as resolved.
Show resolved Hide resolved
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0
golang.org/x/crypto/x509roots/fallback v0.0.0-20240208163226-62c9f1799c91
k8s.io/apimachinery v0.28.3
Expand Down
5 changes: 2 additions & 3 deletions go.sum
BarunKGP marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,6 @@ github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsY
github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/digitalocean/godo v1.1.1/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU=
github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU=
github.com/digitalocean/godo v1.104.1 h1:SZNxjAsskM/su0YW9P8Wx3gU0W1Z13b6tZlYNpl5BnA=
Expand Down Expand Up @@ -2013,8 +2012,6 @@ github.com/prometheus/snmp_exporter v0.24.1/go.mod h1:j6uIGkdR0DXvKn7HJtSkeDj//U
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
github.com/prometheus/statsd_exporter v0.22.8 h1:Qo2D9ZzaQG+id9i5NYNGmbf1aa/KxKbB9aKfMS+Yib0=
github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+PFHOPWGxdXVr6yC8eFOM=
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
Expand Down Expand Up @@ -2373,6 +2370,8 @@ go.opentelemetry.io/collector/consumer v0.87.0 h1:oR5XKZoVF/hwz0FnrYPaHcbbQazHif
go.opentelemetry.io/collector/consumer v0.87.0/go.mod h1:lui5rg1byAT7QPbCY733StCDc/TPxS3hVNXKoVQ3LsI=
go.opentelemetry.io/collector/exporter v0.87.0 h1:DZ0QT2yp1qACmHMxs6W2ho5RPqdevCx9R/LFCxnxi9w=
go.opentelemetry.io/collector/exporter v0.87.0/go.mod h1:SGobdCR0xwQElJT2Sbofo7BprMlV8XeXdsNP9fsNaKY=
go.opentelemetry.io/collector/exporter/debugexporter v0.87.0 h1:xPZme8RnjgXSRG2EKXwV1Uy+e44pqZpSqRWAkYOHsog=
go.opentelemetry.io/collector/exporter/debugexporter v0.87.0/go.mod h1:L3LYJKt//OTHLS6JM3D/GLjTYejGYIqvHJAtIMrxCAI=
go.opentelemetry.io/collector/exporter/loggingexporter v0.87.0 h1:F/WkglGgCSHOFYjafYEAwD/qGpZ5HpawLMWu/Jcf0SE=
go.opentelemetry.io/collector/exporter/loggingexporter v0.87.0/go.mod h1:rYi0mKzgRH6xwsrYN9gb+WBccfoP1SpJ9U0xklrhV7g=
go.opentelemetry.io/collector/exporter/otlpexporter v0.87.0 h1:1seSC+OX1QnbpED0Kuo1DbWQSER+vy88yp4zxBubY4A=
Expand Down
96 changes: 96 additions & 0 deletions internal/component/otelcol/exporter/debug/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package debug

import (
"fmt"

"github.com/grafana/agent/internal/component"
"github.com/grafana/agent/internal/component/otelcol"
"github.com/grafana/agent/internal/component/otelcol/exporter"
"github.com/grafana/agent/internal/featuregate"
otelcomponent "go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configtelemetry"
debugexporter "go.opentelemetry.io/collector/exporter/debugexporter"
otelextension "go.opentelemetry.io/collector/extension"
)

func init() {
component.Register(component.Registration{
Name: "otelcol.exporter.debug",
Args: Arguments{},
Exports: otelcol.ConsumerExports{},
Stability: featuregate.StabilityExperimental,

Build: func(opts component.Options, args component.Arguments) (component.Component, error) {
fact := debugexporter.NewFactory()
return exporter.New(opts, fact, args.(Arguments), exporter.TypeAll)
},
})
}

type Arguments struct {
Verbosity string `river:"verbosity,attr,optional"`
SamplingInitial int `river:"sampling_initial,attr,optional"`
SamplingThereafter int `river:"sampling_thereafter,attr,optional"`
}

func (args Arguments) convertVerbosity() (configtelemetry.Level, error) {
var verbosity configtelemetry.Level
switch args.Verbosity {
case "basic":
verbosity = configtelemetry.LevelBasic
case "normal":
verbosity = configtelemetry.LevelNormal
case "detailed":
verbosity = configtelemetry.LevelDetailed
default:
// Invalid verbosity
// debugexporter only supports basic, normal and detailed levels
return verbosity, fmt.Errorf("invalid verbosity %q", args.Verbosity)
}

return verbosity, nil
}

var _ exporter.Arguments = Arguments{}

// DefaultArguments holds default values for Arguments.
var DefaultArguments = Arguments{
Verbosity: "normal",
SamplingInitial: 2,
SamplingThereafter: 500,
}

// SetToDefault implements river.Defaulter.
func (args *Arguments) SetToDefault() {
*args = DefaultArguments
}

// Convert implements exporter.Arguments.
func (args Arguments) Convert() (otelcomponent.Config, error) {
verbosity, err := args.convertVerbosity()
if err != nil {
return nil, fmt.Errorf("error in conversion to config arguments, %v", err)
}

return &debugexporter.Config{
Verbosity: verbosity,
SamplingInitial: args.SamplingInitial,
SamplingThereafter: args.SamplingThereafter,
}, nil
}

// Extensions implements exporter.Arguments.
func (args Arguments) Extensions() map[otelcomponent.ID]otelextension.Extension {
return nil
}

// Exporters implements exporter.Arguments.
func (args Arguments) Exporters() map[otelcomponent.DataType]map[otelcomponent.ID]otelcomponent.Component {
return nil
}

// DebugMetricsConfig implements receiver.Arguments.
func (args Arguments) DebugMetricsConfig() otelcol.DebugMetricsArguments {
var debugMetrics otelcol.DebugMetricsArguments
return debugMetrics
}
79 changes: 79 additions & 0 deletions internal/component/otelcol/exporter/debug/debug_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package debug_test

import (
"fmt"
"testing"

"github.com/grafana/agent/internal/component/otelcol/exporter/debug"
"github.com/grafana/river"
"github.com/stretchr/testify/require"
otelcomponent "go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configtelemetry"
debugexporter "go.opentelemetry.io/collector/exporter/debugexporter"
)

func Test(t *testing.T) {
tests := []struct {
testName string
args string
expectedReturn debugexporter.Config
errorMsg string
}{
{
testName: "defaultConfig",
args: ``,
expectedReturn: debugexporter.Config{
Verbosity: configtelemetry.LevelNormal,
SamplingInitial: 2,
SamplingThereafter: 500,
},
},

{
testName: "validConfig",
args: `
verbosity = "detailed"
sampling_initial = 5
sampling_thereafter = 20
`,
expectedReturn: debugexporter.Config{
Verbosity: configtelemetry.LevelDetailed,
SamplingInitial: 5,
SamplingThereafter: 20,
},
},

{
testName: "invalidConfig",
args: `
verbosity = "test"
sampling_initial = 5
sampling_thereafter = 20
`,
errorMsg: "error in conversion to config arguments",
},
}

for _, tc := range tests {
t.Run(tc.testName, func(t *testing.T) {
var args debug.Arguments
err := river.Unmarshal([]byte(tc.args), &args)
require.NoError(t, err)

actualPtr, err := args.Convert()
if tc.errorMsg != "" {
require.ErrorContains(t, err, tc.errorMsg)
return
}

require.NoError(t, err)

actual := actualPtr.(*debugexporter.Config)
fmt.Printf("Passed conversion")

require.NoError(t, otelcomponent.ValidateConfig(actual))

require.Equal(t, tc.expectedReturn, *actual)
})
}
}
Loading