blob: 39f6e8b98b8df96346eecb4fc6f81045e4168c61 [file] [log] [blame] [edit]
// Copyright 2017 Google 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 logger
import (
"fmt"
"os"
"time"
"github.com/30x/apid-core"
"github.com/Sirupsen/logrus"
)
const (
configLevel = "log_level"
defaultLevel = logrus.ErrorLevel
moduleField = "module"
environmentField = "env"
)
var std apid.LogService
var config apid.ConfigService
var textFormatter = &logrus.TextFormatter{
FullTimestamp: false,
TimestampFormat: time.StampMilli,
}
func Base() apid.LogService {
if std == nil {
config = apid.Config()
config.SetDefault(configLevel, defaultLevel.String())
logLevel := config.GetString(configLevel)
fmt.Printf("Base log level: %s\n", logLevel)
std = NewLogger(configLevel, logLevel)
}
return std
}
func ForModule(name string) apid.LogService {
return Base().ForModule(name)
}
type logger struct {
*logrus.Entry
}
// creates new logger for module w/ appropriate log level and field
// note: config module xx log level using config var: xx_log_level = "debug"
func (l *logger) ForModule(name string) apid.LogService {
configKey := fmt.Sprintf("%s_%s", name, configLevel)
log := NewLogger(configKey, config.GetString(configKey)).WithField(moduleField, name)
std.Debugf("created logger '%s' at level %s", name, log.(loggerPlus).Level())
return log
}
func (l *logger) ForEnvironment(name string) apid.LogService {
return l.WithField(environmentField, name)
}
func (l *logger) WithField(key string, value interface{}) apid.LogService {
return &logger{l.Entry.WithField(key, value)}
}
func (l *logger) Level() logrus.Level {
return l.Entry.Logger.Level
}
func NewLogger(configKey string, lvlString string) apid.LogService {
var logLevel logrus.Level
if std != nil {
logLevel = std.(loggerPlus).Level()
} else {
logLevel = defaultLevel
}
if lvlString != "" {
lvl, err := logrus.ParseLevel(lvlString)
if err == nil {
logLevel = lvl
} else {
std.Warnf("invalid log level '%s' in config key: '%s'", lvlString, configKey)
}
}
log := &logger{
logrus.NewEntry(
&logrus.Logger{
Out: os.Stderr,
Formatter: textFormatter,
Level: logLevel,
},
),
}
return log
}
type loggerPlus interface {
Level() logrus.Level
}