Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ECS information to logger instance #18820

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-developer.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,4 @@ The list below covers the major changes between 7.0.0-rc2 and master only.
- Add fields validation for histogram subfields. {pull}17759[17759]
- Add IP* fields to `fields.yml` generator script in Filebeat. {issue}17998[17998] {pull}18256[18256]
- Events intended for the Elasticsearch output can now take an `op_type` metadata field of type events.OpType or string to indicate the `op_type` to use for bulk indexing. {pull}12606[12606]
- Add `ECSEnabled()` method to logger instances. {pull}18820[18820]
36 changes: 36 additions & 0 deletions libbeat/logp/configure/logging_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package configure

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/logp"
)

func TestECSEnabled(t *testing.T) {
logger := logp.NewLogger("noECS")
assert.False(t, logger.ECSEnabled())

Logging("mockbeat", common.MustNewConfigFrom(`{"ecs":true}`))
logger = logp.NewLogger("withECS")
assert.True(t, logger.ECSEnabled())
}
4 changes: 2 additions & 2 deletions libbeat/logp/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func init() {
selectors: map[string]struct{}{},
rootLogger: zap.NewNop(),
globalLogger: zap.NewNop(),
logger: newLogger(zap.NewNop(), ""),
logger: newLogger(zap.NewNop(), "", false), //ecsEnabled=false reflects default config
})
}

Expand Down Expand Up @@ -110,7 +110,7 @@ func Configure(cfg Config) error {
selectors: selectors,
rootLogger: root,
globalLogger: root.WithOptions(zap.AddCallerSkip(1)),
logger: newLogger(root, ""),
logger: newLogger(root, "", cfg.ECSEnabled),
observedLogs: observedLogs,
})
return nil
Expand Down
23 changes: 16 additions & 7 deletions libbeat/logp/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@ type LogOption = zap.Option

// Logger logs messages to the configured output.
type Logger struct {
logger *zap.Logger
sugar *zap.SugaredLogger
logger *zap.Logger
sugar *zap.SugaredLogger
ecsEnabled bool
}

func newLogger(rootLogger *zap.Logger, selector string, options ...LogOption) *Logger {
func newLogger(rootLogger *zap.Logger, selector string, ecsEnabled bool, options ...LogOption) *Logger {
log := rootLogger.
WithOptions(zap.AddCallerSkip(1)).
WithOptions(options...).
Named(selector)
return &Logger{log, log.Sugar()}
return &Logger{log, log.Sugar(), ecsEnabled}
}

// NewLogger returns a new Logger labeled with the name of the selector. This
Expand All @@ -47,21 +48,22 @@ func newLogger(rootLogger *zap.Logger, selector string, options ...LogOption) *L
// Instead create new Logger instance that your object reuses. Or if you need to
// log from a static context then you may use logp.L().Infow(), for example.
func NewLogger(selector string, options ...LogOption) *Logger {
return newLogger(loadLogger().rootLogger, selector, options...)
coreLogger := loadLogger()
return newLogger(coreLogger.rootLogger, selector, coreLogger.logger.ecsEnabled, options...)
}

// With creates a child logger and adds structured context to it. Fields added
// to the child don't affect the parent, and vice versa.
func (l *Logger) With(args ...interface{}) *Logger {
sugar := l.sugar.With(args...)
return &Logger{sugar.Desugar(), sugar}
return &Logger{sugar.Desugar(), sugar, l.ecsEnabled}
}

// Named adds a new path segment to the logger's name. Segments are joined by
// periods.
func (l *Logger) Named(name string) *Logger {
logger := l.logger.Named(name)
return &Logger{logger, logger.Sugar()}
return &Logger{logger, logger.Sugar(), l.ecsEnabled}
}

// Sprint
Expand Down Expand Up @@ -213,6 +215,13 @@ func (l *Logger) Recover(msg string) {
}
}

// ECSEnabled returns whether or not logging should be ECS conformant.
// Switching to ECS can mean a breaking change for the log format.
// This information is helpful until all logs are switched to ECS by default.
func (l *Logger) ECSEnabled() bool {
return l.ecsEnabled
}

// L returns an unnamed global logger.
func L() *Logger {
return loadLogger().logger
Expand Down