-
Notifications
You must be signed in to change notification settings - Fork 221
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New otelcol.exporter.debug component
- Loading branch information
Showing
13 changed files
with
432 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
docs/sources/reference/components/otelcol.exporter.debug.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
--- | ||
canonical: https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.debug/ | ||
description: Learn about otelcol.exporter.debug | ||
title: otelcol.exporter.debug | ||
--- | ||
|
||
<span class="badge docs-labels__stage docs-labels__item">Experimental</span> | ||
|
||
# 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"`: A single-line summary of received data is logged to stderr, with a total count of telemetry records for every batch of received logs, metrics or traces. | ||
* `"normal"`: Currently, this produces the same output as `"basic"` verbosity. | ||
* `"detailed"`: All details of every telemetry record are logged to stderr, typically writing multiple lines for every telemetry record. | ||
|
||
Example of `"basic"` and `"normal"` output: | ||
``` | ||
ts=2024-06-13T11:24:13.782957Z level=info msg=TracesExporter component_path=/ component_id=otelcol.exporter.debug.default "resource spans": 1, spans: 2 | ||
``` | ||
|
||
Example of `"detailed"` output: | ||
``` | ||
ts=2024-06-13T11:24:13.782957Z level=info msg=TracesExporter component_path=/ component_id=otelcol.exporter.debug.default "resource spans"=1 spans=2 | ||
ts=2024-06-13T11:24:13.783101Z level=info msg="ResourceSpans #0 | ||
Resource SchemaURL: https://opentelemetry.io/schemas/1.4.0 | ||
Resource attributes: | ||
-> service.name: Str(telemetrygen) | ||
ScopeSpans #0 | ||
ScopeSpans SchemaURL: | ||
InstrumentationScope telemetrygen | ||
Span #0 | ||
Trace ID : 3bde5d3ee82303571bba6e1136781fe4 | ||
Parent ID : 5e9dcf9bac4acc1f | ||
ID : 2cf3ef2899aba35c | ||
Name : okey-dokey | ||
Kind : Server | ||
Start time : 2023-11-11 04:49:03.509369393 +0000 UTC | ||
End time : 2023-11-11 04:49:03.50949377 +0000 UTC | ||
Status code : Unset | ||
Status message : | ||
Attributes: | ||
-> net.peer.ip: Str(1.2.3.4) | ||
-> peer.service: Str(telemetrygen-client) | ||
Span #1 | ||
Trace ID : 3bde5d3ee82303571bba6e1136781fe4 | ||
Parent ID : | ||
ID : 5e9dcf9bac4acc1f | ||
Name : lets-go | ||
Kind : Client | ||
Start time : 2023-11-11 04:49:03.50935117 +0000 UTC | ||
End time : 2023-11-11 04:49:03.50949377 +0000 UTC | ||
Status code : Unset | ||
Status message : | ||
Attributes: | ||
-> net.peer.ip: Str(1.2.3.4) | ||
-> peer.service: Str(telemetrygen-server) | ||
{"kind": "exporter", "data_type": "traces", "name": "debug"}" | ||
``` | ||
|
||
Note that the above `"detailed"` example was edited to replace all instances of `\n` with a new line. | ||
|
||
## 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 | ||
} | ||
``` | ||
<!-- START GENERATED COMPATIBLE COMPONENTS --> | ||
|
||
## Compatible components | ||
|
||
`otelcol.exporter.debug` has exports that can be consumed by the following components: | ||
|
||
- Components that consume [OpenTelemetry `otelcol.Consumer`](../../compatibility/#opentelemetry-otelcolconsumer-consumers) | ||
|
||
{{< admonition type="note" >}} | ||
Connecting some components may not be sensible or components may require further configuration to make the connection work correctly. | ||
Refer to the linked documentation for more details. | ||
{{< /admonition >}} | ||
|
||
<!-- END GENERATED COMPATIBLE COMPONENTS --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package debug | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/grafana/alloy/internal/component" | ||
"github.com/grafana/alloy/internal/component/otelcol" | ||
otelcolCfg "github.com/grafana/alloy/internal/component/otelcol/config" | ||
"github.com/grafana/alloy/internal/component/otelcol/exporter" | ||
"github.com/grafana/alloy/internal/featuregate" | ||
otelcomponent "go.opentelemetry.io/collector/component" | ||
"go.opentelemetry.io/collector/config/configtelemetry" | ||
"go.opentelemetry.io/collector/exporter/debugexporter" | ||
otelextension "go.opentelemetry.io/collector/extension" | ||
) | ||
|
||
func init() { | ||
component.Register(component.Registration{ | ||
Name: "otelcol.exporter.debug", | ||
Stability: featuregate.StabilityExperimental, | ||
Args: Arguments{}, | ||
Exports: otelcol.ConsumerExports{}, | ||
|
||
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 `alloy:"verbosity,attr,optional"` | ||
SamplingInitial int `alloy:"sampling_initial,attr,optional"` | ||
SamplingThereafter int `alloy:"sampling_thereafter,attr,optional"` | ||
|
||
// DebugMetrics configures component internal metrics. Optional. | ||
DebugMetrics otelcolCfg.DebugMetricsArguments `alloy:"debug_metrics,block,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{} | ||
|
||
// SetToDefault implements river.Defaulter. | ||
func (args *Arguments) SetToDefault() { | ||
*args = Arguments{ | ||
Verbosity: "normal", | ||
SamplingInitial: 2, | ||
SamplingThereafter: 500, | ||
} | ||
args.DebugMetrics.SetToDefault() | ||
} | ||
|
||
// 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() otelcolCfg.DebugMetricsArguments { | ||
return args.DebugMetrics | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package debug_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/grafana/alloy/internal/component/otelcol/exporter/debug" | ||
"github.com/grafana/alloy/syntax" | ||
"github.com/stretchr/testify/require" | ||
otelcomponent "go.opentelemetry.io/collector/component" | ||
"go.opentelemetry.io/collector/config/configtelemetry" | ||
"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 := syntax.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) | ||
}) | ||
} | ||
} |
Oops, something went wrong.