core/processlog/options.go
package processlog
import (
"bytes"
"context"
"errors"
"io"
"os"
"time"
)
// PrintFunc is the function used to print data to the desired logger.
type PrintFunc func([]byte)
// stdStreamLogArgs define log inputs.
type stdStreamLogArgs struct {
// StdOut is the standard out stream to split from
StdOut io.ReadCloser
// StdErr is the stderr stream to split from
StdErr io.ReadCloser
// PrintFunc is how the print function is returned
PrintFunc PrintFunc
// LogDir is the directory to log to
LogDir string
// LogFileName is the log file name prefix
LogFileName string
// LogFrequency is how often to write to the lgos
LogFrequency time.Duration
// Accumulator to accumulate logs to.
Accumulator *bytes.Buffer
// Ctx is the context. Note: cancellations may lead to errors in your Wait() function
// nolint: containedctx
Ctx context.Context
}
var (
errCtxNil = errors.New("context cannot be nil")
errStdOutMustBeSet = errors.New("StdOut must be set")
//nolint: errName
errStdErrMustBeSet = errors.New("StdErr must be set")
errLogDirRequired = errors.New("log directory must be set")
)
// Validate validates the stdStreamLogArgs struct.
func (s *stdStreamLogArgs) Validate() error {
if s.Ctx == nil {
return errCtxNil
}
if s.StdOut == nil {
return errStdOutMustBeSet
}
if s.StdErr == nil {
return errStdErrMustBeSet
}
if s.LogDir == "" {
return errLogDirRequired
}
return nil
}
// StdStreamLogArgsOption is a function that modifies a stdStreamLogArgs struct field.
type StdStreamLogArgsOption func(*stdStreamLogArgs)
// WithStdOut returns a function that modifies the StdOut field of a stdStreamLogArgs struct.
func WithStdOut(stdOut io.ReadCloser) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.StdOut = stdOut
}
}
// WithStdErr returns a function that modifies the StdErr field of a stdStreamLogArgs struct.
func WithStdErr(stdErr io.ReadCloser) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.StdErr = stdErr
}
}
// WithReader returns a function that modifies the StdOut or StdErr field of a stdStreamLogArgs struct.
func WithReader(readerType ReaderType, reader io.ReadCloser) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
switch readerType {
case StdOut:
WithStdOut(reader)(args)
case StdErr:
WithStdErr(reader)(args)
}
}
}
// WithPrintFunc returns a function that modifies the PrintFunc field of a stdStreamLogArgs struct.
func WithPrintFunc(printFunc PrintFunc) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.PrintFunc = printFunc
}
}
// WithLogDir returns a function that modifies the LogDir field of a stdStreamLogArgs struct.
func WithLogDir(logDir string) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.LogDir = logDir
}
}
// WithLogFileName returns a function that modifies the LogFileName field of a stdStreamLogArgs struct.
func WithLogFileName(logFileName string) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.LogFileName = logFileName
}
}
// WithLogFrequency returns a function that modifies the LogFrequency field of a stdStreamLogArgs struct.
func WithLogFrequency(logFrequency time.Duration) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.LogFrequency = logFrequency
}
}
// WithAccumulator returns a function that modifies the Accumulator field of a stdStreamLogArgs struct.
func WithAccumulator(accumulator *bytes.Buffer) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.Accumulator = accumulator
}
}
// WithCtx returns a function that modifies the Ctx field of a stdStreamLogArgs struct.
func WithCtx(ctx context.Context) StdStreamLogArgsOption {
return func(args *stdStreamLogArgs) {
args.Ctx = ctx
}
}
// ReaderType is the type of reader (stdout or stderr).
//
//go:generate go run golang.org/x/tools/cmd/stringer -type=ReaderType -linecomment
type ReaderType uint8
const (
// StdOut is the stdout reader type.
StdOut ReaderType = iota // stdout
// StdErr is the stderr reader type.
StdErr ReaderType = iota // stderr
)
// HasReader returns true if the given reader type is set.
func HasReader(readerType ReaderType, opts ...StdStreamLogArgsOption) bool {
args := makeRawArgs(opts)
switch readerType {
case StdOut:
if args.StdOut != nil {
return true
}
case StdErr:
if args.StdErr != nil {
return true
}
}
return false
}
// makeArgs creates a new stdStreamLogArgs struct with the given options applied.
// It takes in a variadic list of StdStreamLogArgsOption functions and applies each of them to the new struct instance.
// It returns the modified struct instance.
func makeArgs(opts []StdStreamLogArgsOption) (_ *stdStreamLogArgs, err error) {
args := makeRawArgs(opts)
if err := args.Validate(); err != nil {
return nil, err
}
return args, nil
}
// makeRawArgs creates a new stdStreamLogArgs struct with the given options applied.
// it performs no validation.
func makeRawArgs(opts []StdStreamLogArgsOption) *stdStreamLogArgs {
args := &stdStreamLogArgs{}
args.LogFileName = "test"
args.LogFrequency = time.Second
// not a problem unless it's missing from user too, we'll validate at the end
args.LogDir, _ = os.MkdirTemp("/tmp/logs", "")
_ = os.MkdirAll("/tmp/logs", os.ModePerm)
args.LogFileName = "log"
args.PrintFunc = func(s []byte) {
// do nothing
}
for _, opt := range opts {
opt(args)
}
return args
}