summaryrefslogtreecommitdiff
path: root/vendor/github.com/op/go-logging
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/op/go-logging')
-rw-r--r--vendor/github.com/op/go-logging/LICENSE27
-rw-r--r--vendor/github.com/op/go-logging/backend.go39
-rw-r--r--vendor/github.com/op/go-logging/examples/example.go49
-rw-r--r--vendor/github.com/op/go-logging/format.go414
-rw-r--r--vendor/github.com/op/go-logging/level.go128
-rw-r--r--vendor/github.com/op/go-logging/log_nix.go109
-rw-r--r--vendor/github.com/op/go-logging/log_windows.go107
-rw-r--r--vendor/github.com/op/go-logging/logger.go259
-rw-r--r--vendor/github.com/op/go-logging/memory.go237
-rw-r--r--vendor/github.com/op/go-logging/multi.go65
-rw-r--r--vendor/github.com/op/go-logging/syslog.go53
-rw-r--r--vendor/github.com/op/go-logging/syslog_fallback.go28
12 files changed, 1515 insertions, 0 deletions
diff --git a/vendor/github.com/op/go-logging/LICENSE b/vendor/github.com/op/go-logging/LICENSE
new file mode 100644
index 0000000..f1f6cfc
--- /dev/null
+++ b/vendor/github.com/op/go-logging/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 Örjan Persson. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/op/go-logging/backend.go b/vendor/github.com/op/go-logging/backend.go
new file mode 100644
index 0000000..74d9201
--- /dev/null
+++ b/vendor/github.com/op/go-logging/backend.go
@@ -0,0 +1,39 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package logging
+
+// defaultBackend is the backend used for all logging calls.
+var defaultBackend LeveledBackend
+
+// Backend is the interface which a log backend need to implement to be able to
+// be used as a logging backend.
+type Backend interface {
+ Log(Level, int, *Record) error
+}
+
+// SetBackend replaces the backend currently set with the given new logging
+// backend.
+func SetBackend(backends ...Backend) LeveledBackend {
+ var backend Backend
+ if len(backends) == 1 {
+ backend = backends[0]
+ } else {
+ backend = MultiLogger(backends...)
+ }
+
+ defaultBackend = AddModuleLevel(backend)
+ return defaultBackend
+}
+
+// SetLevel sets the logging level for the specified module. The module
+// corresponds to the string specified in GetLogger.
+func SetLevel(level Level, module string) {
+ defaultBackend.SetLevel(level, module)
+}
+
+// GetLevel returns the logging level for the specified module.
+func GetLevel(module string) Level {
+ return defaultBackend.GetLevel(module)
+}
diff --git a/vendor/github.com/op/go-logging/examples/example.go b/vendor/github.com/op/go-logging/examples/example.go
new file mode 100644
index 0000000..9f4ddee
--- /dev/null
+++ b/vendor/github.com/op/go-logging/examples/example.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+ "os"
+
+ "github.com/op/go-logging"
+)
+
+var log = logging.MustGetLogger("example")
+
+// Example format string. Everything except the message has a custom color
+// which is dependent on the log level. Many fields have a custom output
+// formatting too, eg. the time returns the hour down to the milli second.
+var format = logging.MustStringFormatter(
+ `%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
+)
+
+// Password is just an example type implementing the Redactor interface. Any
+// time this is logged, the Redacted() function will be called.
+type Password string
+
+func (p Password) Redacted() interface{} {
+ return logging.Redact(string(p))
+}
+
+func main() {
+ // For demo purposes, create two backend for os.Stderr.
+ backend1 := logging.NewLogBackend(os.Stderr, "", 0)
+ backend2 := logging.NewLogBackend(os.Stderr, "", 0)
+
+ // For messages written to backend2 we want to add some additional
+ // information to the output, including the used log level and the name of
+ // the function.
+ backend2Formatter := logging.NewBackendFormatter(backend2, format)
+
+ // Only errors and more severe messages should be sent to backend1
+ backend1Leveled := logging.AddModuleLevel(backend1)
+ backend1Leveled.SetLevel(logging.ERROR, "")
+
+ // Set the backends to be used.
+ logging.SetBackend(backend1Leveled, backend2Formatter)
+
+ log.Debugf("debug %s", Password("secret"))
+ log.Info("info")
+ log.Notice("notice")
+ log.Warning("warning")
+ log.Error("err")
+ log.Critical("crit")
+}
diff --git a/vendor/github.com/op/go-logging/format.go b/vendor/github.com/op/go-logging/format.go
new file mode 100644
index 0000000..7160674
--- /dev/null
+++ b/vendor/github.com/op/go-logging/format.go
@@ -0,0 +1,414 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package logging
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+)
+
+// TODO see Formatter interface in fmt/print.go
+// TODO try text/template, maybe it have enough performance
+// TODO other template systems?
+// TODO make it possible to specify formats per backend?
+type fmtVerb int
+
+const (
+ fmtVerbTime fmtVerb = iota
+ fmtVerbLevel
+ fmtVerbID
+ fmtVerbPid
+ fmtVerbProgram
+ fmtVerbModule
+ fmtVerbMessage
+ fmtVerbLongfile
+ fmtVerbShortfile
+ fmtVerbLongpkg
+ fmtVerbShortpkg
+ fmtVerbLongfunc
+ fmtVerbShortfunc
+ fmtVerbCallpath
+ fmtVerbLevelColor
+
+ // Keep last, there are no match for these below.
+ fmtVerbUnknown
+ fmtVerbStatic
+)
+
+var fmtVerbs = []string{
+ "time",
+ "level",
+ "id",
+ "pid",
+ "program",
+ "module",
+ "message",
+ "longfile",
+ "shortfile",
+ "longpkg",
+ "shortpkg",
+ "longfunc",
+ "shortfunc",
+ "callpath",
+ "color",
+}
+
+const rfc3339Milli = "2006-01-02T15:04:05.999Z07:00"
+
+var defaultVerbsLayout = []string{
+ rfc3339Milli,
+ "s",
+ "d",
+ "d",
+ "s",
+ "s",
+ "s",
+ "s",
+ "s",
+ "s",
+ "s",
+ "s",
+ "s",
+ "0",
+ "",
+}
+
+var (
+ pid = os.Getpid()
+ program = filepath.Base(os.Args[0])
+)
+
+func getFmtVerbByName(name string) fmtVerb {
+ for i, verb := range fmtVerbs {
+ if name == verb {
+ return fmtVerb(i)
+ }
+ }
+ return fmtVerbUnknown
+}
+
+// Formatter is the required interface for a custom log record formatter.
+type Formatter interface {
+ Format(calldepth int, r *Record, w io.Writer) error
+}
+
+// formatter is used by all backends unless otherwise overriden.
+var formatter struct {
+ sync.RWMutex
+ def Formatter
+}
+
+func getFormatter() Formatter {
+ formatter.RLock()
+ defer formatter.RUnlock()
+ return formatter.def
+}
+
+var (
+ // DefaultFormatter is the default formatter used and is only the message.
+ DefaultFormatter = MustStringFormatter("%{message}")
+
+ // GlogFormatter mimics the glog format
+ GlogFormatter = MustStringFormatter("%{level:.1s}%{time:0102 15:04:05.999999} %{pid} %{shortfile}] %{message}")
+)
+
+// SetFormatter sets the default formatter for all new backends. A backend will
+// fetch this value once it is needed to format a record. Note that backends
+// will cache the formatter after the first point. For now, make sure to set
+// the formatter before logging.
+func SetFormatter(f Formatter) {
+ formatter.Lock()
+ defer formatter.Unlock()
+ formatter.def = f
+}
+
+var formatRe = regexp.MustCompile(`%{([a-z]+)(?::(.*?[^\\]))?}`)
+
+type part struct {
+ verb fmtVerb
+ layout string
+}
+
+// stringFormatter contains a list of parts which explains how to build the
+// formatted string passed on to the logging backend.
+type stringFormatter struct {
+ parts []part
+}
+
+// NewStringFormatter returns a new Formatter which outputs the log record as a
+// string based on the 'verbs' specified in the format string.
+//
+// The verbs:
+//
+// General:
+// %{id} Sequence number for log message (uint64).
+// %{pid} Process id (int)
+// %{time} Time when log occurred (time.Time)
+// %{level} Log level (Level)
+// %{module} Module (string)
+// %{program} Basename of os.Args[0] (string)
+// %{message} Message (string)
+// %{longfile} Full file name and line number: /a/b/c/d.go:23
+// %{shortfile} Final file name element and line number: d.go:23
+// %{callpath} Callpath like main.a.b.c...c "..." meaning recursive call ~. meaning truncated path
+// %{color} ANSI color based on log level
+//
+// For normal types, the output can be customized by using the 'verbs' defined
+// in the fmt package, eg. '%{id:04d}' to make the id output be '%04d' as the
+// format string.
+//
+// For time.Time, use the same layout as time.Format to change the time format
+// when output, eg "2006-01-02T15:04:05.999Z-07:00".
+//
+// For the 'color' verb, the output can be adjusted to either use bold colors,
+// i.e., '%{color:bold}' or to reset the ANSI attributes, i.e.,
+// '%{color:reset}' Note that if you use the color verb explicitly, be sure to
+// reset it or else the color state will persist past your log message. e.g.,
+// "%{color:bold}%{time:15:04:05} %{level:-8s}%{color:reset} %{message}" will
+// just colorize the time and level, leaving the message uncolored.
+//
+// For the 'callpath' verb, the output can be adjusted to limit the printing
+// the stack depth. i.e. '%{callpath:3}' will print '~.a.b.c'
+//
+// Colors on Windows is unfortunately not supported right now and is currently
+// a no-op.
+//
+// There's also a couple of experimental 'verbs'. These are exposed to get
+// feedback and needs a bit of tinkering. Hence, they might change in the
+// future.
+//
+// Experimental:
+// %{longpkg} Full package path, eg. github.com/go-logging
+// %{shortpkg} Base package path, eg. go-logging
+// %{longfunc} Full function name, eg. littleEndian.PutUint32
+// %{shortfunc} Base function name, eg. PutUint32
+// %{callpath} Call function path, eg. main.a.b.c
+func NewStringFormatter(format string) (Formatter, error) {
+ var fmter = &stringFormatter{}
+
+ // Find the boundaries of all %{vars}
+ matches := formatRe.FindAllStringSubmatchIndex(format, -1)
+ if matches == nil {
+ return nil, errors.New("logger: invalid log format: " + format)
+ }
+
+ // Collect all variables and static text for the format
+ prev := 0
+ for _, m := range matches {
+ start, end := m[0], m[1]
+ if start > prev {
+ fmter.add(fmtVerbStatic, format[prev:start])
+ }
+
+ name := format[m[2]:m[3]]
+ verb := getFmtVerbByName(name)
+ if verb == fmtVerbUnknown {
+ return nil, errors.New("logger: unknown variable: " + name)
+ }
+
+ // Handle layout customizations or use the default. If this is not for the
+ // time, color formatting or callpath, we need to prefix with %.
+ layout := defaultVerbsLayout[verb]
+ if m[4] != -1 {
+ layout = format[m[4]:m[5]]
+ }
+ if verb != fmtVerbTime && verb != fmtVerbLevelColor && verb != fmtVerbCallpath {
+ layout = "%" + layout
+ }
+
+ fmter.add(verb, layout)
+ prev = end
+ }
+ end := format[prev:]
+ if end != "" {
+ fmter.add(fmtVerbStatic, end)
+ }
+
+ // Make a test run to make sure we can format it correctly.
+ t, err := time.Parse(time.RFC3339, "2010-02-04T21:00:57-08:00")
+ if err != nil {
+ panic(err)
+ }
+ testFmt := "hello %s"
+ r := &Record{
+ ID: 12345,
+ Time: t,
+ Module: "logger",
+ Args: []interface{}{"go"},
+ fmt: &testFmt,
+ }
+ if err := fmter.Format(0, r, &bytes.Buffer{}); err != nil {
+ return nil, err
+ }
+
+ return fmter, nil
+}
+
+// MustStringFormatter is equivalent to NewStringFormatter with a call to panic
+// on error.
+func MustStringFormatter(format string) Formatter {
+ f, err := NewStringFormatter(format)
+ if err != nil {
+ panic("Failed to initialized string formatter: " + err.Error())
+ }
+ return f
+}
+
+func (f *stringFormatter) add(verb fmtVerb, layout string) {
+ f.parts = append(f.parts, part{verb, layout})
+}
+
+func (f *stringFormatter) Format(calldepth int, r *Record, output io.Writer) error {
+ for _, part := range f.parts {
+ if part.verb == fmtVerbStatic {
+ output.Write([]byte(part.layout))
+ } else if part.verb == fmtVerbTime {
+ output.Write([]byte(r.Time.Format(part.layout)))
+ } else if part.verb == fmtVerbLevelColor {
+ doFmtVerbLevelColor(part.layout, r.Level, output)
+ } else if part.verb == fmtVerbCallpath {
+ depth, err := strconv.Atoi(part.layout)
+ if err != nil {
+ depth = 0
+ }
+ output.Write([]byte(formatCallpath(calldepth+1, depth)))
+ } else {
+ var v interface{}
+ switch part.verb {
+ case fmtVerbLevel:
+ v = r.Level
+ break
+ case fmtVerbID:
+ v = r.ID
+ break
+ case fmtVerbPid:
+ v = pid
+ break
+ case fmtVerbProgram:
+ v = program
+ break
+ case fmtVerbModule:
+ v = r.Module
+ break
+ case fmtVerbMessage:
+ v = r.Message()
+ break
+ case fmtVerbLongfile, fmtVerbShortfile:
+ _, file, line, ok := runtime.Caller(calldepth + 1)
+ if !ok {
+ file = "???"
+ line = 0
+ } else if part.verb == fmtVerbShortfile {
+ file = filepath.Base(file)
+ }
+ v = fmt.Sprintf("%s:%d", file, line)
+ case fmtVerbLongfunc, fmtVerbShortfunc,
+ fmtVerbLongpkg, fmtVerbShortpkg:
+ // TODO cache pc
+ v = "???"
+ if pc, _, _, ok := runtime.Caller(calldepth + 1); ok {
+ if f := runtime.FuncForPC(pc); f != nil {
+ v = formatFuncName(part.verb, f.Name())
+ }
+ }
+ default:
+ panic("unhandled format part")
+ }
+ fmt.Fprintf(output, part.layout, v)
+ }
+ }
+ return nil
+}
+
+// formatFuncName tries to extract certain part of the runtime formatted
+// function name to some pre-defined variation.
+//
+// This function is known to not work properly if the package path or name
+// contains a dot.
+func formatFuncName(v fmtVerb, f string) string {
+ i := strings.LastIndex(f, "/")
+ j := strings.Index(f[i+1:], ".")
+ if j < 1 {
+ return "???"
+ }
+ pkg, fun := f[:i+j+1], f[i+j+2:]
+ switch v {
+ case fmtVerbLongpkg:
+ return pkg
+ case fmtVerbShortpkg:
+ return path.Base(pkg)
+ case fmtVerbLongfunc:
+ return fun
+ case fmtVerbShortfunc:
+ i = strings.LastIndex(fun, ".")
+ return fun[i+1:]
+ }
+ panic("unexpected func formatter")
+}
+
+func formatCallpath(calldepth int, depth int) string {
+ v := ""
+ callers := make([]uintptr, 64)
+ n := runtime.Callers(calldepth+2, callers)
+ oldPc := callers[n-1]
+
+ start := n - 3
+ if depth > 0 && start >= depth {
+ start = depth - 1
+ v += "~."
+ }
+ recursiveCall := false
+ for i := start; i >= 0; i-- {
+ pc := callers[i]
+ if oldPc == pc {
+ recursiveCall = true
+ continue
+ }
+ oldPc = pc
+ if recursiveCall {
+ recursiveCall = false
+ v += ".."
+ }
+ if i < start {
+ v += "."
+ }
+ if f := runtime.FuncForPC(pc); f != nil {
+ v += formatFuncName(fmtVerbShortfunc, f.Name())
+ }
+ }
+ return v
+}
+
+// backendFormatter combines a backend with a specific formatter making it
+// possible to have different log formats for different backends.
+type backendFormatter struct {
+ b Backend
+ f Formatter
+}
+
+// NewBackendFormatter creates a new backend which makes all records that
+// passes through it beeing formatted by the specific formatter.
+func NewBackendFormatter(b Backend, f Formatter) Backend {
+ return &backendFormatter{b, f}
+}
+
+// Log implements the Log function required by the Backend interface.
+func (bf *backendFormatter) Log(level Level, calldepth int, r *Record) error {
+ // Make a shallow copy of the record and replace any formatter
+ r2 := *r
+ r2.formatter = bf.f
+ return bf.b.Log(level, calldepth+1, &r2)
+}
diff --git a/vendor/github.com/op/go-logging/level.go b/vendor/github.com/op/go-logging/level.go
new file mode 100644
index 0000000..98dd191
--- /dev/null
+++ b/vendor/github.com/op/go-logging/level.go
@@ -0,0 +1,128 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package logging
+
+import (
+ "errors"
+ "strings"
+ "sync"
+)
+
+// ErrInvalidLogLevel is used when an invalid log level has been used.
+var ErrInvalidLogLevel = errors.New("logger: invalid log level")
+
+// Level defines all available log levels for log messages.
+type Level int
+
+// Log levels.
+const (
+ CRITICAL Level = iota
+ ERROR
+ WARNING
+ NOTICE
+ INFO
+ DEBUG
+)
+
+var levelNames = []string{
+ "CRITICAL",
+ "ERROR",
+ "WARNING",
+ "NOTICE",
+ "INFO",
+ "DEBUG",
+}
+
+// String returns the string representation of a logging level.
+func (p Level) String() string {
+ return levelNames[p]
+}
+
+// LogLevel returns the log level from a string representation.
+func LogLevel(level string) (Level, error) {
+ for i, name := range levelNames {
+ if strings.EqualFold(name, level) {
+ return Level(i), nil
+ }
+ }
+ return ERROR, ErrInvalidLogLevel
+}
+
+// Leveled interface is the interface required to be able to add leveled
+// logging.
+type Leveled interface {
+ GetLevel(string) Level
+ SetLevel(Level, string)
+ IsEnabledFor(Level, string) bool
+}
+
+// LeveledBackend is a log backend with additional knobs for setting levels on
+// individual modules to different levels.
+type LeveledBackend interface {
+ Backend
+ Leveled
+}
+
+type moduleLeveled struct {
+ levels map[string]Level
+ backend Backend
+ formatter Formatter
+ once sync.Once
+}
+
+// AddModuleLevel wraps a log backend with knobs to have different log levels
+// for different modules.
+func AddModuleLevel(backend Backend) LeveledBackend {
+ var leveled LeveledBackend
+ var ok bool
+ if leveled, ok = backend.(LeveledBackend); !ok {
+ leveled = &moduleLeveled{
+ levels: make(map[string]Level),
+ backend: backend,
+ }
+ }
+ return leveled
+}
+
+// GetLevel returns the log level for the given module.
+func (l *moduleLeveled) GetLevel(module string) Level {
+ level, exists := l.levels[module]
+ if exists == false {
+ level, exists = l.levels[""]
+ // no configuration exists, default to debug
+ if exists == false {
+ level = DEBUG
+ }
+ }
+ return level
+}
+
+// SetLevel sets the log level for the given module.
+func (l *moduleLeveled) SetLevel(level Level, module string) {
+ l.levels[module] = level
+}
+
+// IsEnabledFor will return true if logging is enabled for the given module.
+func (l *moduleLeveled) IsEnabledFor(level Level, module string) bool {
+ return level <= l.GetLevel(module)
+}
+
+func (l *moduleLeveled) Log(level Level, calldepth int, rec *Record) (err error) {
+ if l.IsEnabledFor(level, rec.Module) {
+ // TODO get rid of traces of formatter here. BackendFormatter should be used.
+ rec.formatter = l.getFormatterAndCacheCurrent()
+ err = l.backend.Log(level, calldepth+1, rec)
+ }
+ return
+}
+
+func (l *moduleLeveled) getFormatterAndCacheCurrent() Formatter {
+ l.once.Do(func() {
+ if l.formatter == nil {
+ l.formatter = getFormatter()
+ }
+ })
+ return l.formatter
+}
diff --git a/vendor/github.com/op/go-logging/log_nix.go b/vendor/github.com/op/go-logging/log_nix.go
new file mode 100644
index 0000000..4ff2ab1
--- /dev/null
+++ b/vendor/github.com/op/go-logging/log_nix.go
@@ -0,0 +1,109 @@
+// +build !windows
+
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package logging
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "log"
+)
+
+type color int
+
+const (
+ ColorBlack = iota + 30
+ ColorRed
+ ColorGreen
+ ColorYellow
+ ColorBlue
+ ColorMagenta
+ ColorCyan
+ ColorWhite
+)
+
+var (
+ colors = []string{
+ CRITICAL: ColorSeq(ColorMagenta),
+ ERROR: ColorSeq(ColorRed),
+ WARNING: ColorSeq(ColorYellow),
+ NOTICE: ColorSeq(ColorGreen),
+ DEBUG: ColorSeq(ColorCyan),
+ }
+ boldcolors = []string{
+ CRITICAL: ColorSeqBold(ColorMagenta),
+ ERROR: ColorSeqBold(ColorRed),
+ WARNING: ColorSeqBold(ColorYellow),
+ NOTICE: ColorSeqBold(ColorGreen),
+ DEBUG: ColorSeqBold(ColorCyan),
+ }
+)
+
+// LogBackend utilizes the standard log module.
+type LogBackend struct {
+ Logger *log.Logger
+ Color bool
+ ColorConfig []string
+}
+
+// NewLogBackend creates a new LogBackend.
+func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend {
+ return &LogBackend{Logger: log.New(out, prefix, flag)}
+}
+
+// Log implements the Backend interface.
+func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error {
+ if b.Color {
+ col := colors[level]
+ if len(b.ColorConfig) > int(level) && b.ColorConfig[level] != "" {
+ col = b.ColorConfig[level]
+ }
+
+ buf := &bytes.Buffer{}
+ buf.Write([]byte(col))
+ buf.Write([]byte(rec.Formatted(calldepth + 1)))
+ buf.Write([]byte("\033[0m"))
+ // For some reason, the Go logger arbitrarily decided "2" was the correct
+ // call depth...
+ return b.Logger.Output(calldepth+2, buf.String())
+ }
+
+ return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1))
+}
+
+// ConvertColors takes a list of ints representing colors for log levels and
+// converts them into strings for ANSI color formatting
+func ConvertColors(colors []int, bold bool) []string {
+ converted := []string{}
+ for _, i := range colors {
+ if bold {
+ converted = append(converted, ColorSeqBold(color(i)))
+ } else {
+ converted = append(converted, ColorSeq(color(i)))
+ }
+ }
+
+ return converted
+}
+
+func ColorSeq(color color) string {
+ return fmt.Sprintf("\033[%dm", int(color))
+}
+
+func ColorSeqBold(color color) string {
+ return fmt.Sprintf("\033[%d;1m", int(color))
+}
+
+func doFmtVerbLevelColor(layout string, level Level, output io.Writer) {
+ if layout == "bold" {
+ output.Write([]byte(boldcolors[level]))
+ } else if layout == "reset" {
+ output.Write([]byte("\033[0m"))
+ } else {
+ output.Write([]byte(colors[level]))
+ }
+}
diff --git a/vendor/github.com/op/go-logging/log_windows.go b/vendor/github.com/op/go-logging/log_windows.go
new file mode 100644
index 0000000..b8dc92c
--- /dev/null
+++ b/vendor/github.com/op/go-logging/log_windows.go
@@ -0,0 +1,107 @@
+// +build windows
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package logging
+
+import (
+ "bytes"
+ "io"
+ "log"
+ "syscall"
+)
+
+var (
+ kernel32DLL = syscall.NewLazyDLL("kernel32.dll")
+ setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute")
+)
+
+// Character attributes
+// Note:
+// -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan).
+// Clearing all foreground or background colors results in black; setting all creates white.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.
+const (
+ fgBlack = 0x0000
+ fgBlue = 0x0001
+ fgGreen = 0x0002
+ fgCyan = 0x0003
+ fgRed = 0x0004
+ fgMagenta = 0x0005
+ fgYellow = 0x0006
+ fgWhite = 0x0007
+ fgIntensity = 0x0008
+ fgMask = 0x000F
+)
+
+var (
+ colors = []uint16{
+ INFO: fgWhite,
+ CRITICAL: fgMagenta,
+ ERROR: fgRed,
+ WARNING: fgYellow,
+ NOTICE: fgGreen,
+ DEBUG: fgCyan,
+ }
+ boldcolors = []uint16{
+ INFO: fgWhite | fgIntensity,
+ CRITICAL: fgMagenta | fgIntensity,
+ ERROR: fgRed | fgIntensity,
+ WARNING: fgYellow | fgIntensity,
+ NOTICE: fgGreen | fgIntensity,
+ DEBUG: fgCyan | fgIntensity,
+ }
+)
+
+type file interface {
+ Fd() uintptr
+}
+
+// LogBackend utilizes the standard log module.
+type LogBackend struct {
+ Logger *log.Logger
+ Color bool
+
+ // f is set to a non-nil value if the underlying writer which logs writes to
+ // implements the file interface. This makes us able to colorise the output.
+ f file
+}
+
+// NewLogBackend creates a new LogBackend.
+func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend {
+ b := &LogBackend{Logger: log.New(out, prefix, flag)}
+
+ // Unfortunately, the API used only takes an io.Writer where the Windows API
+ // need the actual fd to change colors.
+ if f, ok := out.(file); ok {
+ b.f = f
+ }
+
+ return b
+}
+
+func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error {
+ if b.Color && b.f != nil {
+ buf := &bytes.Buffer{}
+ setConsoleTextAttribute(b.f, colors[level])
+ buf.Write([]byte(rec.Formatted(calldepth + 1)))
+ err := b.Logger.Output(calldepth+2, buf.String())
+ setConsoleTextAttribute(b.f, fgWhite)
+ return err
+ }
+ return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1))
+}
+
+// setConsoleTextAttribute sets the attributes of characters written to the
+// console screen buffer by the WriteFile or WriteConsole function.
+// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.
+func setConsoleTextAttribute(f file, attribute uint16) bool {
+ ok, _, _ := setConsoleTextAttributeProc.Call(f.Fd(), uintptr(attribute), 0)
+ return ok != 0
+}
+
+func doFmtVerbLevelColor(layout string, level Level, output io.Writer) {
+ // TODO not supported on Windows since the io.Writer here is actually a
+ // bytes.Buffer.
+}
diff --git a/vendor/github.com/op/go-logging/logger.go b/vendor/github.com/op/go-logging/logger.go
new file mode 100644
index 0000000..535ed9b
--- /dev/null
+++ b/vendor/github.com/op/go-logging/logger.go
@@ -0,0 +1,259 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package logging implements a logging infrastructure for Go. It supports
+// different logging backends like syslog, file and memory. Multiple backends
+// can be utilized with different log levels per backend and logger.
+package logging
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "strings"
+ "sync/atomic"
+ "time"
+)
+
+// Redactor is an interface for types that may contain sensitive information
+// (like passwords), which shouldn't be printed to the log. The idea was found
+// in relog as part of the vitness project.
+type Redactor interface {
+ Redacted() interface{}
+}
+
+// Redact returns a string of * having the same length as s.
+func Redact(s string) string {
+ return strings.Repeat("*", len(s))
+}
+
+var (
+ // Sequence number is incremented and utilized for all log records created.
+ sequenceNo uint64
+
+ // timeNow is a customizable for testing purposes.
+ timeNow = time.Now
+)
+
+// Record represents a log record and contains the timestamp when the record
+// was created, an increasing id, filename and line and finally the actual
+// formatted log line.
+type Record struct {
+ ID uint64
+ Time time.Time
+ Module string
+ Level Level
+ Args []interface{}
+
+ // message is kept as a pointer to have shallow copies update this once
+ // needed.
+ message *string
+ fmt *string
+ formatter Formatter
+ formatted string
+}
+
+// Formatted returns the formatted log record string.
+func (r *Record) Formatted(calldepth int) string {
+ if r.formatted == "" {
+ var buf bytes.Buffer
+ r.formatter.Format(calldepth+1, r, &buf)
+ r.formatted = buf.String()
+ }
+ return r.formatted
+}
+
+// Message returns the log record message.
+func (r *Record) Message() string {
+ if r.message == nil {
+ // Redact the arguments that implements the Redactor interface
+ for i, arg := range r.Args {
+ if redactor, ok := arg.(Redactor); ok == true {
+ r.Args[i] = redactor.Redacted()
+ }
+ }
+ var buf bytes.Buffer
+ if r.fmt != nil {
+ fmt.Fprintf(&buf, *r.fmt, r.Args...)
+ } else {
+ // use Fprintln to make sure we always get space between arguments
+ fmt.Fprintln(&buf, r.Args...)
+ buf.Truncate(buf.Len() - 1) // strip newline
+ }
+ msg := buf.String()
+ r.message = &msg
+ }
+ return *r.message
+}
+
+// Logger is the actual logger which creates log records based on the functions
+// called and passes them to the underlying logging backend.
+type Logger struct {
+ Module string
+ backend LeveledBackend
+ haveBackend bool
+
+ // ExtraCallDepth can be used to add additional call depth when getting the
+ // calling function. This is normally used when wrapping a logger.
+ ExtraCalldepth int
+}
+
+// SetBackend overrides any previously defined backend for this logger.
+func (l *Logger) SetBackend(backend LeveledBackend) {
+ l.backend = backend
+ l.haveBackend = true
+}
+
+// TODO call NewLogger and remove MustGetLogger?
+
+// GetLogger creates and returns a Logger object based on the module name.
+func GetLogger(module string) (*Logger, error) {
+ return &Logger{Module: module}, nil
+}
+
+// MustGetLogger is like GetLogger but panics if the logger can't be created.
+// It simplifies safe initialization of a global logger for eg. a package.
+func MustGetLogger(module string) *Logger {
+ logger, err := GetLogger(module)
+ if err != nil {
+ panic("logger: " + module + ": " + err.Error())
+ }
+ return logger
+}
+
+// Reset restores the internal state of the logging library.
+func Reset() {
+ // TODO make a global Init() method to be less magic? or make it such that
+ // if there's no backends at all configured, we could use some tricks to
+ // automatically setup backends based if we have a TTY or not.
+ sequenceNo = 0
+ b := SetBackend(NewLogBackend(os.Stderr, "", log.LstdFlags))
+ b.SetLevel(DEBUG, "")
+ SetFormatter(DefaultFormatter)
+ timeNow = time.Now
+}
+
+// IsEnabledFor returns true if the logger is enabled for the given level.
+func (l *Logger) IsEnabledFor(level Level) bool {
+ return defaultBackend.IsEnabledFor(level, l.Module)
+}
+
+func (l *Logger) log(lvl Level, format *string, args ...interface{}) {
+ if !l.IsEnabledFor(lvl) {
+ return
+ }
+
+ // Create the logging record and pass it in to the backend
+ record := &Record{
+ ID: atomic.AddUint64(&sequenceNo, 1),
+ Time: timeNow(),
+ Module: l.Module,
+ Level: lvl,
+ fmt: format,
+ Args: args,
+ }
+
+ // TODO use channels to fan out the records to all backends?
+ // TODO in case of errors, do something (tricky)
+
+ // calldepth=2 brings the stack up to the caller of the level
+ // methods, Info(), Fatal(), etc.
+ // ExtraCallDepth allows this to be extended further up the stack in case we
+ // are wrapping these methods, eg. to expose them package level
+ if l.haveBackend {
+ l.backend.Log(lvl, 2+l.ExtraCalldepth, record)
+ return
+ }
+
+ defaultBackend.Log(lvl, 2+l.ExtraCalldepth, record)
+}
+
+// Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1).
+func (l *Logger) Fatal(args ...interface{}) {
+ l.log(CRITICAL, nil, args...)
+ os.Exit(1)
+}
+
+// Fatalf is equivalent to l.Critical followed by a call to os.Exit(1).
+func (l *Logger) Fatalf(format string, args ...interface{}) {
+ l.log(CRITICAL, &format, args...)
+ os.Exit(1)
+}
+
+// Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic().
+func (l *Logger) Panic(args ...interface{}) {
+ l.log(CRITICAL, nil, args...)
+ panic(fmt.Sprint(args...))
+}
+
+// Panicf is equivalent to l.Critical followed by a call to panic().
+func (l *Logger) Panicf(format string, args ...interface{}) {
+ l.log(CRITICAL, &format, args...)
+ panic(fmt.Sprintf(format, args...))
+}
+
+// Critical logs a message using CRITICAL as log level.
+func (l *Logger) Critical(args ...interface{}) {
+ l.log(CRITICAL, nil, args...)
+}
+
+// Criticalf logs a message using CRITICAL as log level.
+func (l *Logger) Criticalf(format string, args ...interface{}) {
+ l.log(CRITICAL, &format, args...)
+}
+
+// Error logs a message using ERROR as log level.
+func (l *Logger) Error(args ...interface{}) {
+ l.log(ERROR, nil, args...)
+}
+
+// Errorf logs a message using ERROR as log level.
+func (l *Logger) Errorf(format string, args ...interface{}) {
+ l.log(ERROR, &format, args...)
+}
+
+// Warning logs a message using WARNING as log level.
+func (l *Logger) Warning(args ...interface{}) {
+ l.log(WARNING, nil, args...)
+}
+
+// Warningf logs a message using WARNING as log level.
+func (l *Logger) Warningf(format string, args ...interface{}) {
+ l.log(WARNING, &format, args...)
+}
+
+// Notice logs a message using NOTICE as log level.
+func (l *Logger) Notice(args ...interface{}) {
+ l.log(NOTICE, nil, args...)
+}
+
+// Noticef logs a message using NOTICE as log level.
+func (l *Logger) Noticef(format string, args ...interface{}) {
+ l.log(NOTICE, &format, args...)
+}
+
+// Info logs a message using INFO as log level.
+func (l *Logger) Info(args ...interface{}) {
+ l.log(INFO, nil, args...)
+}
+
+// Infof logs a message using INFO as log level.
+func (l *Logger) Infof(format string, args ...interface{}) {
+ l.log(INFO, &format, args...)
+}
+
+// Debug logs a message using DEBUG as log level.
+func (l *Logger) Debug(args ...interface{}) {
+ l.log(DEBUG, nil, args...)
+}
+
+// Debugf logs a message using DEBUG as log level.
+func (l *Logger) Debugf(format string, args ...interface{}) {
+ l.log(DEBUG, &format, args...)
+}
+
+func init() {
+ Reset()
+}
diff --git a/vendor/github.com/op/go-logging/memory.go b/vendor/github.com/op/go-logging/memory.go
new file mode 100644
index 0000000..8d5152c
--- /dev/null
+++ b/vendor/github.com/op/go-logging/memory.go
@@ -0,0 +1,237 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package logging
+
+import (
+ "sync"
+ "sync/atomic"
+ "time"
+ "unsafe"
+)
+
+// TODO pick one of the memory backends and stick with it or share interface.
+
+// InitForTesting is a convenient method when using logging in a test. Once
+// called, the time will be frozen to January 1, 1970 UTC.
+func InitForTesting(level Level) *MemoryBackend {
+ Reset()
+
+ memoryBackend := NewMemoryBackend(10240)
+
+ leveledBackend := AddModuleLevel(memoryBackend)
+ leveledBackend.SetLevel(level, "")
+ SetBackend(leveledBackend)
+
+ timeNow = func() time.Time {
+ return time.Unix(0, 0).UTC()
+ }
+ return memoryBackend
+}
+
+// Node is a record node pointing to an optional next node.
+type node struct {
+ next *node
+ Record *Record
+}
+
+// Next returns the next record node. If there's no node available, it will
+// return nil.
+func (n *node) Next() *node {
+ return n.next
+}
+
+// MemoryBackend is a simple memory based logging backend that will not produce
+// any output but merly keep records, up to the given size, in memory.
+type MemoryBackend struct {
+ size int32
+ maxSize int32
+ head, tail unsafe.Pointer
+}
+
+// NewMemoryBackend creates a simple in-memory logging backend.
+func NewMemoryBackend(size int) *MemoryBackend {
+ return &MemoryBackend{maxSize: int32(size)}
+}
+
+// Log implements the Log method required by Backend.
+func (b *MemoryBackend) Log(level Level, calldepth int, rec *Record) error {
+ var size int32
+
+ n := &node{Record: rec}
+ np := unsafe.Pointer(n)
+
+ // Add the record to the tail. If there's no records available, tail and
+ // head will both be nil. When we successfully set the tail and the previous
+ // value was nil, it's safe to set the head to the current value too.
+ for {
+ tailp := b.tail
+ swapped := atomic.CompareAndSwapPointer(
+ &b.tail,
+ tailp,
+ np,
+ )
+ if swapped == true {
+ if tailp == nil {
+ b.head = np
+ } else {
+ (*node)(tailp).next = n
+ }
+ size = atomic.AddInt32(&b.size, 1)
+ break
+ }
+ }
+
+ // Since one record was added, we might have overflowed the list. Remove
+ // a record if that is the case. The size will fluctate a bit, but
+ // eventual consistent.
+ if b.maxSize > 0 && size > b.maxSize {
+ for {
+ headp := b.head
+ head := (*node)(b.head)
+ if head.next == nil {
+ break
+ }
+ swapped := atomic.CompareAndSwapPointer(
+ &b.head,
+ headp,
+ unsafe.Pointer(head.next),
+ )
+ if swapped == true {
+ atomic.AddInt32(&b.size, -1)
+ break
+ }
+ }
+ }
+ return nil
+}
+
+// Head returns the oldest record node kept in memory. It can be used to
+// iterate over records, one by one, up to the last record.
+//
+// Note: new records can get added while iterating. Hence the number of records
+// iterated over might be larger than the maximum size.
+func (b *MemoryBackend) Head() *node {
+ return (*node)(b.head)
+}
+
+type event int
+
+const (
+ eventFlush event = iota
+ eventStop
+)
+
+// ChannelMemoryBackend is very similar to the MemoryBackend, except that it
+// internally utilizes a channel.
+type ChannelMemoryBackend struct {
+ maxSize int
+ size int
+ incoming chan *Record
+ events chan event
+ mu sync.Mutex
+ running bool
+ flushWg sync.WaitGroup
+ stopWg sync.WaitGroup
+ head, tail *node
+}
+
+// NewChannelMemoryBackend creates a simple in-memory logging backend which
+// utilizes a go channel for communication.
+//
+// Start will automatically be called by this function.
+func NewChannelMemoryBackend(size int) *ChannelMemoryBackend {
+ backend := &ChannelMemoryBackend{
+ maxSize: size,
+ incoming: make(chan *Record, 1024),
+ events: make(chan event),
+ }
+ backend.Start()
+ return backend
+}
+
+// Start launches the internal goroutine which starts processing data from the
+// input channel.
+func (b *ChannelMemoryBackend) Start() {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+
+ // Launch the goroutine unless it's already running.
+ if b.running != true {
+ b.running = true
+ b.stopWg.Add(1)
+ go b.process()
+ }
+}
+
+func (b *ChannelMemoryBackend) process() {
+ defer b.stopWg.Done()
+ for {
+ select {
+ case rec := <-b.incoming:
+ b.insertRecord(rec)
+ case e := <-b.events:
+ switch e {
+ case eventStop:
+ return
+ case eventFlush:
+ for len(b.incoming) > 0 {
+ b.insertRecord(<-b.incoming)
+ }
+ b.flushWg.Done()
+ }
+ }
+ }
+}
+
+func (b *ChannelMemoryBackend) insertRecord(rec *Record) {
+ prev := b.tail
+ b.tail = &node{Record: rec}
+ if prev == nil {
+ b.head = b.tail
+ } else {
+ prev.next = b.tail
+ }
+
+ if b.maxSize > 0 && b.size >= b.maxSize {
+ b.head = b.head.next
+ } else {
+ b.size++
+ }
+}
+
+// Flush waits until all records in the buffered channel have been processed.
+func (b *ChannelMemoryBackend) Flush() {
+ b.flushWg.Add(1)
+ b.events <- eventFlush
+ b.flushWg.Wait()
+}
+
+// Stop signals the internal goroutine to exit and waits until it have.
+func (b *ChannelMemoryBackend) Stop() {
+ b.mu.Lock()
+ if b.running == true {
+ b.running = false
+ b.events <- eventStop
+ }
+ b.mu.Unlock()
+ b.stopWg.Wait()
+}
+
+// Log implements the Log method required by Backend.
+func (b *ChannelMemoryBackend) Log(level Level, calldepth int, rec *Record) error {
+ b.incoming <- rec
+ return nil
+}
+
+// Head returns the oldest record node kept in memory. It can be used to
+// iterate over records, one by one, up to the last record.
+//
+// Note: new records can get added while iterating. Hence the number of records
+// iterated over might be larger than the maximum size.
+func (b *ChannelMemoryBackend) Head() *node {
+ return b.head
+}
diff --git a/vendor/github.com/op/go-logging/multi.go b/vendor/github.com/op/go-logging/multi.go
new file mode 100644
index 0000000..3731653
--- /dev/null
+++ b/vendor/github.com/op/go-logging/multi.go
@@ -0,0 +1,65 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package logging
+
+// TODO remove Level stuff from the multi logger. Do one thing.
+
+// multiLogger is a log multiplexer which can be used to utilize multiple log
+// backends at once.
+type multiLogger struct {
+ backends []LeveledBackend
+}
+
+// MultiLogger creates a logger which contain multiple loggers.
+func MultiLogger(backends ...Backend) LeveledBackend {
+ var leveledBackends []LeveledBackend
+ for _, backend := range backends {
+ leveledBackends = append(leveledBackends, AddModuleLevel(backend))
+ }
+ return &multiLogger{leveledBackends}
+}
+
+// Log passes the log record to all backends.
+func (b *multiLogger) Log(level Level, calldepth int, rec *Record) (err error) {
+ for _, backend := range b.backends {
+ if backend.IsEnabledFor(level, rec.Module) {
+ // Shallow copy of the record for the formatted cache on Record and get the
+ // record formatter from the backend.
+ r2 := *rec
+ if e := backend.Log(level, calldepth+1, &r2); e != nil {
+ err = e
+ }
+ }
+ }
+ return
+}
+
+// GetLevel returns the highest level enabled by all backends.
+func (b *multiLogger) GetLevel(module string) Level {
+ var level Level
+ for _, backend := range b.backends {
+ if backendLevel := backend.GetLevel(module); backendLevel > level {
+ level = backendLevel
+ }
+ }
+ return level
+}
+
+// SetLevel propagates the same level to all backends.
+func (b *multiLogger) SetLevel(level Level, module string) {
+ for _, backend := range b.backends {
+ backend.SetLevel(level, module)
+ }
+}
+
+// IsEnabledFor returns true if any of the backends are enabled for it.
+func (b *multiLogger) IsEnabledFor(level Level, module string) bool {
+ for _, backend := range b.backends {
+ if backend.IsEnabledFor(level, module) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/op/go-logging/syslog.go b/vendor/github.com/op/go-logging/syslog.go
new file mode 100644
index 0000000..4faa531
--- /dev/null
+++ b/vendor/github.com/op/go-logging/syslog.go
@@ -0,0 +1,53 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//+build !windows,!plan9
+
+package logging
+
+import "log/syslog"
+
+// SyslogBackend is a simple logger to syslog backend. It automatically maps
+// the internal log levels to appropriate syslog log levels.
+type SyslogBackend struct {
+ Writer *syslog.Writer
+}
+
+// NewSyslogBackend connects to the syslog daemon using UNIX sockets with the
+// given prefix. If prefix is not given, the prefix will be derived from the
+// launched command.
+func NewSyslogBackend(prefix string) (b *SyslogBackend, err error) {
+ var w *syslog.Writer
+ w, err = syslog.New(syslog.LOG_CRIT, prefix)
+ return &SyslogBackend{w}, err
+}
+
+// NewSyslogBackendPriority is the same as NewSyslogBackend, but with custom
+// syslog priority, like syslog.LOG_LOCAL3|syslog.LOG_DEBUG etc.
+func NewSyslogBackendPriority(prefix string, priority syslog.Priority) (b *SyslogBackend, err error) {
+ var w *syslog.Writer
+ w, err = syslog.New(priority, prefix)
+ return &SyslogBackend{w}, err
+}
+
+// Log implements the Backend interface.
+func (b *SyslogBackend) Log(level Level, calldepth int, rec *Record) error {
+ line := rec.Formatted(calldepth + 1)
+ switch level {
+ case CRITICAL:
+ return b.Writer.Crit(line)
+ case ERROR:
+ return b.Writer.Err(line)
+ case WARNING:
+ return b.Writer.Warning(line)
+ case NOTICE:
+ return b.Writer.Notice(line)
+ case INFO:
+ return b.Writer.Info(line)
+ case DEBUG:
+ return b.Writer.Debug(line)
+ default:
+ }
+ panic("unhandled log level")
+}
diff --git a/vendor/github.com/op/go-logging/syslog_fallback.go b/vendor/github.com/op/go-logging/syslog_fallback.go
new file mode 100644
index 0000000..91bc18d
--- /dev/null
+++ b/vendor/github.com/op/go-logging/syslog_fallback.go
@@ -0,0 +1,28 @@
+// Copyright 2013, Örjan Persson. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//+build windows plan9
+
+package logging
+
+import (
+ "fmt"
+)
+
+type Priority int
+
+type SyslogBackend struct {
+}
+
+func NewSyslogBackend(prefix string) (b *SyslogBackend, err error) {
+ return nil, fmt.Errorf("Platform does not support syslog")
+}
+
+func NewSyslogBackendPriority(prefix string, priority Priority) (b *SyslogBackend, err error) {
+ return nil, fmt.Errorf("Platform does not support syslog")
+}
+
+func (b *SyslogBackend) Log(level Level, calldepth int, rec *Record) error {
+ return fmt.Errorf("Platform does not support syslog")
+}