This repository has been archived by the owner on May 13, 2022. It is now read-only.
/
config.go
147 lines (127 loc) · 3.53 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package logconfig
import (
"bytes"
"encoding/json"
"fmt"
"github.com/eapache/channels"
"github.com/go-kit/kit/log"
"github.com/hyperledger/burrow/logging"
"github.com/BurntSushi/toml"
"github.com/hyperledger/burrow/logging/loggers"
)
type LoggingConfig struct {
RootSink *SinkConfig `toml:",omitempty"`
// Trace debug is very noisy - mostly from Tendermint
Trace bool
// Send to a channel - will not affect progress if logging graph is intensive but output will lag and some logs
// may be missed in shutdown
NonBlocking bool
}
// For encoding a top-level '[logging]' TOML table
type LoggingConfigWrapper struct {
Logging *LoggingConfig `toml:",omitempty"`
}
func DefaultNodeLoggingConfig() *LoggingConfig {
// Output only Burrow messages on stdout
return &LoggingConfig{
RootSink: Sink().
SetOutput(StdoutOutput().SetFormat(loggers.JSONFormat)),
}
}
// Provide a defeault logging config
func New() *LoggingConfig {
return &LoggingConfig{
NonBlocking: false,
RootSink: Sink().SetOutput(StderrOutput().SetFormat(JSONFormat)),
}
}
func (lc *LoggingConfig) WithTrace() *LoggingConfig {
lc.Trace = true
return lc
}
func (lc *LoggingConfig) None() *LoggingConfig {
lc.RootSink = nil
return lc
}
func (lc *LoggingConfig) Root(configure func(sink *SinkConfig) *SinkConfig) *LoggingConfig {
lc.RootSink = configure(Sink())
return lc
}
// Returns the TOML for a top-level logging config wrapped with [logging]
func (lc *LoggingConfig) RootTOMLString() string {
return TOMLString(LoggingConfigWrapper{lc})
}
func (lc *LoggingConfig) TOMLString() string {
return TOMLString(lc)
}
func (lc *LoggingConfig) RootJSONString() string {
return JSONString(LoggingConfigWrapper{lc})
}
func (lc *LoggingConfig) JSONString() string {
return JSONString(lc)
}
func (lc *LoggingConfig) MustLogger() *logging.Logger {
logger, err := lc.Logger()
if err != nil {
panic(err)
}
return logger
}
// Obtain a logger from this LoggingConfig
func (lc *LoggingConfig) Logger() (*logging.Logger, error) {
outputLogger, errCh, err := newLogger(lc)
if err != nil {
return nil, err
}
logger := logging.NewLogger(outputLogger)
if !lc.Trace {
logger.Trace = log.NewNopLogger()
}
go func() {
err := <-errCh.Out()
if err != nil {
fmt.Printf("Logging error: %v", err)
}
}()
return logger, nil
}
// Hot swap logging config by replacing output loggers built from this LoggingConfig
func (lc *LoggingConfig) UpdateLogger(logger *logging.Logger) (channels.Channel, error) {
outputLogger, errCh, err := newLogger(lc)
if err != nil {
return channels.NewDeadChannel(), err
}
logger.SwapOutput(outputLogger)
return errCh, nil
}
// Helpers
func newLogger(loggingConfig *LoggingConfig) (log.Logger, channels.Channel, error) {
outputLogger, _, err := loggingConfig.RootSink.BuildLogger()
if err != nil {
return nil, nil, err
}
var errCh channels.Channel = channels.NewDeadChannel()
var logger log.Logger = loggers.NewBurrowFormatLogger(outputLogger)
if loggingConfig.NonBlocking {
logger, errCh = loggers.NonBlockingLogger(logger)
return logger, errCh, nil
}
return logger, errCh, err
}
func TOMLString(v interface{}) string {
buf := new(bytes.Buffer)
encoder := toml.NewEncoder(buf)
err := encoder.Encode(v)
if err != nil {
// Seems like a reasonable compromise to make the string function clean
return fmt.Sprintf("Error encoding TOML: %s", err)
}
return buf.String()
}
func JSONString(v interface{}) string {
bs, err := json.MarshalIndent(v, "", "\t")
if err != nil {
return fmt.Sprintf("Error encoding JSON: %s", err)
}
return string(bs)
}