Files
2026-01-28 15:01:35 -05:00

135 lines
2.7 KiB
Go

package logcontext
import (
"fmt"
"github.com/michaelquigley/pfxlog"
"github.com/sirupsen/logrus"
)
const (
SelectPath = "selectPath"
EstablishPath = "establishPath"
MaskSelectPath = uint32(1)
MaskEstablishPath = uint32(2)
)
var channelMap = map[string]uint32{}
func init() {
channelMap[SelectPath] = MaskSelectPath
channelMap[EstablishPath] = MaskEstablishPath
}
func GetChannelMask(s string) uint32 {
return channelMap[s]
}
func getDebugLogger() *logrus.Logger {
return pfxlog.LevelLogger(logrus.DebugLevel)
}
type Context interface {
pfxlog.Wirer
SetChannelsMask(s uint32)
GetChannelsMask() uint32
GetFields() map[string]interface{}
GetStringFields() map[string]string
WithFields(fields map[string]interface{}) Context
WithField(field string, value interface{}) Context
Clone() Context
}
func NewContext() Context {
return &contextImpl{
fields: map[string]interface{}{},
}
}
func NewContextWith(channelMask uint32, fields map[string]string) Context {
result := &contextImpl{
channels: channelMask,
fields: map[string]interface{}{},
}
for k, v := range fields {
result.fields[k] = v
}
return result
}
type contextImpl struct {
channels uint32
fields map[string]interface{}
}
func (self *contextImpl) WireEntry(entry *logrus.Entry) *logrus.Entry {
if self != nil {
if len(self.fields) > 0 {
entry = entry.WithFields(self.fields)
}
if self.channels != 0 && entry.Level < logrus.DebugLevel {
if val, found := entry.Data["channels"]; found {
if channels, ok := val.([]string); ok {
for _, channel := range channels {
s := channelMap[channel]
if s&self.channels != 0 {
entry.Logger = getDebugLogger()
break
}
}
}
}
}
}
return entry
}
func (self *contextImpl) GetChannelsMask() uint32 {
return self.channels
}
func (self *contextImpl) SetChannelsMask(s uint32) {
self.channels = s
}
func (self *contextImpl) GetFields() map[string]interface{} {
return self.fields
}
func (self *contextImpl) GetStringFields() map[string]string {
result := map[string]string{}
for k, v := range self.fields {
if s, ok := v.(string); ok {
result[k] = s
} else {
result[k] = fmt.Sprintf("%v", v)
}
}
return result
}
func (self *contextImpl) WithFields(fields map[string]interface{}) Context {
for k, v := range fields {
self.fields[k] = v
}
return self
}
func (self *contextImpl) WithField(k string, v interface{}) Context {
self.fields[k] = v
return self
}
func (self *contextImpl) Clone() Context {
result := &contextImpl{
channels: self.channels,
fields: map[string]interface{}{},
}
for k, v := range self.fields {
result.fields[k] = v
}
return result
}