You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
3.9 KiB
158 lines
3.9 KiB
// Copyright 2015 CoreOS, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package capnslog
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Formatter interface {
|
|
Format(pkg string, level LogLevel, depth int, entries ...interface{})
|
|
Flush()
|
|
}
|
|
|
|
func NewStringFormatter(w io.Writer) Formatter {
|
|
return &StringFormatter{
|
|
w: bufio.NewWriter(w),
|
|
}
|
|
}
|
|
|
|
type StringFormatter struct {
|
|
w *bufio.Writer
|
|
}
|
|
|
|
func (s *StringFormatter) Format(pkg string, l LogLevel, i int, entries ...interface{}) {
|
|
now := time.Now().UTC()
|
|
s.w.WriteString(now.Format(time.RFC3339))
|
|
s.w.WriteByte(' ')
|
|
writeEntries(s.w, pkg, l, i, entries...)
|
|
s.Flush()
|
|
}
|
|
|
|
func writeEntries(w *bufio.Writer, pkg string, _ LogLevel, _ int, entries ...interface{}) {
|
|
if pkg != "" {
|
|
w.WriteString(pkg + ": ")
|
|
}
|
|
str := fmt.Sprint(entries...)
|
|
endsInNL := strings.HasSuffix(str, "\n")
|
|
w.WriteString(str)
|
|
if !endsInNL {
|
|
w.WriteString("\n")
|
|
}
|
|
}
|
|
|
|
func (s *StringFormatter) Flush() {
|
|
s.w.Flush()
|
|
}
|
|
|
|
func NewPrettyFormatter(w io.Writer, debug bool) Formatter {
|
|
return &PrettyFormatter{
|
|
w: bufio.NewWriter(w),
|
|
debug: debug,
|
|
}
|
|
}
|
|
|
|
type PrettyFormatter struct {
|
|
w *bufio.Writer
|
|
debug bool
|
|
}
|
|
|
|
func (c *PrettyFormatter) Format(pkg string, l LogLevel, depth int, entries ...interface{}) {
|
|
now := time.Now()
|
|
ts := now.Format("2006-01-02 15:04:05")
|
|
c.w.WriteString(ts)
|
|
ms := now.Nanosecond() / 1000
|
|
c.w.WriteString(fmt.Sprintf(".%06d", ms))
|
|
if c.debug {
|
|
_, file, line, ok := runtime.Caller(depth) // It's always the same number of frames to the user's call.
|
|
if !ok {
|
|
file = "???"
|
|
line = 1
|
|
} else {
|
|
slash := strings.LastIndex(file, "/")
|
|
if slash >= 0 {
|
|
file = file[slash+1:]
|
|
}
|
|
}
|
|
if line < 0 {
|
|
line = 0 // not a real line number
|
|
}
|
|
c.w.WriteString(fmt.Sprintf(" [%s:%d]", file, line))
|
|
}
|
|
c.w.WriteString(fmt.Sprint(" ", l.Char(), " | "))
|
|
writeEntries(c.w, pkg, l, depth, entries...)
|
|
c.Flush()
|
|
}
|
|
|
|
func (c *PrettyFormatter) Flush() {
|
|
c.w.Flush()
|
|
}
|
|
|
|
// LogFormatter emulates the form of the traditional built-in logger.
|
|
type LogFormatter struct {
|
|
logger *log.Logger
|
|
prefix string
|
|
}
|
|
|
|
// NewLogFormatter is a helper to produce a new LogFormatter struct. It uses the
|
|
// golang log package to actually do the logging work so that logs look similar.
|
|
func NewLogFormatter(w io.Writer, prefix string, flag int) Formatter {
|
|
return &LogFormatter{
|
|
logger: log.New(w, "", flag), // don't use prefix here
|
|
prefix: prefix, // save it instead
|
|
}
|
|
}
|
|
|
|
// Format builds a log message for the LogFormatter. The LogLevel is ignored.
|
|
func (lf *LogFormatter) Format(pkg string, _ LogLevel, _ int, entries ...interface{}) {
|
|
str := fmt.Sprint(entries...)
|
|
prefix := lf.prefix
|
|
if pkg != "" {
|
|
prefix = fmt.Sprintf("%s%s: ", prefix, pkg)
|
|
}
|
|
lf.logger.Output(5, fmt.Sprintf("%s%v", prefix, str)) // call depth is 5
|
|
}
|
|
|
|
// Flush is included so that the interface is complete, but is a no-op.
|
|
func (lf *LogFormatter) Flush() {
|
|
// noop
|
|
}
|
|
|
|
// NilFormatter is a no-op log formatter that does nothing.
|
|
type NilFormatter struct {
|
|
}
|
|
|
|
// NewNilFormatter is a helper to produce a new LogFormatter struct. It logs no
|
|
// messages so that you can cause part of your logging to be silent.
|
|
func NewNilFormatter() Formatter {
|
|
return &NilFormatter{}
|
|
}
|
|
|
|
// Format does nothing.
|
|
func (_ *NilFormatter) Format(_ string, _ LogLevel, _ int, _ ...interface{}) {
|
|
// noop
|
|
}
|
|
|
|
// Flush is included so that the interface is complete, but is a no-op.
|
|
func (_ *NilFormatter) Flush() {
|
|
// noop
|
|
}
|