Skip to content

Commit 21991b7

Browse files
bderrlyAkhigbeEromo
authored andcommitted
[exporter/splunkhecexporter] Add OtelAttrsToHec struct and related config fields (open-telemetry#35476)
**Description:** Adding a new config fields `otel_attrs_to_hec_metadata/*` to replace the `hec_metadata_to_otel_attrs/*` config fields. **Link to tracking Issue:** fixes open-telemetry#35092 **Testing:** No new tests added, modified existing tests. **Documentation:** Adding field-level description to exporter README.md.
1 parent e27778f commit 21991b7

File tree

9 files changed

+208
-15
lines changed

9 files changed

+208
-15
lines changed

.chloggen/iss-35092.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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: deprecation
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: splunkhecexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add `otel_attrs_to_hec_metadata/*` config fields to replace `hec_metadata_to_otel_attrs/*` fields.
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: [35092]
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+
`otel_attrs_to_hec_metadata/*` config fields will replace the `hec_metadata_to_otel_attrs/*` fields in a later release.
20+
21+
# If your change doesn't affect end users or the exported elements of any package,
22+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
23+
# Optional: The change log or logs in which this entry should be included.
24+
# e.g. '[user]' or '[user, api]'
25+
# Include 'user' if the change is relevant to end users.
26+
# Include 'api' if there is a change to a library API.
27+
# Default: '[user]'
28+
change_logs: [user]

exporter/splunkhecexporter/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,18 @@ The following configuration options can also be configured:
5454
- `health_path` (default = '/services/collector/health'): The path reporting [health checks](https://docs.splunk.com/Documentation/Splunk/9.0.1/RESTREF/RESTinput#services.2Fcollector.2Fhealth).
5555
- `health_check_enabled` (default = false): Whether to perform Splunk HEC Health Check during the exporter's startup.
5656
- `export_raw` (default = false): send only the log's body, targeting a Splunk HEC raw endpoint.
57+
- `otel_attrs_to_hec_metadata/source` (default = 'com.splunk.source'): Specifies the mapping of a specific unified model attribute value to the standard source field of a HEC event.
58+
- `otel_attrs_to_hec_metadata/sourcetype` (default = 'com.splunk.sourcetype'): Specifies the mapping of a specific unified model attribute value to the standard sourcetype field of a HEC event.
59+
- `otel_attrs_to_hec_metadata/index` (default = 'com.splunk.index'): Specifies the mapping of a specific unified model attribute value to the standard index field of a HEC event.
60+
- `otel_attrs_to_hec_metadata/host` (default = 'host.name'): Specifies the mapping of a specific unified model attribute value to the standard host field and the `host.name` field of a HEC event.
5761
- `hec_metadata_to_otel_attrs/source` (default = 'com.splunk.source'): Specifies the mapping of a specific unified model attribute value to the standard source field of a HEC event.
62+
**Deprecated** (v0.116.0): prefer `otel_attrs_to_hec_metadata/source`.
5863
- `hec_metadata_to_otel_attrs/sourcetype` (default = 'com.splunk.sourcetype'): Specifies the mapping of a specific unified model attribute value to the standard sourcetype field of a HEC event.
64+
**Deprecated** (v0.116.0): prefer `otel_attrs_to_hec_metadata/sourcetype`.
5965
- `hec_metadata_to_otel_attrs/index` (default = 'com.splunk.index'): Specifies the mapping of a specific unified model attribute value to the standard index field of a HEC event.
66+
**Deprecated** (v0.116.0): prefer `otel_attrs_to_hec_metadata/index`.
6067
- `hec_metadata_to_otel_attrs/host` (default = 'host.name'): Specifies the mapping of a specific unified model attribute value to the standard host field and the `host.name` field of a HEC event.
68+
**Deprecated** (v0.116.0): prefer `otel_attrs_to_hec_metadata/host`.
6169
- `otel_to_hec_fields/severity_text` (default = `otel.log.severity.text`): Specifies the name of the field to map the severity text field of log events.
6270
- `otel_to_hec_fields/severity_number` (default = `otel.log.severity.number`): Specifies the name of the field to map the severity number field of log events.
6371
- `otel_to_hec_fields/name` (default = `"otel.log.name`): Specifies the name of the field to map the name field of log events.

exporter/splunkhecexporter/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ type Config struct {
116116

117117
// App version is used to track telemetry information for Splunk App's using HEC by App version. Defaults to the current OpenTelemetry Collector Contrib build version.
118118
SplunkAppVersion string `mapstructure:"splunk_app_version"`
119+
120+
// OtelAttrsToHec creates a mapping from attributes to HEC specific metadata: source, sourcetype, index and host.
121+
OtelAttrsToHec splunk.HecToOtelAttrs `mapstructure:"otel_attrs_to_hec_metadata"`
122+
119123
// HecToOtelAttrs creates a mapping from attributes to HEC specific metadata: source, sourcetype, index and host.
124+
// Deprecated: [v0.113.0] Use OtelAttrsToHec instead.
120125
HecToOtelAttrs splunk.HecToOtelAttrs `mapstructure:"hec_metadata_to_otel_attrs"`
121126
// HecFields creates a mapping from attributes to HEC fields.
122127
HecFields OtelToHecFields `mapstructure:"otel_to_hec_fields"`

exporter/splunkhecexporter/config_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ func TestLoadConfig(t *testing.T) {
102102
MaxSizeItems: 10,
103103
},
104104
},
105+
OtelAttrsToHec: splunk.HecToOtelAttrs{
106+
Source: "mysource",
107+
SourceType: "mysourcetype",
108+
Index: "myindex",
109+
Host: "myhost",
110+
},
105111
HecToOtelAttrs: splunk.HecToOtelAttrs{
106112
Source: "mysource",
107113
SourceType: "mysourcetype",

exporter/splunkhecexporter/factory.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ func createDefaultConfig() component.Config {
8686
MaxContentLengthMetrics: defaultContentLengthMetricsLimit,
8787
MaxContentLengthTraces: defaultContentLengthTracesLimit,
8888
MaxEventSize: defaultMaxEventSize,
89+
OtelAttrsToHec: splunk.HecToOtelAttrs{
90+
Source: splunk.DefaultSourceLabel,
91+
SourceType: splunk.DefaultSourceTypeLabel,
92+
Index: splunk.DefaultIndexLabel,
93+
Host: conventions.AttributeHostName,
94+
},
8995
HecToOtelAttrs: splunk.HecToOtelAttrs{
9096
Source: splunk.DefaultSourceLabel,
9197
SourceType: splunk.DefaultSourceTypeLabel,

exporter/splunkhecexporter/logdata_to_splunk.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,53 @@ const (
2323
traceIDFieldKey = "trace_id"
2424
)
2525

26+
// copyOtelAttrs copies values from HecToOtelAttrs to OtelAttrsToHec struct.
27+
func copyOtelAttrs(config *Config) {
28+
defaultCfg := createDefaultConfig().(*Config)
29+
if config.OtelAttrsToHec.Equal(defaultCfg.OtelAttrsToHec) {
30+
if !config.HecToOtelAttrs.Equal(defaultCfg.HecToOtelAttrs) {
31+
// Copy settings to ease deprecation of HecToOtelAttrs.
32+
config.OtelAttrsToHec = config.HecToOtelAttrs
33+
}
34+
} else {
35+
if !config.HecToOtelAttrs.Equal(defaultCfg.HecToOtelAttrs) {
36+
// Replace all default fields in OtelAttrsToHec.
37+
if config.OtelAttrsToHec.Source == defaultCfg.OtelAttrsToHec.Source {
38+
config.OtelAttrsToHec.Source = config.HecToOtelAttrs.Source
39+
}
40+
if config.OtelAttrsToHec.SourceType == defaultCfg.OtelAttrsToHec.SourceType {
41+
config.OtelAttrsToHec.SourceType = config.HecToOtelAttrs.SourceType
42+
}
43+
if config.OtelAttrsToHec.Index == defaultCfg.OtelAttrsToHec.Index {
44+
config.OtelAttrsToHec.Index = config.HecToOtelAttrs.Index
45+
}
46+
if config.OtelAttrsToHec.Host == defaultCfg.OtelAttrsToHec.Host {
47+
config.OtelAttrsToHec.Host = config.HecToOtelAttrs.Host
48+
}
49+
}
50+
}
51+
}
52+
2653
func mapLogRecordToSplunkEvent(res pcommon.Resource, lr plog.LogRecord, config *Config) *splunk.Event {
2754
body := lr.Body().AsRaw()
2855
if body == nil || body == "" {
2956
// events with no body are rejected by Splunk.
3057
return nil
3158
}
3259

60+
// Manage the deprecation of HecToOtelAttrs config parameters.
61+
// TODO: remove this once HecToOtelAttrs is removed from Config.
62+
copyOtelAttrs(config)
63+
3364
host := unknownHostName
3465
source := config.Source
3566
sourcetype := config.SourceType
3667
index := config.Index
3768
fields := map[string]any{}
38-
sourceKey := config.HecToOtelAttrs.Source
39-
sourceTypeKey := config.HecToOtelAttrs.SourceType
40-
indexKey := config.HecToOtelAttrs.Index
41-
hostKey := config.HecToOtelAttrs.Host
69+
sourceKey := config.OtelAttrsToHec.Source
70+
sourceTypeKey := config.OtelAttrsToHec.SourceType
71+
indexKey := config.OtelAttrsToHec.Index
72+
hostKey := config.OtelAttrsToHec.Host
4273
severityTextKey := config.HecFields.SeverityText
4374
severityNumberKey := config.HecFields.SeverityNumber
4475
if spanID := lr.SpanID(); !spanID.IsEmpty() {

exporter/splunkhecexporter/logdata_to_splunk_test.go

Lines changed: 105 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,100 @@ import (
1414
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk"
1515
)
1616

17+
func Test_copyOtelAttrs(t *testing.T) {
18+
tests := []struct {
19+
name string
20+
configDataFn func() *Config
21+
wantConfigDataFn func() *Config
22+
}{
23+
{
24+
name: "defaults",
25+
configDataFn: func() *Config {
26+
return createDefaultConfig().(*Config)
27+
},
28+
wantConfigDataFn: func() *Config {
29+
return createDefaultConfig().(*Config)
30+
},
31+
},
32+
{
33+
name: "override hec_metadata_to_otel_attrs",
34+
configDataFn: func() *Config {
35+
cfg := createDefaultConfig().(*Config)
36+
37+
cfg.HecToOtelAttrs.Index = "testIndex"
38+
cfg.HecToOtelAttrs.Source = "testSource"
39+
cfg.HecToOtelAttrs.SourceType = "testSourceType"
40+
cfg.HecToOtelAttrs.Host = "testHost"
41+
42+
return cfg
43+
},
44+
wantConfigDataFn: func() *Config {
45+
cfg := createDefaultConfig().(*Config)
46+
47+
cfg.HecToOtelAttrs.Index = "testIndex"
48+
cfg.HecToOtelAttrs.Source = "testSource"
49+
cfg.HecToOtelAttrs.SourceType = "testSourceType"
50+
cfg.HecToOtelAttrs.Host = "testHost"
51+
52+
cfg.OtelAttrsToHec.Index = "testIndex"
53+
cfg.OtelAttrsToHec.Source = "testSource"
54+
cfg.OtelAttrsToHec.SourceType = "testSourceType"
55+
cfg.OtelAttrsToHec.Host = "testHost"
56+
57+
return cfg
58+
},
59+
},
60+
{
61+
name: "partial otel_attrs_to_hec_metadata",
62+
configDataFn: func() *Config {
63+
cfg := createDefaultConfig().(*Config)
64+
65+
cfg.OtelAttrsToHec.Source = "testSource"
66+
cfg.OtelAttrsToHec.Index = "testIndex"
67+
68+
return cfg
69+
},
70+
wantConfigDataFn: func() *Config {
71+
cfg := createDefaultConfig().(*Config)
72+
73+
cfg.OtelAttrsToHec.Source = "testSource"
74+
cfg.OtelAttrsToHec.Index = "testIndex"
75+
76+
return cfg
77+
},
78+
},
79+
{
80+
name: "prefer otel_attrs_to_hec_metadata",
81+
configDataFn: func() *Config {
82+
cfg := createDefaultConfig().(*Config)
83+
84+
cfg.HecToOtelAttrs.Index = "hecIndex"
85+
86+
cfg.OtelAttrsToHec.Index = "otelIndex"
87+
88+
return cfg
89+
},
90+
wantConfigDataFn: func() *Config {
91+
cfg := createDefaultConfig().(*Config)
92+
93+
cfg.HecToOtelAttrs.Index = "hecIndex"
94+
95+
cfg.OtelAttrsToHec.Index = "otelIndex"
96+
97+
return cfg
98+
},
99+
},
100+
}
101+
102+
for _, tt := range tests {
103+
t.Run(tt.name, func(t *testing.T) {
104+
cfg := tt.configDataFn()
105+
copyOtelAttrs(cfg)
106+
assert.Equal(t, tt.wantConfigDataFn(), cfg)
107+
})
108+
}
109+
}
110+
17111
func Test_mapLogRecordToSplunkEvent(t *testing.T) {
18112
ts := pcommon.Timestamp(123)
19113

@@ -153,18 +247,18 @@ func Test_mapLogRecordToSplunkEvent(t *testing.T) {
153247
},
154248
logResourceFn: pcommon.NewResource,
155249
configDataFn: func() *Config {
156-
return &Config{
157-
HecToOtelAttrs: splunk.HecToOtelAttrs{
158-
Source: "mysource",
159-
SourceType: "mysourcetype",
160-
Index: "myindex",
161-
Host: "myhost",
162-
},
163-
HecFields: OtelToHecFields{
164-
SeverityNumber: "myseveritynum",
165-
SeverityText: "myseverity",
166-
},
250+
config := createDefaultConfig().(*Config)
251+
config.HecToOtelAttrs = splunk.HecToOtelAttrs{
252+
Source: "mysource",
253+
SourceType: "mysourcetype",
254+
Index: "myindex",
255+
Host: "myhost",
256+
}
257+
config.HecFields = OtelToHecFields{
258+
SeverityNumber: "myseveritynum",
259+
SeverityText: "myseverity",
167260
}
261+
return config
168262
},
169263
wantSplunkEvents: []*splunk.Event{
170264
func() *splunk.Event {

exporter/splunkhecexporter/testdata/config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ splunk_hec/allsettings:
3333
max_size_items: 10
3434
splunk_app_name: "OpenTelemetry-Collector Splunk Exporter"
3535
splunk_app_version: "v0.0.1"
36+
otel_attrs_to_hec_metadata:
37+
source: "mysource"
38+
sourcetype: "mysourcetype"
39+
index: "myindex"
40+
host: "myhost"
3641
hec_metadata_to_otel_attrs:
3742
source: "mysource"
3843
sourcetype: "mysourcetype"

internal/splunk/common.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ type HecToOtelAttrs struct {
139139
Host string `mapstructure:"host"`
140140
}
141141

142+
func (h HecToOtelAttrs) Equal(o HecToOtelAttrs) bool {
143+
if h.Host != o.Host ||
144+
h.Source != o.Source ||
145+
h.SourceType != o.SourceType ||
146+
h.Index != o.Index {
147+
return false
148+
}
149+
return true
150+
}
151+
142152
type AckRequest struct {
143153
Acks []uint64 `json:"acks"`
144154
}

0 commit comments

Comments
 (0)