mirror of
https://github.com/mudler/luet.git
synced 2025-07-11 22:28:06 +00:00
Instead of using gox on one side and an action to release, we can merge them together with goreleaser which will build for extra targets (arm, mips if needed in the future) and it also takes care of creating checksums, a source archive, and a changelog and creating a release with all the artifacts. All binaries should respect the old naming convention, so any scripts out there should still work. Signed-off-by: Itxaka <igarcia@suse.com>
183 lines
4.1 KiB
Go
183 lines
4.1 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// assert interface compliance.
|
|
var _ Interface = (*Entry)(nil)
|
|
|
|
// Now returns the current time.
|
|
var Now = time.Now
|
|
|
|
// Entry represents a single log entry.
|
|
type Entry struct {
|
|
Logger *Logger `json:"-"`
|
|
Fields Fields `json:"fields"`
|
|
Level Level `json:"level"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
Message string `json:"message"`
|
|
start time.Time
|
|
fields []Fields
|
|
}
|
|
|
|
// NewEntry returns a new entry for `log`.
|
|
func NewEntry(log *Logger) *Entry {
|
|
return &Entry{
|
|
Logger: log,
|
|
}
|
|
}
|
|
|
|
// WithFields returns a new entry with `fields` set.
|
|
func (e *Entry) WithFields(fields Fielder) *Entry {
|
|
f := []Fields{}
|
|
f = append(f, e.fields...)
|
|
f = append(f, fields.Fields())
|
|
return &Entry{
|
|
Logger: e.Logger,
|
|
fields: f,
|
|
}
|
|
}
|
|
|
|
// WithField returns a new entry with the `key` and `value` set.
|
|
func (e *Entry) WithField(key string, value interface{}) *Entry {
|
|
return e.WithFields(Fields{key: value})
|
|
}
|
|
|
|
// WithDuration returns a new entry with the "duration" field set
|
|
// to the given duration in milliseconds.
|
|
func (e *Entry) WithDuration(d time.Duration) *Entry {
|
|
return e.WithField("duration", d.Milliseconds())
|
|
}
|
|
|
|
// WithError returns a new entry with the "error" set to `err`.
|
|
//
|
|
// The given error may implement .Fielder, if it does the method
|
|
// will add all its `.Fields()` into the returned entry.
|
|
func (e *Entry) WithError(err error) *Entry {
|
|
if err == nil {
|
|
return e
|
|
}
|
|
|
|
ctx := e.WithField("error", err.Error())
|
|
|
|
if s, ok := err.(stackTracer); ok {
|
|
frame := s.StackTrace()[0]
|
|
|
|
name := fmt.Sprintf("%n", frame)
|
|
file := fmt.Sprintf("%+s", frame)
|
|
line := fmt.Sprintf("%d", frame)
|
|
|
|
parts := strings.Split(file, "\n\t")
|
|
if len(parts) > 1 {
|
|
file = parts[1]
|
|
}
|
|
|
|
ctx = ctx.WithField("source", fmt.Sprintf("%s: %s:%s", name, file, line))
|
|
}
|
|
|
|
if f, ok := err.(Fielder); ok {
|
|
ctx = ctx.WithFields(f.Fields())
|
|
}
|
|
|
|
return ctx
|
|
}
|
|
|
|
// Debug level message.
|
|
func (e *Entry) Debug(msg string) {
|
|
e.Logger.log(DebugLevel, e, msg)
|
|
}
|
|
|
|
// Info level message.
|
|
func (e *Entry) Info(msg string) {
|
|
e.Logger.log(InfoLevel, e, msg)
|
|
}
|
|
|
|
// Warn level message.
|
|
func (e *Entry) Warn(msg string) {
|
|
e.Logger.log(WarnLevel, e, msg)
|
|
}
|
|
|
|
// Error level message.
|
|
func (e *Entry) Error(msg string) {
|
|
e.Logger.log(ErrorLevel, e, msg)
|
|
}
|
|
|
|
// Fatal level message, followed by an exit.
|
|
func (e *Entry) Fatal(msg string) {
|
|
e.Logger.log(FatalLevel, e, msg)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Debugf level formatted message.
|
|
func (e *Entry) Debugf(msg string, v ...interface{}) {
|
|
e.Debug(fmt.Sprintf(msg, v...))
|
|
}
|
|
|
|
// Infof level formatted message.
|
|
func (e *Entry) Infof(msg string, v ...interface{}) {
|
|
e.Info(fmt.Sprintf(msg, v...))
|
|
}
|
|
|
|
// Warnf level formatted message.
|
|
func (e *Entry) Warnf(msg string, v ...interface{}) {
|
|
e.Warn(fmt.Sprintf(msg, v...))
|
|
}
|
|
|
|
// Errorf level formatted message.
|
|
func (e *Entry) Errorf(msg string, v ...interface{}) {
|
|
e.Error(fmt.Sprintf(msg, v...))
|
|
}
|
|
|
|
// Fatalf level formatted message, followed by an exit.
|
|
func (e *Entry) Fatalf(msg string, v ...interface{}) {
|
|
e.Fatal(fmt.Sprintf(msg, v...))
|
|
}
|
|
|
|
// Trace returns a new entry with a Stop method to fire off
|
|
// a corresponding completion log, useful with defer.
|
|
func (e *Entry) Trace(msg string) *Entry {
|
|
e.Info(msg)
|
|
v := e.WithFields(e.Fields)
|
|
v.Message = msg
|
|
v.start = time.Now()
|
|
return v
|
|
}
|
|
|
|
// Stop should be used with Trace, to fire off the completion message. When
|
|
// an `err` is passed the "error" field is set, and the log level is error.
|
|
func (e *Entry) Stop(err *error) {
|
|
if err == nil || *err == nil {
|
|
e.WithDuration(time.Since(e.start)).Info(e.Message)
|
|
} else {
|
|
e.WithDuration(time.Since(e.start)).WithError(*err).Error(e.Message)
|
|
}
|
|
}
|
|
|
|
// mergedFields returns the fields list collapsed into a single map.
|
|
func (e *Entry) mergedFields() Fields {
|
|
f := Fields{}
|
|
|
|
for _, fields := range e.fields {
|
|
for k, v := range fields {
|
|
f[k] = v
|
|
}
|
|
}
|
|
|
|
return f
|
|
}
|
|
|
|
// finalize returns a copy of the Entry with Fields merged.
|
|
func (e *Entry) finalize(level Level, msg string) *Entry {
|
|
return &Entry{
|
|
Logger: e.Logger,
|
|
Fields: e.mergedFields(),
|
|
Level: level,
|
|
Message: msg,
|
|
Timestamp: Now(),
|
|
}
|
|
}
|