Init configuration from file #3
99
configuration.go
Normal file
99
configuration.go
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type ourConfig struct {
|
||||
name string
|
||||
bufferLen int64
|
||||
subname string
|
||||
provider string
|
||||
config string
|
||||
}
|
||||
|
||||
// ConfigureFromFile configures logging from a provided file
|
||||
func ConfigureFromFile(filename string) error {
|
||||
bytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ConfigureFromBytes(bytes)
|
||||
}
|
||||
|
||||
// ConfigureFromBytes configures logging from provided []byte
|
||||
func ConfigureFromBytes(config []byte) error {
|
||||
configs := []ourConfig{}
|
||||
configMap := make(map[string]interface{})
|
||||
|
||||
err := json.Unmarshal(config, &configMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaultBufferLen, ok := configMap["DEFAULT_BUFFER_LEN"].(int64)
|
||||
if !ok || defaultBufferLen == 0 {
|
||||
defaultBufferLen = 1000
|
||||
}
|
||||
|
||||
for name, loggerconfigInterface := range configMap {
|
||||
if name == "DEFAULT_BUFFER_LEN" {
|
||||
continue
|
||||
}
|
||||
loggerconfig, ok := loggerconfigInterface.(map[string]interface{})
|
||||
if !ok {
|
||||
return &ErrBadConfig{
|
||||
message: fmt.Sprintf("Bad configuration for %s", name),
|
||||
}
|
||||
}
|
||||
for subname, subloggerconfigInterface := range loggerconfig {
|
||||
subloggerconfig, ok := subloggerconfigInterface.(map[string]interface{})
|
||||
if !ok {
|
||||
return &ErrBadConfig{
|
||||
message: fmt.Sprintf("Bad configuration for %s:%s", name, subname),
|
||||
}
|
||||
}
|
||||
bufferLen, ok := loggerconfig["bufferLen"].(int64)
|
||||
if !ok || bufferLen == 0 {
|
||||
bufferLen = defaultBufferLen
|
||||
}
|
||||
provider, ok := subloggerconfig["provider"].(string)
|
||||
if !ok || provider == "" {
|
||||
provider = subname
|
||||
}
|
||||
subconfigInterface, ok := subloggerconfig["config"]
|
||||
|
||||
subconfig, err := json.Marshal(subconfigInterface)
|
||||
if err != nil {
|
||||
return &ErrBadConfig{
|
||||
message: fmt.Sprintf("Bad configuration for %s:%s, provider %s: %v", name, subname, provider, err),
|
||||
}
|
||||
}
|
||||
configs = append(configs, ourConfig{
|
||||
name: name,
|
||||
subname: subname,
|
||||
bufferLen: bufferLen,
|
||||
provider: provider,
|
||||
config: string(subconfig),
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(configs) == 0 {
|
||||
return &ErrBadConfig{
|
||||
message: fmt.Sprintf("Bad configuration. No loggers."),
|
||||
}
|
||||
}
|
||||
for _, c := range configs {
|
||||
err = NewNamedLogger(c.name, c.bufferLen, c.subname, c.provider, c.config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
55
log.go
55
log.go
@ -2,11 +2,29 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package log provides a more comprehensive logging system than that which go provides by default
|
||||
//
|
||||
// There are several methods for configuration including programmatically using the NewNamedLogger
|
||||
// and NewLogger functions. There is also an init provided method to read a log configuration file
|
||||
// provided as an argument to program: --log-config-file
|
||||
//
|
||||
// This configuration file is a JSON file of the form:
|
||||
// {
|
||||
// "DEFAULT_BUFFER_LEN":1000,
|
||||
// "default": {
|
||||
// "bufferLen": 1000,
|
||||
// "console": {
|
||||
// "provider": "console",
|
||||
// "config": { "colorize": true, "flags": "stdflags", "stacktraceLevel": "error" }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -18,6 +36,15 @@ var (
|
||||
hasDefaultLogger = false
|
||||
)
|
||||
|
||||
// ErrBadConfig represent a bad configuration error
|
||||
type ErrBadConfig struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e *ErrBadConfig) Error() string {
|
||||
return fmt.Sprintf("Bad Configuration: %s", e.message)
|
||||
}
|
||||
|
||||
// NewLogger create a logger for the default logger
|
||||
func NewLogger(bufLen int64, name, provider, config string) *Logger {
|
||||
if hasDefaultLogger {
|
||||
@ -227,8 +254,36 @@ func (l *LoggerAsWriter) Log(msg string) {
|
||||
}
|
||||
|
||||
func init() {
|
||||
configFile := ""
|
||||
nextArg := false
|
||||
for _, arg := range os.Args {
|
||||
if nextArg {
|
||||
configFile = arg
|
||||
break
|
||||
}
|
||||
if arg == "--log-config-file" {
|
||||
nextArg = true
|
||||
} else if strings.HasPrefix(arg, "--log-config-file=") {
|
||||
configFile = strings.TrimPrefix(arg, "--log-config-file=")
|
||||
}
|
||||
}
|
||||
if _, err := os.Lstat(configFile); err != nil {
|
||||
configFile = ""
|
||||
}
|
||||
var err error
|
||||
|
||||
if configFile != "" {
|
||||
err = ConfigureFromFile(configFile)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// create a default log to write to console
|
||||
NewLogger(1000, "std", "console", fmt.Sprintf(`{"flags":%d, "stacktraceLevel":"error"}`,
|
||||
|
||||
FlagsFromString("shortfile,shortfuncname,level,microseconds,date,shortfile")))
|
||||
hasDefaultLogger = true
|
||||
if err != nil {
|
||||
Error("Error reading provided config file: %s Err: %v", configFile, err)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user
If config load successfully, the default logger should be disabled I think.
Take a look at line 278:
if there's no error during configuration from the provided configuration then
init()
returns here.OK. Just found we need add reactions on code comments.