zerr: integration with slog logger
This commit is contained in:
parent
4c951daa41
commit
f1b7598e1e
|
@ -1,7 +1,10 @@
|
||||||
package zcaller
|
package zcaller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Current returns the ProgramCounter of the caller.
|
// Current returns the ProgramCounter of the caller.
|
||||||
|
@ -38,3 +41,48 @@ func Frame(pc uintptr) runtime.Frame {
|
||||||
frame, _ := frames.Next()
|
frame, _ := frames.Next()
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Caller represents the caller of a function.
|
||||||
|
//
|
||||||
|
// It gives helper methods to get the caller's information.
|
||||||
|
type Caller uintptr
|
||||||
|
|
||||||
|
func (ca Caller) LogValue() slog.Value {
|
||||||
|
if ca == 0 {
|
||||||
|
return slog.AnyValue(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ca.Frame().LogValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ca Caller) Frame() RuntimeFrame {
|
||||||
|
return RuntimeFrame{Frame(uintptr(ca))}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuntimeFrame struct {
|
||||||
|
runtime.Frame
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ru RuntimeFrame) LogValue() slog.Value {
|
||||||
|
return slog.GroupValue(
|
||||||
|
slog.String("file", ru.ShortFile()),
|
||||||
|
slog.Int("line", ru.Line),
|
||||||
|
slog.String("function", ru.ShortFunction()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f RuntimeFrame) ShortFile() string {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return f.File
|
||||||
|
}
|
||||||
|
if after, found := strings.CutPrefix(f.File, wd); found {
|
||||||
|
return strings.TrimPrefix(after, string(os.PathSeparator))
|
||||||
|
}
|
||||||
|
return f.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f RuntimeFrame) ShortFunction() string {
|
||||||
|
split := strings.Split(f.Function, string(os.PathSeparator))
|
||||||
|
return split[len(split)-1]
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"connectrpc.com/connect"
|
"connectrpc.com/connect"
|
||||||
"github.com/pborman/indent"
|
"github.com/pborman/indent"
|
||||||
|
"gitlab.bareksa.com/backend/zen/core/zcaller"
|
||||||
"gitlab.bareksa.com/backend/zen/core/zoptions"
|
"gitlab.bareksa.com/backend/zen/core/zoptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -91,6 +92,9 @@ func (mu *Err) Error() string {
|
||||||
|
|
||||||
// LogValue returns log fields to be consumed by logger.
|
// LogValue returns log fields to be consumed by logger.
|
||||||
func (mu *Err) LogValue() slog.Value {
|
func (mu *Err) LogValue() slog.Value {
|
||||||
|
if len(mu.errs) == 0 {
|
||||||
|
return slog.AnyValue(nil)
|
||||||
|
}
|
||||||
attrs := make([]slog.Attr, 0, 8)
|
attrs := make([]slog.Attr, 0, 8)
|
||||||
if len(mu.message) > 0 {
|
if len(mu.message) > 0 {
|
||||||
attrs = append(attrs, slog.String("message", mu.message))
|
attrs = append(attrs, slog.String("message", mu.message))
|
||||||
|
@ -98,13 +102,46 @@ func (mu *Err) LogValue() slog.Value {
|
||||||
if len(mu.publicMessage) > 0 {
|
if len(mu.publicMessage) > 0 {
|
||||||
attrs = append(attrs, slog.String("public", mu.message))
|
attrs = append(attrs, slog.String("public", mu.message))
|
||||||
}
|
}
|
||||||
|
if len(mu.id) > 0 {
|
||||||
|
attrs = append(attrs, slog.String("id", mu.id))
|
||||||
|
}
|
||||||
if mu.code != connect.CodeUnknown && mu.code != connect.CodeInternal {
|
if mu.code != connect.CodeUnknown && mu.code != connect.CodeInternal {
|
||||||
attrs = append(attrs, slog.String("code", mu.code.String()))
|
attrs = append(attrs, slog.String("code", mu.code.String()))
|
||||||
}
|
}
|
||||||
if mu.sequence.IsRoot() {
|
if mu.caller != 0 {
|
||||||
|
attrs = append(attrs, slog.Attr{Key: "caller", Value: zcaller.Caller(mu.caller).LogValue()})
|
||||||
|
}
|
||||||
|
attrs = append(attrs, slog.Attr{Key: "error", Value: mu.RootErrorLog()})
|
||||||
|
return slog.GroupValue(attrs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mu *Err) LogRecord() slog.Record {
|
||||||
|
record := slog.NewRecord(mu.GetTime(), slog.LevelError, mu.GetMessage(), mu.GetCaller())
|
||||||
|
code := mu.GetCode()
|
||||||
|
if public := mu.GetPublicMessage(); public != "" {
|
||||||
|
record.AddAttrs(slog.String("public", public))
|
||||||
|
}
|
||||||
|
if code != 0 && code != connect.CodeUnknown && code != connect.CodeInternal {
|
||||||
|
record.AddAttrs(slog.String("code", code.String()))
|
||||||
|
}
|
||||||
|
if id := mu.GetID(); id != "" {
|
||||||
|
record.AddAttrs(slog.String("id", id))
|
||||||
|
}
|
||||||
|
if len(mu.GetDetails()) > 0 {
|
||||||
|
record.AddAttrs(slog.Group("details", mu.GetDetails()...))
|
||||||
|
}
|
||||||
|
record.AddAttrs(slog.Attr{Key: "error", Value: mu.RootErrorLog()})
|
||||||
|
return record
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mu *Err) RootErrorLog() slog.Value {
|
||||||
|
if len(mu.errs) == 0 {
|
||||||
|
return slog.AnyValue(nil)
|
||||||
}
|
}
|
||||||
if len(mu.errs) == 1 {
|
if len(mu.errs) == 1 {
|
||||||
|
return errorValuer{mu.errs[0]}.LogValue()
|
||||||
}
|
}
|
||||||
|
attrs := make([]slog.Attr, 0, len(mu.errs))
|
||||||
i := 0
|
i := 0
|
||||||
for _, err := range mu.errs {
|
for _, err := range mu.errs {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -13,6 +13,8 @@ type Error interface {
|
||||||
error
|
error
|
||||||
// LogValue returns log fields to be consumed by logger.
|
// LogValue returns log fields to be consumed by logger.
|
||||||
LogValue() slog.Value
|
LogValue() slog.Value
|
||||||
|
// LogRecord returns log records to be consumed by logger.
|
||||||
|
LogRecord() slog.Record
|
||||||
|
|
||||||
// Code sets error code.
|
// Code sets error code.
|
||||||
Code(code connect.Code) Error
|
Code(code connect.Code) Error
|
||||||
|
|
|
@ -1,53 +1 @@
|
||||||
package zlog
|
package zlog
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"gitlab.bareksa.com/backend/zen/core/zcaller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Caller represents the caller of a function.
|
|
||||||
//
|
|
||||||
// It gives helper methods to get the caller's information.
|
|
||||||
type Caller uintptr
|
|
||||||
|
|
||||||
func (ca Caller) LogValue() slog.Value {
|
|
||||||
if ca == 0 {
|
|
||||||
return slog.AnyValue(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
f := frame{ca.Frame()}
|
|
||||||
|
|
||||||
return slog.GroupValue(
|
|
||||||
slog.String("file", f.ShortFile()),
|
|
||||||
slog.Int("line", f.Line),
|
|
||||||
slog.String("function", f.ShortFunction()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ca Caller) Frame() runtime.Frame {
|
|
||||||
return zcaller.Frame(uintptr(ca))
|
|
||||||
}
|
|
||||||
|
|
||||||
type frame struct {
|
|
||||||
runtime.Frame
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f frame) ShortFile() string {
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return f.File
|
|
||||||
}
|
|
||||||
if after, found := strings.CutPrefix(f.File, wd); found {
|
|
||||||
return strings.TrimPrefix(after, string(os.PathSeparator))
|
|
||||||
}
|
|
||||||
return f.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f frame) ShortFunction() string {
|
|
||||||
split := strings.Split(f.Function, string(os.PathSeparator))
|
|
||||||
return split[len(split)-1]
|
|
||||||
}
|
|
||||||
|
|
11
core/zlog/error.go
Normal file
11
core/zlog/error.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package zlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gitlab.bareksa.com/backend/zen/core/zerr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (zl *ZLog) LogError(ctx context.Context, err zerr.Error) {
|
||||||
|
LogRecord(ctx, err.LogRecord())
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/tidwall/pretty"
|
"github.com/tidwall/pretty"
|
||||||
|
"gitlab.bareksa.com/backend/zen/core/zcaller"
|
||||||
"gitlab.bareksa.com/backend/zen/internal/bufferpool"
|
"gitlab.bareksa.com/backend/zen/internal/bufferpool"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ func (lo *ZLog) Handle(ctx context.Context, record slog.Record) error {
|
||||||
defer buf.Close()
|
defer buf.Close()
|
||||||
|
|
||||||
if record.PC != 0 && lo.opts.HandlerOptions.AddSource {
|
if record.PC != 0 && lo.opts.HandlerOptions.AddSource {
|
||||||
f := frame{Caller(record.PC).Frame()}
|
f := zcaller.Caller(record.PC).Frame()
|
||||||
levelColor.Fprint(buf, f.ShortFile())
|
levelColor.Fprint(buf, f.ShortFile())
|
||||||
levelColor.Fprint(buf, ":")
|
levelColor.Fprint(buf, ":")
|
||||||
levelColor.Fprint(buf, f.Line)
|
levelColor.Fprint(buf, f.Line)
|
||||||
|
|
3
core/ztelemetry/service.go
Normal file
3
core/ztelemetry/service.go
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package ztelemetry
|
||||||
|
|
||||||
|
type ServiceMetadata struct{}
|
Loading…
Reference in a new issue