mirror of
https://github.com/bluenviron/mediamtx
synced 2024-12-16 03:34:45 +00:00
158 lines
3.0 KiB
Go
158 lines
3.0 KiB
Go
// Package logger contains a logger implementation.
|
|
package logger
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gookit/color"
|
|
)
|
|
|
|
// Logger is a log handler.
|
|
type Logger struct {
|
|
level Level
|
|
|
|
destinations []destination
|
|
mutex sync.Mutex
|
|
}
|
|
|
|
// New allocates a log handler.
|
|
func New(level Level, destinations []Destination, filePath string) (*Logger, error) {
|
|
lh := &Logger{
|
|
level: level,
|
|
}
|
|
|
|
for _, destType := range destinations {
|
|
switch destType {
|
|
case DestinationStdout:
|
|
lh.destinations = append(lh.destinations, newDestionationStdout())
|
|
|
|
case DestinationFile:
|
|
dest, err := newDestinationFile(filePath)
|
|
if err != nil {
|
|
lh.Close()
|
|
return nil, err
|
|
}
|
|
lh.destinations = append(lh.destinations, dest)
|
|
|
|
case DestinationSyslog:
|
|
dest, err := newDestinationSyslog()
|
|
if err != nil {
|
|
lh.Close()
|
|
return nil, err
|
|
}
|
|
lh.destinations = append(lh.destinations, dest)
|
|
}
|
|
}
|
|
|
|
return lh, nil
|
|
}
|
|
|
|
// Close closes a log handler.
|
|
func (lh *Logger) Close() {
|
|
for _, dest := range lh.destinations {
|
|
dest.close()
|
|
}
|
|
}
|
|
|
|
// https://golang.org/src/log/log.go#L78
|
|
func itoa(i int, wid int) []byte {
|
|
// Assemble decimal in reverse order.
|
|
var b [20]byte
|
|
bp := len(b) - 1
|
|
for i >= 10 || wid > 1 {
|
|
wid--
|
|
q := i / 10
|
|
b[bp] = byte('0' + i - q*10)
|
|
bp--
|
|
i = q
|
|
}
|
|
// i < 10
|
|
b[bp] = byte('0' + i)
|
|
return b[bp:]
|
|
}
|
|
|
|
func writeTime(buf *bytes.Buffer, t time.Time, useColor bool) {
|
|
var intbuf bytes.Buffer
|
|
|
|
// date
|
|
year, month, day := t.Date()
|
|
intbuf.Write(itoa(year, 4))
|
|
intbuf.WriteByte('/')
|
|
intbuf.Write(itoa(int(month), 2))
|
|
intbuf.WriteByte('/')
|
|
intbuf.Write(itoa(day, 2))
|
|
intbuf.WriteByte(' ')
|
|
|
|
// time
|
|
hour, min, sec := t.Clock()
|
|
intbuf.Write(itoa(hour, 2))
|
|
intbuf.WriteByte(':')
|
|
intbuf.Write(itoa(min, 2))
|
|
intbuf.WriteByte(':')
|
|
intbuf.Write(itoa(sec, 2))
|
|
intbuf.WriteByte(' ')
|
|
|
|
if useColor {
|
|
buf.WriteString(color.RenderString(color.Gray.Code(), intbuf.String()))
|
|
} else {
|
|
buf.WriteString(intbuf.String())
|
|
}
|
|
}
|
|
|
|
func writeLevel(buf *bytes.Buffer, level Level, useColor bool) {
|
|
switch level {
|
|
case Debug:
|
|
if useColor {
|
|
buf.WriteString(color.RenderString(color.Debug.Code(), "DEB"))
|
|
} else {
|
|
buf.WriteString("DEB")
|
|
}
|
|
|
|
case Info:
|
|
if useColor {
|
|
buf.WriteString(color.RenderString(color.Green.Code(), "INF"))
|
|
} else {
|
|
buf.WriteString("INF")
|
|
}
|
|
|
|
case Warn:
|
|
if useColor {
|
|
buf.WriteString(color.RenderString(color.Warn.Code(), "WAR"))
|
|
} else {
|
|
buf.WriteString("WAR")
|
|
}
|
|
|
|
case Error:
|
|
if useColor {
|
|
buf.WriteString(color.RenderString(color.Error.Code(), "ERR"))
|
|
} else {
|
|
buf.WriteString("ERR")
|
|
}
|
|
}
|
|
buf.WriteByte(' ')
|
|
}
|
|
|
|
func writeContent(buf *bytes.Buffer, format string, args []interface{}) {
|
|
buf.Write([]byte(fmt.Sprintf(format, args...)))
|
|
buf.WriteByte('\n')
|
|
}
|
|
|
|
// Log writes a log entry.
|
|
func (lh *Logger) Log(level Level, format string, args ...interface{}) {
|
|
if level < lh.level {
|
|
return
|
|
}
|
|
|
|
lh.mutex.Lock()
|
|
defer lh.mutex.Unlock()
|
|
|
|
t := time.Now()
|
|
|
|
for _, dest := range lh.destinations {
|
|
dest.log(t, level, format, args...)
|
|
}
|
|
}
|