92 lines
1.6 KiB
Go
92 lines
1.6 KiB
Go
package logging
|
|
|
|
import (
|
|
"io"
|
|
"sync"
|
|
)
|
|
|
|
type writerIndent struct{}
|
|
|
|
var indentKey = writerIndent{}
|
|
|
|
func getIndent(writer io.Writer) int {
|
|
value, ok := getKey(writer, indentKey)
|
|
if !ok {
|
|
value = 0
|
|
}
|
|
return value.(int)
|
|
}
|
|
|
|
func incIndent(writer io.Writer) int {
|
|
value, ok := upsetKey(writer, indentKey, func(value any, fresh bool) any {
|
|
if fresh {
|
|
return 0
|
|
}
|
|
return value.(int) + 1
|
|
})
|
|
if !ok {
|
|
return 0
|
|
}
|
|
return value.(int)
|
|
}
|
|
|
|
func decIndent(writer io.Writer) int {
|
|
value, ok := upsetKey(writer, indentKey, func(value any, fresh bool) any {
|
|
if fresh {
|
|
return 0
|
|
}
|
|
level := value.(int) - 1
|
|
if level < 0 {
|
|
level = 0
|
|
}
|
|
return level
|
|
})
|
|
if !ok {
|
|
return 0
|
|
}
|
|
return value.(int)
|
|
}
|
|
|
|
// KEY-VALUE STORE for writers
|
|
|
|
var writerDataMutex sync.RWMutex
|
|
var writerDataData = make(map[uintptr]map[any]any)
|
|
|
|
func getKey(writer io.Writer, key any) (value any, ok bool) {
|
|
uid, ok := id(writer)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
writerDataMutex.RLock()
|
|
defer writerDataMutex.RUnlock()
|
|
|
|
value, ok = writerDataData[uid][key]
|
|
return
|
|
}
|
|
|
|
func upsetKey(writer io.Writer, key any, update func(value any, fresh bool) any) (any, bool) {
|
|
uid, ok := id(writer)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
writerDataMutex.Lock()
|
|
defer writerDataMutex.Unlock()
|
|
|
|
values, ok := writerDataData[uid]
|
|
if !ok {
|
|
values = make(map[any]any)
|
|
writerDataData[uid] = values
|
|
}
|
|
values[key] = update(values[key], !ok)
|
|
return values[key], true
|
|
}
|
|
|
|
func id(writer io.Writer) (uintptr, bool) {
|
|
file, ok := writer.(interface{ Fd() uintptr })
|
|
if !ok {
|
|
return 0, false
|
|
}
|
|
return file.Fd(), true
|
|
}
|