mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2025-02-16 09:59:49 +03:00
all: slog logger
This commit is contained in:
parent
9a74d5d98b
commit
3d7f734ac9
6 changed files with 102 additions and 33 deletions
|
@ -1,6 +1,8 @@
|
||||||
package aghos
|
package aghos
|
||||||
|
|
||||||
// ConfigureSyslog reroutes standard logger output to syslog.
|
import "io"
|
||||||
func ConfigureSyslog(serviceName string) error {
|
|
||||||
|
// ConfigureSyslog returns an output rerouted to syslog.
|
||||||
|
func ConfigureSyslog(serviceName string) (w io.Writer, err error) {
|
||||||
return configureSyslog(serviceName)
|
return configureSyslog(serviceName)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,15 @@
|
||||||
package aghos
|
package aghos
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func configureSyslog(serviceName string) error {
|
func configureSyslog(serviceName string) (w io.Writer, err error) {
|
||||||
w, err := syslog.New(syslog.LOG_NOTICE|syslog.LOG_USER, serviceName)
|
w, err = syslog.New(syslog.LOG_NOTICE|syslog.LOG_USER, serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.SetOutput(w)
|
|
||||||
return nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
package aghos
|
package aghos
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
"golang.org/x/sys/windows/svc/eventlog"
|
"golang.org/x/sys/windows/svc/eventlog"
|
||||||
)
|
)
|
||||||
|
@ -19,23 +19,26 @@ func (w *eventLogWriter) Write(b []byte) (int, error) {
|
||||||
return len(b), w.el.Info(1, string(b))
|
return len(b), w.el.Info(1, string(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureSyslog(serviceName string) error {
|
func configureSyslog(serviceName string) (w io.Writer, err error) {
|
||||||
// Note that the eventlog src is the same as the service name
|
// Note that the eventlog src is the same as the service name. Otherwise,
|
||||||
// Otherwise, we will get "the description for event id cannot be found" warning in every log record
|
// we will get "the description for event id cannot be found" warning in
|
||||||
|
// every log record.
|
||||||
|
|
||||||
// Continue if we receive "registry key already exists" or if we get
|
// Continue if we receive "registry key already exists" or if we get
|
||||||
// ERROR_ACCESS_DENIED so that we can log without administrative permissions
|
// ERROR_ACCESS_DENIED so that we can log without administrative permissions
|
||||||
// for pre-existing eventlog sources.
|
// for pre-existing eventlog sources.
|
||||||
if err := eventlog.InstallAsEventCreate(serviceName, eventlog.Info|eventlog.Warning|eventlog.Error); err != nil {
|
err = eventlog.InstallAsEventCreate(serviceName, eventlog.Info|eventlog.Warning|eventlog.Error)
|
||||||
if !strings.Contains(err.Error(), "registry key already exists") && err != windows.ERROR_ACCESS_DENIED {
|
if err != nil {
|
||||||
return err
|
if !strings.Contains(err.Error(), "registry key already exists") &&
|
||||||
|
err != windows.ERROR_ACCESS_DENIED {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
el, err := eventlog.Open(serviceName)
|
el, err := eventlog.Open(serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetOutput(&eventLogWriter{el: el})
|
return &eventLogWriter{el: el}, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/hostsfile"
|
"github.com/AdguardTeam/golibs/hostsfile"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
|
"github.com/AdguardTeam/golibs/logutil/slogutil"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/AdguardTeam/golibs/osutil"
|
"github.com/AdguardTeam/golibs/osutil"
|
||||||
)
|
)
|
||||||
|
@ -547,15 +548,21 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
|
||||||
// Configure config filename.
|
// Configure config filename.
|
||||||
initConfigFilename(opts)
|
initConfigFilename(opts)
|
||||||
|
|
||||||
|
ls := getLogSettings(opts)
|
||||||
|
|
||||||
// Configure log level and output.
|
// Configure log level and output.
|
||||||
err = configureLogger(opts)
|
err = configureLogger(ls)
|
||||||
|
fatalOnError(err)
|
||||||
|
|
||||||
|
// Configure slog logger.
|
||||||
|
l, err := initLogger(ls)
|
||||||
fatalOnError(err)
|
fatalOnError(err)
|
||||||
|
|
||||||
// Print the first message after logger is configured.
|
// Print the first message after logger is configured.
|
||||||
log.Info(version.Full())
|
l.Info(version.Full())
|
||||||
log.Debug("current working directory is %s", Context.workDir)
|
l.Debug("current working directory is set", "work_dir", Context.workDir)
|
||||||
if opts.runningAsService {
|
if opts.runningAsService {
|
||||||
log.Info("AdGuard Home is running as a service")
|
l.Info("AdGuard Home is running as a service")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setupContext(opts)
|
err = setupContext(opts)
|
||||||
|
@ -586,7 +593,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
confPath := configFilePath()
|
confPath := configFilePath()
|
||||||
log.Debug("using config path %q for updater", confPath)
|
l.Debug("using config path for updater", "path", confPath)
|
||||||
|
|
||||||
upd := updater.NewUpdater(&updater.Config{
|
upd := updater.NewUpdater(&updater.Config{
|
||||||
Client: config.Filtering.HTTPClient,
|
Client: config.Filtering.HTTPClient,
|
||||||
|
@ -628,7 +635,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
|
||||||
|
|
||||||
Context.tls, err = newTLSManager(config.TLS, config.DNS.ServePlainDNS)
|
Context.tls, err = newTLSManager(config.TLS, config.DNS.ServePlainDNS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("initializing tls: %s", err)
|
l.Error("initializing tls", slogutil.KeyError, err)
|
||||||
onConfigModified()
|
onConfigModified()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,7 +659,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
|
||||||
if Context.dhcpServer != nil {
|
if Context.dhcpServer != nil {
|
||||||
err = Context.dhcpServer.Start()
|
err = Context.dhcpServer.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("starting dhcp server: %s", err)
|
l.Error("starting dhcp server", slogutil.KeyError, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,14 @@ package home
|
||||||
import (
|
import (
|
||||||
"cmp"
|
"cmp"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
|
"github.com/AdguardTeam/golibs/logutil/slogutil"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
@ -16,10 +19,58 @@ import (
|
||||||
// for logger output.
|
// for logger output.
|
||||||
const configSyslog = "syslog"
|
const configSyslog = "syslog"
|
||||||
|
|
||||||
// configureLogger configures logger level and output.
|
// initLogger returns new [*slog.Logger] configured with the given settings.
|
||||||
func configureLogger(opts options) (err error) {
|
func initLogger(ls *logSettings) (l *slog.Logger, err error) {
|
||||||
ls := getLogSettings(opts)
|
if !ls.Enabled {
|
||||||
|
return slogutil.NewDiscardLogger(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
w, err := logOutput(ls)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot initialize log output: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return slogutil.New(&slogutil.Config{
|
||||||
|
Output: w,
|
||||||
|
Format: slogutil.FormatDefault,
|
||||||
|
AddTimestamp: true,
|
||||||
|
Verbose: ls.Verbose,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// logOutput returns a log output [io.Writer] configured with the settings.
|
||||||
|
func logOutput(ls *logSettings) (w io.Writer, err error) {
|
||||||
|
if ls.File == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if ls.File == configSyslog {
|
||||||
|
// Use syslog where it is possible and eventlog on Windows.
|
||||||
|
w, err = aghos.ConfigureSyslog(serviceName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot initialize syslog: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return w, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logFilePath := ls.File
|
||||||
|
if !filepath.IsAbs(logFilePath) {
|
||||||
|
logFilePath = filepath.Join(Context.workDir, logFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lumberjack.Logger{
|
||||||
|
Filename: logFilePath,
|
||||||
|
Compress: ls.Compress,
|
||||||
|
LocalTime: ls.LocalTime,
|
||||||
|
MaxBackups: ls.MaxBackups,
|
||||||
|
MaxSize: ls.MaxSize,
|
||||||
|
MaxAge: ls.MaxAge,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// configureLogger configures logger level and output.
|
||||||
|
func configureLogger(ls *logSettings) (err error) {
|
||||||
// Configure logger level.
|
// Configure logger level.
|
||||||
if !ls.Enabled {
|
if !ls.Enabled {
|
||||||
log.SetLevel(log.OFF)
|
log.SetLevel(log.OFF)
|
||||||
|
@ -33,16 +84,19 @@ func configureLogger(opts options) (err error) {
|
||||||
|
|
||||||
// Write logs to stdout by default.
|
// Write logs to stdout by default.
|
||||||
if ls.File == "" {
|
if ls.File == "" {
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ls.File == configSyslog {
|
if ls.File == configSyslog {
|
||||||
// Use syslog where it is possible and eventlog on Windows.
|
// Use syslog where it is possible and eventlog on Windows.
|
||||||
err = aghos.ConfigureSyslog(serviceName)
|
var w io.Writer
|
||||||
|
w, err = aghos.ConfigureSyslog(serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot initialize syslog: %w", err)
|
return fmt.Errorf("cannot initialize syslog: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.SetOutput(w)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +114,7 @@ func configureLogger(opts options) (err error) {
|
||||||
MaxAge: ls.MaxAge,
|
MaxAge: ls.MaxAge,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// getLogSettings returns a log settings object properly initialized from opts.
|
// getLogSettings returns a log settings object properly initialized from opts.
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||||
|
@ -22,10 +23,13 @@ func setLog(opts *options) (err error) {
|
||||||
case "stderr":
|
case "stderr":
|
||||||
log.SetOutput(os.Stderr)
|
log.SetOutput(os.Stderr)
|
||||||
case "syslog":
|
case "syslog":
|
||||||
err = aghos.ConfigureSyslog(syslogServiceName)
|
var w io.Writer
|
||||||
|
w, err = aghos.ConfigureSyslog(syslogServiceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initializing syslog: %w", err)
|
return fmt.Errorf("initializing syslog: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.SetOutput(w)
|
||||||
default:
|
default:
|
||||||
// TODO(a.garipov): Use the path.
|
// TODO(a.garipov): Use the path.
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue