Skip to content

Commit

Permalink
otelcol.receiver.zipkin: new component (#2685)
Browse files Browse the repository at this point in the history
This commit adds otelcol.receiver.zipkin as a new Flow component,
wrapping around the upstream zipkin receiver from the OpenTelemetry
Collector otelcol-contrib distribution.

otelcol.receiver.zipkin spawns an HTTP server which can read
Zipkin-formatted traces over the network.

Closes #2293.
  • Loading branch information
rfratto authored Jan 9, 2023
1 parent 14b9e86 commit 0aad04c
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Main (unreleased)
- `phlare.scrape` collects application performance profiles. (@cyriltovena)
- `phlare.write` sends application performance profiles to Grafana Phlare. (@cyriltovena)

- `otelcol.receiver.zipkin` receives Zipkin-formatted traces. (@rfratto)

### Enhancements

- Handle faro-web-sdk `View` meta in app_agent_receiver. (@rlankfo)
Expand Down
1 change: 1 addition & 0 deletions component/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
_ "github.com/grafana/agent/component/otelcol/receiver/kafka" // Import otelcol.receiver.kafka
_ "github.com/grafana/agent/component/otelcol/receiver/otlp" // Import otelcol.receiver.otlp
_ "github.com/grafana/agent/component/otelcol/receiver/prometheus" // Import otelcol.receiver.prometheus
_ "github.com/grafana/agent/component/otelcol/receiver/zipkin" // Import otelcol.receiver.zipkin
_ "github.com/grafana/agent/component/phlare/scrape" // Import phlare.scrape
_ "github.com/grafana/agent/component/phlare/write" // Import phlare.write
_ "github.com/grafana/agent/component/prometheus/integration/node_exporter" // Import prometheus.integration.node_exporter
Expand Down
2 changes: 2 additions & 0 deletions component/otelcol/receiver/kafka/kafka.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ func (args *Arguments) UnmarshalRiver(f func(interface{}) error) error {
// Convert implements receiver.Arguments.
func (args Arguments) Convert() otelconfig.Receiver {
return &kafkareceiver.Config{
ReceiverSettings: otelconfig.NewReceiverSettings(otelconfig.NewComponentID("kafka")),

Brokers: args.Brokers,
ProtocolVersion: args.ProtocolVersion,
Topic: args.Topic,
Expand Down
79 changes: 79 additions & 0 deletions component/otelcol/receiver/zipkin/zipkin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Package zipkin provides an otelcol.receiver.zipkin component.
package zipkin

import (
"github.com/grafana/agent/component"
"github.com/grafana/agent/component/otelcol"
"github.com/grafana/agent/component/otelcol/receiver"
"github.com/grafana/agent/pkg/river"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver"
otelcomponent "go.opentelemetry.io/collector/component"
otelconfig "go.opentelemetry.io/collector/config"
)

func init() {
component.Register(component.Registration{
Name: "otelcol.receiver.zipkin",
Args: Arguments{},

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

// Arguments configures the otelcol.receiver.zipkin component.
type Arguments struct {
ParseStringTags bool `river:"parse_string_tags,attr,optional"`

HTTPServer otelcol.HTTPServerArguments `river:"http,block,optional"`

// Output configures where to send received data. Required.
Output *otelcol.ConsumerArguments `river:"output,block"`
}

var (
_ receiver.Arguments = Arguments{}
_ river.Unmarshaler = (*Arguments)(nil)
)

// DefaultArguments holds default settings for otelcol.receiver.zipkin.
var DefaultArguments = Arguments{
HTTPServer: otelcol.HTTPServerArguments{
Endpoint: "0.0.0.0:9411",
},
}

// UnmarshalRiver applies defaults to args before unmarshaling.
func (args *Arguments) UnmarshalRiver(f func(interface{}) error) error {
*args = DefaultArguments

type arguments Arguments
return f((*arguments)(args))
}

// Convert implements receiver.Arguments.
func (args Arguments) Convert() otelconfig.Receiver {
return &zipkinreceiver.Config{
ReceiverSettings: otelconfig.NewReceiverSettings(otelconfig.NewComponentID("zipkin")),

ParseStringTags: args.ParseStringTags,
HTTPServerSettings: *args.HTTPServer.Convert(),
}
}

// Extensions implements receiver.Arguments.
func (args Arguments) Extensions() map[otelconfig.ComponentID]otelcomponent.Extension {
return nil
}

// Exporters implements receiver.Arguments.
func (args Arguments) Exporters() map[otelconfig.DataType]map[otelconfig.ComponentID]otelcomponent.Exporter {
return nil
}

// NextConsumers implements receiver.Arguments.
func (args Arguments) NextConsumers() *otelcol.ConsumerArguments {
return args.Output
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,15 @@ Name | Type | Description | Default | Required
`allowed_headers` | `list(string)` | Accepted headers from CORS requests. | `["X-Requested-With"]` | no
`max_age` | `number` | Configures the `Access-Control-Max-Age` response header. | | no

The `allowed_headers` specifies which headers are acceptable from a CORS
request. The following headers are always implicitly allowed:
The `allowed_headers` argument specifies which headers are acceptable from a
CORS request. The following headers are always implicitly allowed:

* `Accept`
* `Accept-Language`
* `Content-Type`
* `Content-Language`

If `allowed_headers` includes `"*"`, all headers will be permitted.
If `allowed_headers` includes `"*"`, all headers are permitted.

### output block

Expand Down
155 changes: 155 additions & 0 deletions docs/sources/flow/reference/components/otelcol.receiver.zipkin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
aliases:
- /docs/agent/latest/flow/reference/components/otelcol.receiver.zipkin
title: otelcol.receiver.zipkin
---

# otelcol.receiver.zipkin

`otelcol.receiver.zipkin` accepts Zipkin-formatted traces over the network and
forwards it to other `otelcol.*` components.

> **NOTE**: `otelcol.receiver.zipkin` is a wrapper over the upstream
> OpenTelemetry Collector `zipkin` receiver. Bug reports or feature requests
> will be redirected to the upstream repository, if necessary.
Multiple `otelcol.receiver.zipkin` components can be specified by giving them
different labels.

## Usage

```river
otelcol.receiver.zipkin "LABEL" {
output {
traces = [...]
}
}
```

## Arguments

`otelcol.receiver.zipkin` supports the following arguments:

Name | Type | Description | Default | Required
---- | ---- | ----------- | ------- | --------
`parse_string_tags` | `bool` | Parse string tags and binary annotations into non-string types. | `false` | no

If `parse_string_tags` is `true`, string tags and binary annotations are
converted to `int`, `bool`, and `float` if possible. String tags and binary
annotations that cannot be converted remain unchanged.

## Blocks

The following blocks are supported inside the definition of
`otelcol.receiver.zipkin`:

Hierarchy | Block | Description | Required
--------- | ----- | ----------- | --------
http | [http][] | Configures the HTTP server to receive telemetry data. | no
http > tls | [tls][] | Configures TLS for the HTTP server. | no
http > cors | [cors][] | Configures CORS for the HTTP server. | no
output | [output][] | Configures where to send received traces. | yes

The `>` symbol indicates deeper levels of nesting. For example, `grpc > tls`
refers to a `tls` block defined inside a `grpc` block.

[http]: #http-block
[tls]: #tls-block
[cors]: #cors-block
[output]: #output-block

### http block

The `http` block configures the HTTP server used by the component.

The following arguments are supported:

Name | Type | Description | Default | Required
---- | ---- | ----------- | ------- | --------
`endpoint` | `string` | `host:port` to listen for traffic on. | `"0.0.0.0:9411"` | no
`max_request_body_size` | `string` | Maximum request body size the server will allow. No limit when unset. | | no
`include_metadata` | `boolean` | Propagate incoming connection metadata to downstream consumers. | | no

### tls block

The `tls` block configures TLS settings used for a server. If the `tls` block
isn't provided, TLS won't be used for connections to the server.

The following arguments are supported:

Name | Type | Description | Default | Required
---- | ---- | ----------- | ------- | --------
`ca_file` | `string` | Path to the CA file. | | no
`cert_file` | `string` | Path to the TLS certificate. | | no
`key_file` | `string` | Path to the TLS certificate key. | | no
`min_version` | `string` | Minimum acceptable TLS version for connections. | `"TLS 1.2"` | no
`max_version` | `string` | Maximum acceptable TLS version for connections. | `"TLS 1.3"` | no
`reload_interval` | `duration` | Frequency to reload the certificates. | | no
`client_ca_file` | `string` | Path to the CA file used to authenticate client certificates. | | no

### cors block

The `cors` block configures CORS settings for an HTTP server.

The following arguments are supported:

Name | Type | Description | Default | Required
---- | ---- | ----------- | ------- | --------
`allowed_origins` | `list(string)` | Allowed values for the `Origin` header. | | no
`allowed_headers` | `list(string)` | Accepted headers from CORS requests. | `["X-Requested-With"]` | no
`max_age` | `number` | Configures the `Access-Control-Max-Age` response header. | | no

The `allowed_headers` argument specifies which headers are acceptable from a
CORS request. The following headers are always implicitly allowed:

* `Accept`
* `Accept-Language`
* `Content-Type`
* `Content-Language`

If `allowed_headers` includes `"*"`, all headers are permitted.

### output block

{{< docs/shared lookup="flow/reference/components/output-block.md" source="agent" >}}

## Exported fields

`otelcol.receiver.zipkin` does not export any fields.

## Component health

`otelcol.receiver.zipkin` is only reported as unhealthy if given an invalid
configuration.

## Debug information

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

## Example

This example forwards received traces through a batch processor before finally
sending it to an OTLP-capable endpoint:

```river
otelcol.receiver.zipkin "default" {
output {
traces = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch "default" {
output {
metrics = [otelcol.exporter.otlp.default.input]
logs = [otelcol.exporter.otlp.default.input]
traces = [otelcol.exporter.otlp.default.input]
}
}
otelcol.exporter.otlp "default" {
client {
endpoint = env("OTLP_ENDPOINT")
}
}
```

0 comments on commit 0aad04c

Please sign in to comment.