mirror of
https://github.com/taigrr/log-socket
synced 2026-03-20 18:22:24 -07:00
enable namespaced logging
This commit is contained in:
70
log/log.go
70
log/log.go
@@ -16,10 +16,13 @@ var (
|
||||
stderrClient *Client
|
||||
cleanup sync.Once
|
||||
stderrFinished chan bool
|
||||
namespaces map[string]bool
|
||||
namespacesMux sync.RWMutex
|
||||
)
|
||||
|
||||
func init() {
|
||||
stderrClient = CreateClient()
|
||||
namespaces = make(map[string]bool)
|
||||
stderrClient = CreateClient(DefaultNamespace)
|
||||
stderrClient.SetLogLevel(LTrace)
|
||||
stderrFinished = make(chan bool, 1)
|
||||
go stderrClient.logStdErr()
|
||||
@@ -27,16 +30,30 @@ func init() {
|
||||
|
||||
func (c *Client) logStdErr() {
|
||||
for e := range c.writer {
|
||||
if e.level >= c.LogLevel {
|
||||
fmt.Fprintf(os.Stderr, "%s\t%s\t%s\t%s\n", e.Timestamp.String(), e.Level, e.Output, e.File)
|
||||
if e.level >= c.LogLevel && c.matchesNamespace(e.Namespace) {
|
||||
fmt.Fprintf(os.Stderr, "%s\t%s\t[%s]\t%s\t%s\n", e.Timestamp.String(), e.Level, e.Namespace, e.Output, e.File)
|
||||
}
|
||||
}
|
||||
stderrFinished <- true
|
||||
}
|
||||
|
||||
func CreateClient() *Client {
|
||||
func (c *Client) matchesNamespace(namespace string) bool {
|
||||
// Empty Namespaces slice means match all
|
||||
if len(c.Namespaces) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, ns := range c.Namespaces {
|
||||
if ns == namespace {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func CreateClient(namespaces ...string) *Client {
|
||||
var client Client
|
||||
client.initialized = true
|
||||
client.Namespaces = namespaces
|
||||
client.writer = make(LogWriter, 1000)
|
||||
sliceTex.Lock()
|
||||
clients = append(clients, &client)
|
||||
@@ -78,9 +95,18 @@ func (c *Client) GetLogLevel() Level {
|
||||
}
|
||||
|
||||
func createLog(e Entry) {
|
||||
// Track namespace
|
||||
namespacesMux.Lock()
|
||||
namespaces[e.Namespace] = true
|
||||
namespacesMux.Unlock()
|
||||
|
||||
sliceTex.Lock()
|
||||
for _, c := range clients {
|
||||
func(c *Client, e Entry) {
|
||||
// Filter by namespace if client has filters specified
|
||||
if !c.matchesNamespace(e.Namespace) {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case c.writer <- e:
|
||||
// try to clear out one of the older entries
|
||||
@@ -96,6 +122,18 @@ func createLog(e Entry) {
|
||||
sliceTex.Unlock()
|
||||
}
|
||||
|
||||
// GetNamespaces returns a list of all namespaces that have been used
|
||||
func GetNamespaces() []string {
|
||||
namespacesMux.RLock()
|
||||
defer namespacesMux.RUnlock()
|
||||
|
||||
result := make([]string, 0, len(namespaces))
|
||||
for ns := range namespaces {
|
||||
result = append(result, ns)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func SetLogLevel(level Level) {
|
||||
stderrClient.LogLevel = level
|
||||
}
|
||||
@@ -123,6 +161,7 @@ func Trace(args ...any) {
|
||||
Output: output,
|
||||
File: fileInfo(2),
|
||||
Level: "TRACE",
|
||||
Namespace: DefaultNamespace,
|
||||
level: LTrace,
|
||||
}
|
||||
createLog(e)
|
||||
@@ -137,6 +176,7 @@ func Tracef(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "TRACE",
|
||||
level: LTrace,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -150,6 +190,7 @@ func Traceln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "TRACE",
|
||||
level: LTrace,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -163,6 +204,7 @@ func Debug(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "DEBUG",
|
||||
level: LDebug,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -176,6 +218,7 @@ func Debugf(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "DEBUG",
|
||||
level: LDebug,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -189,6 +232,7 @@ func Debugln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "DEBUG",
|
||||
level: LDebug,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -202,6 +246,7 @@ func Info(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "INFO",
|
||||
level: LInfo,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -215,6 +260,7 @@ func Infof(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "INFO",
|
||||
level: LInfo,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -228,6 +274,7 @@ func Infoln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "INFO",
|
||||
level: LInfo,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -241,6 +288,7 @@ func Notice(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "NOTICE",
|
||||
level: LNotice,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -254,6 +302,7 @@ func Noticef(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "NOTICE",
|
||||
level: LNotice,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -267,6 +316,7 @@ func Noticeln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "NOTICE",
|
||||
level: LNotice,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -280,6 +330,7 @@ func Warn(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "WARN",
|
||||
level: LWarn,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -293,6 +344,7 @@ func Warnf(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "WARN",
|
||||
level: LWarn,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -306,6 +358,7 @@ func Warnln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "WARN",
|
||||
level: LWarn,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -319,6 +372,7 @@ func Error(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "ERROR",
|
||||
level: LError,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -332,6 +386,7 @@ func Errorf(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "ERROR",
|
||||
level: LError,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -345,6 +400,7 @@ func Errorln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "ERROR",
|
||||
level: LError,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -358,6 +414,7 @@ func Panic(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "PANIC",
|
||||
level: LPanic,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
if len(args) >= 0 {
|
||||
@@ -381,6 +438,7 @@ func Panicf(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "PANIC",
|
||||
level: LPanic,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
if len(args) >= 0 {
|
||||
@@ -403,6 +461,7 @@ func Panicln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "PANIC",
|
||||
level: LPanic,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
if len(args) >= 0 {
|
||||
@@ -426,6 +485,7 @@ func Fatal(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "FATAL",
|
||||
level: LFatal,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
Flush()
|
||||
@@ -441,6 +501,7 @@ func Fatalf(format string, args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "FATAL",
|
||||
level: LFatal,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
Flush()
|
||||
@@ -455,6 +516,7 @@ func Fatalln(args ...any) {
|
||||
File: fileInfo(2),
|
||||
Level: "FATAL",
|
||||
level: LFatal,
|
||||
Namespace: DefaultNamespace,
|
||||
}
|
||||
createLog(e)
|
||||
Flush()
|
||||
|
||||
@@ -13,7 +13,7 @@ func TestCreateDestroy(t *testing.T) {
|
||||
t.Errorf("Expected 1 client, but found %d", len(clients))
|
||||
}
|
||||
// Create a new client, ensure it's added
|
||||
c := CreateClient()
|
||||
c := CreateClient("test")
|
||||
if len(clients) != 2 {
|
||||
t.Errorf("Expected 2 clients, but found %d", len(clients))
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func TestCreateDestroy(t *testing.T) {
|
||||
// SetLogLevel set log level of logger
|
||||
func TestSetLogLevel(t *testing.T) {
|
||||
logLevels := [...]Level{LTrace, LDebug, LInfo, LWarn, LError, LPanic, LFatal}
|
||||
c := CreateClient()
|
||||
c := CreateClient("test")
|
||||
for _, x := range logLevels {
|
||||
c.SetLogLevel(x)
|
||||
if c.GetLogLevel() != x {
|
||||
@@ -38,7 +38,7 @@ func TestSetLogLevel(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkDebugSerial(b *testing.B) {
|
||||
c := CreateClient()
|
||||
c := CreateClient("test")
|
||||
var x sync.WaitGroup
|
||||
x.Add(b.N)
|
||||
for i := 0; i < b.N; i++ {
|
||||
@@ -55,7 +55,7 @@ func BenchmarkDebugSerial(b *testing.B) {
|
||||
// Trace ensure logs come out in the right order
|
||||
func TestOrder(t *testing.T) {
|
||||
testString := "Testing trace: "
|
||||
c := CreateClient()
|
||||
c := CreateClient(DefaultNamespace)
|
||||
c.SetLogLevel(LTrace)
|
||||
|
||||
for i := 0; i < 5000; i++ {
|
||||
|
||||
@@ -8,7 +8,14 @@ import (
|
||||
)
|
||||
|
||||
func Default() *Logger {
|
||||
return &Logger{FileInfoDepth: 0}
|
||||
return &Logger{FileInfoDepth: 0, Namespace: DefaultNamespace}
|
||||
}
|
||||
|
||||
func NewLogger(namespace string) *Logger {
|
||||
if namespace == "" {
|
||||
namespace = DefaultNamespace
|
||||
}
|
||||
return &Logger{FileInfoDepth: 0, Namespace: namespace}
|
||||
}
|
||||
|
||||
func (l *Logger) SetInfoDepth(depth int) {
|
||||
@@ -24,6 +31,7 @@ func (l Logger) Trace(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "TRACE",
|
||||
level: LTrace,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -37,6 +45,7 @@ func (l Logger) Tracef(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "TRACE",
|
||||
level: LTrace,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -50,6 +59,7 @@ func (l Logger) Traceln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "TRACE",
|
||||
level: LTrace,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -63,6 +73,7 @@ func (l Logger) Debug(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "DEBUG",
|
||||
level: LDebug,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -76,6 +87,7 @@ func (l Logger) Debugf(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "DEBUG",
|
||||
level: LDebug,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -89,6 +101,7 @@ func (l Logger) Info(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "INFO",
|
||||
level: LInfo,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -102,6 +115,7 @@ func (l Logger) Infof(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "INFO",
|
||||
level: LInfo,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -115,6 +129,7 @@ func (l Logger) Infoln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "INFO",
|
||||
level: LInfo,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -128,6 +143,7 @@ func (l Logger) Notice(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "NOTICE",
|
||||
level: LNotice,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -141,6 +157,7 @@ func (l Logger) Noticef(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "NOTICE",
|
||||
level: LNotice,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -154,6 +171,7 @@ func (l Logger) Noticeln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "NOTICE",
|
||||
level: LNotice,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -167,6 +185,7 @@ func (l Logger) Warn(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "WARN",
|
||||
level: LWarn,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -180,6 +199,7 @@ func (l Logger) Warnf(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "WARN",
|
||||
level: LWarn,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -193,6 +213,7 @@ func (l Logger) Warnln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "WARN",
|
||||
level: LWarn,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -206,6 +227,7 @@ func (l Logger) Error(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "ERROR",
|
||||
level: LError,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -219,6 +241,7 @@ func (l Logger) Errorf(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "ERROR",
|
||||
level: LError,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -232,6 +255,7 @@ func (l Logger) Errorln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "ERROR",
|
||||
level: LError,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
}
|
||||
@@ -245,6 +269,7 @@ func (l Logger) Panic(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "PANIC",
|
||||
level: LPanic,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
if len(args) >= 0 {
|
||||
@@ -268,6 +293,7 @@ func (l Logger) Panicf(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "PANIC",
|
||||
level: LPanic,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
if len(args) >= 0 {
|
||||
@@ -291,6 +317,7 @@ func (l Logger) Panicln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "PANIC",
|
||||
level: LPanic,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
if len(args) >= 0 {
|
||||
@@ -314,6 +341,7 @@ func (l Logger) Fatal(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "FATAL",
|
||||
level: LFatal,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
Flush()
|
||||
@@ -329,6 +357,7 @@ func (l Logger) Fatalf(format string, args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "FATAL",
|
||||
level: LFatal,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
Flush()
|
||||
@@ -344,6 +373,7 @@ func (l Logger) Fatalln(args ...any) {
|
||||
File: fileInfo(l.FileInfoDepth),
|
||||
Level: "FATAL",
|
||||
level: LFatal,
|
||||
Namespace: l.Namespace,
|
||||
}
|
||||
createLog(e)
|
||||
Flush()
|
||||
|
||||
@@ -13,12 +13,15 @@ const (
|
||||
LFatal
|
||||
)
|
||||
|
||||
const DefaultNamespace = "default"
|
||||
|
||||
type (
|
||||
LogWriter chan Entry
|
||||
Level int
|
||||
|
||||
Client struct {
|
||||
LogLevel Level `json:"level"`
|
||||
LogLevel Level `json:"level"`
|
||||
Namespaces []string `json:"namespaces"` // Empty slice means all namespaces
|
||||
writer LogWriter
|
||||
initialized bool
|
||||
}
|
||||
@@ -27,9 +30,11 @@ type (
|
||||
Output string `json:"output"`
|
||||
File string `json:"file"`
|
||||
Level string `json:"level"`
|
||||
Namespace string `json:"namespace"`
|
||||
level Level
|
||||
}
|
||||
Logger struct {
|
||||
FileInfoDepth int
|
||||
Namespace string
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user