mirror of
https://github.com/zrepl/zrepl.git
synced 2025-08-17 18:31:02 +02:00
move implementation to internal/
directory (#828)
This commit is contained in:
committed by
GitHub
parent
b9b9ad10cf
commit
908807bd59
186
internal/logger/datastructures.go
Normal file
186
internal/logger/datastructures.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Level int
|
||||
|
||||
func (l Level) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(l.String())
|
||||
}
|
||||
|
||||
func (l *Level) UnmarshalJSON(input []byte) (err error) {
|
||||
var s string
|
||||
if err = json.Unmarshal(input, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
*l, err = ParseLevel(s)
|
||||
return err
|
||||
}
|
||||
|
||||
// implement flag.Value
|
||||
// implement github.com/spf13/pflag.Value
|
||||
func (l *Level) Set(s string) error {
|
||||
newl, err := ParseLevel(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*l = newl
|
||||
return nil
|
||||
}
|
||||
|
||||
// implement github.com/spf13/pflag.Value
|
||||
func (l *Level) Type() string {
|
||||
var buf bytes.Buffer
|
||||
for i, l := range AllLevels {
|
||||
fmt.Fprintf(&buf, "%s", l)
|
||||
if i != len(AllLevels)-1 {
|
||||
fmt.Fprintf(&buf, "|")
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("(%s)", buf.String())
|
||||
}
|
||||
|
||||
const (
|
||||
Debug Level = iota
|
||||
Info
|
||||
Warn
|
||||
Error
|
||||
)
|
||||
|
||||
func (l Level) Short() string {
|
||||
switch l {
|
||||
case Debug:
|
||||
return "DEBG"
|
||||
case Info:
|
||||
return "INFO"
|
||||
case Warn:
|
||||
return "WARN"
|
||||
case Error:
|
||||
return "ERRO"
|
||||
default:
|
||||
return l.String()
|
||||
}
|
||||
}
|
||||
|
||||
func (l Level) String() string {
|
||||
switch l {
|
||||
case Debug:
|
||||
return "debug"
|
||||
case Info:
|
||||
return "info"
|
||||
case Warn:
|
||||
return "warn"
|
||||
case Error:
|
||||
return "error"
|
||||
default:
|
||||
return fmt.Sprintf("unknown level %d", l)
|
||||
}
|
||||
}
|
||||
|
||||
func ParseLevel(s string) (l Level, err error) {
|
||||
for _, l := range AllLevels {
|
||||
if s == l.String() {
|
||||
return l, nil
|
||||
}
|
||||
}
|
||||
return -1, errors.Errorf("unknown level '%s'", s)
|
||||
}
|
||||
|
||||
// Levels ordered least severe to most severe
|
||||
var AllLevels []Level = []Level{Debug, Info, Warn, Error}
|
||||
|
||||
type Fields map[string]interface{}
|
||||
|
||||
type Entry struct {
|
||||
Level Level
|
||||
Message string
|
||||
Time time.Time
|
||||
Fields Fields
|
||||
}
|
||||
|
||||
func (e Entry) Color() *color.Color {
|
||||
c := color.New()
|
||||
switch e.Level {
|
||||
case Debug:
|
||||
c.Add(color.FgHiBlue)
|
||||
case Info:
|
||||
c.Add(color.FgHiGreen)
|
||||
case Warn:
|
||||
c.Add(color.FgHiYellow)
|
||||
case Error:
|
||||
c.Add(color.FgHiRed)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// An outlet receives log entries produced by the Logger and writes them to some destination.
|
||||
type Outlet interface {
|
||||
// Write the entry to the destination.
|
||||
//
|
||||
// Logger waits for all outlets to return from WriteEntry() before returning from the log call.
|
||||
// An implementation of Outlet must assert that it does not block in WriteEntry.
|
||||
// Otherwise, it will slow down the program.
|
||||
//
|
||||
// Note: os.Stderr is also used by logger.Logger for reporting errors returned by outlets
|
||||
// => you probably don't want to log there
|
||||
WriteEntry(entry Entry) error
|
||||
}
|
||||
|
||||
type Outlets struct {
|
||||
mtx sync.RWMutex
|
||||
outs map[Level][]Outlet
|
||||
}
|
||||
|
||||
func NewOutlets() *Outlets {
|
||||
return &Outlets{
|
||||
mtx: sync.RWMutex{},
|
||||
outs: make(map[Level][]Outlet, len(AllLevels)),
|
||||
}
|
||||
}
|
||||
|
||||
func (os *Outlets) DeepCopy() (copy *Outlets) {
|
||||
copy = NewOutlets()
|
||||
for level := range os.outs {
|
||||
copy.outs[level] = append(copy.outs[level], os.outs[level]...)
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
func (os *Outlets) Add(outlet Outlet, minLevel Level) {
|
||||
os.mtx.Lock()
|
||||
defer os.mtx.Unlock()
|
||||
for _, l := range AllLevels[minLevel:] {
|
||||
os.outs[l] = append(os.outs[l], outlet)
|
||||
}
|
||||
}
|
||||
|
||||
func (os *Outlets) Get(level Level) []Outlet {
|
||||
os.mtx.RLock()
|
||||
defer os.mtx.RUnlock()
|
||||
return os.outs[level]
|
||||
}
|
||||
|
||||
// Return the first outlet added to this Outlets list using Add()
|
||||
// with minLevel <= Error.
|
||||
// If no such outlet is in this Outlets list, a discarding outlet is returned.
|
||||
func (os *Outlets) GetLoggerErrorOutlet() Outlet {
|
||||
os.mtx.RLock()
|
||||
defer os.mtx.RUnlock()
|
||||
if len(os.outs[Error]) < 1 {
|
||||
return nullOutlet{}
|
||||
}
|
||||
return os.outs[Error][0]
|
||||
}
|
||||
|
||||
type nullOutlet struct{}
|
||||
|
||||
func (nullOutlet) WriteEntry(entry Entry) error { return nil }
|
Reference in New Issue
Block a user