log

package
v0.25.2 Latest Latest
Warning

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

Go to latest
Published: Apr 5, 2024 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package log provides a global logger for zerolog.

Example

This example uses command-line flags to demonstrate various outputs depending on the chosen log level.

package main

import (
	"context"
	"flag"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		debug := flag.Bool("debug", false, "sets log level to debug")

		flag.Parse()

		// Default level for this example is info, unless debug flag is present
		zerolog.SetGlobalLevel(zerolog.InfoLevel)
		if *debug {
			zerolog.SetGlobalLevel(zerolog.DebugLevel)
		}

		log.Debug(context.Background()).Msg("This message appears only when log level set to Debug")
		log.Info(context.Background()).Msg("This message appears when log level set to Debug or Info")

		if e := log.Debug(context.Background()); e.Enabled() {
			// Compute log output only if enabled.
			value := "bar"
			e.Str("foo", value).Msg("some debug message")
		}
	})
}
Output:

{"level":"info","time":"2008-01-08T17:05:05Z","message":"This message appears when log level set to Debug or Info"}

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrUnknownAccessLogField = errors.New("unknown access log field")

ErrUnknownAccessLogField indicates that an access log field is unknown.

View Source
var ErrUnknownAuthorizeLogField = errors.New("unknown authorize log field")

ErrUnknownAuthorizeLogField indicates that an authorize log field is unknown.

Functions

func AccessHandler added in v0.0.5

func AccessHandler(f func(r *http.Request, status, size int, duration time.Duration)) func(next http.Handler) http.Handler

AccessHandler returns a handler that call f after each request.

func CanonicalHeaderKey added in v0.23.0

func CanonicalHeaderKey(k string) string

CanonicalHeaderKey converts a header name into its canonical form using http.CanonicalHeaderKey. It also supports HTTP/2 headers that start with : by lowercasing them.

func Ctx

func Ctx(ctx context.Context) *zerolog.Logger

Ctx returns the Logger associated with the ctx. If no logger is associated, a disabled logger is returned.

func Debug

func Debug(ctx context.Context) *zerolog.Event

Debug starts a new message with debug level.

You must call Msg on the returned event in order to send the event.

Example

Example of a log at a particular "level" (in this case, "debug")

package main

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Debug(context.Background()).Msg("hello world")
	})
}
Output:

{"level":"debug","time":"2008-01-08T17:05:05Z","message":"hello world"}

func Error

func Error(ctx context.Context) *zerolog.Event

Error starts a new message with error level.

You must call Msg on the returned event in order to send the event.

Example

Example of a log at a particular "level" (in this case, "error")

package main

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Error(context.Background()).Msg("hello world")
	})
}
Output:

{"level":"error","time":"2008-01-08T17:05:05Z","message":"hello world"}

func Fatal

func Fatal() *zerolog.Event

Fatal starts a new message with fatal level. The os.Exit(1) function is called by the Msg method.

You must call Msg on the returned event in order to send the event.

Example

Example of a log at a particular "level" (in this case, "fatal")

package main

import (
	"errors"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		err := errors.New("a repo man spends his life getting into tense situations")
		service := "myservice"

		log.Fatal().
			Err(err).
			Str("service", service).
			Msg("Cannot start")
	})
	// Outputs: {"level":"fatal","time":"2008-01-08T17:05:05Z","error":"a repo man spends his life getting into tense situations","service":"myservice","message":"Cannot start myservice"}
}
Output:

func FromRequest added in v0.0.2

func FromRequest(r *http.Request) *zerolog.Logger

FromRequest gets the logger in the request's context. This is a shortcut for log.Ctx(r.Context())

func GetHeaderField added in v0.23.0

func GetHeaderField[TField interface{ ~string }](field TField) (headerName string, ok bool)

GetHeaderField returns the header name for a field that represents logging a header value.

func HTTPHeaders added in v0.23.0

func HTTPHeaders[TField interface{ ~string }](
	evt *zerolog.Event,
	fields []TField,
	src map[string]string,
) *zerolog.Event

HTTPHeaders logs http headers based on supplied fields and a map of all headers.

func HeadersHandler added in v0.5.1

func HeadersHandler(headers []string) func(next http.Handler) http.Handler

HeadersHandler adds the provided set of header keys to the log context.

https://tools.ietf.org/html/rfc7239 https://en.wikipedia.org/wiki/X-Forwarded-For https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For

func Info

func Info(ctx context.Context) *zerolog.Event

Info starts a new message with info level.

You must call Msg on the returned event in order to send the event.

Example

Example of a log at a particular "level" (in this case, "info")

package main

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Info(context.Background()).Msg("hello world")
	})
}
Output:

{"level":"info","time":"2008-01-08T17:05:05Z","message":"hello world"}

func Level

func Level(ctx context.Context, level zerolog.Level) *zerolog.Logger

Level creates a child logger with the minimum accepted level set to level.

func Log

func Log(_ context.Context) *zerolog.Event

Log starts a new message with no level. Setting zerolog.GlobalLevel to zerolog.Disabled will still disable events produced by this method.

You must call Msg on the returned event in order to send the event.

Example

Example of a log with no particular "level"

package main

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Log(context.Background()).Msg("hello world")
	})
}
Output:

{"time":"2008-01-08T17:05:05Z","message":"hello world"}

func Logger

func Logger() *zerolog.Logger

Logger returns the zerolog Logger.

func NewHandler added in v0.0.5

func NewHandler(getLogger func() *zerolog.Logger) func(http.Handler) http.Handler

NewHandler injects log into requests context.

func Panic

func Panic() *zerolog.Event

Panic starts a new message with panic level. The message is also sent to the panic function.

You must call Msg on the returned event in order to send the event.

func Print

func Print(v ...interface{})

Print sends a log event using debug level and no extra field. Arguments are handled in the manner of fmt.Print.

Example

Simple logging example using the Print function in the log package Note that both Print and Printf are at the debug log level by default

package main

import (
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Print("hello world")
	})
}
Output:

{"level":"debug","time":"2008-01-08T17:05:05Z","message":"hello world"}

func Printf

func Printf(format string, v ...interface{})

Printf sends a log event using debug level and no extra field. Arguments are handled in the manner of fmt.Printf.

Example

Simple logging example using the Printf function in the log package

package main

import (
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Printf("hello %s", "world")
	})
}
Output:

{"level":"debug","time":"2008-01-08T17:05:05Z","message":"hello world"}

func RefererHandler added in v0.0.5

func RefererHandler(fieldKey string) func(next http.Handler) http.Handler

RefererHandler adds the request's referer as a field to the context's logger using fieldKey as field key.

func RemoteAddrHandler added in v0.0.5

func RemoteAddrHandler(fieldKey string) func(next http.Handler) http.Handler

RemoteAddrHandler adds the request's remote address as a field to the context's logger using fieldKey as field key.

func RequestIDHandler added in v0.0.5

func RequestIDHandler(fieldKey string) func(next http.Handler) http.Handler

RequestIDHandler adds the request's id as a field to the context's logger using fieldKey as field key.

func SetLevel added in v0.0.3

func SetLevel(level zerolog.Level)

SetLevel sets the minimum global log level.

Example
package main

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.SetLevel(zerolog.InfoLevel)
		log.Debug(context.Background()).Msg("Debug")
		log.Info(context.Background()).Msg("Debug or Info")
		log.SetLevel(zerolog.WarnLevel)
		log.Debug(context.Background()).Msg("Debug")
		log.Info(context.Background()).Msg("Debug or Info")
		log.Warn(context.Background()).Msg("Debug or Info or Warn")
		log.SetLevel(zerolog.ErrorLevel)
		log.Debug(context.Background()).Msg("Debug")
		log.Info(context.Background()).Msg("Debug or Info")
		log.Warn(context.Background()).Msg("Debug or Info or Warn")
		log.Error(context.Background()).Msg("Debug or Info or Warn or Error")
		log.SetLevel(zerolog.DebugLevel)
		log.Debug(context.Background()).Msg("Debug")
	})
}
Output:

{"level":"info","time":"2008-01-08T17:05:05Z","message":"Debug or Info"}
{"level":"warn","time":"2008-01-08T17:05:05Z","message":"Debug or Info or Warn"}
{"level":"error","time":"2008-01-08T17:05:05Z","message":"Debug or Info or Warn or Error"}
{"level":"debug","time":"2008-01-08T17:05:05Z","message":"Debug"}

func UserAgentHandler added in v0.0.5

func UserAgentHandler(fieldKey string) func(next http.Handler) http.Handler

UserAgentHandler adds the request's user-agent as a field to the context's logger using fieldKey as field key.

func Warn

func Warn(ctx context.Context) *zerolog.Event

Warn starts a new message with warn level.

You must call Msg on the returned event in order to send the event.

Example

Example of a log at a particular "level" (in this case, "warn")

package main

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		log.Warn(context.Background()).Msg("hello world")
	})
}
Output:

{"level":"warn","time":"2008-01-08T17:05:05Z","message":"hello world"}

func WarnCookieSecret added in v0.20.0

func WarnCookieSecret()

WarnCookieSecret warns about the cookie secret.

func WarnNoTLSCertificate added in v0.20.0

func WarnNoTLSCertificate(domain string)

WarnNoTLSCertificate warns about no TLS certificate.

func WarnWebSocketHTTP1_1 added in v0.20.0

func WarnWebSocketHTTP1_1(clusterID string)

WarnWebSocketHTTP1_1 warns about falling back to http 1.1 due to web socket support.

func With

func With() zerolog.Context

With creates a child logger with the field added to its context.

Example
package main

import (
	"os"
	"time"

	"github.com/rs/zerolog"
	zerologlog "github.com/rs/zerolog/log"

	"github.com/pomerium/pomerium/internal/log"
)

func captureOutput(f func()) {

	originalTimestampFunc := zerolog.TimestampFunc
	zerolog.TimestampFunc = func() time.Time {
		return time.Date(2008, 1, 8, 17, 5, 5, 0, time.UTC)
	}

	originalLogger := zerologlog.Logger
	newLogger := originalLogger.
		Output(os.Stdout).
		Level(zerolog.TraceLevel)
	zerologlog.Logger = newLogger
	zerolog.DefaultContextLogger = &newLogger

	f()

	zerolog.DefaultContextLogger = &originalLogger
	zerolog.TimestampFunc = originalTimestampFunc
	zerologlog.Logger = originalLogger
}

func main() {
	captureOutput(func() {
		sublog := log.With().Str("foo", "bar").Logger()
		sublog.Debug().Msg("hello world")
	})
}
Output:

{"level":"debug","foo":"bar","time":"2008-01-08T17:05:05Z","message":"hello world"}

func WithContext added in v0.14.0

func WithContext(ctx context.Context, update func(c zerolog.Context) zerolog.Context) context.Context

WithContext returns a context that has an associated logger and extra fields set via update

func ZapLogger added in v0.11.0

func ZapLogger() *zap.Logger

ZapLogger returns the global zap logger.

Types

type AccessLogField added in v0.23.0

type AccessLogField string

An AccessLogField is a field in the access logs.

const (
	AccessLogFieldAuthority           AccessLogField = "authority"
	AccessLogFieldDuration            AccessLogField = "duration"
	AccessLogFieldForwardedFor        AccessLogField = "forwarded-for"
	AccessLogFieldIP                  AccessLogField = "ip"
	AccessLogFieldMethod              AccessLogField = "method"
	AccessLogFieldPath                AccessLogField = "path"
	AccessLogFieldQuery               AccessLogField = "query"
	AccessLogFieldReferer             AccessLogField = "referer"
	AccessLogFieldRequestID           AccessLogField = "request-id"
	AccessLogFieldResponseCode        AccessLogField = "response-code"
	AccessLogFieldResponseCodeDetails AccessLogField = "response-code-details"
	AccessLogFieldSize                AccessLogField = "size"
	AccessLogFieldUpstreamCluster     AccessLogField = "upstream-cluster"
	AccessLogFieldUserAgent           AccessLogField = "user-agent"
)

known access log fields

func DefaultAccessLogFields added in v0.23.0

func DefaultAccessLogFields() []AccessLogField

DefaultAccessLogFields returns the default access log fields.

func (AccessLogField) Validate added in v0.23.0

func (field AccessLogField) Validate() error

Validate returns an error if the access log field is invalid.

type AuthorizeLogField added in v0.23.0

type AuthorizeLogField string

An AuthorizeLogField is a field in the authorize logs.

const (
	AuthorizeLogFieldCheckRequestID       AuthorizeLogField = "check-request-id"
	AuthorizeLogFieldEmail                AuthorizeLogField = "email"
	AuthorizeLogFieldHeaders                                = AuthorizeLogField(headersFieldName)
	AuthorizeLogFieldHost                 AuthorizeLogField = "host"
	AuthorizeLogFieldIDToken              AuthorizeLogField = "id-token"
	AuthorizeLogFieldIDTokenClaims        AuthorizeLogField = "id-token-claims"
	AuthorizeLogFieldImpersonateEmail     AuthorizeLogField = "impersonate-email"
	AuthorizeLogFieldImpersonateSessionID AuthorizeLogField = "impersonate-session-id"
	AuthorizeLogFieldImpersonateUserID    AuthorizeLogField = "impersonate-user-id"
	AuthorizeLogFieldIP                   AuthorizeLogField = "ip"
	AuthorizeLogFieldMethod               AuthorizeLogField = "method"
	AuthorizeLogFieldPath                 AuthorizeLogField = "path"
	AuthorizeLogFieldQuery                AuthorizeLogField = "query"
	AuthorizeLogFieldRequestID            AuthorizeLogField = "request-id"
	AuthorizeLogFieldServiceAccountID     AuthorizeLogField = "service-account-id"
	AuthorizeLogFieldSessionID            AuthorizeLogField = "session-id"
	AuthorizeLogFieldUser                 AuthorizeLogField = "user"
)

known authorize log fields

func DefaultAuthorizeLogFields added in v0.23.0

func DefaultAuthorizeLogFields() []AuthorizeLogField

DefaultAuthorizeLogFields returns the default authorize log fields.

func (AuthorizeLogField) Validate added in v0.23.0

func (field AuthorizeLogField) Validate() error

Validate returns an error if the authorize log field is invalid.

type MultiWriter added in v0.25.0

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

A MultiWriter dispatches writes to multiple writers.

var Writer *MultiWriter

Writer is where logs are written.

func NewMultiWriter added in v0.25.0

func NewMultiWriter() *MultiWriter

NewMultiWriter creates a new MultiWriter

func (*MultiWriter) Add added in v0.25.0

func (m *MultiWriter) Add(w io.Writer)

Add adds a writer to the multi writer.

func (*MultiWriter) Remove added in v0.25.0

func (m *MultiWriter) Remove(w io.Writer)

Remove removes a writer from the multi writer.

func (*MultiWriter) Write added in v0.25.0

func (m *MultiWriter) Write(data []byte) (int, error)

Write writes data to all the writers. The last count and error are returned.

type StdLogWrapper added in v0.0.3

type StdLogWrapper struct {
	*zerolog.Logger
}

StdLogWrapper can be used to wrap logs originating from the from std library's ErrorFunction argument in http.Serve and httputil.ReverseProxy.

func (*StdLogWrapper) Write added in v0.0.3

func (l *StdLogWrapper) Write(p []byte) (n int, err error)

Jump to

Keyboard shortcuts

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