Skip to content

Commit 5f2cc23

Browse files
djaglowskimfyuce
authored andcommitted
[pkg/stanza] Consolidate attribute code into single package (open-telemetry#30449)
This change simplifies the reader package by pulling all file resolution logic into a single package. It also moves related config and attribute name constants into the same package.
1 parent 0a432d9 commit 5f2cc23

File tree

10 files changed

+264
-283
lines changed

10 files changed

+264
-283
lines changed
Lines changed: 27 additions & 0 deletions
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: deprecation
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: pkg/stanza
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Deprecate pkg/stanza/attrs package in favor of pkg/stanza/fileconsumer/attrs
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: [30449]
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: [api]

pkg/stanza/attrs/attrs.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,22 @@
33

44
package attrs // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/attrs"
55

6+
import fca "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/attrs"
7+
68
const (
7-
LogFileName = "log.file.name"
8-
LogFilePath = "log.file.path"
9-
LogFileNameResolved = "log.file.name_resolved"
10-
LogFilePathResolved = "log.file.path_resolved"
9+
// Deprecated: [v0.93.0] Use pkg/stanza/fileconsumer/attrs.LogFileName instead.
10+
// Will be removed in v0.94.0.
11+
LogFileName = fca.LogFileName
12+
13+
// Deprecated: [v0.92.0] Use pkg/stanza/fileconsumer/attrs.LogFilePath instead.
14+
// Will be removed in v0.94.0.
15+
LogFilePath = fca.LogFilePath
16+
17+
// Deprecated: [v0.92.0] Use pkg/stanza/fileconsumer/attrs.LogFileNameResolved instead.
18+
// Will be removed in v0.94.0.
19+
LogFileNameResolved = fca.LogFileNameResolved
20+
21+
// Deprecated: [v0.92.0] Use pkg/stanza/fileconsumer/attrs.LogFilePathResolved instead.
22+
// Will be removed in v0.94.0.
23+
LogFilePathResolved = fca.LogFilePathResolved
1124
)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package attrs // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/attrs"
5+
6+
import (
7+
"fmt"
8+
"path/filepath"
9+
"runtime"
10+
)
11+
12+
const (
13+
LogFileName = "log.file.name"
14+
LogFilePath = "log.file.path"
15+
LogFileNameResolved = "log.file.name_resolved"
16+
LogFilePathResolved = "log.file.path_resolved"
17+
)
18+
19+
type Resolver struct {
20+
IncludeFileName bool `mapstructure:"include_file_name,omitempty"`
21+
IncludeFilePath bool `mapstructure:"include_file_path,omitempty"`
22+
IncludeFileNameResolved bool `mapstructure:"include_file_name_resolved,omitempty"`
23+
IncludeFilePathResolved bool `mapstructure:"include_file_path_resolved,omitempty"`
24+
}
25+
26+
func (r *Resolver) Resolve(path string) (attributes map[string]any, err error) {
27+
// size 2 is sufficient if not resolving symlinks. This optimizes for the most performant cases.
28+
attributes = make(map[string]any, 2)
29+
if r.IncludeFileName {
30+
attributes[LogFileName] = filepath.Base(path)
31+
}
32+
if r.IncludeFilePath {
33+
attributes[LogFilePath] = path
34+
}
35+
if !r.IncludeFileNameResolved && !r.IncludeFilePathResolved {
36+
return attributes, nil
37+
}
38+
39+
resolved := path
40+
// Dirty solution, waiting for this permanent fix https://github.com/golang/go/issues/39786
41+
// EvalSymlinks on windows is partially working depending on the way you use Symlinks and Junctions
42+
if runtime.GOOS != "windows" {
43+
resolved, err = filepath.EvalSymlinks(path)
44+
if err != nil {
45+
return nil, fmt.Errorf("resolve symlinks: %w", err)
46+
}
47+
}
48+
abs, err := filepath.Abs(resolved)
49+
if err != nil {
50+
return nil, fmt.Errorf("resolve abs: %w", err)
51+
}
52+
53+
if r.IncludeFileNameResolved {
54+
attributes[LogFileNameResolved] = filepath.Base(abs)
55+
}
56+
if r.IncludeFilePathResolved {
57+
attributes[LogFilePathResolved] = abs
58+
}
59+
return attributes, nil
60+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package attrs
5+
6+
import (
7+
"fmt"
8+
"path/filepath"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/filetest"
14+
)
15+
16+
func TestResolver(t *testing.T) {
17+
t.Parallel()
18+
19+
for i := 0; i < 16; i++ {
20+
21+
// Create a 4 bit string where each bit represents the value of a config option
22+
bitString := fmt.Sprintf("%04b", i)
23+
24+
// Create a resolver with a config that matches the bit pattern of i
25+
r := Resolver{
26+
IncludeFileName: bitString[0] == '1',
27+
IncludeFilePath: bitString[1] == '1',
28+
IncludeFileNameResolved: bitString[2] == '1',
29+
IncludeFilePathResolved: bitString[3] == '1',
30+
}
31+
32+
t.Run(bitString, func(t *testing.T) {
33+
// Create a file
34+
tempDir := t.TempDir()
35+
temp := filetest.OpenTemp(t, tempDir)
36+
37+
attributes, err := r.Resolve(temp.Name())
38+
assert.NoError(t, err)
39+
40+
var expectLen int
41+
if r.IncludeFileName {
42+
expectLen++
43+
assert.Equal(t, filepath.Base(temp.Name()), attributes[LogFileName])
44+
} else {
45+
assert.Empty(t, attributes[LogFileName])
46+
}
47+
if r.IncludeFilePath {
48+
expectLen++
49+
assert.Equal(t, temp.Name(), attributes[LogFilePath])
50+
} else {
51+
assert.Empty(t, attributes[LogFilePath])
52+
}
53+
54+
// We don't have an independent way to resolve the path, so the only meangingful validate
55+
// is to ensure that the resolver returns nothing vs something based on the config.
56+
if r.IncludeFileNameResolved {
57+
expectLen++
58+
assert.NotNil(t, attributes[LogFileNameResolved])
59+
assert.IsType(t, "", attributes[LogFileNameResolved])
60+
} else {
61+
assert.Empty(t, attributes[LogFileNameResolved])
62+
}
63+
if r.IncludeFilePathResolved {
64+
expectLen++
65+
assert.NotNil(t, attributes[LogFilePathResolved])
66+
assert.IsType(t, "", attributes[LogFilePathResolved])
67+
} else {
68+
assert.Empty(t, attributes[LogFilePathResolved])
69+
}
70+
assert.Equal(t, expectLen, len(attributes))
71+
})
72+
}
73+
}

pkg/stanza/fileconsumer/config.go

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"golang.org/x/text/encoding"
1515

1616
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/decode"
17+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/attrs"
1718
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/emit"
1819
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/fingerprint"
1920
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header"
@@ -55,29 +56,28 @@ func NewConfig() *Config {
5556
MaxLogSize: reader.DefaultMaxLogSize,
5657
Encoding: defaultEncoding,
5758
FlushPeriod: reader.DefaultFlushPeriod,
58-
IncludeFileName: true,
59+
Resolver: attrs.Resolver{
60+
IncludeFileName: true,
61+
},
5962
}
6063
}
6164

6265
// Config is the configuration of a file input operator
6366
type Config struct {
64-
matcher.Criteria `mapstructure:",squash"`
65-
PollInterval time.Duration `mapstructure:"poll_interval,omitempty"`
66-
MaxConcurrentFiles int `mapstructure:"max_concurrent_files,omitempty"`
67-
MaxBatches int `mapstructure:"max_batches,omitempty"`
68-
StartAt string `mapstructure:"start_at,omitempty"`
69-
FingerprintSize helper.ByteSize `mapstructure:"fingerprint_size,omitempty"`
70-
MaxLogSize helper.ByteSize `mapstructure:"max_log_size,omitempty"`
71-
Encoding string `mapstructure:"encoding,omitempty"`
72-
SplitConfig split.Config `mapstructure:"multiline,omitempty"`
73-
TrimConfig trim.Config `mapstructure:",squash,omitempty"`
74-
FlushPeriod time.Duration `mapstructure:"force_flush_period,omitempty"`
75-
IncludeFileName bool `mapstructure:"include_file_name,omitempty"`
76-
IncludeFilePath bool `mapstructure:"include_file_path,omitempty"`
77-
IncludeFileNameResolved bool `mapstructure:"include_file_name_resolved,omitempty"`
78-
IncludeFilePathResolved bool `mapstructure:"include_file_path_resolved,omitempty"`
79-
Header *HeaderConfig `mapstructure:"header,omitempty"`
80-
DeleteAfterRead bool `mapstructure:"delete_after_read,omitempty"`
67+
matcher.Criteria `mapstructure:",squash"`
68+
attrs.Resolver `mapstructure:",squash"`
69+
PollInterval time.Duration `mapstructure:"poll_interval,omitempty"`
70+
MaxConcurrentFiles int `mapstructure:"max_concurrent_files,omitempty"`
71+
MaxBatches int `mapstructure:"max_batches,omitempty"`
72+
StartAt string `mapstructure:"start_at,omitempty"`
73+
FingerprintSize helper.ByteSize `mapstructure:"fingerprint_size,omitempty"`
74+
MaxLogSize helper.ByteSize `mapstructure:"max_log_size,omitempty"`
75+
Encoding string `mapstructure:"encoding,omitempty"`
76+
SplitConfig split.Config `mapstructure:"multiline,omitempty"`
77+
TrimConfig trim.Config `mapstructure:",squash,omitempty"`
78+
FlushPeriod time.Duration `mapstructure:"force_flush_period,omitempty"`
79+
Header *HeaderConfig `mapstructure:"header,omitempty"`
80+
DeleteAfterRead bool `mapstructure:"delete_after_read,omitempty"`
8181
}
8282

8383
type HeaderConfig struct {
@@ -150,21 +150,18 @@ func (c Config) buildManager(logger *zap.SugaredLogger, emit emit.Callback, spli
150150
}
151151

152152
readerFactory := reader.Factory{
153-
SugaredLogger: logger.With("component", "fileconsumer"),
154-
FromBeginning: startAtBeginning,
155-
FingerprintSize: int(c.FingerprintSize),
156-
MaxLogSize: int(c.MaxLogSize),
157-
Encoding: enc,
158-
SplitFunc: splitFunc,
159-
TrimFunc: trimFunc,
160-
FlushTimeout: c.FlushPeriod,
161-
EmitFunc: emit,
162-
IncludeFileName: c.IncludeFileName,
163-
IncludeFilePath: c.IncludeFilePath,
164-
IncludeFileNameResolved: c.IncludeFileNameResolved,
165-
IncludeFilePathResolved: c.IncludeFilePathResolved,
166-
HeaderConfig: hCfg,
167-
DeleteAtEOF: c.DeleteAfterRead,
153+
SugaredLogger: logger.With("component", "fileconsumer"),
154+
FromBeginning: startAtBeginning,
155+
FingerprintSize: int(c.FingerprintSize),
156+
MaxLogSize: int(c.MaxLogSize),
157+
Encoding: enc,
158+
SplitFunc: splitFunc,
159+
TrimFunc: trimFunc,
160+
FlushTimeout: c.FlushPeriod,
161+
EmitFunc: emit,
162+
Attributes: c.Resolver,
163+
HeaderConfig: hCfg,
164+
DeleteAtEOF: c.DeleteAfterRead,
168165
}
169166

170167
return &Manager{

pkg/stanza/fileconsumer/file_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/stretchr/testify/require"
1919
"go.opentelemetry.io/collector/featuregate"
2020

21-
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/attrs"
21+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/attrs"
2222
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/emittest"
2323
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/filetest"
2424
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/reader"

0 commit comments

Comments
 (0)