mirror of
https://github.com/owncast/owncast.git
synced 2024-11-27 08:29:57 +03:00
142 lines
3.4 KiB
Go
142 lines
3.4 KiB
Go
package logging
|
|
|
|
// Custom logging hooks for powering our logs API.
|
|
// Modeled after https://github.com/sirupsen/logrus/blob/master/hooks/test/test.go
|
|
|
|
import (
|
|
"math"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
"time"
|
|
|
|
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
|
"github.com/owncast/owncast/utils"
|
|
"github.com/rifflock/lfshook"
|
|
"github.com/sirupsen/logrus"
|
|
logger "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const maxLogEntries = 500
|
|
|
|
// OCLogger represents the owncast internal logging.
|
|
type OCLogger struct {
|
|
Entries []logrus.Entry
|
|
Warnings []logrus.Entry
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// Logger is the shared instance of the internal logger.
|
|
var Logger *OCLogger
|
|
|
|
// Setup configures our custom logging destinations.
|
|
func Setup(enableDebugOptions bool, enableVerboseLogging bool) {
|
|
// Create the logging directory if needed
|
|
loggingDirectory := filepath.Dir(getLogFilePath())
|
|
if !utils.DoesFileExists(loggingDirectory) {
|
|
if err := os.Mkdir(loggingDirectory, 0o700); err != nil {
|
|
logger.Errorln("unable to create logs directory", loggingDirectory, err)
|
|
}
|
|
}
|
|
|
|
// Write logs to a file
|
|
path := getLogFilePath()
|
|
writer, _ := rotatelogs.New(
|
|
path+".%Y%m%d%H%M",
|
|
rotatelogs.WithLinkName(path),
|
|
rotatelogs.WithMaxAge(time.Duration(86400)*time.Second),
|
|
rotatelogs.WithRotationTime(time.Duration(604800)*time.Second),
|
|
)
|
|
|
|
logMapping := lfshook.WriterMap{
|
|
logrus.InfoLevel: writer,
|
|
logrus.DebugLevel: writer,
|
|
logrus.TraceLevel: writer,
|
|
logrus.WarnLevel: writer,
|
|
logrus.ErrorLevel: writer,
|
|
logrus.FatalLevel: writer,
|
|
}
|
|
|
|
logger.AddHook(lfshook.NewHook(
|
|
logMapping,
|
|
&logger.TextFormatter{},
|
|
))
|
|
|
|
if enableVerboseLogging {
|
|
logrus.SetLevel(logrus.TraceLevel)
|
|
} else {
|
|
logrus.SetLevel(logrus.InfoLevel)
|
|
}
|
|
|
|
// Write to stdout console
|
|
logger.SetOutput(os.Stdout)
|
|
|
|
// Write to our custom logging hook for the log API
|
|
_logger := new(OCLogger)
|
|
logger.AddHook(_logger)
|
|
|
|
if enableDebugOptions {
|
|
logrus.SetReportCaller(true)
|
|
}
|
|
|
|
Logger = _logger
|
|
}
|
|
|
|
// Fire runs for every logging request.
|
|
func (l *OCLogger) Fire(e *logger.Entry) error {
|
|
// Store all log messages to return back in the logging API
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
|
|
// Append to log entries
|
|
if len(l.Entries) > maxLogEntries {
|
|
l.Entries = l.Entries[1:]
|
|
}
|
|
l.Entries = append(l.Entries, *e)
|
|
|
|
if e.Level <= logger.WarnLevel {
|
|
if len(l.Warnings) > maxLogEntries {
|
|
l.Warnings = l.Warnings[1:]
|
|
}
|
|
l.Warnings = append(l.Warnings, *e)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Levels specifies what log levels we care about.
|
|
func (l *OCLogger) Levels() []logrus.Level {
|
|
return logrus.AllLevels
|
|
}
|
|
|
|
// AllEntries returns all entries that were logged.
|
|
func (l *OCLogger) AllEntries() []*logrus.Entry {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
|
|
// Make a copy so the returned value won't race with future log requests
|
|
logCount := int(math.Min(float64(len(l.Entries)), maxLogEntries))
|
|
entries := make([]*logrus.Entry, logCount)
|
|
for i := 0; i < len(entries); i++ {
|
|
// Make a copy, for safety
|
|
entries[len(entries)-logCount:][i] = &l.Entries[i]
|
|
}
|
|
|
|
return entries
|
|
}
|
|
|
|
// WarningEntries returns all warning or greater that were logged.
|
|
func (l *OCLogger) WarningEntries() []*logrus.Entry {
|
|
l.mu.RLock()
|
|
defer l.mu.RUnlock()
|
|
|
|
// Make a copy so the returned value won't race with future log requests
|
|
logCount := int(math.Min(float64(len(l.Warnings)), maxLogEntries))
|
|
entries := make([]*logrus.Entry, logCount)
|
|
for i := 0; i < len(entries); i++ {
|
|
// Make a copy, for safety
|
|
entries[len(entries)-logCount:][i] = &l.Warnings[i]
|
|
}
|
|
|
|
return entries
|
|
}
|