pkg/output/file/file.go (69 lines of code) (raw):

// Package file implements the output of logs to a file. // // Configuration file supports either writing to a file or a directory // with random names. delimiter is required. This is the string to // write between log entries. Normally a new line "\n" // // output: // type: file // filename: "/var/tmp/rally.ndjson" // delimiter: "/n" // // or // // output: // type: file // directory: "/var/tmp" // pattern: "rally_*" // delimiter: "\r\n" // // directory and pattern are used in os.CreateTemp call package file import ( "io" "os" "github.com/elastic/go-ucfg" "github.com/elastic/spigot/pkg/output" ) // OutputName is the name of the output in the configuration file and registry const Name = "file" // Output stores pointer to an io.WriteCloser. This is where the log // entries will be written. It also stores the delimiter that will be // added between log entries. type Output struct { delimiter string pWriteCloser io.WriteCloser directory string pattern string } func init() { output.Register(Name, New) } // New is the Factory for creating a new file output. Calling this // results in a file handle being opened to write the log data to. func New(cfg *ucfg.Config) (output.Output, error) { var pOsFile *os.File var err error c := defaultConfig() if err = cfg.Unpack(&c); err != nil { return nil, err } if c.Directory != "" && c.Pattern != "" { pOsFile, err = os.CreateTemp(c.Directory, c.Pattern) if err != nil { return nil, err } } if c.Filename != "" { pOsFile, err = os.Create(c.Filename) if err != nil { return nil, err } } out := Output{ pWriteCloser: pOsFile, delimiter: c.Delimiter, directory: c.Directory, pattern: c.Pattern, } return &out, nil } // Write writes the log entry to the file handle that is opened with // new and appends the delimiter. func (o *Output) Write(b []byte) (n int, err error) { j, err := o.pWriteCloser.Write(b) if err != nil { return j, err } k, err := o.pWriteCloser.Write([]byte(o.delimiter)) return j + k, err } // Close closes the io.WriteCloser. Writes after this will fail. func (o *Output) Close() error { return o.pWriteCloser.Close() } func (o *Output) NewInterval() error { if o.directory == "" && o.pattern == "" { return nil } if err := o.Close(); err != nil { return err } pOsFile, err := os.CreateTemp(o.directory, o.pattern) if err != nil { return err } o.pWriteCloser = pOsFile return nil }