README
¶
⚡ zapgcl 
(experimental)
Formerly https://github.com/jonstaryuk/gcloudzap Modified https://github.com/dhduvall/gcloudzap
This package provides a zap logger that forwards entries to the Google Stackdriver Logging service as structured payloads.
Quickstart
Outside of Google Compute Engine, just add the environment variable GOOGLE_APPLICATION_CREDENTIALS
with a path to a JSON credential file. For more info on this approach, see the docs.
Option 1: Less configuration
import "github.com/pigfoot/zapgcl"
log, err := zapgcl.NewDevelopment("your-project-id", "your-log-id")
if err != nil {
panic(err)
}
log.Sugar().
With("simple", true).
With("foo", "bar").
Info("This will get written to both stderr and Stackdriver Logging.")
// don't forget this log contain google logging handle
// if program terminates too early, then log may not send to stackdriver
log.Sync()
Option 2: More flexibility
import (
"go.uber.org/zap"
"cloud.google.com/go/logging"
"github.com/pigfoot/zapgcl"
)
// Configure the pieces
client, err := logging.NewClient(...)
defer client.Close()
cfg := zap.Config{...}
// Create a logger
log, err := zapgcl.New(cfg, client, "your-log-id", zap.Option(), ...)
Option 3: Most flexibility
import (
"go.uber.org/zap/zapcore"
"cloud.google.com/go/logging"
"github.com/pigfoot/zapgcl"
)
// Configure the pieces
client, err := logging.NewClient(...)
baseCore := zapcore.NewCore(...)
// Create a core
core := zapgcl.Tee(baseCore, client, "your-log-id")
Option 4: middleware integrate with Gin
package main
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
"github.com/pigfoot/zapgcl"
)
func main() {
r := gin.New()
logger, _ := zapdrive.NewProduction("projects/project_id", "LogID")
// Add a ginzap middleware, which:
// - Logs all requests, like a combined access and error log.
// - Logs to stdout.
// - RFC3339 with UTC time format.
r.Use(zapgcl.ZipGin(logger, time.RFC3339, true))
// Logs all panic to error log
// - stack means whether output the stack info.
r.Use(zapgcl.RecoveryWithZap(logger, true))
// Example ping request.
r.GET("/ping", func(c *gin.Context) {
c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example when panic happen.
r.GET("/panic", func(c *gin.Context) {
panic("An unexpected error happen!")
})
// Listen and Server in 0.0.0.0:8080
r.Run(":8080")
}
Documentation
¶
Overview ¶
Package gcloudzap provides a zap logger that forwards entries to the Google Stackdriver Logging service as structured payloads.
All zap.Logger instances created with this package are safe for concurrent use.
Network calls (which are delegated to the Google Cloud Platform package) are asynchronous and payloads are buffered. These benchmarks, on a MacBook Pro 2.4 GHz Core i5, are a loose approximation of latencies on the critical path for the zapcore.Core implementation provided by this package.
$ go test -bench . github.com/dhduvall/gcloudzap goos: darwin goarch: amd64 pkg: github.com/dhduvall/gcloudzap BenchmarkCoreClone-4 2000000 607 ns/op BenchmarkCoreWrite-4 1000000 2811 ns/op
Zap docs: https://godoc.org/go.uber.org/zap
Stackdriver Logging docs: https://cloud.google.com/logging/docs/
Code structure based on https://github.com/gin-contrib/zap package.
Index ¶
- Constants
- Variables
- func New(cfg zap.Config, client *gcl.Client, logID string, opts ...zap.Option) (*zap.Logger, error)
- func NewDevelopment(projectID string, logID string) (*zap.Logger, error)
- func NewProduction(projectID string, logID string) (*zap.Logger, error)
- func RecoveryWithZap(logger *zap.Logger, stack bool) gin.HandlerFunc
- func Tee(zc zapcore.Core, client *gcl.Client, gclLogID string) zapcore.Core
- func ZapGin(logger *zap.Logger, utc bool) gin.HandlerFunc
- type Core
- type GoogleCloudLogger
Constants ¶
const ( // InsertIDKey is the payload field key to use to set the insertId field // in the LogEntry object. InsertIDKey = "logging.googleapis.com/insertId" )
Variables ¶
var DefaultSeverityMapping = map[zapcore.Level]gcl.Severity{ zapcore.DebugLevel: gcl.Debug, zapcore.InfoLevel: gcl.Info, zapcore.WarnLevel: gcl.Warning, zapcore.ErrorLevel: gcl.Error, zapcore.DPanicLevel: gcl.Critical, zapcore.PanicLevel: gcl.Critical, zapcore.FatalLevel: gcl.Critical, }
DefaultSeverityMapping is the default mapping of zap's Levels to Google's Severities.
Functions ¶
func New ¶
New creates a new zap.Logger which will write entries to Stackdriver in addition to the destination specified by the provided zap configuration.
func NewDevelopment ¶
NewDevelopment builds a development Logger that writes DebugLevel and above logs to standard error in a human-friendly format, as well as to Stackdriver using Application Default Credentials.
func NewProduction ¶
NewProduction builds a production Logger that writes InfoLevel and above logs to standard error as JSON, as well as to Stackdriver using Application Default Credentials.
func RecoveryWithZap ¶
func RecoveryWithZap(logger *zap.Logger, stack bool) gin.HandlerFunc
RecoveryWithZap returns a gin.HandlerFunc (middleware) that recovers from any panics and logs requests using uber-go/zap. All errors are logged using zap.Error(). stack means whether output the stack info. The stack info is easy to find where the error occurs but the stack info is too large.
func Tee ¶
Tee returns a zapcore.Core that writes entries to both the provided core and to Stackdriver using the provided client and log ID.
For fields to be written to Stackdriver, you must use the With() method on the returned Core rather than just on zc. (This function has no way of knowing about fields that already exist on zc. They will be preserved when writing to zc's existing destination, but not to Stackdriver.)
func ZapGin ¶
func ZapGin(logger *zap.Logger, utc bool) gin.HandlerFunc
ZapGin returns a gin.HandlerFunc (middleware) that logs requests using uber-go/zap.
Requests with errors are logged using zap.Error(). Requests without errors are logged using zap.Info().
It receives:
- A boolean stating whether to use UTC time zone or local.
Types ¶
type Core ¶
type Core struct { // Logger is a logging.Logger instance from the Google Cloud Platform Go // library. Logger GoogleCloudLogger // Provide your own mapping of zapcore's Levels to Google's Severities, or // use DefaultSeverityMapping. All of the Core's children will default to // using this map. // // This must not be mutated after the Core's first use. SeverityMapping map[zapcore.Level]gcl.Severity // MinLevel is the minimum level for a log entry to be written. MinLevel zapcore.Level // contains filtered or unexported fields }
A Core implements zapcore.Core and writes entries to a Logger from the Google Cloud package.
It's safe for concurrent use by multiple goroutines as long as it's not mutated after first use.
func (*Core) Check ¶
func (c *Core) Check(e zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry
Check implements zapcore.Core.
func (*Core) Write ¶
Write implements zapcore.Core. It writes a log entry to Stackdriver.
Certain fields in the zapcore.Entry are used to populate the Stackdriver entry. The Message field maps to "message", and the LoggerName and Stack fields map to "logger" and "stack", respectively, if they're present. The Caller field is mapped to the Stackdriver entry object's SourceLocation field.
type GoogleCloudLogger ¶
GoogleCloudLogger encapsulates the important methods of gcl.Logger