logadapter

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2019 License: MIT Imports: 13 Imported by: 0

README

logrus-stackdriver-formatter

Go Report Card GoDoc License MIT

Logrus-stackdriver-formatter provides:

In addition to supporting level-based logging to Stackdriver, for Error, Fatal and Panic levels it will append error context for Error Reporting.

Installation

go get -u github.com/TV4/logrus-stackdriver-formatter
Logrus Usage
package main

import (

stackdriver "github.com/StevenACoffman/logrus-stackdriver-formatter"
"github.com/sirupsen/logrus"
)

var log = logrus.New()

func init() {
    log.Formatter = stackdriver.NewFormatter(
        stackdriver.WithService("your-service"), 
        stackdriver.WithVersion("v0.1.0"),
    )
    log.Level = logrus.DebugLevel

    log.Info("ready to log!")
}

Here's a sample entry (prettified) from the example:

{
  "serviceContext": {
    "service": "test-service",
    "version": "v0.1.0"
  },
  "message": "unable to parse integer: strconv.ParseInt: parsing \"text\": invalid syntax",
  "severity": "ERROR",
  "context": {
    "reportLocation": {
      "file": "github.com/StevenACoffman/logrus-stackdriver-formatter/example_test.go",
      "line": 21,
      "function": "ExampleLogError"
    }
  }
}
HTTP request context

If you'd like to add additional context like the httpRequest, here's a convenience function for creating a HTTP logger:

func httpLogger(logger *logrus.Logger, r *http.Request) *logrus.Entry {
    return logger.WithFields(logrus.Fields{
        "httpRequest": map[string]interface{}{
            "method":    r.Method,
            "url":       r.URL.String(),
            "userAgent": r.Header.Get("User-Agent"),
            "referrer":  r.Header.Get("Referer"),
        },
    })
}

Then, in your HTTP handler, create a new context logger and all your log entries will have the HTTP request context appended to them:

func handler(w http.ResponseWriter, r *http.Request) {
    httplog := httpLogger(log, r)
    // ...
    httplog.Infof("Logging with HTTP request context")
}
Go-kit Log Adapter

Go-kit log is wrapped to encode conventions, enforce type-safety, provide leveled logging, and so on. It can be used for both typical application log events, and log-structured data streams.

Typical application logging
import (
	"os"
	logadapter "github.com/StevenACoffman/logrus-stackdriver-formatter"
	kitlog "github.com/go-kit/kit/log"
)

func main() {
	w := kitlog.NewSyncWriter(os.Stderr)
	logger := logadapter.InitLogrusGoKitLogger(w)
	logger.Log("question", "what is the meaning of life?", "answer", 42)

	// Output:
	// question="what is the meaning of life?" answer=42
}
Contextual Loggers
import (
	"os"
	logadapter "github.com/StevenACoffman/logrus-stackdriver-formatter"
	kitlog "github.com/go-kit/kit/log"
)

func main() {
	logger := logadapter.InitLogrusGoKitLogger(kitlog.NewSyncWriter(os.Stderr))
	logger = kitlog.With(logger, "instance_id", 123)

	logger.Log("msg", "starting")
	NewWorker(kitlog.With(logger, "component", "worker")).Run()
	NewSlacker(kitlog.With(logger, "component", "slacker")).Run()
}

// Output:
// instance_id=123 msg=starting
// instance_id=123 component=worker msg=running
// instance_id=123 component=slacker msg=running

Enhancements

go-kit's package log is centered on the one-method Logger interface.

type Logger interface {
	Log(keyvals ...interface{}) error
}

This interface, and its supporting code like is the product of much iteration and evaluation. For more details on the evolution of the Logger interface, see The Hunt for a Logger Interface, a talk by Chris Hines. Also, please see #63, #76, #131, #157, #164, and #252 to review historical conversations about package log and the Logger interface.

Value-add packages and suggestions, like improvements to the leveled logger, are of course welcome. Good proposals should

Alternatives

  • Both go-kit log and logr both provide to developers clean, minimal surface area for sending log messages. However, neither has direct, first-class stackdriver support.
  • Uber's Zap is very performant, but it's SugaredLogger API is unfamiliar to me.

So one choice could be logr -> zapr -> zap -> zap-stackdriver or zapdriver but zapr still uses dep, didn't have go module support.

I could also have gone with go-kit log -> zap -> zap-stackdriver or zapdriver.

Instead, I pulled a bunch of people's forks together into this piece of mad science because it seemed like it would work. ¯\_(ツ)_/¯

Documentation

Overview

Package logadapter provides an adapter to the go-kit log.Logger interface.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InitLogging added in v0.4.0

func InitLogging(w io.Writer, opts ...Option) *logrus.Logger

InitLogging initializes a logrus logger to send things to stackdriver.

func LoggingMiddleware added in v0.4.0

func LoggingMiddleware(log *logrus.Logger) func(http.Handler) http.Handler

LoggingMiddleware is a middleware for writing request logs in a structured format to stackdriver.

Types

type Context added in v0.4.0

type Context struct {
	Data           map[string]interface{} `json:"data,omitempty"`
	ReportLocation *ReportLocation        `json:"reportLocation,omitempty"`
	HTTPRequest    *HTTPRequest           `json:"httpRequest,omitempty"`
	PubSubRequest  map[string]interface{} `json:"pubSubRequest,omitempty"`
	GRPCRequest    map[string]interface{} `json:"grpcRequest,omitempty"`
}

Context is sent with every message to stackdriver.

type Entry added in v0.4.0

type Entry struct {
	LogName        string          `json:"logName,omitempty"`
	Timestamp      string          `json:"timestamp,omitempty"`
	Trace          string          `json:"trace,omitempty"`
	ServiceContext *ServiceContext `json:"serviceContext,omitempty"`
	Message        string          `json:"message,omitempty"`
	Severity       severity        `json:"severity,omitempty"`
	Context        *Context        `json:"context,omitempty"`
	SourceLocation *ReportLocation `json:"sourceLocation,omitempty"`
}

Entry stores a log entry.

type Formatter

type Formatter struct {
	Service       string
	Version       string
	ProjectID     string
	StackSkip     []string
	SkipTimestamp bool
	RegexSkip     string
}

Formatter implements Stackdriver formatting for logrus.

func NewFormatter

func NewFormatter(options ...Option) *Formatter

NewFormatter returns a new Formatter.

func (*Formatter) Format

func (f *Formatter) Format(e *logrus.Entry) ([]byte, error)

Format formats a logrus entry according to the Stackdriver specifications.

func (*Formatter) ToEntry added in v0.4.0

func (f *Formatter) ToEntry(e *logrus.Entry) (Entry, error)

ToEntry formats a logrus entry to a stackdriver entry.

type HTTPRequest added in v0.4.0

type HTTPRequest struct {
	RequestMethod                  string `json:"requestMethod,omitempty"`
	RequestURL                     string `json:"requestUrl,omitempty"`
	RequestSize                    string `json:"requestSize,omitempty"`
	Status                         string `json:"status,omitempty"`
	ResponseSize                   string `json:"responseSize,omitempty"`
	UserAgent                      string `json:"userAgent,omitempty"`
	RemoteIP                       string `json:"remoteIp,omitempty"`
	ServerIP                       string `json:"serverIp,omitempty"`
	Referer                        string `json:"referer,omitempty"`
	Latency                        string `json:"latency,omitempty"`
	CacheLookup                    bool   `json:"cacheLookup,omitempty"`
	CacheHit                       bool   `json:"cacheHit,omitempty"`
	CacheValidatedWithOriginServer bool   `json:"cacheValidatedWithOriginServer,omitempty"`
	CacheFillBytes                 string `json:"cacheFillBytes,omitempty"`
	Protocol                       string `json:"protocol,omitempty"`
}

HTTPRequest defines details of a request and response to append to a log.

type LogrusGoKitLogger added in v0.4.0

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

LogrusGoKitLogger is a gokit-compatible wrapper for logrus.LogrusGoKitLogger

func InitLogrusGoKitLogger added in v0.4.0

func InitLogrusGoKitLogger(w io.Writer, opts ...Option) *LogrusGoKitLogger

InitLogrusGoKitLogger initializes a go kit logger to send things to stackdriver.

func NewLogrusGoKitLogger added in v0.4.0

func NewLogrusGoKitLogger(logger logrusLogger) *LogrusGoKitLogger

NewLogrusGoKitLogger creates a gokit-compatible logger

func (LogrusGoKitLogger) Log added in v0.4.0

func (l LogrusGoKitLogger) Log(keyvals ...interface{}) error

Log implements the fundamental Logger interface

type Option

type Option func(*Formatter)

Option lets you configure the Formatter.

func WithProjectID added in v0.4.0

func WithProjectID(i string) Option

WithProjectID makes sure all entries have your Project information.

func WithRegexSkip added in v0.4.0

func WithRegexSkip(v string) Option

WithRegexSkip lets you configure which functions or packages should be skipped for locating the error.

func WithService

func WithService(n string) Option

WithService lets you configure the service name used for error reporting.

func WithSkipTimestamp added in v0.4.0

func WithSkipTimestamp() Option

WithSkipTimestamp lets you avoid setting the timestamp

func WithStackSkip

func WithStackSkip(v string) Option

WithStackSkip lets you configure which packages should be skipped for locating the error.

func WithVersion

func WithVersion(v string) Option

WithVersion lets you configure the service version used for error reporting.

type ReportLocation added in v0.4.0

type ReportLocation struct {
	FilePath     string `json:"file,omitempty"`
	LineNumber   int    `json:"line,omitempty"`
	FunctionName string `json:"function,omitempty"`
}

ReportLocation is the information about where an error occurred.

type ServiceContext added in v0.4.0

type ServiceContext struct {
	Service string `json:"service,omitempty"`
	Version string `json:"version,omitempty"`
}

ServiceContext provides the data about the service we are sending to Google.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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