Skip to content

Commit

Permalink
split owner info files in two for other system than linux
Browse files Browse the repository at this point in the history
  • Loading branch information
tprelle committed Mar 27, 2024
1 parent cb4691a commit 459f97c
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .chloggen/add_include_file_infos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ change_type: enhancement
component: filelogreceiver

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: When reading a file on filelogreceiver, if include_file_owner_name is true, it will add the file owner name as the attribute `log.file.owner.name` and if include_file_group_name is true, it will add the file group name as the attribute `log.file.group.name`.
note: When reading a file on filelogreceiver on linux or solaris, if include_file_owner_name is true, it will add the file owner name as the attribute `log.file.owner.name` and if include_file_group_name is true, it will add the file group name as the attribute `log.file.group.name`.

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [30775]
Expand Down
4 changes: 2 additions & 2 deletions pkg/stanza/docs/operators/file_input.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ The `file_input` operator reads logs from files. It will place the lines read in
| `include_file_path` | `false` | Whether to add the file path as the attribute `log.file.path`. |
| `include_file_name_resolved` | `false` | Whether to add the file name after symlinks resolution as the attribute `log.file.name_resolved`. |
| `include_file_path_resolved` | `false` | Whether to add the file path after symlinks resolution as the attribute `log.file.path_resolved`. |
| `include_file_owner_name` | `false` | Whether to add the file owner name as the attribute `log.file.owner.name` |
| `include_file_group_name` | `false` | Whether to add the file group name as the attribute `log.file.group.name` |
| `include_file_owner_name` | `false` | Whether to add the file owner name as the attribute `log.file.owner.name`. Only supported for linux or solaris. |
| `include_file_group_name` | `false` | Whether to add the file group name as the attribute `log.file.group.name`. Only supported for linux or solaris. |
| `preserve_leading_whitespaces` | `false` | Whether to preserve leading whitespaces. |
| `preserve_trailing_whitespaces` | `false` | Whether to preserve trailing whitespaces. |
| `start_at` | `end` | At startup, where to start reading logs from the file. Options are `beginning` or `end`. This setting will be ignored if previously read file offsets are retrieved from a persistence mechanism. |
Expand Down
26 changes: 0 additions & 26 deletions pkg/stanza/fileconsumer/attrs/attrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ package attrs // import "github.com/open-telemetry/opentelemetry-collector-contr
import (
"fmt"
"os"
"os/user"
"path/filepath"
"runtime"
"syscall"
)

const (
Expand All @@ -30,30 +28,6 @@ type Resolver struct {
IncludeFileGroupName bool `mapstructure:"include_file_group_name,omitempty"`
}

func (r *Resolver) addOwnerInfo(file *os.File, attributes map[string]any) (err error) {
var fileInfo, errStat = file.Stat()
if errStat != nil {
return fmt.Errorf("resolve file stat: %w", err)
}
var fileStat = fileInfo.Sys().(*syscall.Stat_t)

if r.IncludeFileOwnerName {
var fileOwner, errFileUser = user.LookupId(fmt.Sprint(fileStat.Uid))
if errFileUser != nil {
return fmt.Errorf("resolve file owner name: %w", errFileUser)
}
attributes[LogFileOwnerName] = fileOwner.Username
}
if r.IncludeFileGroupName {
var fileGroup, errFileGroup = user.LookupGroupId(fmt.Sprint(fileStat.Gid))
if errFileGroup != nil {
return fmt.Errorf("resolve file group name: %w", errFileGroup)
}
attributes[LogFileGroupName] = fileGroup.Name
}
return nil
}

func (r *Resolver) Resolve(file *os.File) (attributes map[string]any, err error) {
var path = file.Name()
// size 2 is sufficient if not resolving symlinks. This optimizes for the most performant cases.
Expand Down
5 changes: 3 additions & 2 deletions pkg/stanza/fileconsumer/attrs/attrs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package attrs
import (
"fmt"
"path/filepath"
"runtime"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -69,15 +70,15 @@ func TestResolver(t *testing.T) {
} else {
assert.Empty(t, attributes[LogFilePathResolved])
}
if r.IncludeFileOwnerName {
if (runtime.GOOS == "linux" || runtime.GOOS == "solaris") && r.IncludeFileOwnerName {
expectLen++
assert.NotNil(t, attributes[LogFileOwnerName])
assert.IsType(t, "", attributes[LogFileOwnerName])
} else {
assert.Empty(t, attributes[LogFileOwnerName])
assert.Empty(t, attributes[LogFileOwnerName])
}
if r.IncludeFileGroupName {
if (runtime.GOOS == "linux" || runtime.GOOS == "solaris") && r.IncludeFileGroupName {
expectLen++
assert.NotNil(t, attributes[LogFileGroupName])
assert.IsType(t, "", attributes[LogFileGroupName])
Expand Down
34 changes: 34 additions & 0 deletions pkg/stanza/fileconsumer/attrs/ownerInfo_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//go:build linux || solaris

package attrs

import (
"fmt"
"os"
"os/user"
"syscall"
)

func (r *Resolver) addOwnerInfo(file *os.File, attributes map[string]any) (err error) {
var fileInfo, errStat = file.Stat()
if errStat != nil {
return fmt.Errorf("resolve file stat: %w", err)
}
var fileStat = fileInfo.Sys().(*syscall.Stat_t)

if r.IncludeFileOwnerName {
var fileOwner, errFileUser = user.LookupId(fmt.Sprint(fileStat.Uid))
if errFileUser != nil {
return fmt.Errorf("resolve file owner name: %w", errFileUser)
}
attributes[LogFileOwnerName] = fileOwner.Username
}
if r.IncludeFileGroupName {
var fileGroup, errFileGroup = user.LookupGroupId(fmt.Sprint(fileStat.Gid))
if errFileGroup != nil {
return fmt.Errorf("resolve file group name: %w", errFileGroup)
}
attributes[LogFileGroupName] = fileGroup.Name
}
return nil
}
12 changes: 12 additions & 0 deletions pkg/stanza/fileconsumer/attrs/ownerInfo_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//go:build !linux && !solaris

package attrs

import (
"fmt"
"os"
)

func (r *Resolver) addOwnerInfo(file *os.File, attributes map[string]any) (err error) {
return fmt.Errorf("addOwnerInfo it's only implemented for linux or solaris: %w", err)
}
4 changes: 4 additions & 0 deletions pkg/stanza/fileconsumer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"bufio"
"errors"
"fmt"
"runtime"
"time"

"go.opentelemetry.io/collector/featuregate"
Expand Down Expand Up @@ -145,6 +146,9 @@ func (c Config) Build(logger *zap.SugaredLogger, emit emit.Callback, opts ...Opt
if err != nil {
return nil, err
}
if (runtime.GOOS != "linux" && runtime.GOOS != "solaris") && (c.Resolver.IncludeFileOwnerName || c.Resolver.IncludeFileGroupName) {
return nil, fmt.Errorf("include_file_owner_name or include_file_group_name it's only supported for linux or solaris: %w", err)
}

readerFactory := reader.Factory{
SugaredLogger: logger.With("component", "fileconsumer"),
Expand Down
4 changes: 2 additions & 2 deletions pkg/stanza/operator/input/file/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func TestAddFileResolvedFields(t *testing.T) {
cfg.IncludeFilePath = true
cfg.IncludeFileNameResolved = true
cfg.IncludeFilePathResolved = true
cfg.IncludeFileOwnerName = true
cfg.IncludeFileGroupName = true
cfg.IncludeFileOwnerName = (runtime.GOOS == "linux" || runtime.GOOS == "solaris")
cfg.IncludeFileGroupName = (runtime.GOOS == "linux" || runtime.GOOS == "solaris")
})

// Create temp dir with log file
Expand Down
4 changes: 2 additions & 2 deletions receiver/filelogreceiver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Tails and parses logs from files.
| `include_file_path` | `false` | Whether to add the file path as the attribute `log.file.path`. |
| `include_file_name_resolved` | `false` | Whether to add the file name after symlinks resolution as the attribute `log.file.name_resolved`. |
| `include_file_path_resolved` | `false` | Whether to add the file path after symlinks resolution as the attribute `log.file.path_resolved`. |
| `include_file_owner_name` | `false` | Whether to add the file owner name as the attribute `log.file.owner.name` |
| `include_file_group_name` | `false` | Whether to add the file group name as the attribute `log.file.group.name` |
| `include_file_owner_name` | `false` | Whether to add the file owner name as the attribute `log.file.owner.name`. Only supported for linux or solaris. |
| `include_file_group_name` | `false` | Whether to add the file group name as the attribute `log.file.group.name`. Only supported for linux or solaris. |
| `poll_interval` | 200ms | The [duration](#time-parameters) between filesystem polls. |
| `fingerprint_size` | `1kb` | The number of bytes with which to identify a file. The first bytes in the file are used as the fingerprint. Decreasing this value at any point will cause existing fingerprints to forgotten, meaning that all files will be read from the beginning (one time) |
| `max_log_size` | `1MiB` | The maximum size of a log entry to read. A log entry will be truncated if it is larger than `max_log_size`. Protects against reading large amounts of data into memory. |
Expand Down

0 comments on commit 459f97c

Please sign in to comment.