config

package module
v0.0.0-...-b4a0a85 Latest Latest
Warning

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

Go to latest
Published: Jan 2, 2017 License: Apache-2.0 Imports: 8 Imported by: 1

README

GoDoc Go Report Card Build Status

Abstract

Package log15-config enables configuration of log15 from some arbitrary maps. It does not read any config files, you can use your favourite way of configuring your application. This is a deliberate design decition in order to decouple reading of a configuration from the act of instantiating Handlers and Loggers from this configuration.

Usage

See this example. Detailed examples for all Handlers can be found in the tests. Also please check log15's documentation for the behaviour of the individual handlers.

func getMapFromConfiguration(config string) (map[string]interface{}, error) {
	configMap := make(map[string]interface{})
	err := yaml.Unmarshal([]byte(config), &configMap)
	if err != nil {
		return nil, err
	}
	return configMap, err
}

func Example() {
	var exampleConfiguration = `
  # default for all handlers
  level: INFO
  bufsize: 100  # buffer up to 100 messages before blocking
  extra:
      mark: test
      user: alice

  handlers:
    - kind: stdout  # determines the Handler used
      format: terminal

    - kind: stderr
      format: json
      level: warn	# don't show

    - kind: stdout
      format: logfmt
      level: debug
`

	configMap, err := getMapFromConfiguration(exampleConfiguration)
	if err != nil {
		panic(err)
	}

	log, err := config.Logger(configMap)
	if err != nil {
		panic(err)
	}

	log.Info("Hello, world!")
	log.Debug("user1", "user", "bob")

	l1 := log.New("user", "carol") // issue in log15! won't override, but use both!
	l1.Debug("about user")
}

Look at the Examples for more handler configurations

The kinds for the Handlers are:

  • stdout: StreamHandler to os.Stdout

    • format: see Formats below
  • stderr: StreamHandler to os.Stderr

    • format: see Formats below
  • file: FileHandler to a file

    • format: see Formats below
    • path: path to file
  • syslog. SyslogHandler

    • tag: testing
    • facility: local6

also implemented: MatchFilterHandler, MultiHandler, BufferedHandler,FailoverHandler

Format:

one of "terminal","json","logfmt" or a key of a custom format as shown below

Adding a Handler

This is accomplished with the help of mapstructure-hooks. You need:

  1. A struct that will hold your config and implements HandlerConfig. Use LevelHandlerConfig for proper level handling.
type AwesomeHandlerConfig struct {
        LevelHandlerConfig `mapstructure:",squash"`
        AwesomeData string // an example for your data
}

Take care that alle fields are exported, otherwise reflection in mapstruct will fail!

  1. A function to create an empty config to be filled by mapstruct:
func NewAwesomeHandlerConfig() interface{}{
        return &AwesomeHandlerConfig{}
}
  1. Register from init() function

add to config/handler.go's Init():

hooks.Register(HandlerConfigType, "gelf", NewGelfConfig)

Adding a Format

Register the format with AddFormat:

	// add the testingformat to the options
	config.AddFormat("test", func() log15.Format {
		//excludes := []string{"called", "testing", "testrun"}
		excludes := []string{}
		return TerminalTestFormat(excludes)
	})

License

Licensed under Apache 2.0 License

Documentation

Overview

Example
package main

import (
	"time"

	"github.com/gernoteger/log15-config"
	"gopkg.in/yaml.v2"
)

func getMapFromConfiguration(config string) (map[string]interface{}, error) {
	configMap := make(map[string]interface{})
	err := yaml.Unmarshal([]byte(config), &configMap)
	if err != nil {
		return nil, err
	}
	return configMap, err
}

func main() {
	var exampleConfiguration = `
  # default for all handlers
  level: INFO

  # optionally buffer up to bufsize messages; if omitted (or 0) we don't buffer
  bufsize: 100
  extra:
      mark: test
      user: alice

  handlers:
    - kind: stdout
      format: terminal

    - kind: stderr
      format: json
      level: warn	# don't show

    - kind: stdout
      format: logfmt
      level: debug

    - kind: syslog      # syslog is only available on linux
      tag: testing
      facility: local6

    # 2 ways to configure net
    - kind: net
      url: udp://localhost:4242
      format: json
      level: debug
    - kind: net
      url: tcp://localhost:4242
      format: json
      level: debug

    - kind: multi
      handlers:
        - kind: stdout
          format: terminal
        - kind: stderr
          format: json
        - kind: stdout
          format: logfmt

    - kind: filter  # MatchFilterHandler
      key: matcher
      value: foo
      handler:
        kind: stdout
        format: json

    - kind: failover
      handlers:
        - kind: stdout
          format: terminal
        - kind: stderr
          format: json
        - kind: stdout
          format: logfmt

    # a buffered handler encloses other. Instead of using this preferably use the bufsize parameter above to enclose
    # the whole tree into a buffered handler instead.
    - kind: buffer
      level: debug # w/o this, the nested handler(s) won't be activated!!
      bufsize: 100
      handler:
        kind: net
        url: tcp://localhost:4242
        format: json
`
	//hooks.Register(HandlerConfigType, "failover", NewFailoverConfig)

	configMap, err := getMapFromConfiguration(exampleConfiguration)
	if err != nil {
		panic(err)
	}

	log, err := config.Logger(configMap)
	if err != nil {
		panic(err)
	}

	log.Info("Hello, world!")
	log.Debug("user1", "user", "bob")

	l1 := log.New("user", "carol") // issue in log15! won't override, but use both!
	l1.Debug("about user")

	time.Sleep(100 * time.Millisecond) // need this to finish all async log messages. Bufferedhandler doesn't expose a means to see if the channel is closed...

	// disabling output below for tests by immediately prepending this line since dates will never be right. to execute, just insert blank line after this ons.
	
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var HandlerConfigType = reflect.TypeOf((*HandlerConfig)(nil)).Elem()

use for registry functions

View Source
var SyslogFacilities = map[string]syslog.Priority{
	"kern":     syslog.LOG_KERN,
	"user":     syslog.LOG_USER,
	"mail":     syslog.LOG_MAIL,
	"daemon":   syslog.LOG_DAEMON,
	"auth":     syslog.LOG_AUTH,
	"syslog":   syslog.LOG_SYSLOG,
	"lpr":      syslog.LOG_LPR,
	"news":     syslog.LOG_NEWS,
	"uucp":     syslog.LOG_UUCP,
	"cron":     syslog.LOG_CRON,
	"authpriv": syslog.LOG_AUTHPRIV,
	"ftp":      syslog.LOG_FTP,

	"local0": syslog.LOG_LOCAL0,
	"local1": syslog.LOG_LOCAL1,
	"local2": syslog.LOG_LOCAL2,
	"local3": syslog.LOG_LOCAL3,
	"local4": syslog.LOG_LOCAL4,
	"local5": syslog.LOG_LOCAL5,
	"local6": syslog.LOG_LOCAL6,
	"local7": syslog.LOG_LOCAL7,
}

see https://tools.ietf.org/html/rfc3164 and https://en.wikipedia.org/wiki/Syslog

Functions

func AddFormat

func AddFormat(key string, newFunc NewFormatFunc)

AddFormat adds a Format to the list. You can even replace the old ones!!

func Logger

func Logger(config map[string]interface{}) (log15.Logger, error)

Logger creates a new Logger from a configuration map

func NewBufferConfig

func NewBufferConfig() interface{}

func NewFailoverConfig

func NewFailoverConfig() interface{}

func NewFileConfig

func NewFileConfig() interface{}

func NewMatchFilterConfig

func NewMatchFilterConfig() interface{}

func NewMultiConfig

func NewMultiConfig() interface{}

func NewNetConfig

func NewNetConfig() interface{}

func NewStderrConfig

func NewStderrConfig() interface{}

func NewStdoutConfig

func NewStdoutConfig() interface{}

func NewSyslogConfig

func NewSyslogConfig() interface{}

func Register

func Register()

registers all handlers

Types

type BufferConfig

type BufferConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Handler            HandlerConfig
	BufSize            int
}

BufferConfig is a buffered handler

func (*BufferConfig) NewHandler

func (c *BufferConfig) NewHandler() (log15.Handler, error)

type FailoverConfig

type FailoverConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Handlers           []HandlerConfig
}

FailoverConfig configure FailoverHandler

func (*FailoverConfig) NewHandler

func (c *FailoverConfig) NewHandler() (log15.Handler, error)

type FileConfig

type FileConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Path               string
	Format             Fmt
}

func (*FileConfig) NewHandler

func (c *FileConfig) NewHandler() (log15.Handler, error)

type Fmt

type Fmt string

func (Fmt) NewFormat

func (f Fmt) NewFormat() log15.Format

type Handler

type Handler int

Just the selector for the Handler!

const (
	HandlerStdout Handler = iota
	HandlerStderr
)

GLEF is not a format, it's a handler!!

type HandlerConfig

type HandlerConfig interface {
	NewHandler() (log15.Handler, error)
	GetLevel() string
}

HandlerConfig will create Handlers from a config

type LevelHandlerConfig

type LevelHandlerConfig struct {
	Level string
}

func (*LevelHandlerConfig) GetLevel

func (c *LevelHandlerConfig) GetLevel() string

type LoggerConfig

type LoggerConfig struct {
	Level    string
	Handlers []HandlerConfig

	// if > 0 we buffer the logs. Defaults to 100 for short bursts
	BufSize int

	// extra fields to be added
	//Extra map[string]interface{}
	Extra log15.Ctx
}

LoggerConfig is the central configuration that will be populated from logfiles by various Method One LoggerConfig will produce one logger

func NewLoggerConfig

func NewLoggerConfig(configMap map[string]interface{}) (*LoggerConfig, error)

LoggerConfig creates a new config from map data

func (*LoggerConfig) NewLogger

func (c *LoggerConfig) NewLogger() (log15.Logger, error)

NewLogger produces a new logger from a configuration TODO: candidate for function!

type MatchFilterConfig

type MatchFilterConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Handler            HandlerConfig
	Key                string
	Value              interface{}
}

MatchFilterHandler onyl fires if field matches value

func (*MatchFilterConfig) NewHandler

func (c *MatchFilterConfig) NewHandler() (log15.Handler, error)

type MultiConfig

type MultiConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Handlers           []HandlerConfig
}

MultiHandler fans out to all handlers

func (*MultiConfig) NewHandler

func (c *MultiConfig) NewHandler() (log15.Handler, error)

type NetConfig

type NetConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Format             Fmt
	URL                string
}

func (*NetConfig) NewHandler

func (c *NetConfig) NewHandler() (log15.Handler, error)

type NewFormatFunc

type NewFormatFunc func() log15.Format

NewFormatFunc creates a new format

type StreamConfig

type StreamConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Handler            Handler // for differentiation of stdion, stdout
	Format             Fmt
}

func NewStreamConfig

func NewStreamConfig() *StreamConfig

return a ConsoleConfig with default values

func (*StreamConfig) GetLevel

func (c *StreamConfig) GetLevel() string

func (*StreamConfig) NewHandler

func (c *StreamConfig) NewHandler() (log15.Handler, error)

type SyslogConfig

type SyslogConfig struct {
	LevelHandlerConfig `mapstructure:",squash"`
	Format             Fmt

	URL string // url; if omitted, local syslog is used

	// see https://en.wikipedia.org/wiki/Syslog
	Facility string // kern.. or 0..24, see SyslogFacilities

	Tag string // typical name of application
}

BufferConfig is a buffered handkler

func (*SyslogConfig) NewHandler

func (c *SyslogConfig) NewHandler() (log15.Handler, error)

Jump to

Keyboard shortcuts

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