Logs refactoring after #780

This commit is contained in:
Alex X
2023-12-11 18:07:38 +03:00
parent 1f3a32023f
commit d3bc18c369
4 changed files with 199 additions and 163 deletions
+4 -24
View File
@@ -254,35 +254,15 @@ func restartHandler(w http.ResponseWriter, r *http.Request) {
go shell.Restart()
}
// logHandler handles HTTP requests for log buffer operations.
// It supports two HTTP methods:
// - GET: Retrieves the content of in-memory log and sends it back to the client as plain text.
// - DELETE: Clear the in-memory log buffer.
//
// The function expects a valid http.ResponseWriter and an http.Request as parameters.
// For a GET request, it reads the log from in-memory buffer and writes
// the content to the response writer with a "text/plain" content type.
//
// For a DELETE request, it clears the in-memory buffer.
//
// For any other HTTP method, it responds with an HTTP 400 (Bad Request) status.
//
// Parameters:
// - w http.ResponseWriter: The response writer to write the HTTP response to.
// - r *http.Request: The HTTP request object containing the request details.
//
// No return values are provided since the function writes directly to the response writer.
func logHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
// Send current state of the log file immediately
data := app.LogCollector.Bytes()
Response(w, data, "text/plain")
w.Header().Set("Content-Type", "application/jsonlines")
_, _ = app.MemoryLog.WriteTo(w)
case "DELETE":
app.LogCollector.Reset()
Response(w, "Log truncated", "text/plain")
app.MemoryLog.Reset()
Response(w, "OK", "text/plain")
default:
http.Error(w, "Method not allowed", http.StatusBadRequest)
}
-48
View File
@@ -1,21 +1,16 @@
package app
import (
"bytes"
"errors"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/AlexxIT/go2rtc/pkg/shell"
"github.com/AlexxIT/go2rtc/pkg/yaml"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
@@ -27,8 +22,6 @@ var Info = map[string]any{
"version": Version,
}
var LogCollector bytes.Buffer
func Init() {
var confs Config
var version bool
@@ -90,32 +83,6 @@ func Init() {
migrateStore()
}
func NewLogger(format string, level string) zerolog.Logger {
var writer io.Writer = os.Stdout
if format != "json" {
writer = zerolog.ConsoleWriter{
Out: writer, TimeFormat: "15:04:05.000",
NoColor: writer != os.Stdout || format == "text",
}
}
memoryLogger := zerolog.ConsoleWriter{
Out: &LogCollector, TimeFormat: "15:04:05.000",
NoColor: true,
}
writer = zerolog.MultiLevelWriter(writer, memoryLogger)
zerolog.TimeFieldFormat = time.RFC3339Nano
lvl, err := zerolog.ParseLevel(level)
if err != nil || lvl == zerolog.NoLevel {
lvl = zerolog.InfoLevel
}
return zerolog.New(writer).With().Timestamp().Logger().Level(lvl)
}
func LoadConfig(v any) {
for _, data := range configs {
if err := yaml.Unmarshal(data, v); err != nil {
@@ -124,18 +91,6 @@ func LoadConfig(v any) {
}
}
func GetLogger(module string) zerolog.Logger {
if s, ok := modules[module]; ok {
lvl, err := zerolog.ParseLevel(s)
if err == nil {
return log.Level(lvl)
}
log.Warn().Err(err).Caller().Send()
}
return log.Logger
}
func PatchConfig(key string, value any, path ...string) error {
if ConfigPath == "" {
return errors.New("config file disabled")
@@ -166,6 +121,3 @@ func (c *Config) Set(value string) error {
}
var configs [][]byte
// modules log levels
var modules map[string]string
+117
View File
@@ -0,0 +1,117 @@
package app
import (
"io"
"os"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
var MemoryLog *circularBuffer
func NewLogger(format string, level string) zerolog.Logger {
var writer io.Writer = os.Stdout
if format != "json" {
writer = zerolog.ConsoleWriter{
Out: writer, TimeFormat: "15:04:05.000", NoColor: format == "text",
}
}
MemoryLog = newBuffer(16)
writer = zerolog.MultiLevelWriter(writer, MemoryLog)
zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs
lvl, err := zerolog.ParseLevel(level)
if err != nil || lvl == zerolog.NoLevel {
lvl = zerolog.InfoLevel
}
return zerolog.New(writer).With().Timestamp().Logger().Level(lvl)
}
func GetLogger(module string) zerolog.Logger {
if s, ok := modules[module]; ok {
lvl, err := zerolog.ParseLevel(s)
if err == nil {
return log.Level(lvl)
}
log.Warn().Err(err).Caller().Send()
}
return log.Logger
}
// modules log levels
var modules map[string]string
const chunkSize = 1 << 16
type circularBuffer struct {
chunks [][]byte
r, w int
}
func newBuffer(chunks int) *circularBuffer {
b := &circularBuffer{chunks: make([][]byte, 0, chunks)}
// create first chunk
b.chunks = append(b.chunks, make([]byte, 0, chunkSize))
return b
}
func (b *circularBuffer) Write(p []byte) (n int, err error) {
n = len(p)
// check if chunk has size
if len(b.chunks[b.w])+n > chunkSize {
// increase write chunk index
if b.w++; b.w == cap(b.chunks) {
b.w = 0
}
// check overflow
if b.r == b.w {
// increase read chunk index
if b.r++; b.r == cap(b.chunks) {
b.r = 0
}
}
// check if current chunk exists
if b.w == len(b.chunks) {
// allocate new chunk
b.chunks = append(b.chunks, make([]byte, 0, chunkSize))
} else {
// reset len of current chunk
b.chunks[b.w] = b.chunks[b.w][:0]
}
}
b.chunks[b.w] = append(b.chunks[b.w], p...)
return
}
func (b *circularBuffer) WriteTo(w io.Writer) (n int64, err error) {
for i := b.r; ; {
var nn int
if nn, err = w.Write(b.chunks[i]); err != nil {
return
}
n += int64(nn)
if i == b.w {
break
}
if i++; i == cap(b.chunks) {
i = 0
}
}
return
}
func (b *circularBuffer) Reset() {
b.chunks[0] = b.chunks[0][:0]
b.r = 0
b.w = 0
}