logger

package module
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2023 License: MIT Imports: 14 Imported by: 0

README

go-logger GoDoc Build Status

Library for integrating zap logger with Sentry.

Installation

go get -u go.pr0ger.dev/logger

Show me the code

// Create core for logging to stdout/stderr
localCore := logger.NewCore(true)

// Create core splitter to logging both to local and sentry
// zapcore.NewTee also can be used, but is not recommended if you want to use RequestLogger middleware
core := logger.NewSentryCoreWrapper(localCore, sentry.CurrentHub())

// And create logger
log := zap.New(core)

log.Debug("this event will be logged to stdout but will not appear in request breadcrumbs")

// Create handler for network requests
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    log := logger.Ctx(r.Context())

    log.Debug("some debug logs from request")

    // Create an HTTP client with our transport 
    client := http.Client{
        Transport: logger.NewBreadcrumbTransport(sentry.LevelInfo, http.DefaultTransport),
    }
    
    // We need to pass current context to HTTP request so transport will know where to log
    req, _ := http.NewRequestWithContext(r.Context(), http.MethodGet, "https://go.pr0ger.dev/logger", nil)

    resp, err := client.Do(req)
    if err != nil {
        log.Warn("request failed", zap.Error(err))
    } else {
        log.Info(fmt.Sprintf("Response status: %s", resp.Status))
        resp.Body.Close()
    }

    log.Error("let's assume we have an error here")
})

// And use it with our middleware
server := &http.Server{
    Addr:    ":8080",
    Handler: logger.RequestLogger(log)(handler),
}

_ = server.ListenAndServe()

event

Documentation

Overview

Example (BreadcrumbTransport)
// This will not work without SENTRY_DSN environment variable
_ = sentry.Init(sentry.ClientOptions{
	Transport: sentry.NewHTTPSyncTransport(),
})

// Create non-default http-client with
client := http.Client{
	Transport: NewBreadcrumbTransport(sentry.LevelDebug, nil),
}

// Create context with sentry.Hub
// This is not required: if hub is not available from context sentry.CurrentHub() will be used instead
ctx := WithHub(context.Background(), sentry.CurrentHub())

req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://go.pr0ger.dev/", nil)
resp, err := client.Do(req)
if err != nil {
	// Either send error to sentry
	sentry.CaptureException(err)
	return
}
defer resp.Body.Close()

// Or just log response
sentry.CaptureMessage(fmt.Sprintf("Response status: %s", resp.Status))

// Either way it will contain full info about request in breadcrumb
Output:

Example (Simple)
// This will not work without SENTRY_DSN environment variable
_ = sentry.Init(sentry.ClientOptions{
	Transport: sentry.NewHTTPSyncTransport(),
})

// Create logger for logging directly to sentry (without local output)
log := zap.New(NewSentryCore(sentry.CurrentHub()))

log.Debug("this message will be logged as breadcrumb", zap.Int("key", 1337))
log.Error("and this will create event in sentry")

log.Error("and this message will attach stacktrace", zap.Error(errors.New("error from pkg/errors")))
Output:

Example (WebServer)
// This will not work without SENTRY_DSN environment variable
_ = sentry.Init(sentry.ClientOptions{
	Transport:        sentry.NewHTTPSyncTransport(),
	TracesSampleRate: 1,
})

// Create core for logging to stdout/stderr
localCore := NewCore(true)

// Create core splitter to logging both to local and sentry
// zapcore.NewTee also can be used, but is not recommended if you want to use RequestLogger middleware
core := NewSentryCoreWrapper(localCore, sentry.CurrentHub())

// And create logger
logger := zap.New(core)

logger.Debug("this event will be logged to stdout but will not appear in request breadcrumbs")

// Create handler for network requests
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	log := Ctx(r.Context())

	log.Debug("some debug logs from request")

	// Create an HTTP client with our transport
	client := http.Client{
		Transport: NewBreadcrumbTransport(sentry.LevelInfo, http.DefaultTransport),
	}

	// We need to pass current context to HTTP request so transport will know where to log
	req, _ := http.NewRequestWithContext(r.Context(), http.MethodGet, "https://go.pr0ger.dev/logger", nil)

	resp, err := client.Do(req)
	if err != nil {
		log.Warn("request failed", zap.Error(err))
	} else {
		log.Info(fmt.Sprintf("Response status: %s", resp.Status))
		resp.Body.Close()
	}

	_, _ = w.Write([]byte("ok"))

	log.Error("let's assume we have an error here")
})

// And use it with our middleware
server := &http.Server{
	Addr:    ":8080",
	Handler: RequestLogger(logger)(handler),
}

_ = server.ListenAndServe()
Output:

Index

Examples

Constants

View Source
const (
	// BreadcrumbTypeDefault describes a generic breadcrumb.
	BreadcrumbTypeDefault = "default"

	// BreadcrumbTypeHTTP describes an HTTP request breadcrumb.
	BreadcrumbTypeHTTP = "http"
)

https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/#breadcrumb-types

View Source
const (
	BreadcrumbDataURL        = "url"
	BreadcrumbDataMethod     = "method"
	BreadcrumbDataStatusCode = "status_code"
	BreadcrumbDataReason     = "reason"
)

Describes data for an HTTP request breadcrumb https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/#http

Variables

This section is empty.

Functions

func Ctx

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

Ctx returns the in-context Logger for a request. If no logger is associated returns no-op logger.

func ForkedLogger added in v1.3.0

func ForkedLogger(logger *zap.Logger) *zap.Logger

ForkedLogger will return a new logger with isolated sentry.Hub. No-op if logger is not using SentryCore.

func Hub

func Hub(ctx context.Context) *sentry.Hub

Hub returns the sentry.Hub associated with the context. If no hub is associated returns CurrentHub().

func NewBreadcrumbTransport

func NewBreadcrumbTransport(level sentry.Level, transport http.RoundTripper) http.RoundTripper

func NewCore

func NewCore(debug bool) zapcore.Core

NewCore will create handy Core with sensible defaults: - messages with error level and higher will go to stderr, everything else to stdout - use json encoder for production and console for development.

func NewSentryCore

func NewSentryCore(hub *sentry.Hub, options ...SentryCoreOption) zapcore.Core

func NewSentryCoreWrapper

func NewSentryCoreWrapper(localCore zapcore.Core, hub *sentry.Hub, options ...SentryCoreOption) zapcore.Core

NewSentryCoreWrapper creates a Core that duplicates log entries into provided local Core and implicitly created Sentry core.

func RequestID added in v1.2.0

func RequestID(ctx context.Context) string

func RequestLogger

func RequestLogger(logger *zap.Logger) func(next http.Handler) http.Handler

RequestLogger is a middleware for injecting sentry.Hub and zap.Logger into request context. If provided logger has sentryCoreWrapper as core injected logger will have core with same local core and sentry core based on an empty Hub for each request so breadcrumbs list will be empty each time. In other case logger.Core() will be used as a local core and sentry core will be created if sentry is initialized.

func SentryLevel

func SentryLevel(level zapcore.Level) sentry.Level

func SpanStatus added in v1.3.0

func SpanStatus(httpCode int) sentry.SpanStatus

func WithExtraFields added in v1.4.0

func WithExtraFields(fieldsGenerator func(r *http.Request) []zap.Field) func(next http.Handler) http.Handler

WithExtraFields is a middleware for injecting extra field to the logger injected by RequestLogger middleware.

func WithHub

func WithHub(ctx context.Context, hub *sentry.Hub) context.Context

WithHub returns a copy of provided context with added hub field.

func WithLogger

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

WithLogger returns a copy of provided context with added logger field.

func WithRequestID added in v1.2.0

func WithRequestID(ctx context.Context, requestID string) context.Context

WithRequestID returns a copy of provided context with added request id field.

Types

type SentryCore

type SentryCore struct {
	zapcore.LevelEnabler

	BreadcrumbLevel zapcore.Level
	EventLevel      zapcore.Level
	// contains filtered or unexported fields
}

func (*SentryCore) Check

func (*SentryCore) Sync

func (s *SentryCore) Sync() error

func (*SentryCore) With

func (s *SentryCore) With(fields []zapcore.Field) zapcore.Core

func (*SentryCore) Write

func (s *SentryCore) Write(ent zapcore.Entry, fields []zapcore.Field) error

type SentryCoreOption

type SentryCoreOption func(*SentryCore)
func BreadcrumbLevel(level zapcore.Level) SentryCoreOption

BreadcrumbLevel will set a minimum level of messages should be stored as breadcrumbs.

func EventLevel

func EventLevel(level zapcore.Level) SentryCoreOption

EventLevel will set a minimum level of messages should be sent as events.

type WrapResponseWriter added in v1.2.0

type WrapResponseWriter interface {
	http.ResponseWriter

	Status() int

	BytesWritten() int
}

func NewWrapResponseWriter added in v1.2.0

func NewWrapResponseWriter(w http.ResponseWriter, protoMajor int) WrapResponseWriter

Jump to

Keyboard shortcuts

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