stalog

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2021 License: Apache-2.0 Imports: 13 Imported by: 4

README

stackdriver-request-context-log

Stackdriver Logging Go library for grouping a request log and application logs.

With this library all application logs in the request are grouped and displayed under the request log (like App Engine).

screenshot

Note that the interface of this library is still ALPHA level quality.
Breaking changes will be introduced frequently.

Install

go get -u github.com/gcp-kit/stalog

Example

This simple example shows how to integrate this library into your web application.

package main

import (
	"fmt"
	"net/http"
	"os"

	log "github.com/gcp-kit/stalog"
)

func main() {
	mux := http.NewServeMux()

	// Set request handler
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// Get request context logger
		logger := log.RequestContextLogger(r)

		// These logs are grouped with the request log
		logger.Debugf("Hi")
		logger.Infof("Hello")
		logger.Warnf("World")

		fmt.Fprintf(w, "OK\n")
	})

	projectId := "my-gcp-project"

	// Make config for this library
	config := log.NewConfig(projectId)
	config.RequestLogOut = os.Stderr            // request log to stderr
	config.ContextLogOut = os.Stdout            // context log to stdout
	config.Severity = log.SeverityInfo          // only over INFO logs are logged
	config.AdditionalData = log.AdditionalData{ // set additional fields for all logs
		"service": "foo",
		"version": 1.0,
	}

	// Set middleware for the request log to be automatically logged
	handler := log.RequestLogging(config)(mux)

	// Run server
	fmt.Println("Waiting requests on port 8080...")
	if err := http.ListenAndServe(":8080", handler); err != nil {
		panic(err)
	}
}

When this application receives a HTTP request GET /, following logs will be logged (with pretty print for display purposes only).

// STDOUT
{
  "time": "2018-10-10T16:46:07.476567+09:00",
  "logging.googleapis.com/trace": "projects/my-gcp-project/traces/a8cb3e640add456cf7ed58e4a0589ea0",
  "logging.googleapis.com/sourceLocation": {
    "file": "main.go",
    "line": "21",
    "function": "main.main.func1"
  },
  "severity": "INFO",
  "message": "Hello",
  "data": {
    "service": "foo",
    "version": 1
  }
}
{
  "time": "2018-10-10T16:46:07.476806+09:00",
  "logging.googleapis.com/trace": "projects/my-gcp-project/traces/a8cb3e640add456cf7ed58e4a0589ea0",
  "logging.googleapis.com/sourceLocation": {
    "file": "main.go",
    "line": "22",
    "function": "main.main.func1"
  },
  "severity": "WARNING",
  "message": "World",
  "data": {
    "service": "foo",
    "version": 1
  }
}

// STDERR
{
  "time": "2018-10-10T16:46:07.47682+09:00",
  "logging.googleapis.com/trace": "projects/my-gcp-project/traces/a8cb3e640add456cf7ed58e4a0589ea0",
  "severity": "WARNING",
  "httpRequest": {
    "requestMethod": "GET",
    "requestUrl": "/",
    "requestSize": "0",
    "status": 200,
    "responseSize": "3",
    "userAgent": "curl/7.58.0",
    "remoteIp": "[::1]:61352",
    "serverIp": "192.168.86.31",
    "referer": "",
    "latency": "0.000304s",
    "cacheLookup": false,
    "cacheHit": false,
    "cacheValidatedWithOriginServer": false,
    "protocol": "HTTP/1.1"
  },
  "data": {
    "service": "foo",
    "version": 1
  }
}

The log format is based on LogEntry's structured payload so that you can pass these logs to Stackdriver Logging agent.

Stackdriver Logging agent setting

GKE

No settings required. All logs from STDOUT and STDERR are collected by default agents.

GCE

For GCE, you have to install agents manually (docs).
Please install them and create config file like following,

# request log
<source>
    @type tail
    format json
    path /tmp/my_request_log
    pos_file /var/lib/google-fluentd/pos/my-request-log.pos
    read_from_head true
    time_format %Y-%m-%dT%H:%M:%S.%N%Z
    tag my-request-log
</source>

# app log
<source>
    @type tail
    format json
    path /tmp/my_app_log
    pos_file /var/lib/google-fluentd/pos/my-app-log.pos
    read_from_head true
    time_format %Y-%m-%dT%H:%M:%S.%N%Z
    tag my-app-log
</source>

Don't forget to specify time_format %Y-%m-%dT%H:%M:%S.%N%Z to each <source></source> directive.

How logs are grouped

This library leverages the grouping feature of Stackdriver Logging. See following references fore more details.

Disclaimer

This is not an official Google product.

Documentation

Overview

Package stalog provides application logger for Cloud Logging.

Index

Constants

This section is empty.

Variables

View Source
var ContextLoggerKey = &contextKey{}

Functions

func RequestLogging

func RequestLogging(config *Config) func(http.Handler) http.Handler

RequestLogging creates the middleware which logs a request log and creates a request-context logger

func RequestLoggingWithEcho

func RequestLoggingWithEcho(config *Config) echo.MiddlewareFunc

RequestLoggingWithEcho creates the middleware which logs a request log and creates a request-context logger

func RequestLoggingWithFunc

func RequestLoggingWithFunc(config *Config, w http.ResponseWriter, r *http.Request, next http.HandlerFunc)

RequestLoggingWithFunc for WebHook

Types

type AdditionalData

type AdditionalData map[string]interface{}

type Config

type Config struct {
	ProjectId string

	// Output for request log
	RequestLogOut io.Writer

	// Output for context log (application log)
	ContextLogOut io.Writer

	Severity       Severity
	AdditionalData AdditionalData

	// nest level for runtime.Caller (default: 2)
	Skip int
}

Config is the configuration for `RequestLogging` middleware.

func NewConfig

func NewConfig(projectId string) *Config

NewConfig creates a config with default settings.

type ContextLogger

type ContextLogger struct {
	Trace          string
	Severity       Severity
	AdditionalData AdditionalData

	Skip int
	// contains filtered or unexported fields
}

ContextLogger is the logger which is combined with the request

func RequestContextLogger

func RequestContextLogger(r *http.Request) *ContextLogger

RequestContextLogger gets request-context logger for the request. You must use `RequestLogging` middleware in advance for this function to work.

func (*ContextLogger) Alert

func (l *ContextLogger) Alert(args ...interface{})

Alert logs a message at ALERT severity

func (*ContextLogger) Alertf

func (l *ContextLogger) Alertf(format string, args ...interface{})

Alertf logs a message at ALERT severity

func (*ContextLogger) Alertln

func (l *ContextLogger) Alertln(args ...interface{})

Alertln logs a message at ALERT severity

func (*ContextLogger) Critical

func (l *ContextLogger) Critical(args ...interface{})

Critical logs a message at CRITICAL severity

func (*ContextLogger) Criticalf

func (l *ContextLogger) Criticalf(format string, args ...interface{})

Criticalf logs a message at CRITICAL severity

func (*ContextLogger) Criticalln

func (l *ContextLogger) Criticalln(args ...interface{})

Criticalln logs a message at CRITICAL severity

func (*ContextLogger) Debug

func (l *ContextLogger) Debug(args ...interface{})

Debug logs a message at DEBUG severity

func (*ContextLogger) Debugf

func (l *ContextLogger) Debugf(format string, args ...interface{})

Debugf logs a message at DEBUG severity

func (*ContextLogger) Debugln

func (l *ContextLogger) Debugln(args ...interface{})

Debugln logs a message at DEBUG severity

func (*ContextLogger) Default

func (l *ContextLogger) Default(args ...interface{})

Default logs a message at DEFAULT severity

func (*ContextLogger) Defaultf

func (l *ContextLogger) Defaultf(format string, args ...interface{})

Defaultf logs a message at DEFAULT severity

func (*ContextLogger) Defaultln

func (l *ContextLogger) Defaultln(args ...interface{})

Defaultln logs a message at DEFAULT severity

func (*ContextLogger) Emergency

func (l *ContextLogger) Emergency(args ...interface{})

Emergency logs a message at EMERGENCY severity

func (*ContextLogger) Emergencyf

func (l *ContextLogger) Emergencyf(format string, args ...interface{})

Emergencyf logs a message at EMERGENCY severity

func (*ContextLogger) Emergencyln

func (l *ContextLogger) Emergencyln(args ...interface{})

Emergencyln logs a message at EMERGENCY severity

func (*ContextLogger) Error

func (l *ContextLogger) Error(args ...interface{})

Error logs a message at ERROR severity

func (*ContextLogger) Errorf

func (l *ContextLogger) Errorf(format string, args ...interface{})

Errorf logs a message at ERROR severity

func (*ContextLogger) Errorln

func (l *ContextLogger) Errorln(args ...interface{})

Errorln logs a message at ERROR severity

func (*ContextLogger) Info

func (l *ContextLogger) Info(args ...interface{})

Info logs a message at INFO severity

func (*ContextLogger) Infof

func (l *ContextLogger) Infof(format string, args ...interface{})

Infof logs a message at INFO severity

func (*ContextLogger) Infoln

func (l *ContextLogger) Infoln(args ...interface{})

Infoln logs a message at INFO severity

func (*ContextLogger) Notice

func (l *ContextLogger) Notice(args ...interface{})

Notice logs a message at NOTICE severity

func (*ContextLogger) Noticef

func (l *ContextLogger) Noticef(format string, args ...interface{})

Noticef logs a message at NOTICE severity

func (*ContextLogger) Noticeln

func (l *ContextLogger) Noticeln(args ...interface{})

Noticeln logs a message at NOTICE severity

func (*ContextLogger) Warn

func (l *ContextLogger) Warn(args ...interface{})

Warn logs a message at WARNING severity

func (*ContextLogger) Warnf

func (l *ContextLogger) Warnf(format string, args ...interface{})

Warnf logs a message at WARNING severity

func (*ContextLogger) Warning

func (l *ContextLogger) Warning(args ...interface{})

Warning logs a message at WARNING severity

func (*ContextLogger) Warningf

func (l *ContextLogger) Warningf(format string, args ...interface{})

Warningf logs a message at WARNING severity

func (*ContextLogger) Warningln

func (l *ContextLogger) Warningln(args ...interface{})

Warningln logs a message at WARNING severity

func (*ContextLogger) Warnln

func (l *ContextLogger) Warnln(args ...interface{})

Warnln logs a message at WARNING severity

type HTTPRequest

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

type HTTPRequestLog

type HTTPRequestLog struct {
	Time           string         `json:"time"`
	Trace          string         `json:"logging.googleapis.com/trace"`
	Severity       string         `json:"severity"`
	HTTPRequest    HTTPRequest    `json:"httpRequest"`
	AdditionalData AdditionalData `json:"data,omitempty"`
}

type Reserve

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

func NewReserve

func NewReserve(config *Config, r *http.Request) *Reserve

func (*Reserve) LastHandling

func (rv *Reserve) LastHandling(wrw *wrappedResponseWriter)

type Severity

type Severity int

Severity is the level of log. More details: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity

const (
	SeverityDefault Severity = iota * 100
	SeverityDebug
	SeverityInfo
	SeverityNotice
	SeverityWarning
	SeverityError
	SeverityCritical
	SeverityAlert
	SeverityEmergency
)

func (Severity) String

func (s Severity) String() string

String returns text representation for the severity

type SourceLocation

type SourceLocation struct {
	File     string `json:"file"`
	Line     string `json:"line"`
	Function string `json:"function"`
}

Directories

Path Synopsis
example
chi

Jump to

Keyboard shortcuts

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