Files
Anders Eknert 2378494a23 Modernize fixes and some string building improvements (#8993)
Mostly automated fixes from running:
```
go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest --fix ./...
```

But carefully reviewed, and several fixes reverted as they looked like
they potentially could be less performant, and in a few cases due to
bugs in the analyzer that changed semantics of the code. Will report
these upstream.

Mostly good fixes though!

Signed-off-by: Anders Eknert <anders.eknert@apple.com>
2026-08-10 12:49:15 +02:00

106 lines
2.7 KiB
Go

// Copyright 2021 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.
package logging
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"github.com/sirupsen/logrus"
"github.com/open-policy-agent/opa/v1/logging"
)
func GetLevel(level string) (logging.Level, error) {
switch strings.ToLower(level) {
case "debug":
return logging.Debug, nil
case "", "info":
return logging.Info, nil
case "warn":
return logging.Warn, nil
case "error":
return logging.Error, nil
default:
return logging.Debug, fmt.Errorf("invalid log level: %v", level)
}
}
func GetFormatter(format, timestampFormat string) logrus.Formatter {
switch format {
case "text":
return &prettyFormatter{}
case "json-pretty":
return &logrus.JSONFormatter{PrettyPrint: true, TimestampFormat: timestampFormat}
default:
return &logrus.JSONFormatter{TimestampFormat: timestampFormat}
}
}
// prettyFormatter implements the Logrus Formatter interface
// and provides a more simple, but easier to read, text formatter
// option than the default logrus.TextFormatter.
type prettyFormatter struct{}
func spaces(num int) string {
return strings.Repeat(" ", num)
}
func (*prettyFormatter) Format(e *logrus.Entry) ([]byte, error) {
b := new(bytes.Buffer)
level := strings.ToUpper(e.Level.String())
fmt.Fprintf(b, "[%s] %s\n", level, e.Message)
// Format each key for optimal ease of human reading
fieldIndent := 2
multiLineIndent := 6
for k, v := range e.Data {
// Special case for multi-line strings, keep them as-is
// but indent them. Everything else gets json'd
stringVal, ok := v.(string)
if ok && strings.Contains(stringVal, "\n") {
sb := strings.Builder{}
for i, line := range strings.Split(stringVal, "\n") {
// match the json indent helper by not indenting the first value
if i != 0 {
sb.WriteString(spaces(multiLineIndent))
}
sb.WriteString(line)
sb.WriteByte('\n')
stringVal = sb.String()
}
} else if ok && json.Valid([]byte(stringVal)) {
var tmp bytes.Buffer
err := json.Indent(&tmp, []byte(stringVal), spaces(multiLineIndent), spaces(2))
if err != nil {
return nil, err
}
stringVal = tmp.String()
} else {
jsonVal, err := json.MarshalIndent(v, spaces(multiLineIndent), spaces(2))
if err != nil {
return nil, err
}
stringVal = string(jsonVal)
}
b.WriteString(spaces(fieldIndent))
b.WriteString(k)
if strings.Contains(stringVal, "\n") {
b.WriteString(" = |\n")
b.WriteString(spaces(multiLineIndent))
} else {
b.WriteString(" = ")
}
b.WriteString(stringVal)
b.WriteByte('\n')
}
b.WriteByte('\n')
return b.Bytes(), nil
}