Skip to content

Commit

Permalink
Extract exportSettings into structure + add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-majlis-s1 committed Oct 20, 2023
1 parent 972e8f5 commit e73d477
Show file tree
Hide file tree
Showing 7 changed files with 394 additions and 109 deletions.
9 changes: 5 additions & 4 deletions exporter/datasetexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ Make sure to provide the appropriate server host value in the `serverHost` attri

Enabled attributes are exported in the order:

1. Body
2. Resource attributes
3. Scope attributes
4. Log attributes
1. Log properties
2. Body
3. Resource attributes
4. Scope attributes
5. Log attributes

If there is a name conflict, the `export_distinguishing_suffix` value is appended to the later attribute's name. If the `export_distinguishing_suffix` value is an empty string, then the value from the last attribute is used.

Expand Down
40 changes: 23 additions & 17 deletions exporter/datasetexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,44 @@ import (
"go.opentelemetry.io/collector/exporter/exporterhelper"
)

const tracesExportSeparatorDefault = "."
const tracesExportDistinguishingSuffix = "_"
const exportSeparatorDefault = "."
const exportDistinguishingSuffix = "_"

type TracesSettings struct {
// exportSettings configures separator and distinguishing suffixes for all exported fields
type exportSettings struct {
// ExportSeparator is separator used when flattening exported attributes
// Default value: .
ExportSeparator string `mapstructure:"export_separator"`

// ExportDistinguishingSuffix is suffix used to be appended to the end of attribute name in case of collision
// Default value: _
ExportDistinguishingSuffix string `mapstructure:"export_distinguishing_suffix"`
}

// newDefaultExportSettings returns the default settings for exportSettings.
func newDefaultExportSettings() exportSettings {
return exportSettings{
ExportSeparator: exportSeparatorDefault,
ExportDistinguishingSuffix: exportDistinguishingSuffix,
}
}

type TracesSettings struct {
// exportSettings configures separator and distinguishing suffixes for all exported fields
exportSettings `mapstructure:",squash"`
}

// newDefaultTracesSettings returns the default settings for TracesSettings.
func newDefaultTracesSettings() TracesSettings {
return TracesSettings{
ExportSeparator: tracesExportSeparatorDefault,
ExportDistinguishingSuffix: tracesExportDistinguishingSuffix,
exportSettings: newDefaultExportSettings(),
}
}

const logsExportResourceInfoDefault = false
const logsExportResourcePrefixDefault = "resource.attributes."
const logsExportScopeInfoDefault = true
const logsExportScopePrefixDefault = "scope.attributes."
const logsExportSeparatorDefault = "."
const logsExportDistinguishingSuffix = "_"
const logsDecomposeComplexMessageFieldDefault = false
const logsDecomposedComplexMessageFieldPrefixDefault = "body.map."

Expand All @@ -65,14 +77,6 @@ type LogsSettings struct {
// Default value: scope.attributes.
ExportScopePrefix string `mapstructure:"export_scope_prefix"`

// ExportSeparator is separator used when flattening exported attributes
// Default value: .
ExportSeparator string `mapstructure:"export_separator"`

// ExportDistinguishingSuffix is suffix used to be appended to the end of attribute name in case of collision
// Default value: _
ExportDistinguishingSuffix string `mapstructure:"export_distinguishing_suffix"`

// DecomposeComplexMessageField is an optional flag to signal that message / body of complex types (e.g. a map) should be
// decomposed / deconstructed into multiple fields. This is usually done outside of the main DataSet integration on the
// client side (e.g. as part of the attribute processor or similar) or on the server side (DataSet server side JSON parser
Expand All @@ -82,6 +86,9 @@ type LogsSettings struct {
// DecomposedComplexMessagePrefix is prefix for the decomposed complex message (see DecomposeComplexMessageField).
// Default value: body.map.
DecomposedComplexMessagePrefix string `mapstructure:"decomposed_complex_message_prefix"`

// exportSettings configures separator and distinguishing suffixes for all exported fields
exportSettings `mapstructure:",squash"`
}

// newDefaultLogsSettings returns the default settings for LogsSettings.
Expand All @@ -91,10 +98,9 @@ func newDefaultLogsSettings() LogsSettings {
ExportResourcePrefix: logsExportResourcePrefixDefault,
ExportScopeInfo: logsExportScopeInfoDefault,
ExportScopePrefix: logsExportScopePrefixDefault,
ExportSeparator: logsExportSeparatorDefault,
ExportDistinguishingSuffix: logsExportDistinguishingSuffix,
DecomposeComplexMessageField: logsDecomposeComplexMessageFieldDefault,
DecomposedComplexMessagePrefix: logsDecomposedComplexMessageFieldPrefixDefault,
exportSettings: newDefaultExportSettings(),
}
}

Expand Down
19 changes: 13 additions & 6 deletions exporter/datasetexporter/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ func TestConfigUseDefaults(t *testing.T) {
assert.Equal(t, logsExportResourcePrefixDefault, config.LogsSettings.ExportResourcePrefix)
assert.Equal(t, logsExportScopeInfoDefault, config.LogsSettings.ExportScopeInfo)
assert.Equal(t, logsExportScopePrefixDefault, config.LogsSettings.ExportScopePrefix)
assert.Equal(t, logsExportSeparatorDefault, config.LogsSettings.ExportSeparator)
assert.Equal(t, logsDecomposeComplexMessageFieldDefault, config.LogsSettings.DecomposeComplexMessageField)
assert.Equal(t, exportSeparatorDefault, config.LogsSettings.exportSettings.ExportSeparator)
assert.Equal(t, exportDistinguishingSuffix, config.LogsSettings.exportSettings.ExportDistinguishingSuffix)
assert.Equal(t, exportSeparatorDefault, config.TracesSettings.exportSettings.ExportSeparator)
assert.Equal(t, exportDistinguishingSuffix, config.TracesSettings.exportSettings.ExportDistinguishingSuffix)
}

func TestConfigValidate(t *testing.T) {
Expand Down Expand Up @@ -110,18 +113,22 @@ func TestConfigString(t *testing.T) {
GroupBy: []string{"field1", "field2"},
},
TracesSettings: TracesSettings{
ExportSeparator: "TTT",
ExportDistinguishingSuffix: "UUU",
exportSettings: exportSettings{
ExportSeparator: "TTT",
ExportDistinguishingSuffix: "UUU",
},
},
LogsSettings: LogsSettings{
ExportResourceInfo: true,
ExportResourcePrefix: "AAA",
ExportScopeInfo: true,
ExportScopePrefix: "BBB",
ExportSeparator: "CCC",
ExportDistinguishingSuffix: "DDD",
DecomposeComplexMessageField: true,
DecomposedComplexMessagePrefix: "EEE",
exportSettings: exportSettings{
ExportSeparator: "CCC",
ExportDistinguishingSuffix: "DDD",
},
},
ServerHostSettings: ServerHostSettings{
ServerHost: "foo-bar",
Expand All @@ -133,7 +140,7 @@ func TestConfigString(t *testing.T) {
}

assert.Equal(t,
"DatasetURL: https://example.com; BufferSettings: {MaxLifetime:123ns GroupBy:[field1 field2] RetryInitialInterval:0s RetryMaxInterval:0s RetryMaxElapsedTime:0s RetryShutdownTimeout:0s}; LogsSettings: {ExportResourceInfo:true ExportResourcePrefix:AAA ExportScopeInfo:true ExportScopePrefix:BBB ExportSeparator:CCC ExportDistinguishingSuffix:DDD DecomposeComplexMessageField:true DecomposedComplexMessagePrefix:EEE}; TracesSettings: {ExportSeparator:TTT ExportDistinguishingSuffix:UUU}; ServerHostSettings: {UseHostName:false ServerHost:foo-bar}; RetrySettings: {Enabled:true InitialInterval:5s RandomizationFactor:0.5 Multiplier:1.5 MaxInterval:30s MaxElapsedTime:5m0s}; QueueSettings: {Enabled:true NumConsumers:10 QueueSize:1000 StorageID:<nil>}; TimeoutSettings: {Timeout:5s}",
"DatasetURL: https://example.com; BufferSettings: {MaxLifetime:123ns GroupBy:[field1 field2] RetryInitialInterval:0s RetryMaxInterval:0s RetryMaxElapsedTime:0s RetryShutdownTimeout:0s}; LogsSettings: {ExportResourceInfo:true ExportResourcePrefix:AAA ExportScopeInfo:true ExportScopePrefix:BBB DecomposeComplexMessageField:true DecomposedComplexMessagePrefix:EEE exportSettings:{ExportSeparator:CCC ExportDistinguishingSuffix:DDD}}; TracesSettings: {exportSettings:{ExportSeparator:TTT ExportDistinguishingSuffix:UUU}}; ServerHostSettings: {UseHostName:false ServerHost:foo-bar}; RetrySettings: {Enabled:true InitialInterval:5s RandomizationFactor:0.5 Multiplier:1.5 MaxInterval:30s MaxElapsedTime:5m0s}; QueueSettings: {Enabled:true NumConsumers:10 QueueSize:1000 StorageID:<nil>}; TimeoutSettings: {Timeout:5s}",
config.String(),
)
}
Expand Down
7 changes: 7 additions & 0 deletions exporter/datasetexporter/datasetexporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package datasetexporter
import "go.opentelemetry.io/collector/pdata/pcommon"

func fillAttributes(attr pcommon.Map, allTypes bool, valueSuffix string) {
// simple types
attr.PutStr("string", "string"+valueSuffix)
if allTypes {
attr.PutDouble("double", 2.0)
Expand All @@ -14,15 +15,21 @@ func fillAttributes(attr pcommon.Map, allTypes bool, valueSuffix string) {
attr.PutInt("int", 3)
}

// map
attr.PutEmptyMap("empty_map")
mVal := attr.PutEmptyMap("map")
mVal.PutStr("map_string", "map_string"+valueSuffix)
mVal.PutEmpty("map_empty")
mVal2 := mVal.PutEmptyMap("map_map")
mVal2.PutStr("map_map_string", "map_map_string"+valueSuffix)

// slice
attr.PutEmptySlice("empty_slice")
sVal := attr.PutEmptySlice("slice")
sVal.AppendEmpty()
sVal.At(0).SetStr("slice_string" + valueSuffix)

// colliding attributes
attr.PutStr("span_id", "filled_span_id"+valueSuffix)
attr.PutStr("name", "filled_name"+valueSuffix)
}
14 changes: 9 additions & 5 deletions exporter/datasetexporter/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,22 @@ func TestLoadConfig(t *testing.T) {
RetryShutdownTimeout: 24 * time.Second,
},
TracesSettings: TracesSettings{
ExportSeparator: "_Y_",
ExportDistinguishingSuffix: "_T_",
exportSettings: exportSettings{
ExportSeparator: "_Y_",
ExportDistinguishingSuffix: "_T_",
},
},
LogsSettings: LogsSettings{
ExportResourceInfo: true,
ExportResourcePrefix: "_resource_",
ExportScopeInfo: true,
ExportScopePrefix: "_scope_",
ExportSeparator: "_X_",
ExportDistinguishingSuffix: "_L_",
DecomposeComplexMessageField: true,
DecomposedComplexMessagePrefix: "_body_",
exportSettings: exportSettings{
ExportSeparator: "_X_",
ExportDistinguishingSuffix: "_L_",
},
},
ServerHostSettings: ServerHostSettings{
UseHostName: false,
Expand Down Expand Up @@ -156,7 +160,7 @@ func createExporterTests() []CreateTest {
{
name: "broken",
config: &Config{},
expectedError: fmt.Errorf("cannot get DataSetExpoter: cannot convert config: DatasetURL: ; BufferSettings: {MaxLifetime:0s GroupBy:[] RetryInitialInterval:0s RetryMaxInterval:0s RetryMaxElapsedTime:0s RetryShutdownTimeout:0s}; LogsSettings: {ExportResourceInfo:false ExportResourcePrefix: ExportScopeInfo:false ExportScopePrefix: ExportSeparator: ExportDistinguishingSuffix: DecomposeComplexMessageField:false DecomposedComplexMessagePrefix:}; TracesSettings: {ExportSeparator: ExportDistinguishingSuffix:}; ServerHostSettings: {UseHostName:false ServerHost:}; RetrySettings: {Enabled:false InitialInterval:0s RandomizationFactor:0 Multiplier:0 MaxInterval:0s MaxElapsedTime:0s}; QueueSettings: {Enabled:false NumConsumers:0 QueueSize:0 StorageID:<nil>}; TimeoutSettings: {Timeout:0s}; config is not valid: api_key is required"),
expectedError: fmt.Errorf("cannot get DataSetExpoter: cannot convert config: DatasetURL: ; BufferSettings: {MaxLifetime:0s GroupBy:[] RetryInitialInterval:0s RetryMaxInterval:0s RetryMaxElapsedTime:0s RetryShutdownTimeout:0s}; LogsSettings: {ExportResourceInfo:false ExportResourcePrefix: ExportScopeInfo:false ExportScopePrefix: DecomposeComplexMessageField:false DecomposedComplexMessagePrefix: exportSettings:{ExportSeparator: ExportDistinguishingSuffix:}}; TracesSettings: {exportSettings:{ExportSeparator: ExportDistinguishingSuffix:}}; ServerHostSettings: {UseHostName:false ServerHost:}; RetrySettings: {Enabled:false InitialInterval:0s RandomizationFactor:0 Multiplier:0 MaxInterval:0s MaxElapsedTime:0s}; QueueSettings: {Enabled:false NumConsumers:0 QueueSize:0 StorageID:<nil>}; TimeoutSettings: {Timeout:0s}; config is not valid: api_key is required"),
},
{
name: "valid",
Expand Down
Loading

0 comments on commit e73d477

Please sign in to comment.