Categorygithub.com/hellofresh/logging-go
repositorypackage
0.4.0
Repository: https://github.com/hellofresh/logging-go.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author

# README

hellofresh/logging-go

Build Status Coverage Status GoDoc Go Report Card


Note: This project is in maintenance mode. There can be bug fixes, but no feature development.


Generic logging configuration library written in Go

This is generic logging configuration library that we at HelloFresh use in our projects to write applications logs to different log collecting solutions.

Key Features

  • Uses logrus as logging library
  • Allows applying logging configuration from config file or environment variables, uses viper under the hood
  • The following hooks/writers are available:
    • stderr
    • stdout
    • discard aka /dev/null
    • logstash
    • syslog
    • graylog

Installation

go get -u github.com/hellofresh/logging-go

Usage

Standalone logging configuring

YAML config file example

level: info
format: logstash
formatSettings:
  type: MyService
  ts: RFC3339Nano
writer: stderr
hooks:
- format: logstash
  settings: {network: udp, host: logstash.mycompany.io, port: 8911, type: MyService, ts: RFC3339Nano}
- format: syslog
  settings: {network: udp, host: localhost, port: 514, tag: MyService, facility: LOG_LOCAL0, severity: LOG_INFO}
- format: graylog
  settings: {host: graylog.mycompany.io, port: 9000}
- format: stackdriver
  settings: {service: myservice, version: v1}

Environment variable config example

export LOG_LEVEL="info"
export LOG_FORMAT="logstash"
export LOG_FORMAT_SETTINGS="type=MyService,ts:RFC3339Nano"
export LOG_WRITER="stderr"
export LOG_HOOKS='[{"format":"logstash", "settings":{"type":"MyService","ts":"RFC3339Nano", "network": "udp","host":"logstash.mycompany.io","port": "8911"}},{"format":"syslog","settings":{"network": "udp", "host":"localhost", "port": "514", "tag": "MyService", "facility": "LOG_LOCAL0", "severity": "LOG_INFO"}},{"format":"graylog","settings":{"host":"graylog.mycompany.io","port":"9000"}},{"format":"stackdriver", "settings":{"service":"myservice","version":"v1"}}]'

Loading and applying configuration

package main

import (
        "github.com/hellofresh/logging-go"
        log "github.com/sirupsen/logrus"
        "github.com/spf13/viper"
)

func main() {
      logging.InitDefaults(viper.GetViper(), "")
      logConfig, err := logging.Load(viper.GetViper(), "/path/to/config.yml")
      if nil != err {
            panic(err)
      }

      err = logConfig.Apply()
      if nil != err {
            panic(err)
      }
      defer logConfig.Flush()

      log.Info("Logger successfully initialised!")
}

Logging as part of the global config

YAML config file example

foo: rule
bar: 34
log:
    level: info
    format: json
    output: stderr
    hooks:
    - format: logstash
      settings: {network: udp, host: logstash.mycompany.io, port: 8911, type: MyService, ts: RFC3339Nano}
    - format: syslog
      settings: {network: udp, host: localhost, port: 514, tag: MyService, facility: LOG_LOCAL0, severity: LOG_INFO}
    - format: graylog
      settings: {host: graylog.mycompany.io, port: 9000}
    - format: stackdriver
      settings: {service: myservice, version: v1}

Environment variable config example

export APP_FOO="rule"
export APP_BAR="34"
export LOG_LEVEL="info"
export LOG_FORMAT="json"
export LOG_WRITER="stderr"
export LOG_HOOKS='[{"format":"logstash", "settings":{"type":"MyService","ts":"RFC3339Nano", "network": "udp","host":"logstash.mycompany.io","port": "8911"}},{"format":"syslog","settings":{"network": "udp", "host":"localhost", "port": "514", "tag": "MyService", "facility": "LOG_LOCAL0", "severity": "LOG_INFO"}},{"format":"graylog","settings":{"host":"graylog.mycompany.io","port":"9000"}},{"format":"stackdriver", "settings":{"service":"myservice","version":"v1"}}]'

Loading and applying configuration

package main

import (
        "github.com/hellofresh/logging-go"
        log "github.com/sirupsen/logrus"
        "github.com/spf13/viper"
)

func init() {
        viper.SetDefault("foo", "foo")
        viper.SetDefault("bar", 42)
        logging.InitDefaults(viper.GetViper(), "log")
}

type AppConfig struct {
        Foo string `envconfig:"APP_FOO"`
        Bar int    `envconfig:"APP_BAR"`

        Log logging.LogConfig
}

func LoadAppConfig() (*AppConfig, error) {
        var instance AppConfig
        
        ...
        
        return &instance, nil
}

func main() {
        appConfig, err := LoadAppConfig()
        if nil != err {
                panic(err)
        }

        err = appConfig.Log.Apply()
        if nil != err {
                panic(err)
        }
        defer appConfig.Log.Flush()

        log.Info("Application successfully initialised!")
}

Track requests metrics with middleware

package main

import (
        "net/http"
        
        "github.com/go-chi/chi"
        "github.com/hellofresh/logging-go/middleware"
)

func main() {
        appConfig, err := LoadAppConfig()
        if nil != err {
                panic(err)
        }

        err = appConfig.Log.Apply()
        if nil != err {
                panic(err)
        }
        defer appConfig.Log.Flush()

        r := chi.NewRouter()
        r.Use(middleware.New())

        r.GET("/", func(c *gin.Context) {
                c.JSON(http.StatusOK, "I'm producing logs!")
        })

        http.ListenAndServe(":8080", r)
}

Configuration

Base logger

  • level (env LOG_LEVEL, default: info): panic, fatal, error, warn (warning), info, debug (see logrus.ParseLevel())
  • format (env LOG_FORMAT, default: json):
    • text - plain text
    • json - all fields encoded into JSON string
    • logstash - same as json but includes additional logstash fields (e.g. @version) and format settings (see bellow)
  • formatSettings (env LOG_FORMAT_SETTINGS):
    • type (used only for logstash format) - any valid string field that will be added to all log entries
    • ts (used only for logstash format) - timestamp field format, the following values are available: RFC3339, RFC3339Nano (become time.RFC3339 and time.RFC3339Nano time package constants)
  • writer (env LOG_WRITER, default: stderr): stderr, stdout, discard
  • hooks (env LOG_HOOKS) - each hook has te following fields: format and settings. Currently te following formats are available:

logstash

Uses github.com/bshuster-repo/logrus-logstash-hook implementation

SettingRequiredDescription
hostYESLogstash host name or IP address
portYESLogstash host port
networkYESudp or tcp
typenosame as formatSettings.type
tsnosame as formatSettings.type

syslog

Not supported on Windows. Uses logstash implementation of log/syslog

SettingRequiredDescription
hostYESSyslog host name or IP address
portYESSyslog host port
networkYESudp or tcp
severityYESseverity part of syslog priority (LOG_INFO, LOG_NOTICE, etc.)
facilityYESfacility part of syslog priority (LOG_LOCAL0, LOG_CRON, etc.)
tagnoany valid string that will be sent to syslog as tag

graylog

Uses github.com/gemnasium/logrus-graylog-hook implementation

SettingRequiredDescription
hostYESGraylog host name or IP address
portYESGraylog host port
asyncnosend log messages to Graylog in synchronous or asynchronous mode, string value must be parsable to bool

Stackdriver

Stackdriver formatter for Google Cloud Container Engine(GKE/Kubernetes).

Uses github.com/TV4/logrus-stackdriver-formatter implementation

SettingRequiredDescription
servicenoOptional Service Name referring to this logger
versionnoOptional Service version

Contributing

To start contributing, please check CONTRIBUTING.

Documentation