Skip to content

Commit

Permalink
feat: JobLoggerFactory (nektos#1496)
Browse files Browse the repository at this point in the history
Remove overriding io.Stdout in TestMaskValues to prevent deadlock in GitHub Actions
  • Loading branch information
ChristopherHX committed Dec 9, 2022
1 parent 0f8861b commit 7d99512
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 35 deletions.
78 changes: 46 additions & 32 deletions pkg/runner/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,48 @@ func WithMasks(ctx context.Context, masks *[]string) context.Context {
return context.WithValue(ctx, masksContextKeyVal, masks)
}

type JobLoggerFactory interface {
WithJobLogger() *logrus.Logger
}

type jobLoggerFactoryContextKey string

var jobLoggerFactoryContextKeyVal = (jobLoggerFactoryContextKey)("jobloggerkey")

func WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory) context.Context {
return context.WithValue(ctx, jobLoggerFactoryContextKeyVal, factory)
}

// WithJobLogger attaches a new logger to context that is aware of steps
func WithJobLogger(ctx context.Context, jobID string, jobName string, config *Config, masks *[]string, matrix map[string]interface{}) context.Context {
mux.Lock()
defer mux.Unlock()

var formatter logrus.Formatter
if config.JSONLogger {
formatter = &jobLogJSONFormatter{
formatter: &logrus.JSONFormatter{},
masker: valueMasker(config.InsecureSecrets, config.Secrets),
}
ctx = WithMasks(ctx, masks)

var logger *logrus.Logger
if jobLoggerFactory, ok := ctx.Value(jobLoggerFactoryContextKeyVal).(JobLoggerFactory); ok && jobLoggerFactory != nil {
logger = jobLoggerFactory.WithJobLogger()
} else {
formatter = &jobLogFormatter{
color: colors[nextColor%len(colors)],
masker: valueMasker(config.InsecureSecrets, config.Secrets),
var formatter logrus.Formatter
if config.JSONLogger {
formatter = &logrus.JSONFormatter{}
} else {
mux.Lock()
defer mux.Unlock()
nextColor++
formatter = &jobLogFormatter{
color: colors[nextColor%len(colors)],
}
}
}

nextColor++
ctx = WithMasks(ctx, masks)
logger = logrus.New()
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.GetLevel())
logger.SetFormatter(formatter)
}

logger := logrus.New()
logger.SetFormatter(formatter)
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.GetLevel())
logger.SetFormatter(&maskedFormatter{
Formatter: logger.Formatter,
masker: valueMasker(config.InsecureSecrets, config.Secrets),
})
rtn := logger.WithFields(logrus.Fields{
"job": jobName,
"jobID": jobID,
Expand Down Expand Up @@ -149,16 +166,22 @@ func valueMasker(insecureSecrets bool, secrets map[string]string) entryProcessor
}
}

type jobLogFormatter struct {
color int
type maskedFormatter struct {
logrus.Formatter
masker entryProcessor
}

func (f *maskedFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return f.Formatter.Format(f.masker(entry))
}

type jobLogFormatter struct {
color int
}

func (f *jobLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
b := &bytes.Buffer{}

entry = f.masker(entry)

if f.isColored(entry) {
f.printColored(b, entry)
} else {
Expand Down Expand Up @@ -225,12 +248,3 @@ func checkIfTerminal(w io.Writer) bool {
return false
}
}

type jobLogJSONFormatter struct {
masker entryProcessor
formatter *logrus.JSONFormatter
}

func (f *jobLogJSONFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return f.formatter.Format(f.masker(entry))
}
19 changes: 16 additions & 3 deletions pkg/runner/runner_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package runner

import (
"bytes"
"context"
"fmt"
"io"
"os"
"path/filepath"
"runtime"
Expand Down Expand Up @@ -343,6 +345,17 @@ func TestRunDifferentArchitecture(t *testing.T) {
tjfi.runTest(context.Background(), t, &Config{ContainerArchitecture: "linux/arm64"})
}

type maskJobLoggerFactory struct {
Output bytes.Buffer
}

func (f *maskJobLoggerFactory) WithJobLogger() *log.Logger {
logger := log.New()
logger.SetOutput(io.MultiWriter(&f.Output, os.Stdout))
logger.SetLevel(log.DebugLevel)
return logger
}

func TestMaskValues(t *testing.T) {
assertNoSecret := func(text string, secret string) {
index := strings.Index(text, "composite secret")
Expand All @@ -366,9 +379,9 @@ func TestMaskValues(t *testing.T) {
platforms: platforms,
}

output := captureOutput(t, func() {
tjfi.runTest(context.Background(), t, &Config{})
})
logger := &maskJobLoggerFactory{}
tjfi.runTest(WithJobLoggerFactory(common.WithLogger(context.Background(), logger.WithJobLogger()), logger), t, &Config{})
output := logger.Output.String()

assertNoSecret(output, "secret value")
assertNoSecret(output, "YWJjCg==")
Expand Down

0 comments on commit 7d99512

Please sign in to comment.