mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 13:28:01 -05:00
Logrus hooks for terminal vs log-file output (#16102)
## Review after #16059 **What type of PR is this?** Feature **What does this PR do?** This PR introduces logrus writer hooks into the logging of prysm. when log-format is text: - set the default logrus output to be `io.Discard` - create a writer hook for terminal, with formatting and coloring enabled. - create a separate writer hook for log-file (if enabled), without coloring. This immediately allows for having formatted/colored terminal logs, while keeping the log-file clean.
This commit is contained in:
4
changelog/bastin_logrus-hooks-add.md
Normal file
4
changelog/bastin_logrus-hooks-add.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
### Added
|
||||||
|
|
||||||
|
- Added separate logrus hooks for handling the formatting and output of terminal logs vs log-file logs, instead of the
|
||||||
|
default logrus output.
|
||||||
@@ -4,6 +4,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
runtimeDebug "runtime/debug"
|
runtimeDebug "runtime/debug"
|
||||||
@@ -172,14 +173,20 @@ func before(ctx *cli.Context) error {
|
|||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case "text":
|
case "text":
|
||||||
|
// disabling logrus default output so we can control it via different hooks
|
||||||
|
logrus.SetOutput(io.Discard)
|
||||||
|
|
||||||
|
// create a custom formatter and hook for terminal output
|
||||||
formatter := new(prefixed.TextFormatter)
|
formatter := new(prefixed.TextFormatter)
|
||||||
formatter.TimestampFormat = "2006-01-02 15:04:05.00"
|
formatter.TimestampFormat = "2006-01-02 15:04:05.00"
|
||||||
formatter.FullTimestamp = true
|
formatter.FullTimestamp = true
|
||||||
|
formatter.ForceFormatting = true
|
||||||
|
formatter.ForceColors = true
|
||||||
|
|
||||||
// If persistent log files are written - we disable the log messages coloring because
|
logrus.AddHook(&logs.WriterHook{
|
||||||
// the colors are ANSI codes and seen as gibberish in the log files.
|
Formatter: formatter,
|
||||||
formatter.DisableColors = ctx.String(cmd.LogFileName.Name) != ""
|
Writer: os.Stderr,
|
||||||
logrus.SetFormatter(formatter)
|
})
|
||||||
case "fluentd":
|
case "fluentd":
|
||||||
f := joonix.NewFormatter()
|
f := joonix.NewFormatter()
|
||||||
|
|
||||||
@@ -202,7 +209,7 @@ func before(ctx *cli.Context) error {
|
|||||||
|
|
||||||
logFileName := ctx.String(cmd.LogFileName.Name)
|
logFileName := ctx.String(cmd.LogFileName.Name)
|
||||||
if logFileName != "" {
|
if logFileName != "" {
|
||||||
if err := logs.ConfigurePersistentLogging(logFileName); err != nil {
|
if err := logs.ConfigurePersistentLogging(logFileName, format); err != nil {
|
||||||
log.WithError(err).Error("Failed to configuring logging to disk.")
|
log.WithError(err).Error("Failed to configuring logging to disk.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func main() {
|
|||||||
|
|
||||||
logFileName := ctx.String(cmd.LogFileName.Name)
|
logFileName := ctx.String(cmd.LogFileName.Name)
|
||||||
if logFileName != "" {
|
if logFileName != "" {
|
||||||
if err := logs.ConfigurePersistentLogging(logFileName); err != nil {
|
if err := logs.ConfigurePersistentLogging(logFileName, format); err != nil {
|
||||||
log.WithError(err).Error("Failed to configuring logging to disk.")
|
log.WithError(err).Error("Failed to configuring logging to disk.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
runtimeDebug "runtime/debug"
|
runtimeDebug "runtime/debug"
|
||||||
@@ -151,13 +152,20 @@ func main() {
|
|||||||
format := ctx.String(cmd.LogFormat.Name)
|
format := ctx.String(cmd.LogFormat.Name)
|
||||||
switch format {
|
switch format {
|
||||||
case "text":
|
case "text":
|
||||||
|
// disabling logrus default output so we can control it via different hooks
|
||||||
|
logrus.SetOutput(io.Discard)
|
||||||
|
|
||||||
|
// create a custom formatter and hook for terminal output
|
||||||
formatter := new(prefixed.TextFormatter)
|
formatter := new(prefixed.TextFormatter)
|
||||||
formatter.TimestampFormat = "2006-01-02 15:04:05.00"
|
formatter.TimestampFormat = "2006-01-02 15:04:05.00"
|
||||||
formatter.FullTimestamp = true
|
formatter.FullTimestamp = true
|
||||||
// If persistent log files are written - we disable the log messages coloring because
|
formatter.ForceFormatting = true
|
||||||
// the colors are ANSI codes and seen as gibberish in the log files.
|
formatter.ForceColors = true
|
||||||
formatter.DisableColors = logFileName != ""
|
|
||||||
logrus.SetFormatter(formatter)
|
logrus.AddHook(&logs.WriterHook{
|
||||||
|
Formatter: formatter,
|
||||||
|
Writer: os.Stderr,
|
||||||
|
})
|
||||||
case "fluentd":
|
case "fluentd":
|
||||||
f := joonix.NewFormatter()
|
f := joonix.NewFormatter()
|
||||||
if err := joonix.DisableTimestampFormat(f); err != nil {
|
if err := joonix.DisableTimestampFormat(f); err != nil {
|
||||||
@@ -177,7 +185,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if logFileName != "" {
|
if logFileName != "" {
|
||||||
if err := logs.ConfigurePersistentLogging(logFileName); err != nil {
|
if err := logs.ConfigurePersistentLogging(logFileName, format); err != nil {
|
||||||
log.WithError(err).Error("Failed to configuring logging to disk.")
|
log.WithError(err).Error("Failed to configuring logging to disk.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
|||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"hook.go",
|
||||||
"logutil.go",
|
"logutil.go",
|
||||||
"stream.go",
|
"stream.go",
|
||||||
],
|
],
|
||||||
@@ -14,6 +15,7 @@ go_library(
|
|||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//crypto/rand:go_default_library",
|
"//crypto/rand:go_default_library",
|
||||||
"//io/file:go_default_library",
|
"//io/file:go_default_library",
|
||||||
|
"//runtime/logging/logrus-prefixed-formatter:go_default_library",
|
||||||
"@com_github_hashicorp_golang_lru//:go_default_library",
|
"@com_github_hashicorp_golang_lru//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
],
|
],
|
||||||
|
|||||||
29
io/logs/hook.go
Normal file
29
io/logs/hook.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WriterHook struct {
|
||||||
|
AllowedLevels []logrus.Level
|
||||||
|
Writer io.Writer
|
||||||
|
Formatter logrus.Formatter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *WriterHook) Levels() []logrus.Level {
|
||||||
|
if hook.AllowedLevels == nil || len(hook.AllowedLevels) == 0 {
|
||||||
|
return logrus.AllLevels
|
||||||
|
}
|
||||||
|
return hook.AllowedLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *WriterHook) Fire(entry *logrus.Entry) error {
|
||||||
|
line, err := hook.Formatter.Format(entry)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = hook.Writer.Write(line)
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/OffchainLabs/prysm/v7/config/params"
|
"github.com/OffchainLabs/prysm/v7/config/params"
|
||||||
"github.com/OffchainLabs/prysm/v7/io/file"
|
"github.com/OffchainLabs/prysm/v7/io/file"
|
||||||
|
prefixed "github.com/OffchainLabs/prysm/v7/runtime/logging/logrus-prefixed-formatter"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ func addLogWriter(w io.Writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConfigurePersistentLogging adds a log-to-file writer. File content is identical to stdout.
|
// ConfigurePersistentLogging adds a log-to-file writer. File content is identical to stdout.
|
||||||
func ConfigurePersistentLogging(logFileName string) error {
|
func ConfigurePersistentLogging(logFileName string, format string) error {
|
||||||
logrus.WithField("logFileName", logFileName).Info("Logs will be made persistent")
|
logrus.WithField("logFileName", logFileName).Info("Logs will be made persistent")
|
||||||
if err := file.MkdirAll(filepath.Dir(logFileName)); err != nil {
|
if err := file.MkdirAll(filepath.Dir(logFileName)); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -30,7 +31,25 @@ func ConfigurePersistentLogging(logFileName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
addLogWriter(f)
|
if format != "text" {
|
||||||
|
addLogWriter(f)
|
||||||
|
|
||||||
|
logrus.Info("File logging initialized")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create formatter and writer hook
|
||||||
|
formatter := new(prefixed.TextFormatter)
|
||||||
|
formatter.TimestampFormat = "2006-01-02 15:04:05.00"
|
||||||
|
formatter.FullTimestamp = true
|
||||||
|
// If persistent log files are written - we disable the log messages coloring because
|
||||||
|
// the colors are ANSI codes and seen as gibberish in the log files.
|
||||||
|
formatter.DisableColors = true
|
||||||
|
|
||||||
|
logrus.AddHook(&WriterHook{
|
||||||
|
Formatter: formatter,
|
||||||
|
Writer: f,
|
||||||
|
})
|
||||||
|
|
||||||
logrus.Info("File logging initialized")
|
logrus.Info("File logging initialized")
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ func TestConfigurePersistantLogging(t *testing.T) {
|
|||||||
logFileName := "test.log"
|
logFileName := "test.log"
|
||||||
existingDirectory := "test-1-existing-testing-dir"
|
existingDirectory := "test-1-existing-testing-dir"
|
||||||
|
|
||||||
err := ConfigurePersistentLogging(fmt.Sprintf("%s/%s/%s", testParentDir, existingDirectory, logFileName))
|
err := ConfigurePersistentLogging(fmt.Sprintf("%s/%s/%s", testParentDir, existingDirectory, logFileName), "text")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// 2. Test creation of file along with parent directory
|
// 2. Test creation of file along with parent directory
|
||||||
nonExistingDirectory := "test-2-non-existing-testing-dir"
|
nonExistingDirectory := "test-2-non-existing-testing-dir"
|
||||||
|
|
||||||
err = ConfigurePersistentLogging(fmt.Sprintf("%s/%s/%s", testParentDir, nonExistingDirectory, logFileName))
|
err = ConfigurePersistentLogging(fmt.Sprintf("%s/%s/%s", testParentDir, nonExistingDirectory, logFileName), "text")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// 3. Test creation of file in an existing parent directory with a non-existing sub-directory
|
// 3. Test creation of file in an existing parent directory with a non-existing sub-directory
|
||||||
@@ -51,7 +51,7 @@ func TestConfigurePersistantLogging(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ConfigurePersistentLogging(fmt.Sprintf("%s/%s/%s/%s", testParentDir, existingDirectory, nonExistingSubDirectory, logFileName))
|
err = ConfigurePersistentLogging(fmt.Sprintf("%s/%s/%s/%s", testParentDir, existingDirectory, nonExistingSubDirectory, logFileName), "text")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
//4. Create log file in a directory without 700 permissions
|
//4. Create log file in a directory without 700 permissions
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *logFileName != "" {
|
if *logFileName != "" {
|
||||||
if err := logs.ConfigurePersistentLogging(*logFileName); err != nil {
|
if err := logs.ConfigurePersistentLogging(*logFileName, "text"); err != nil {
|
||||||
log.WithError(err).Error("Failed to configuring logging to disk.")
|
log.WithError(err).Error("Failed to configuring logging to disk.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user