Skip to content

Commit 0132c15

Browse files
mterharzeck-ops
authored andcommitted
[receiver/libhoney] Libhoney receiver log signal (open-telemetry#36827)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description This PR is the implementation for the logs signal related to the new libhoney receiver. <!-- Issue number (e.g. open-telemetry#1234) or full URL to issue, if applicable. --> #### Link to tracking issue open-telemetry#36693
1 parent a8403ff commit 0132c15

File tree

16 files changed

+1508
-188
lines changed

16 files changed

+1508
-188
lines changed
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: libhoneyreceiver
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Implement log signal for libhoney receiver
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [36693]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

receiver/libhoneyreceiver/README.md

+15-14
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,21 @@ The following setting is required for refinery traffic since:
4545
- "/1/batch"
4646
include_metadata: true
4747
auth_api: https://api.honeycomb.io
48-
resources:
49-
service_name: service_name
50-
scopes:
51-
library_name: library.name
52-
library_version: library.version
53-
attributes:
54-
trace_id: trace_id
55-
parent_id: parent_id
56-
span_id: span_id
57-
name: name
58-
error: error
59-
spankind: span.kind
60-
durationFields:
61-
- duration_ms
48+
fields:
49+
resources:
50+
service_name: service_name
51+
scopes:
52+
library_name: library.name
53+
library_version: library.version
54+
attributes:
55+
trace_id: trace_id
56+
parent_id: parent_id
57+
span_id: span_id
58+
name: name
59+
error: error
60+
spankind: span.kind
61+
durationFields:
62+
- duration_ms
6263
```
6364
6465
### Telemetry data types supported

receiver/libhoneyreceiver/config.go

+9-25
Original file line numberDiff line numberDiff line change
@@ -11,51 +11,35 @@ import (
1111

1212
"go.opentelemetry.io/collector/config/confighttp"
1313
"go.opentelemetry.io/collector/confmap"
14+
15+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver/internal/libhoneyevent"
1416
)
1517

1618
// Config represents the receiver config settings within the collector's config.yaml
1719
type Config struct {
18-
HTTP *HTTPConfig `mapstructure:"http"`
19-
AuthAPI string `mapstructure:"auth_api"`
20-
Wrapper string `mapstructure:"wrapper"`
21-
Resources ResourcesConfig `mapstructure:"resources"`
22-
Scopes ScopesConfig `mapstructure:"scopes"`
23-
Attributes AttributesConfig `mapstructure:"attributes"`
20+
HTTP *HTTPConfig `mapstructure:"http"`
21+
AuthAPI string `mapstructure:"auth_api"`
22+
Wrapper string `mapstructure:"wrapper"`
23+
FieldMapConfig libhoneyevent.FieldMapConfig `mapstructure:"fields"`
2424
}
2525

26+
// HTTPConfig defines the configuration for the HTTP server receiving traces.
2627
type HTTPConfig struct {
2728
*confighttp.ServerConfig `mapstructure:",squash"`
2829

2930
// The URL path to receive traces on. If omitted "/" will be used.
3031
TracesURLPaths []string `mapstructure:"traces_url_paths,omitempty"`
3132
}
3233

33-
type ResourcesConfig struct {
34-
ServiceName string `mapstructure:"service_name"`
35-
}
36-
37-
type ScopesConfig struct {
38-
LibraryName string `mapstructure:"library_name"`
39-
LibraryVersion string `mapstructure:"library_version"`
40-
}
41-
42-
type AttributesConfig struct {
43-
TraceID string `mapstructure:"trace_id"`
44-
ParentID string `mapstructure:"parent_id"`
45-
SpanID string `mapstructure:"span_id"`
46-
Name string `mapstructure:"name"`
47-
Error string `mapstructure:"error"`
48-
SpanKind string `mapstructure:"spankind"`
49-
DurationFields []string `mapstructure:"durationFields"`
50-
}
51-
34+
// Validate ensures the HTTP configuration is set.
5235
func (cfg *Config) Validate() error {
5336
if cfg.HTTP == nil {
5437
return errors.New("must specify at least one protocol when using the arbitrary JSON receiver")
5538
}
5639
return nil
5740
}
5841

42+
// Unmarshal unmarshals the configuration from the given configuration and then checks for errors.
5943
func (cfg *Config) Unmarshal(conf *confmap.Conf) error {
6044
// first load the config normally
6145
err := conf.Unmarshal(cfg)
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package libhoneyreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver"
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
"go.opentelemetry.io/collector/component/componenttest"
12+
)
13+
14+
func TestCreateDefaultConfig(t *testing.T) {
15+
factory := NewFactory()
16+
cfg := factory.CreateDefaultConfig()
17+
assert.NotNil(t, cfg, "failed to create default config")
18+
assert.NoError(t, componenttest.CheckConfigStruct(cfg))
19+
20+
libhoneyCfg, ok := cfg.(*Config)
21+
require.True(t, ok, "invalid Config type")
22+
23+
assert.Equal(t, "localhost:8080", libhoneyCfg.HTTP.Endpoint)
24+
assert.Equal(t, []string{"/events", "/event", "/batch"}, libhoneyCfg.HTTP.TracesURLPaths)
25+
assert.Equal(t, "", libhoneyCfg.AuthAPI)
26+
assert.Equal(t, "service.name", libhoneyCfg.FieldMapConfig.Resources.ServiceName)
27+
assert.Equal(t, "library.name", libhoneyCfg.FieldMapConfig.Scopes.LibraryName)
28+
assert.Equal(t, []string{"duration_ms"}, libhoneyCfg.FieldMapConfig.Attributes.DurationFields)
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package encoder // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver/encoder"
5+
6+
import (
7+
"bytes"
8+
9+
"github.com/gogo/protobuf/jsonpb"
10+
"go.opentelemetry.io/collector/pdata/plog/plogotlp"
11+
"go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp"
12+
"go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp"
13+
spb "google.golang.org/genproto/googleapis/rpc/status"
14+
)
15+
16+
const (
17+
PbContentType = "application/x-protobuf"
18+
JsonContentType = "application/json"
19+
MsgpackContentType = "application/x-msgpack"
20+
)
21+
22+
var (
23+
JsEncoder = &JsonEncoder{}
24+
JsonPbMarshaler = &jsonpb.Marshaler{}
25+
MpEncoder = &msgpackEncoder{}
26+
)
27+
28+
type Encoder interface {
29+
UnmarshalTracesRequest(buf []byte) (ptraceotlp.ExportRequest, error)
30+
UnmarshalMetricsRequest(buf []byte) (pmetricotlp.ExportRequest, error)
31+
UnmarshalLogsRequest(buf []byte) (plogotlp.ExportRequest, error)
32+
33+
MarshalTracesResponse(ptraceotlp.ExportResponse) ([]byte, error)
34+
MarshalMetricsResponse(pmetricotlp.ExportResponse) ([]byte, error)
35+
MarshalLogsResponse(plogotlp.ExportResponse) ([]byte, error)
36+
37+
MarshalStatus(rsp *spb.Status) ([]byte, error)
38+
39+
ContentType() string
40+
}
41+
42+
type JsonEncoder struct{}
43+
44+
func (JsonEncoder) UnmarshalTracesRequest(buf []byte) (ptraceotlp.ExportRequest, error) {
45+
req := ptraceotlp.NewExportRequest()
46+
err := req.UnmarshalJSON(buf)
47+
return req, err
48+
}
49+
50+
func (JsonEncoder) UnmarshalMetricsRequest(buf []byte) (pmetricotlp.ExportRequest, error) {
51+
req := pmetricotlp.NewExportRequest()
52+
err := req.UnmarshalJSON(buf)
53+
return req, err
54+
}
55+
56+
func (JsonEncoder) UnmarshalLogsRequest(buf []byte) (plogotlp.ExportRequest, error) {
57+
req := plogotlp.NewExportRequest()
58+
err := req.UnmarshalJSON(buf)
59+
return req, err
60+
}
61+
62+
func (JsonEncoder) MarshalTracesResponse(resp ptraceotlp.ExportResponse) ([]byte, error) {
63+
return resp.MarshalJSON()
64+
}
65+
66+
func (JsonEncoder) MarshalMetricsResponse(resp pmetricotlp.ExportResponse) ([]byte, error) {
67+
return resp.MarshalJSON()
68+
}
69+
70+
func (JsonEncoder) MarshalLogsResponse(resp plogotlp.ExportResponse) ([]byte, error) {
71+
return resp.MarshalJSON()
72+
}
73+
74+
func (JsonEncoder) MarshalStatus(resp *spb.Status) ([]byte, error) {
75+
buf := new(bytes.Buffer)
76+
err := JsonPbMarshaler.Marshal(buf, resp)
77+
return buf.Bytes(), err
78+
}
79+
80+
func (JsonEncoder) ContentType() string {
81+
return JsonContentType
82+
}
83+
84+
// messagepack responses seem to work in JSON so leaving this alone for now.
85+
type msgpackEncoder struct{}
86+
87+
func (msgpackEncoder) UnmarshalTracesRequest(buf []byte) (ptraceotlp.ExportRequest, error) {
88+
req := ptraceotlp.NewExportRequest()
89+
err := req.UnmarshalJSON(buf)
90+
return req, err
91+
}
92+
93+
func (msgpackEncoder) UnmarshalMetricsRequest(buf []byte) (pmetricotlp.ExportRequest, error) {
94+
req := pmetricotlp.NewExportRequest()
95+
err := req.UnmarshalJSON(buf)
96+
return req, err
97+
}
98+
99+
func (msgpackEncoder) UnmarshalLogsRequest(buf []byte) (plogotlp.ExportRequest, error) {
100+
req := plogotlp.NewExportRequest()
101+
err := req.UnmarshalJSON(buf)
102+
return req, err
103+
}
104+
105+
func (msgpackEncoder) MarshalTracesResponse(resp ptraceotlp.ExportResponse) ([]byte, error) {
106+
return resp.MarshalJSON()
107+
}
108+
109+
func (msgpackEncoder) MarshalMetricsResponse(resp pmetricotlp.ExportResponse) ([]byte, error) {
110+
return resp.MarshalJSON()
111+
}
112+
113+
func (msgpackEncoder) MarshalLogsResponse(resp plogotlp.ExportResponse) ([]byte, error) {
114+
return resp.MarshalJSON()
115+
}
116+
117+
func (msgpackEncoder) MarshalStatus(resp *spb.Status) ([]byte, error) {
118+
buf := new(bytes.Buffer)
119+
err := JsonPbMarshaler.Marshal(buf, resp)
120+
return buf.Bytes(), err
121+
}
122+
123+
func (msgpackEncoder) ContentType() string {
124+
return MsgpackContentType
125+
}

receiver/libhoneyreceiver/factory.go

+18-15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"go.opentelemetry.io/collector/receiver"
1414

1515
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent"
16+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver/internal/libhoneyevent"
1617
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver/internal/metadata"
1718
)
1819

@@ -44,21 +45,23 @@ func createDefaultConfig() component.Config {
4445
TracesURLPaths: defaultTracesURLPaths,
4546
},
4647
AuthAPI: "",
47-
Resources: ResourcesConfig{
48-
ServiceName: "service.name",
49-
},
50-
Scopes: ScopesConfig{
51-
LibraryName: "library.name",
52-
LibraryVersion: "library.version",
53-
},
54-
Attributes: AttributesConfig{
55-
TraceID: "trace.trace_id",
56-
SpanID: "trace.span_id",
57-
ParentID: "trace.parent_id",
58-
Name: "name",
59-
Error: "error",
60-
SpanKind: "span.kind",
61-
DurationFields: durationFieldsArr,
48+
FieldMapConfig: libhoneyevent.FieldMapConfig{
49+
Resources: libhoneyevent.ResourcesConfig{
50+
ServiceName: "service.name",
51+
},
52+
Scopes: libhoneyevent.ScopesConfig{
53+
LibraryName: "library.name",
54+
LibraryVersion: "library.version",
55+
},
56+
Attributes: libhoneyevent.AttributesConfig{
57+
TraceID: "trace.trace_id",
58+
SpanID: "trace.span_id",
59+
ParentID: "trace.parent_id",
60+
Name: "name",
61+
Error: "error",
62+
SpanKind: "span.kind",
63+
DurationFields: durationFieldsArr,
64+
},
6265
},
6366
}
6467
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package libhoneyreceiver
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
"go.opentelemetry.io/collector/component/componenttest"
12+
"go.opentelemetry.io/collector/consumer/consumertest"
13+
"go.opentelemetry.io/collector/receiver/receivertest"
14+
15+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver/internal/metadata"
16+
)
17+
18+
func TestCreateTracesReceiver(t *testing.T) {
19+
factory := NewFactory()
20+
cfg := factory.CreateDefaultConfig()
21+
set := receivertest.NewNopSettings()
22+
tReceiver, err := factory.CreateTraces(context.Background(), set, cfg, consumertest.NewNop())
23+
24+
assert.NoError(t, err, "receiver creation failed")
25+
assert.NotNil(t, tReceiver, "receiver creation failed")
26+
27+
assert.NoError(t, tReceiver.Start(context.Background(), componenttest.NewNopHost()))
28+
assert.NoError(t, tReceiver.Shutdown(context.Background()))
29+
}
30+
31+
func TestCreateLogsReceiver(t *testing.T) {
32+
factory := NewFactory()
33+
cfg := factory.CreateDefaultConfig()
34+
set := receivertest.NewNopSettings()
35+
lReceiver, err := factory.CreateLogs(context.Background(), set, cfg, consumertest.NewNop())
36+
37+
assert.NoError(t, err, "receiver creation failed")
38+
assert.NotNil(t, lReceiver, "receiver creation failed")
39+
40+
assert.NoError(t, lReceiver.Start(context.Background(), componenttest.NewNopHost()))
41+
assert.NoError(t, lReceiver.Shutdown(context.Background()))
42+
}
43+
44+
func TestType(t *testing.T) {
45+
factory := NewFactory()
46+
assert.Equal(t, metadata.Type, factory.Type())
47+
}

0 commit comments

Comments
 (0)