logging

package module
v0.0.0-...-f22c914 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2023 License: Apache-2.0 Imports: 27 Imported by: 577

README

StreamingFast Logging library

reference License

This is the logging library used as part of StreamingFast.

Usage

In all library packages (by convention, use the import path):

var zlog *zap.Logger

func init() {
	logging.Register("github.com/path/to/my/package", &zlog)
}

In main packages:

var zlog *zap.Logger

func setupLogger() {
	logging.Register("main", &zlog)

	logging.Set(logging.MustCreateLogger())
	// Optionally set a different logger here and there,
	// using a regexp matching the registered names:
	//logging.Set(zap.NewNop(), "eosdb")
}

In tests (to avoid a race between the init() statements)

func init() {
	if os.Getenv("DEBUG") != "" {
		logging.Override(logging.MustCreateLoggerWithLevel("test", zap.NewAtomicLevelAt(zap.DebugLevel)), ""))
	}
}

You can switch log levels dynamically, by poking the port 1065 like this:

On listening servers (port 1065, hint: logs!)

  • curl http://localhost:1065/ -XPUT -d '{"level": "debug"}'

Contributing

Issues and PR in this repo related strictly to the streamingfast logging library.

Report any protocol-specific issues in their respective repositories

Please first refer to the general StreamingFast contribution guide, if you wish to contribute to this code base.

License

Apache 2.0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AutoStartServer = true

Functions

func BasicLoggingConfig deprecated

func BasicLoggingConfig(serviceName string, atomicLevel zap.AtomicLevel, opts ...zap.Option) *zap.Config

Deprecated: Will be removed in a future version, use `InstantiateLoggers` and configure it the way you want instead.

func CreateLogger

func CreateLogger(serviceName string, opts ...zap.Option) (*zap.Logger, error)

CreateLogger can be used to create the correct zap logger based on the environment.

First, if an environment variable `ZAP_PRETTY` pretty is present, a `zapdriver.NewProduction` is used but logging all levels (`Debug` level and more). Furthermore, this logger will print everything into the standard output of the process (opposed to standard error by default). If the env is set, it overrides everything. If the value of the `ZAP_PRETTY` environment variable is a valid Zap level (`debug`, `info`, `warn`, `error`), the logger level will be configured using the value. In all other cases, `debug` level is used as the default.

Then, if in production, automatically a `zap.NewProduction()` is returned. The production environment is determined based on the presence of the `/.dockerenv` file.

In all other cases, return a `zap.NewDevelopment()` logger.

func CreateLoggerWithLevel

func CreateLoggerWithLevel(serviceName string, atomicLevel zap.AtomicLevel, opts ...zap.Option) (*zap.Logger, error)

CreateLoggerWithLevel behaves exactly like `CreateLogger`, but you can pass the atomic level that should be used for the logger that will use this atomic level. By keeping a reference to it, later on, you will be able to change the level at runtime by calling `atomicLevel.SetLevel` on your reference and logger level will be changed.

func Debug

func Debug(ctx context.Context, fallbackLogger *zap.Logger, msg string, fields ...zapcore.Field)

Debug is a shortcut for `Logger(ctx, zlog).Debug("some message", ...some fields)`

func Error

func Error(ctx context.Context, fallbackLogger *zap.Logger, msg string, fields ...zapcore.Field)

Error is a shortcut for `Logger(ctx, zlog).Error("some message", ...some fields)`

func Extend

func Extend(extender LoggerExtender, regexps ...string)

Extend is different than `Set` by being able to re-configure the existing logger set for all registered logger in the registry. This is useful for example to add a field to the currently set logger:

``` logger.Extend(func (current *zap.Logger) { return current.With("name", "value") }, "github.com/dfuse-io/app.*") ```

func FlagFields

func FlagFields(extraFields ...zap.Field) []zap.Field

FlagFields returns all flag as `zap.Field` element for easy logging

func Info

func Info(ctx context.Context, fallbackLogger *zap.Logger, msg string, fields ...zapcore.Field)

Info is a shortcut for `Logger(ctx, zlog).Info("some message", ...some fields)`

func InstantiateLoggers

func InstantiateLoggers(opts ...InstantiateOption)

InstantiateLoggers correctly instantiate all the loggers of your application at the correct level based on various source of information. The source of information that are checked are

- Environment variable (WARN, DEBUG, INFO, ERROR) - InstantiateOption passed directly to this method (take precedences over environment variable)

Loggers are created by calling `PackageLogger("<shortName>", "<packageID>")` and are registered internally.

Here the set of rules used and the outcome they are giving:

  1. If a production environment is detected (for now, only checking if file /.dockerenv exists) Use a JSON StackDriver compatible format

  2. Otherwise Use a developer friendly colored format

This need some more documentation, it's not documenting the other options that someone can pass around.

*Note* The InstantiateLoggers should be called only once per process. That could be enforced

in the future.

func IsProductionEnvironment

func IsProductionEnvironment() bool

func IsTraceEnabled deprecated

func IsTraceEnabled(shortName string, packageID string) bool

IsTraceEnabled receives the a short name value (usually the app name) and the fully qualified package identifier (i.e. `github.com/dfuse-io/logging/subpackage`) and determines if tracing should be enabled for such values.

To take the decision, this function inspects the `TRACE` environment variable. If the variable is **not** set, tracing is disabled. If the value is either `true`, `*` or `.*`, then tracing is enabled.

For other values, we split the `TRACE` value using `,` separator. For each split element, if the element matches directly the short name, tracing is enabled and if the element as a Regexp object matches (partially, not fully) the `packageID`, tracing is enabled.

The method also supports deny elements. If you prefix the element with `-`, it means disable trace for this match. This is applied after all allow element has been processed, so it's possible to enabled except a specific package (i.e. `TRACE=.*,-github.com/specific/package`).

In all other cases, tracing is disabled.

Deprecated: Define your logger and `Tracer` directly with `var zlog, tracer = logging.PackageLogger(<shortName>, "...")` instead of separately, `tracer.Enabled()` can then be used to determine if tracing should be enabled (can be enable dynamically).

func LevelFromEnvironment

func LevelFromEnvironment() zap.AtomicLevel

func Logger

func Logger(ctx context.Context, fallbackLogger *zap.Logger) *zap.Logger

Logger is used to retrieved the logger from the context. If no logger is present in the context, the `fallbackLogger` received in parameter is returned instead.

func MustCreateLogger deprecated

func MustCreateLogger(opts ...zap.Option) *zap.Logger

Deprecated: You should use MustCreateLoggerWithServiceName

func MustCreateLoggerWithLevel

func MustCreateLoggerWithLevel(serviceName string, atomicLevel zap.AtomicLevel, opts ...zap.Option) *zap.Logger

MustCreateLoggerWithLevel behaves exactly like `MustCreateLogger`, but you can pass the atomic level that should be used for the logger that will use this atomic level. By keeping a reference to it, later on, you will be able to change the level at runtime by calling `atomicLevel.SetLevel` on your reference and logger level will be changed.

func MustCreateLoggerWithServiceName

func MustCreateLoggerWithServiceName(serviceName string, opts ...zap.Option) *zap.Logger

MustCreateLogger has the same behavior as `CreateLogger` function. However, it automatically panic if the logger was not created successfully.

func NewEncoder

func NewEncoder(verbosity int, enableColors bool) zapcore.Encoder

func Override deprecated

func Override(logger *zap.Logger)

Override sets the given logger on previously registered and next registrations. Useful in tests.

Deprecated: Call `logging.InstantiateLoggers` directly and use the `logging.WithDefaultSpec` to configure the various loggers.

func Register deprecated

func Register(packageID string, zlogPtr **zap.Logger, options ...LoggerOption)

Deprecated: Use `var zlog, _ = logging.PackageLogger(<shortName>, "...")` instead.

func Set

func Set(logger *zap.Logger, regexps ...string)

func TestingOverride deprecated

func TestingOverride()

TestingOverride calls `Override` (or `Set`, see below) with a development logger setup correctly with the right level based on some environment variables.

By default, override using a `zap.NewDevelopment` logger (`info`), if environment variable `DEBUG` is set to anything or environment variable `TRACE` is set to `true`, logger is set in `debug` level.

If `DEBUG` is set to something else than `true` and/or if `TRACE` is set to something else than

Deprecated: Call `logging.InstantiateLoggers` directly instead.

func Warn

func Warn(ctx context.Context, fallbackLogger *zap.Logger, msg string, fields ...zapcore.Field)

Warn is a shortcut for `Logger(ctx, zlog).Warn("some message", ...some fields)`

func WithLevel

func WithLevel(level zapcore.Level) zap.Option

WithLevel returns a zap WrapCore option that change the underlying level.

*Important!* This does not work with all underlying core

implementation. See https://github.com/uber-go/zap/issues/581#issuecomment-600641485
for details.

func WithLogger

func WithLogger(ctx context.Context, logger *zap.Logger) context.Context

WithLogger is used to create a new context with a logger added to it so it can be later retrieved using `Logger`.

Types

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

func (Encoder) AddArray

func (enc Encoder) AddArray(key string, arr zapcore.ArrayMarshaler) error

func (Encoder) AddBinary

func (enc Encoder) AddBinary(key string, val []byte)

func (Encoder) AddBool

func (enc Encoder) AddBool(key string, val bool)

func (Encoder) AddByteString

func (enc Encoder) AddByteString(key string, val []byte)

func (Encoder) AddComplex128

func (enc Encoder) AddComplex128(key string, val complex128)

func (Encoder) AddComplex64

func (enc Encoder) AddComplex64(k string, v complex64)

func (Encoder) AddDuration

func (enc Encoder) AddDuration(key string, val time.Duration)

func (Encoder) AddFloat32

func (enc Encoder) AddFloat32(k string, v float32)

func (Encoder) AddFloat64

func (enc Encoder) AddFloat64(key string, val float64)

func (Encoder) AddInt

func (enc Encoder) AddInt(k string, v int)

func (Encoder) AddInt16

func (enc Encoder) AddInt16(k string, v int16)

func (Encoder) AddInt32

func (enc Encoder) AddInt32(k string, v int32)

func (Encoder) AddInt64

func (enc Encoder) AddInt64(key string, val int64)

func (Encoder) AddInt8

func (enc Encoder) AddInt8(k string, v int8)

func (Encoder) AddObject

func (enc Encoder) AddObject(key string, obj zapcore.ObjectMarshaler) error

func (Encoder) AddReflected

func (enc Encoder) AddReflected(key string, obj interface{}) error

func (Encoder) AddString

func (enc Encoder) AddString(key, val string)

func (Encoder) AddTime

func (enc Encoder) AddTime(key string, val time.Time)

func (Encoder) AddUint

func (enc Encoder) AddUint(k string, v uint)

func (Encoder) AddUint16

func (enc Encoder) AddUint16(k string, v uint16)

func (Encoder) AddUint32

func (enc Encoder) AddUint32(k string, v uint32)

func (Encoder) AddUint64

func (enc Encoder) AddUint64(key string, val uint64)

func (Encoder) AddUint8

func (enc Encoder) AddUint8(k string, v uint8)

func (Encoder) AddUintptr

func (enc Encoder) AddUintptr(k string, v uintptr)

func (Encoder) AppendArray

func (enc Encoder) AppendArray(arr zapcore.ArrayMarshaler) error

func (Encoder) AppendBool

func (enc Encoder) AppendBool(val bool)

func (Encoder) AppendByteString

func (enc Encoder) AppendByteString(val []byte)

func (Encoder) AppendComplex128

func (enc Encoder) AppendComplex128(val complex128)

func (Encoder) AppendComplex64

func (enc Encoder) AppendComplex64(v complex64)

func (Encoder) AppendDuration

func (enc Encoder) AppendDuration(val time.Duration)

func (Encoder) AppendFloat32

func (enc Encoder) AppendFloat32(v float32)

func (Encoder) AppendFloat64

func (enc Encoder) AppendFloat64(v float64)

func (Encoder) AppendInt

func (enc Encoder) AppendInt(v int)

func (Encoder) AppendInt16

func (enc Encoder) AppendInt16(v int16)

func (Encoder) AppendInt32

func (enc Encoder) AppendInt32(v int32)

func (Encoder) AppendInt64

func (enc Encoder) AppendInt64(val int64)

func (Encoder) AppendInt8

func (enc Encoder) AppendInt8(v int8)

func (Encoder) AppendObject

func (enc Encoder) AppendObject(obj zapcore.ObjectMarshaler) error

func (Encoder) AppendReflected

func (enc Encoder) AppendReflected(val interface{}) error

func (Encoder) AppendString

func (enc Encoder) AppendString(val string)

func (Encoder) AppendTime

func (enc Encoder) AppendTime(val time.Time)

func (Encoder) AppendTimeLayout

func (enc Encoder) AppendTimeLayout(time time.Time, layout string)

func (Encoder) AppendUint

func (enc Encoder) AppendUint(v uint)

func (Encoder) AppendUint16

func (enc Encoder) AppendUint16(v uint16)

func (Encoder) AppendUint32

func (enc Encoder) AppendUint32(v uint32)

func (Encoder) AppendUint64

func (enc Encoder) AppendUint64(val uint64)

func (Encoder) AppendUint8

func (enc Encoder) AppendUint8(v uint8)

func (Encoder) AppendUintptr

func (enc Encoder) AppendUintptr(v uintptr)

func (Encoder) Clone

func (c Encoder) Clone() zapcore.Encoder

func (Encoder) EncodeEntry

func (c Encoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error)

func (Encoder) OpenNamespace

func (enc Encoder) OpenNamespace(key string)

type InstantiateOption

type InstantiateOption interface {
	// contains filtered or unexported methods
}

func WithConsoleToStderr

func WithConsoleToStderr() InstantiateOption

WithConsoleToStderr configures the console to log to `stderr`, which is the default.

func WithConsoleToStdout

func WithConsoleToStdout() InstantiateOption

WithConsoleToStdout configures the console to log to `stdout` instead of the default which is to log to `stderr`.

func WithDefaultLevel

func WithDefaultLevel(level zapcore.Level) InstantiateOption

WithDefaultLevel is going to set `level` as the default level for all loggers instantiated.

func WithDefaultSpec

func WithDefaultSpec(specs ...string) InstantiateOption

WithDefaultSpec is going to set `level` of the loggers affected by the spec, each entry being of the form `<matcher>=<level>` where the `matcher` is the matching input (can be a short name directly or a regex matched against short name and package ID second).

This has more precedence over `WithDefaultLevel` which means that it's possible to use `WithDefaultLevel(zapcore.InfoLevel)` and then be more specific providing `WithDefaultSpec(...)` with some entries.

func WithLogLevelSwitcherServerAutoStart

func WithLogLevelSwitcherServerAutoStart() InstantiateOption

WithLogLevelSwitcherServerAutoStart is going to start the HTTP server that enables switching log levels dynamically based on a key without relying on the built-in production environment detector to determine if in production and only then starting the HTTP server.

If not specified, the default behavior is to start the HTTP server for dynamic log switching only if the production environment detector detected that we are in a production environment.

Once the HTTP server is started, you can use:

curl -XPUT -d '{"level":"debug","inputs":"true"}' http://localhost:1065

Which in this example above, would change all

func WithLogLevelSwitcherServerListeningAddress

func WithLogLevelSwitcherServerListeningAddress(addr string) InstantiateOption

WithLogLevelSwitcherServerListeningAddress configures the listening address the HTTP server log level switcher listens to if started.

**Note** This does **not** automatically activate the level switcher server, you still must used `WithSwitcherServerAutoStart` option or start it manually for this option to have any effect.

func WithOutputToFile

func WithOutputToFile(logFile string) InstantiateOption

WithOutputToFile configures the loggers to write to the `logFile` received in the argument in **addition** to the console logging that is performed automatically.

The actual format of the log file will a JSON fromat `stackdriver` format which is ultimately just a JSON logger with formatted in such that is ingestible by Stackdriver compatible ingestor(s) (todays know as Google Cloud Operations).

func WithProductionDetector

func WithProductionDetector(productionLoggerDetector func() bool) InstantiateOption

WithProductionDetector changes the production environment detector to the one provided as argument.

The default production environment detector tries to infer if running inside a container through various checks. If you want to use a different production environment detector, use this option.

func WithProductionLogger

func WithProductionLogger() InstantiateOption

The actual production logger is automatically inferred based on various environmental conditions, defaulting to `stackdriver` format which is ultimately just a JSON logger with formatted in such that is ingestible by Stackdriver compatible ingestor(s) (todays know as Google Cloud Operations).

func WithReportAllErrors

func WithReportAllErrors() InstantiateOption

func WithServiceName deprecated

func WithServiceName(name string) InstantiateOption

Deprecated: Will be removed in a future version, if your were using that in `ApplicationLogger`, use `RootLogger` and set the option there then in a `init` func in your main entry point, call `InstantiateLoggers`.

func WithSwitcherServerAutoStart deprecated

func WithSwitcherServerAutoStart() InstantiateOption

Deprecated: Use `WithLogLevelSwitcherServerAutoStart` instead

func WithSwitcherServerListeningAddress deprecated

func WithSwitcherServerListeningAddress(addr string) InstantiateOption

Deprecated: Use `WithLogLevelSwitcherServerListeningAddress` instead

type LoggerExtender

type LoggerExtender func(*zap.Logger) *zap.Logger

type LoggerOption

type LoggerOption interface {
	// contains filtered or unexported methods
}

LoggerOption are option parameters that you can set when creating a `PackageLogger`.

func LoggerDefaultLevel

func LoggerDefaultLevel(level zapcore.Level) LoggerOption

LoggerDefaultLevel can be used to set the default level of the logger if nothing else is overriding it.

While the library offers you to set the default level, we recommend to not use this method unless you feel is strictly necessary, specially in libraries code. Indeed, setting for example your level to `INFO` on the loggers of your library would mean that anyone importing your code and instantiating the loggers would automatically see your `INFO` log line which is usually disruptive.

Instead of using this, use `logging.WithDefaultSpec` to specify a default level via the logger's short name for example.

func LoggerOnUpdate

func LoggerOnUpdate(onUpdate func(newLogger *zap.Logger)) LoggerOption

LoggerOnUpdate enable you to have a hook function that will receive the new logger that is going to be assigned to your logger instance. This is useful in some situation where you need to update other instances or re-configuring a bit the logger when a new one is attached.

This is called **after** the instance has been re-assigned.

func RegisterOnUpdate deprecated

func RegisterOnUpdate(onUpdate func(newLogger *zap.Logger)) LoggerOption

Deprecated: Use LoggerOnUpdate instead.

type Registry

type Registry interface {
	InstantiateLogger(packageID string)
	Register(shortName string, packageID string, options ...LoggerOption) (*zap.Logger, Tracer)
	SetLevel(filterString string, level zapcore.Level, tracer bool)
	GetLoggerByPackageID(packageID string) (*zap.Logger, Tracer, bool)
}

func NewRegistry

func NewRegistry(name string) Registry

type TestLogger

type TestLogger struct {
	// contains filtered or unexported fields
}

func NewTestLogger

func NewTestLogger(t testing.T) *TestLogger

func (*TestLogger) Instance

func (l *TestLogger) Instance() *zap.Logger

Instance returns the actual *zap.Logger you should pass to your dependency to accumulate log lines and inspect them later on.

func (*TestLogger) RecordedLines

func (w *TestLogger) RecordedLines(t testing.T) (out []string)

RecordedLines returns all the logged line seen, each line being a full fledged JSON value

type Tracer

type Tracer interface {
	Enabled() bool
}

func ApplicationLogger

func ApplicationLogger(shortName string, packageID string, opts ...InstantiateOption) (*zap.Logger, Tracer)

ApplicationLogger calls `RootLogger` followed by `InstantiateLoggers`. It's a one-liner when creating scripts to both create the root logger and instantiate all loggers.

If you require configuring some details of the root logger, make the two calls manually.

func PackageLogger

func PackageLogger(shortName string, packageID string, registerOptions ...LoggerOption) (*zap.Logger, Tracer)

PackageLogger creates a new no-op logger (via `zap.NewNop`) and automatically registered it withing the logging registry with a tracer that can be be used for conditionally tracing code.

You should used this in packages that are not `main` packages

func RootLogger

func RootLogger(shortName string, packageID string, opts ...LoggerOption) (*zap.Logger, Tracer)

RootLogger should be used to get a logger for a top-level binary application which will immediately activate all registered loggers with a logger. The actual logger for all component used is deried based on the identified environment and from environment variables.

Here the set of rules used and the outcome they are giving:

  1. If a production environment is detected (for now, only checking if file /.dockerenv exists) Use a JSON StackDriver compatible format

  2. Otherwise Use a developer friendly colored format

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL