1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00
sap-jenkins-library/pkg/log/log.go
Oliver Nocon eafe383d54
Add error category parsing to cmd execution (#1703)
* Add error category parsing to cmd execution

It is now possible to define `ErrorCategoryMapping` as a `map[string][]string` on a `Command`.
The format contains the category as key which has a list of error patterns assigned.
Example:

```
cmd := Command{
  ErrorCategoryMapping: map[string][]string
    "build": {"build failed"},
    "compliance": {"vulnerabilities found", "outdated components found"},
    "test": {"some tests failed"},
  },
}
```

Setting this map triggers console log parsing when executing a command.
If a match is found the error category is stored and
it will automatically be added to the `errorDetails.json`.

* clean up go.mod

* fix test

* fix test

* Update DEVELOPMENT.md

* fix tests

* address long console content without line breaks

* scan condition update

* fix test

* add missing comment for exported function

* Update pkg/command/command.go

Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>

Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>
Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
2020-06-24 10:04:05 +02:00

118 lines
2.9 KiB
Go

package log
import (
"fmt"
"io"
"strings"
"github.com/sirupsen/logrus"
)
//PiperLogFormatter is the custom formatter of piper
type PiperLogFormatter struct {
logrus.TextFormatter
logFormat string
}
const (
logFormatPlain = "plain"
logFormatDefault = "default"
logFormatWithTimestamp = "timestamp"
)
//Format the log message
func (formatter *PiperLogFormatter) Format(entry *logrus.Entry) (bytes []byte, err error) {
message := ""
stepName := entry.Data["stepName"]
if stepName == nil {
stepName = "(noStepName)"
}
errorMessageSnippet := ""
if entry.Data[logrus.ErrorKey] != nil {
errorMessageSnippet = fmt.Sprintf(" - %s", entry.Data[logrus.ErrorKey])
}
level, _ := entry.Level.MarshalText()
levelString := string(level)
if levelString == "warning" {
levelString = "warn"
}
switch formatter.logFormat {
case logFormatDefault:
message = fmt.Sprintf("%-5s %-6s - %s%s\n", levelString, stepName, entry.Message, errorMessageSnippet)
case logFormatWithTimestamp:
message = fmt.Sprintf("%s %-5s %-6s %s%s\n", entry.Time.Format("15:04:05"), levelString, stepName, entry.Message, errorMessageSnippet)
case logFormatPlain:
message = fmt.Sprintf("%s%s\n", entry.Message, errorMessageSnippet)
default:
formattedMessage, err := formatter.TextFormatter.Format(entry)
if err != nil {
return nil, err
}
message = string(formattedMessage)
}
for _, secret := range secrets {
message = strings.Replace(message, secret, "****", -1)
}
return []byte(message), nil
}
// LibraryRepository that is passed into with -ldflags
var LibraryRepository string
var logger *logrus.Entry
var secrets []string
// Entry returns the logger entry or creates one if none is present.
func Entry() *logrus.Entry {
if logger == nil {
logger = logrus.WithField("library", LibraryRepository)
logger.Logger.SetFormatter(&PiperLogFormatter{})
}
return logger
}
// Writer returns an io.Writer into which a tool's output can be redirected.
func Writer() io.Writer {
return &logrusWriter{logger: Entry()}
}
// SetVerbose sets the log level with respect to verbose flag.
func SetVerbose(verbose bool) {
if verbose {
//Logger().Debugf("logging set to level: %s", level)
logrus.SetLevel(logrus.DebugLevel)
}
}
// SetFormatter specifies the log format to use for piper's output
func SetFormatter(logFormat string) {
Entry().Logger.SetFormatter(&PiperLogFormatter{logFormat: logFormat})
}
// SetStepName sets the stepName field.
func SetStepName(stepName string) {
logger = Entry().WithField("stepName", stepName)
}
// DeferExitHandler registers a logrus exit handler to allow cleanup activities.
func DeferExitHandler(handler func()) {
logrus.DeferExitHandler(handler)
}
// RegisterHook registers a logrus hook
func RegisterHook(hook logrus.Hook) {
logrus.AddHook(hook)
}
func RegisterSecret(secret string) {
if len(secret) > 0 {
secrets = append(secrets, secret)
}
}