wip: log
This commit is contained in:
parent
8a480acde7
commit
5f7befe02c
@ -7,7 +7,11 @@ type Trace struct {
|
||||
}
|
||||
|
||||
func (t *Trace) Error() string {
|
||||
return "[debug trace available]"
|
||||
return ""
|
||||
}
|
||||
|
||||
func (t *Trace) Trace() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetTraces() error {
|
||||
|
||||
@ -3,5 +3,5 @@ package debugframes
|
||||
type PanicTrace []byte
|
||||
|
||||
func (p PanicTrace) Error() string {
|
||||
return "[panic trace available]"
|
||||
return ""
|
||||
}
|
||||
|
||||
27
log/errlog_test.go
Normal file
27
log/errlog_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/rs/zerolog"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrint(t *testing.T) {
|
||||
Print("key", errors.New("hello world"))
|
||||
}
|
||||
|
||||
type testWriter struct {
|
||||
}
|
||||
|
||||
func (t testWriter) Write(b []byte) (int, error) {
|
||||
return 0, errors.New("write error")
|
||||
}
|
||||
|
||||
func TestErrWrite(t *testing.T) {
|
||||
var (
|
||||
tw testWriter
|
||||
logger zerolog.Logger
|
||||
)
|
||||
logger = zerolog.New(tw)
|
||||
logger.Error().Str("test", "one").Msg("hello")
|
||||
}
|
||||
@ -7,17 +7,18 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
path string
|
||||
file *os.File
|
||||
}
|
||||
type File os.File
|
||||
|
||||
const (
|
||||
filenameKey = "file"
|
||||
)
|
||||
|
||||
func NewLogFile(configKey string) (*File, error) {
|
||||
var err error
|
||||
var (
|
||||
err error
|
||||
path string
|
||||
file *os.File
|
||||
)
|
||||
if viper.IsSet(configKey) {
|
||||
return nil, nil
|
||||
}
|
||||
@ -27,22 +28,23 @@ func NewLogFile(configKey string) (*File, error) {
|
||||
return nil, fmt.Errorf("missing file key config %s", fileKey)
|
||||
}
|
||||
|
||||
file := &File{
|
||||
path: viper.GetString(fileKey),
|
||||
}
|
||||
if file.file, err = os.OpenFile(file.path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil {
|
||||
path = viper.GetString(fileKey)
|
||||
if file, err = os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return file, nil
|
||||
return (*File)(file), nil
|
||||
}
|
||||
|
||||
func (f *File) Write(b []byte) (int, error) {
|
||||
return 0, nil
|
||||
var file *os.File
|
||||
file = (*os.File)(f)
|
||||
return file.Write(b)
|
||||
}
|
||||
|
||||
func (f *File) Close() error {
|
||||
return f.file.Close()
|
||||
of := (*os.File)(f)
|
||||
return of.Close()
|
||||
}
|
||||
|
||||
func (f *File) Rotate() error {
|
||||
78
log/log.go
78
log/log.go
@ -1,9 +1,10 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"fmt"
|
||||
"github.com/rs/zerolog"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Level zerolog.Level
|
||||
@ -15,6 +16,11 @@ type ProcessLogConfig interface {
|
||||
FileName() string
|
||||
}
|
||||
|
||||
type Traceable interface {
|
||||
error
|
||||
Trace() []string
|
||||
}
|
||||
|
||||
const (
|
||||
Trace Level = Level(zerolog.TraceLevel)
|
||||
Debug Level = Level(zerolog.DebugLevel)
|
||||
@ -28,42 +34,41 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
globalLevel Level = Error
|
||||
logger zerolog.Logger
|
||||
globalLevel Level = Error
|
||||
logger zerolog.Logger
|
||||
onLogWriterError zerolog.Logger
|
||||
writer *Writer
|
||||
DefaultOutlet io.Writer
|
||||
)
|
||||
|
||||
func init() {
|
||||
DefaultOutlet = os.Stderr
|
||||
writer = NewWriter()
|
||||
logger = zerolog.New(writer)
|
||||
onLogWriterError = logger.Output(DefaultOutlet)
|
||||
SetGlobalLevel(globalLevel)
|
||||
logger = zerolog.New(os.Stderr)
|
||||
}
|
||||
|
||||
func (l Level) Print(a ...any) {
|
||||
// var event *zerolog.Event
|
||||
// for _, i := range a {
|
||||
// if event == nil {
|
||||
// event = logger.WithLevel(zerolog.Level(l))
|
||||
// }
|
||||
// switch v := i.(type) {
|
||||
// case daemon.ProcessLogEntry:
|
||||
// event = event.Str("type", v.Descriptor.InstanceType().String()).Str("origin", "child process").
|
||||
// Str("name", v.Descriptor.Name())
|
||||
// if v.Descriptor.InstanceType() == daemon.Cron {
|
||||
// event = event.Str("instance_name", v.Descriptor.InstanceName())
|
||||
// }
|
||||
// event.Str("entry", v.LogEntry).Send()
|
||||
// event = nil
|
||||
// //TODO: add logic to process cron or service specific log config
|
||||
// }
|
||||
// }
|
||||
l.Fields(a...).Send()
|
||||
}
|
||||
|
||||
func (l Level) Fields(a ...any) *Payload {
|
||||
func (l Level) PrintTo(outlets []io.Writer, a ...any) {
|
||||
l.Fields(a...).Send(outlets...)
|
||||
}
|
||||
|
||||
func (l Level) Fields(a ...any) (p *Payload) {
|
||||
p = (*Payload)(logger.WithLevel(zerolog.Level(l)).Timestamp())
|
||||
return p.Fields(a...)
|
||||
}
|
||||
|
||||
func (p *Payload) Fields(a ...any) *Payload {
|
||||
var (
|
||||
event *zerolog.Event
|
||||
key string
|
||||
)
|
||||
|
||||
event = logger.WithLevel(zerolog.Level(l))
|
||||
event = (*zerolog.Event)(p)
|
||||
for i, part := range a {
|
||||
if i%2 == 0 {
|
||||
key = part.(string)
|
||||
@ -71,16 +76,39 @@ func (l Level) Fields(a ...any) *Payload {
|
||||
switch v := part.(type) {
|
||||
case string:
|
||||
event = event.Str(key, v)
|
||||
case error:
|
||||
event = event.Err(v)
|
||||
|
||||
default:
|
||||
event = event.Str(key, fmt.Sprintf("[no data type handle] %v", v))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return (*Payload)(event)
|
||||
}
|
||||
|
||||
func (p *Payload) Send(ws ...io.Writer) {
|
||||
event := (*zerolog.Event)(p)
|
||||
|
||||
writer.Lock()
|
||||
defer writer.Unlock()
|
||||
|
||||
if len(ws) == 0 {
|
||||
writer.Writers(DefaultOutlet)
|
||||
} else {
|
||||
writer.Writers(ws...)
|
||||
}
|
||||
event.Send()
|
||||
}
|
||||
|
||||
func Print(a ...any) {
|
||||
globalLevel.Print(a...)
|
||||
}
|
||||
|
||||
func PrintTo(outlets []io.Writer, a ...any) {
|
||||
globalLevel.PrintTo(outlets, a...)
|
||||
}
|
||||
|
||||
func SetGlobalLevel(l Level) {
|
||||
globalLevel = l
|
||||
zerolog.SetGlobalLevel(zerolog.Level(globalLevel))
|
||||
|
||||
@ -1,31 +1,90 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Writer struct {
|
||||
writer io.Writer
|
||||
mtx *sync.Mutex
|
||||
} //TODO: create a writer implementation using this struct, ensure sync and prevent abrupt truncation when stopping
|
||||
var (
|
||||
noError = errors.New("no error")
|
||||
ec = make(chan error)
|
||||
)
|
||||
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
type Writer struct {
|
||||
writers []io.Writer
|
||||
mtx *sync.Mutex
|
||||
}
|
||||
|
||||
func NewWriter() *Writer {
|
||||
return &Writer{
|
||||
writer: w,
|
||||
mtx: &sync.Mutex{},
|
||||
writers: make([]io.Writer, 0),
|
||||
mtx: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Writer) Write(b []byte) (int, error) {
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
return w.writer.Write(b)
|
||||
}
|
||||
var (
|
||||
ctr int
|
||||
sw io.Writer
|
||||
err error
|
||||
)
|
||||
|
||||
func (w *Writer) Close() {
|
||||
if wc, ok := w.writer.(io.WriteCloser); ok {
|
||||
_ = wc.Close()
|
||||
for _, ww := range w.writers {
|
||||
if ww == DefaultOutlet {
|
||||
sw = ww
|
||||
} else {
|
||||
ctr++
|
||||
go subWriter(ww, b, ec)
|
||||
}
|
||||
}
|
||||
|
||||
if sw != nil {
|
||||
_, _ = sw.Write(b)
|
||||
}
|
||||
|
||||
for i := 0; i < ctr; i++ {
|
||||
if err = <-ec; err != noError {
|
||||
onLogWriterError.Error().Err(err).Msg("subWriter error")
|
||||
}
|
||||
}
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (w *Writer) Lock() {
|
||||
w.mtx.Lock()
|
||||
}
|
||||
|
||||
func (w *Writer) Unlock() {
|
||||
w.writers[0] = DefaultOutlet
|
||||
w.writers = w.writers[:1]
|
||||
w.mtx.Unlock()
|
||||
}
|
||||
|
||||
func (w *Writer) Writers(ws ...io.Writer) {
|
||||
if len(ws) == 0 {
|
||||
w.writers[0] = DefaultOutlet
|
||||
w.writers = w.writers[:1]
|
||||
} else {
|
||||
w.writers = append(w.writers, ws...)
|
||||
}
|
||||
}
|
||||
|
||||
func subWriter(w io.Writer, b []byte, errchan chan<- error) {
|
||||
defer func() {
|
||||
if o := recover(); o != nil {
|
||||
errchan <- fmt.Errorf("subWriter panic: %v", o)
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err := w.Write(b); err != nil {
|
||||
errchan <- err
|
||||
} else {
|
||||
errchan <- noError
|
||||
}
|
||||
}
|
||||
|
||||
//func (w *Writer) Close() {
|
||||
//}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user