Skip to content

Commit 37b8231

Browse files
author
rafaelcarvalhedo
committed
feat: elasticapmreceiver
1 parent 7914d62 commit 37b8231

40 files changed

+1762
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
golang 1.20

receiver/elasticapmreceiver/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Leo Orpilla III
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

receiver/elasticapmreceiver/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Elastic APM Receiver
2+
3+
An experimental [OpenTelemetry Collector][otel-collector] receiver for Elastic APM trace data.
4+
5+
Elastic APM agents export telemetry data to [Elastic APM Server][apm-server] via the [Events Intake API][events-v2].
6+
With this receiver, agents can point to an OpenTelemetry Collector instance instead and export trace data to any backend supported by OpenTelemetry.
7+
8+
Metrics and logs are currently **not supported**.
9+
10+
![Elastic RUM JS Agent to OpenTelemetry Collector to Jaeger](./docs/jaeger_sample.png)
11+
12+
**This is a proof of concept. It is not intended for production use.**
13+
14+
## Getting Started
15+
16+
⚠️ This receiver must be built from source. See [Build](#build) for instructions.
17+
18+
The receiver can be configured using the following settings:
19+
20+
- `endpoint` the URI where this receiver can be contacted (default: `0.0.0.0:8200`)
21+
- `events_url_path` the path to the [Events Intake V2][events-v2] endpoint (default: `/intake/v2/events`)
22+
- `rum_events_url_path` the path to the [RUM Events Intake V2][rum-v2] endpoint (default: `/intake/v2/rum/events`)
23+
- `max_event_size_bytes` the maximum size of an event in bytes (default: `300KiB`)
24+
- `batch_size` the maximum number of events to process in a single batch (default: `10`)
25+
26+
See [OTel Collector Server Configuration][server-configuration] for more options (e.g. CORS, TLS, Headers, Auth).
27+
28+
29+
## Build
30+
31+
Use [OpenTelemetry Collector Builder][ocb] to build a binary with this receiver included.
32+
33+
Extend `builder-config.yaml` to include a receiver configuration for the Elastic APM receiver. For example:
34+
35+
```yaml
36+
receivers:
37+
- gomod: github.com/ldgrp/elasticapmreceiver v0.0.0
38+
```
39+
40+
Then build the binary:
41+
42+
```bash
43+
$ ocb --config builder-config.yaml
44+
```
45+
46+
## How it works
47+
48+
This receiver depends heavily on the latest [`elastic/apm-data`][apm-data] package to process incoming
49+
requests and convert them into an `APMEvent` struct. This struct is then converted
50+
to an OpenTelemetry span and scheduled for export.
51+
52+
- The Elastic APM RUM JS Agent exports transactions with a `duration` attribute, without a `timestamp` attribute.
53+
Traditionally, APM Server is in charge of setting the `timestamp` attribute https://github.com/elastic/apm-server/issues/723. Equivalently, this receiver sets the `timestamp` attribute to the current time.
54+
55+
- Elastic APM Agents periodically poll APM Server for [configuration changes][central-config]. This receiver does not support this feature.
56+
57+
[apm-data]: https://github.com/elastic/apm-data
58+
[apm-server]: https://www.elastic.co/guide/en/apm/guide/current/getting-started-apm-server.html
59+
[central-config]: https://www.elastic.co/guide/en/kibana/8.9/agent-configuration.html#agent-configuration
60+
[elastic-apm]: https://www.elastic.co/guide/en/observability/current/index.html
61+
[events-v2]: https://www.elastic.co/guide/en/apm/guide/current/api-events.html
62+
[ocb]: https://github.com/open-telemetry/opentelemetry-collector/tree/main/cmd/builder
63+
[otel-collector]: https://opentelemetry.io/docs/collector/
64+
[rum-v2]: https://www.elastic.co/guide/en/apm/guide/current/api-events.html
65+
[server-configuration]: https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/confighttp#server-configuration

receiver/elasticapmreceiver/config.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package elasticapmreceiver
2+
3+
import (
4+
"go.opentelemetry.io/collector/config/confighttp"
5+
)
6+
7+
type Config struct {
8+
*confighttp.HTTPServerSettings `mapstructure:",squash"`
9+
EventsURLPath string `mapstructure:"events_url_path"`
10+
RUMEventsUrlPath string `mapstructure:"rum_events_url_path"`
11+
MaxEventSize int `mapstructure:"max_event_size_bytes"`
12+
BatchSize int `mapstructure:"batch_size"`
13+
}
14+
15+
func (cfg *Config) Validate() error {
16+
return nil
17+
}
66.5 KB
Loading
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package elasticapmreceiver
2+
3+
import (
4+
"context"
5+
6+
"go.opentelemetry.io/collector/component"
7+
"go.opentelemetry.io/collector/config/confighttp"
8+
"go.opentelemetry.io/collector/consumer"
9+
"go.opentelemetry.io/collector/receiver"
10+
)
11+
12+
const (
13+
typeStr = "elasticapm"
14+
defaultHTTPEndpoint = "0.0.0.0:8200"
15+
defaultEventsURLPath = "/intake/v2/events"
16+
defaultRUMEventsURLPath = "/intake/v2/rum/events"
17+
defaultMaxEventSizeBytes = 300 * 1024
18+
defaultBatchSize = 10
19+
)
20+
21+
func NewFactory() receiver.Factory {
22+
return receiver.NewFactory(
23+
typeStr,
24+
createDefaultConfig,
25+
receiver.WithTraces(createTraces, component.StabilityLevelDevelopment),
26+
)
27+
}
28+
29+
func createDefaultConfig() component.Config {
30+
return &Config{
31+
HTTPServerSettings: &confighttp.HTTPServerSettings{
32+
Endpoint: defaultHTTPEndpoint,
33+
},
34+
EventsURLPath: defaultEventsURLPath,
35+
RUMEventsUrlPath: defaultRUMEventsURLPath,
36+
MaxEventSize: defaultMaxEventSizeBytes,
37+
BatchSize: defaultBatchSize,
38+
}
39+
}
40+
41+
func createTraces(
42+
_ context.Context,
43+
params receiver.CreateSettings,
44+
baseCfg component.Config,
45+
nextConsumer consumer.Traces,
46+
) (receiver.Traces, error) {
47+
cfg := baseCfg.(*Config)
48+
r, err := newElasticAPMReceiver(cfg, params)
49+
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
if err = r.registerTraceConsumer(nextConsumer); err != nil {
55+
return nil, err
56+
}
57+
58+
return r, nil
59+
}

receiver/elasticapmreceiver/go.mod

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module github.com/zgsolucoes/opentelemetry-collector-contrib/receiver/elasticapmreceiver
2+
3+
go 1.22.0
4+
5+
toolchain go1.23.6
6+
7+
require (
8+
github.com/elastic/apm-data v0.1.1-0.20230803060036-9180b59d7888
9+
go.opentelemetry.io/collector/component v0.119.0
10+
go.opentelemetry.io/collector/config/confighttp v0.82.0
11+
go.opentelemetry.io/collector/consumer v1.25.0
12+
go.opentelemetry.io/collector/pdata v1.25.0
13+
go.opentelemetry.io/collector/receiver v0.119.0
14+
go.opentelemetry.io/collector/semconv v0.82.0
15+
go.uber.org/zap v1.27.0
16+
)
17+
18+
require (
19+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
20+
go.opentelemetry.io/collector v0.82.0 // indirect
21+
go.opentelemetry.io/collector/pipeline v0.119.0 // indirect
22+
)
23+
24+
require (
25+
github.com/armon/go-radix v1.0.0 // indirect
26+
github.com/elastic/go-licenser v0.4.0 // indirect
27+
github.com/elastic/go-sysinfo v1.7.1 // indirect
28+
github.com/elastic/go-windows v1.0.1 // indirect
29+
github.com/felixge/httpsnoop v1.0.3 // indirect
30+
github.com/fsnotify/fsnotify v1.6.0 // indirect
31+
github.com/go-logr/logr v1.4.2 // indirect
32+
github.com/go-logr/stdr v1.2.2 // indirect
33+
github.com/gofrs/uuid v4.3.1+incompatible // indirect
34+
github.com/gogo/protobuf v1.3.2 // indirect
35+
github.com/golang/snappy v0.0.4 // indirect
36+
github.com/jcchavezs/porto v0.1.0 // indirect
37+
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
38+
github.com/json-iterator/go v1.1.12 // indirect
39+
github.com/klauspost/compress v1.16.7 // indirect
40+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
41+
github.com/modern-go/reflect2 v1.0.2 // indirect
42+
github.com/pkg/errors v0.9.1 // indirect
43+
github.com/prometheus/procfs v0.10.1 // indirect
44+
github.com/rs/cors v1.9.0 // indirect
45+
github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
46+
go.elastic.co/apm/v2 v2.2.0 // indirect
47+
go.elastic.co/fastjson v1.3.0 // indirect
48+
go.opentelemetry.io/collector/config/configauth v0.82.0 // indirect
49+
go.opentelemetry.io/collector/config/configcompression v0.82.0 // indirect
50+
go.opentelemetry.io/collector/config/configopaque v0.82.0 // indirect
51+
go.opentelemetry.io/collector/config/configtelemetry v0.119.0 // indirect
52+
go.opentelemetry.io/collector/config/configtls v0.82.0 // indirect
53+
go.opentelemetry.io/collector/config/internal v0.82.0 // indirect
54+
go.opentelemetry.io/collector/extension v0.82.0 // indirect
55+
go.opentelemetry.io/collector/extension/auth v0.82.0 // indirect
56+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect
57+
go.opentelemetry.io/otel v1.34.0 // indirect
58+
go.opentelemetry.io/otel/metric v1.34.0 // indirect
59+
go.opentelemetry.io/otel/trace v1.34.0 // indirect
60+
go.uber.org/multierr v1.11.0 // indirect
61+
golang.org/x/mod v0.17.0 // indirect
62+
golang.org/x/net v0.33.0 // indirect
63+
golang.org/x/sync v0.10.0
64+
golang.org/x/sys v0.29.0 // indirect
65+
golang.org/x/text v0.21.0 // indirect
66+
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
67+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect
68+
google.golang.org/grpc v1.70.0 // indirect
69+
google.golang.org/protobuf v1.36.4
70+
howett.net/plist v1.0.0 // indirect
71+
)

0 commit comments

Comments
 (0)