1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-16 11:09:33 +02:00
sap-jenkins-library/pkg/log/writer.go
2020-05-06 13:35:40 +02:00

69 lines
1.6 KiB
Go

package log
import (
"bytes"
"strings"
"sync"
)
type logTarget interface {
Info(args ...interface{})
Warn(args ...interface{})
Error(args ...interface{})
}
// logrusWriter can be used as the destination for a tool's std output and forwards
// chunks between linebreaks to the logrus framework. This works around a problem
// with using Entry().Writer() directly, since that doesn't support chunks
// larger than 64K without linebreaks.
// Implementation copied from https://github.com/sirupsen/logrus/issues/564
type logrusWriter struct {
logger logTarget
buffer bytes.Buffer
mutex sync.Mutex
}
func (w *logrusWriter) Write(buffer []byte) (int, error) {
w.mutex.Lock()
defer w.mutex.Unlock()
origLen := len(buffer)
for {
if len(buffer) == 0 {
return origLen, nil
}
linebreakIndex := bytes.IndexByte(buffer, '\n')
if linebreakIndex < 0 {
w.buffer.Write(buffer)
return origLen, nil
}
w.buffer.Write(buffer[:linebreakIndex])
w.alwaysFlush()
buffer = buffer[linebreakIndex+1:]
}
}
func (w *logrusWriter) alwaysFlush() {
message := w.buffer.String()
w.buffer.Reset()
// Align level with underlying tool (like maven or npm)
// This is to avoid confusion when maven or npm print errors or warnings which piper would print as "info"
if strings.Contains(message, "ERROR") || strings.Contains(message, "ERR!") {
w.logger.Error(message)
} else if strings.Contains(message, "WARN") {
w.logger.Warn(message)
} else {
w.logger.Info(message)
}
}
func (w *logrusWriter) Flush() {
w.mutex.Lock()
defer w.mutex.Unlock()
if w.buffer.Len() != 0 {
w.alwaysFlush()
}
}