Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file rotation based on file age to file output plugin #5547

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions plugins/outputs/file/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ This plugin writes telegraf metrics to files
## Files to write to, "stdout" is a specially handled file.
files = ["stdout", "/tmp/metrics.out"]

## If this is defined, files will be rotated by the time.Duration specified
#rotate_max_age = "1m"
flexd marked this conversation as resolved.
Show resolved Hide resolved

## Data format to output.
## Each data format has its own unique set of configuration options, read
## more about them here:
Expand Down
43 changes: 32 additions & 11 deletions plugins/outputs/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import (
"fmt"
"io"
"os"
"time"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/rotate"
"github.com/influxdata/telegraf/plugins/outputs"
"github.com/influxdata/telegraf/plugins/serializers"
)

type File struct {
Files []string
Files []string
RotateMaxAge string

writers []io.Writer
writer io.Writer
closers []io.Closer

serializer serializers.Serializer
Expand All @@ -23,6 +26,9 @@ var sampleConfig = `
## Files to write to, "stdout" is a specially handled file.
files = ["stdout", "/tmp/metrics.out"]

## If this is defined, files will be rotated by the time.Duration specified
#rotate_max_age = "1m"
flexd marked this conversation as resolved.
Show resolved Hide resolved

## Data format to output.
## Each data format has its own unique set of configuration options, read
## more about them here:
Expand All @@ -35,23 +41,38 @@ func (f *File) SetSerializer(serializer serializers.Serializer) {
}

func (f *File) Connect() error {
writers := []io.Writer{}

if len(f.Files) == 0 {
f.Files = []string{"stdout"}
}

for _, file := range f.Files {
if file == "stdout" {
f.writers = append(f.writers, os.Stdout)
writers = append(writers, os.Stdout)
} else {
of, err := os.OpenFile(file, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModeAppend|0644)
var of io.WriteCloser
var err error
if f.RotateMaxAge != "" {
maxAge, err := time.ParseDuration(f.RotateMaxAge)
if err != nil {
return err
}

// Only rotate by file age for now, keep no archives.
of, err = rotate.NewFileWriter(file, maxAge, 0, -1)
} else {
// Just open a normal file
of, err = rotate.NewFileWriter(file, 0, 0, -1)
}
if err != nil {
return err
}

f.writers = append(f.writers, of)
writers = append(writers, of)
f.closers = append(f.closers, of)
}
}
f.writer = io.MultiWriter(writers...)
return nil
}

Expand All @@ -76,19 +97,19 @@ func (f *File) Description() string {

func (f *File) Write(metrics []telegraf.Metric) error {
var writeErr error = nil

for _, metric := range metrics {
b, err := f.serializer.Serialize(metric)
if err != nil {
return fmt.Errorf("failed to serialize message: %s", err)
}

for _, writer := range f.writers {
_, err = writer.Write(b)
if err != nil && writer != os.Stdout {
writeErr = fmt.Errorf("E! failed to write message: %s, %s", b, err)
}
_, err = f.writer.Write(b)
if err != nil && f.writer != os.Stdout {
flexd marked this conversation as resolved.
Show resolved Hide resolved
writeErr = fmt.Errorf("E! failed to write message: %s, %s", b, err)
}
}

return writeErr
}

Expand Down