5 changed files with 138 additions and 2 deletions
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
package admin |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"net/http" |
||||
"time" |
||||
|
||||
"github.com/owncast/owncast/logging" |
||||
"github.com/sirupsen/logrus" |
||||
) |
||||
|
||||
// GetLogs will return all logs
|
||||
func GetLogs(w http.ResponseWriter, r *http.Request) { |
||||
logs := logging.Logger.AllEntries() |
||||
response := make([]logsResponse, 0) |
||||
|
||||
for i := 0; i < len(logs); i++ { |
||||
response = append(response, fromEntry(logs[i])) |
||||
} |
||||
|
||||
w.Header().Set("Content-Type", "application/json") |
||||
json.NewEncoder(w).Encode(response) |
||||
} |
||||
|
||||
// GetWarnings will return only warning and error logs
|
||||
func GetWarnings(w http.ResponseWriter, r *http.Request) { |
||||
logs := logging.Logger.WarningEntries() |
||||
response := make([]logsResponse, 0) |
||||
|
||||
for i := 0; i < len(logs); i++ { |
||||
response = append(response, fromEntry(logs[i])) |
||||
} |
||||
|
||||
w.Header().Set("Content-Type", "application/json") |
||||
json.NewEncoder(w).Encode(response) |
||||
} |
||||
|
||||
type logsResponse struct { |
||||
Message string `json:"message"` |
||||
Level string `json:"level"` |
||||
Time time.Time `json:"time"` |
||||
} |
||||
|
||||
func fromEntry(e *logrus.Entry) logsResponse { |
||||
return logsResponse{ |
||||
Message: e.Message, |
||||
Level: e.Level.String(), |
||||
Time: e.Time, |
||||
} |
||||
} |
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
package logging |
||||
|
||||
// Custom logging hooks for powering our logs API.
|
||||
// Modeled after https://github.com/sirupsen/logrus/blob/master/hooks/test/test.go
|
||||
|
||||
import ( |
||||
"os" |
||||
"sync" |
||||
|
||||
"github.com/sirupsen/logrus" |
||||
logger "github.com/sirupsen/logrus" |
||||
) |
||||
|
||||
const maxLogEntries = 500 |
||||
|
||||
type OCLogger struct { |
||||
Entries []logrus.Entry |
||||
mu sync.RWMutex |
||||
} |
||||
|
||||
var Logger *OCLogger |
||||
|
||||
// Setup configures our custom logging destinations
|
||||
func Setup() { |
||||
logger.SetOutput(os.Stdout) // Send all logs to console
|
||||
|
||||
_logger := new(OCLogger) |
||||
logger.AddHook(_logger) |
||||
|
||||
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() |
||||
|
||||
if len(l.Entries) > maxLogEntries { |
||||
l.Entries = l.Entries[1:] |
||||
} |
||||
l.Entries = append(l.Entries, *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
|
||||
entries := make([]*logrus.Entry, len(l.Entries)) |
||||
for i := 0; i < len(l.Entries); i++ { |
||||
// Make a copy, for safety
|
||||
entries[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
|
||||
entries := make([]*logrus.Entry, 0) |
||||
for i := 0; i < len(l.Entries); i++ { |
||||
if l.Entries[i].Level <= logrus.WarnLevel { |
||||
// Make a copy, for safety
|
||||
entries = append(entries, &l.Entries[i]) |
||||
} |
||||
} |
||||
|
||||
return entries |
||||
} |
Loading…
Reference in new issue