@@ -21,7 +21,7 @@ import (
2121 "errors"
2222 "flag"
2323 "fmt"
24- "io/ioutil "
24+ "io"
2525 golog "log"
2626 "os"
2727 "path/filepath"
@@ -68,36 +68,33 @@ func Configure(cfg Config) error {
6868 return ConfigureWithOutputs (cfg )
6969}
7070
71- // ConfigureWithOutputs XXX: is used by elastic-agent only (See file: x-pack/elastic-agent/pkg/core/logger/logger.go).
72- // The agent requires that the output specified in the config object is configured and merged with the
73- // logging outputs given.
74- func ConfigureWithOutputs (cfg Config , outputs ... zapcore.Core ) error {
71+ func createSink (defaultLoggerCfg Config , outputs ... zapcore.Core ) (zapcore.Core , zap.AtomicLevel , * observer.ObservedLogs , map [string ]struct {}, error ) {
7572 var (
7673 sink zapcore.Core
7774 observedLogs * observer.ObservedLogs
7875 err error
7976 level zap.AtomicLevel
8077 )
8178
82- level = zap .NewAtomicLevelAt (cfg .Level .ZapLevel ())
79+ level = zap .NewAtomicLevelAt (defaultLoggerCfg .Level .ZapLevel ())
8380 // Build a single output (stderr has priority if more than one are enabled).
84- if cfg .toObserver {
81+ if defaultLoggerCfg .toObserver {
8582 sink , observedLogs = observer .New (level )
8683 } else {
87- sink , err = createLogOutput (cfg , level )
84+ sink , err = createLogOutput (defaultLoggerCfg , level )
8885 }
8986 if err != nil {
90- return fmt .Errorf ("failed to build log output: %w" , err )
87+ return nil , level , nil , nil , fmt .Errorf ("failed to build log output: %w" , err )
9188 }
9289
9390 // Default logger is always discard, debug level below will
9491 // possibly re-enable it.
95- golog .SetOutput (ioutil .Discard )
92+ golog .SetOutput (io .Discard )
9693
9794 // Enabled selectors when debug is enabled.
98- selectors := make (map [string ]struct {}, len (cfg .Selectors ))
99- if cfg .Level .Enabled (DebugLevel ) && len (cfg .Selectors ) > 0 {
100- for _ , sel := range cfg .Selectors {
95+ selectors := make (map [string ]struct {}, len (defaultLoggerCfg .Selectors ))
96+ if defaultLoggerCfg .Level .Enabled (DebugLevel ) && len (defaultLoggerCfg .Selectors ) > 0 {
97+ for _ , sel := range defaultLoggerCfg .Selectors {
10198 selectors [strings .TrimSpace (sel )] = struct {}{}
10299 }
103100
@@ -118,7 +115,73 @@ func ConfigureWithOutputs(cfg Config, outputs ...zapcore.Core) error {
118115 }
119116
120117 sink = newMultiCore (append (outputs , sink )... )
121- root := zap .New (sink , makeOptions (cfg )... )
118+
119+ return sink , level , observedLogs , selectors , err
120+ }
121+
122+ // ConfigureWithOutputs configures the global logger to use an output created
123+ // from `defaultLoggerCfg` and all the outputs passed by `outputs`.
124+ // This function needs to be exported because it's used by `logp/configure`
125+ func ConfigureWithOutputs (defaultLoggerCfg Config , outputs ... zapcore.Core ) error {
126+ sink , level , observedLogs , selectors , err := createSink (defaultLoggerCfg , outputs ... )
127+ if err != nil {
128+ return err
129+ }
130+ root := zap .New (sink , makeOptions (defaultLoggerCfg )... )
131+ storeLogger (& coreLogger {
132+ selectors : selectors ,
133+ rootLogger : root ,
134+ globalLogger : root .WithOptions (zap .AddCallerSkip (1 )),
135+ logger : newLogger (root , "" ),
136+ level : level ,
137+ observedLogs : observedLogs ,
138+ })
139+ return nil
140+ }
141+
142+ // ConfigureWithTypedOutput configures the global logger to use typed outputs.
143+ //
144+ // If a log entry matches the defined key/value, this entry is logged using the
145+ // core generated from `typedLoggerCfg`, otherwise it will be logged by all
146+ // cores in `outputs` and the one generated from `defaultLoggerCfg`.
147+ // Arguments:
148+ // - `defaultLoggerCfg` is used to create a new core that will be the default
149+ // output from the logger
150+ // - `typedLoggerCfg` is used to create a new output that will only be used
151+ // when the log entry matches `entry[logKey] = kind`
152+ // - `key` is the key the typed logger will look at
153+ // - `value` is the value compared against the `logKey` entry
154+ // - `outputs` is a list of cores that will be added together with the core
155+ // generated by `defaultLoggerCfg` as the default output for the loggger.
156+ //
157+ // If `defaultLoggerCfg.toObserver` is true, then `typedLoggerCfg` is ignored
158+ // and a single sink is used so all logs can be observed.
159+ func ConfigureWithTypedOutput (defaultLoggerCfg , typedLoggerCfg Config , key , value string , outputs ... zapcore.Core ) error {
160+ sink , level , observedLogs , selectors , err := createSink (defaultLoggerCfg , outputs ... )
161+ if err != nil {
162+ return err
163+ }
164+
165+ var typedCore zapcore.Core
166+ if defaultLoggerCfg .toObserver {
167+ typedCore = sink
168+ } else {
169+ typedCore , err = createLogOutput (typedLoggerCfg , level )
170+ }
171+ if err != nil {
172+ return fmt .Errorf ("could not create typed logger output: %w" , err )
173+ }
174+
175+ sink = & typedLoggerCore {
176+ defaultCore : sink ,
177+ typedCore : typedCore ,
178+ key : key ,
179+ value : value ,
180+ }
181+
182+ sink = selectiveWrapper (sink , selectors )
183+
184+ root := zap .New (sink , makeOptions (defaultLoggerCfg )... )
122185 storeLogger (& coreLogger {
123186 selectors : selectors ,
124187 rootLogger : root ,
@@ -215,7 +278,7 @@ func makeStderrOutput(cfg Config, enab zapcore.LevelEnabler) (zapcore.Core, erro
215278}
216279
217280func makeDiscardOutput (cfg Config , enab zapcore.LevelEnabler ) (zapcore.Core , error ) {
218- discard := zapcore .AddSync (ioutil .Discard )
281+ discard := zapcore .AddSync (io .Discard )
219282 return newCore (buildEncoder (cfg ), discard , enab ), nil
220283}
221284
0 commit comments