Skip to content

Commit

Permalink
[exporter/honeycombmarker] Separate config and exporter struct (open-…
Browse files Browse the repository at this point in the history
…telemetry#30402)

**Description:** <Describe what has changed.>
Decouples the exporter's struct from the config. Also fixes a typo in
the readme
  • Loading branch information
TylerHelmuth authored Jan 10, 2024
1 parent b2fdfec commit 4b5b9b4
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 40 deletions.
4 changes: 2 additions & 2 deletions exporter/honeycombmarkerexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ exporters:
# Creates a new marker anytime the exporter sees a k8s event with a reason of Backoff
- type: k8s-backoff-events
rules:
- log_conditions:
- IsMap(body) and IsMap(body["object"]) and body["object"]["reason"] == "Backoff"
log_conditions:
- IsMap(body) and IsMap(body["object"]) and body["object"]["reason"] == "Backoff"
```
4 changes: 0 additions & 4 deletions exporter/honeycombmarkerexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ import (
"go.opentelemetry.io/collector/exporter/exporterhelper"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/expr"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterottl"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllog"
)

// Config defines configuration for the Honeycomb Marker exporter.
Expand Down Expand Up @@ -57,8 +55,6 @@ type Marker struct {
type Rules struct {
// LogConditions is the list of ottllog conditions that determine a match
LogConditions []string `mapstructure:"log_conditions"`

logBoolExpr expr.BoolExpr[ottllog.TransformContext]
}

var _ component.Config = (*Config)(nil)
Expand Down
55 changes: 35 additions & 20 deletions exporter/honeycombmarkerexporter/logs_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import (
"strings"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/config/configopaque"
"go.opentelemetry.io/collector/exporter"
"go.opentelemetry.io/collector/pdata/plog"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/expr"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterottl"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllog"
Expand All @@ -29,12 +32,19 @@ const (
honeycombTeam = "X-Honeycomb-Team"
)

type marker struct {
Marker
logBoolExpr expr.BoolExpr[ottllog.TransformContext]
}

type honeycombLogsExporter struct {
set component.TelemetrySettings
markers []Marker
client *http.Client
config *Config
userAgentHeader string
set component.TelemetrySettings
client *http.Client
httpClientSettings confighttp.HTTPClientSettings
apiURL string
apiKey configopaque.String
markers []marker
userAgentHeader string
}

func newHoneycombLogsExporter(set exporter.CreateSettings, config *Config) (*honeycombLogsExporter, error) {
Expand All @@ -43,19 +53,24 @@ func newHoneycombLogsExporter(set exporter.CreateSettings, config *Config) (*hon
}

telemetrySettings := set.TelemetrySettings
markers := make([]marker, len(config.Markers))
for i, m := range config.Markers {
matchLogConditions, err := filterottl.NewBoolExprForLog(m.Rules.LogConditions, filterottl.StandardLogFuncs(), ottl.PropagateError, telemetrySettings)
if err != nil {
return nil, fmt.Errorf("failed to parse log conditions: %w", err)
}

config.Markers[i].Rules.logBoolExpr = matchLogConditions
markers[i] = marker{
Marker: m,
logBoolExpr: matchLogConditions,
}
}
logsExp := &honeycombLogsExporter{
set: telemetrySettings,
markers: config.Markers,
config: config,
userAgentHeader: fmt.Sprintf("%s/%s (%s/%s)", set.BuildInfo.Description, set.BuildInfo.Version, runtime.GOOS, runtime.GOARCH),
set: telemetrySettings,
httpClientSettings: config.HTTPClientSettings,
apiURL: config.APIURL,
apiKey: config.APIKey,
markers: markers,
userAgentHeader: fmt.Sprintf("%s/%s (%s/%s)", set.BuildInfo.Description, set.BuildInfo.Version, runtime.GOOS, runtime.GOARCH),
}
return logsExp, nil
}
Expand All @@ -70,7 +85,7 @@ func (e *honeycombLogsExporter) exportMarkers(ctx context.Context, ld plog.Logs)
logRecord := logs.At(k)
tCtx := ottllog.NewTransformContext(logRecord, slogs.Scope(), rlogs.Resource())
for _, m := range e.markers {
match, err := m.Rules.logBoolExpr.Eval(ctx, tCtx)
match, err := m.logBoolExpr.Eval(ctx, tCtx)
if err != nil {
return err
}
Expand All @@ -88,17 +103,17 @@ func (e *honeycombLogsExporter) exportMarkers(ctx context.Context, ld plog.Logs)
return nil
}

func (e *honeycombLogsExporter) sendMarker(ctx context.Context, marker Marker, logRecord plog.LogRecord) error {
func (e *honeycombLogsExporter) sendMarker(ctx context.Context, m marker, logRecord plog.LogRecord) error {
requestMap := map[string]string{
"type": marker.Type,
"type": m.Type,
}

messageValue, found := logRecord.Attributes().Get(marker.MessageKey)
messageValue, found := logRecord.Attributes().Get(m.MessageKey)
if found {
requestMap["message"] = messageValue.AsString()
}

URLValue, found := logRecord.Attributes().Get(marker.URLKey)
URLValue, found := logRecord.Attributes().Get(m.URLKey)
if found {
requestMap["url"] = URLValue.AsString()
}
Expand All @@ -108,19 +123,19 @@ func (e *honeycombLogsExporter) sendMarker(ctx context.Context, marker Marker, l
return err
}

datasetSlug := marker.DatasetSlug
datasetSlug := m.DatasetSlug
if datasetSlug == "" {
datasetSlug = defaultDatasetSlug
}

url := fmt.Sprintf("%s/1/markers/%s", strings.TrimRight(e.config.APIURL, "/"), datasetSlug)
url := fmt.Sprintf("%s/1/markers/%s", strings.TrimRight(e.apiURL, "/"), datasetSlug)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(request))
if err != nil {
return err
}

req.Header.Set(contentType, "application/json")
req.Header.Set(honeycombTeam, fmt.Sprint(e.config.APIKey))
req.Header.Set(honeycombTeam, string(e.apiKey))
req.Header.Set(userAgentHeaderKey, e.userAgentHeader)

resp, err := e.client.Do(req)
Expand All @@ -144,7 +159,7 @@ func (e *honeycombLogsExporter) sendMarker(ctx context.Context, marker Marker, l
}

func (e *honeycombLogsExporter) start(_ context.Context, host component.Host) (err error) {
client, err := e.config.HTTPClientSettings.ToClient(host, e.set)
client, err := e.httpClientSettings.ToClient(host, e.set)

if err != nil {
return err
Expand Down
23 changes: 9 additions & 14 deletions exporter/honeycombmarkerexporter/logs_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ import (

func TestExportMarkers(t *testing.T) {
tests := []struct {
name string
config Config
attributeMap map[string]string
expectedAPIKey string
expectedURL string
name string
config Config
attributeMap map[string]string
expectedURL string
}{
{
name: "all fields",
Expand All @@ -49,8 +48,7 @@ func TestExportMarkers(t *testing.T) {
"url": "https://api.testhost.io",
"type": "test-type",
},
expectedAPIKey: "test-apikey",
expectedURL: "/1/markers/test-dataset",
expectedURL: "/1/markers/test-dataset",
},
{
name: "no message key",
Expand All @@ -73,8 +71,7 @@ func TestExportMarkers(t *testing.T) {
"url": "https://api.testhost.io",
"type": "test-type",
},
expectedAPIKey: "test-apikey",
expectedURL: "/1/markers/test-dataset",
expectedURL: "/1/markers/test-dataset",
},
{
name: "no url",
Expand All @@ -97,8 +94,7 @@ func TestExportMarkers(t *testing.T) {
"message": "this is a test message",
"type": "test-type",
},
expectedAPIKey: "test-apikey",
expectedURL: "/1/markers/test-dataset",
expectedURL: "/1/markers/test-dataset",
},
{
name: "no dataset_slug",
Expand All @@ -118,8 +114,7 @@ func TestExportMarkers(t *testing.T) {
attributeMap: map[string]string{
"type": "test-type",
},
expectedAPIKey: "test-apikey",
expectedURL: "/1/markers/__all__",
expectedURL: "/1/markers/__all__",
},
}

Expand All @@ -139,7 +134,7 @@ func TestExportMarkers(t *testing.T) {
assert.Contains(t, req.URL.Path, tt.expectedURL)

apiKey := req.Header.Get(honeycombTeam)
assert.Equal(t, tt.expectedAPIKey, apiKey)
assert.Equal(t, string(tt.config.APIKey), apiKey)

userAgent := req.Header.Get(userAgentHeaderKey)
assert.NotEmpty(t, userAgent)
Expand Down

0 comments on commit 4b5b9b4

Please sign in to comment.