| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package vlog |
| |
| import ( |
| "flag" |
| "fmt" |
| |
| "github.com/cosmosnicolaou/llog" |
| ) |
| |
| var ( |
| toStderr bool |
| alsoToStderr bool |
| logDir string |
| verbosity Level |
| stderrThreshold StderrThreshold = StderrThreshold(llog.ErrorLog) |
| vmodule ModuleSpec |
| traceLocation TraceLocation |
| maxStackBufSize int |
| ) |
| |
| var flagDefs = []struct { |
| name string |
| variable interface{} |
| defaultValue interface{} |
| description string |
| }{ |
| {"log_dir", &logDir, "", "if non-empty, write log files to this directory"}, |
| {"logtostderr", &toStderr, false, "log to standard error instead of files"}, |
| {"alsologtostderr", &alsoToStderr, true, "log to standard error as well as files"}, |
| {"max_stack_buf_size", &maxStackBufSize, 4192 * 1024, "max size in bytes of the buffer to use for logging stack traces"}, |
| {"v", &verbosity, nil, "log level for V logs"}, |
| {"stderrthreshold", &stderrThreshold, nil, "logs at or above this threshold go to stderr"}, |
| {"vmodule", &vmodule, nil, "comma-separated list of pattern=N settings for file-filtered logging"}, |
| {"log_backtrace_at", &traceLocation, nil, "when logging hits line file:N, emit a stack trace"}, |
| } |
| |
| func init() { |
| istest := false |
| if flag.CommandLine.Lookup("test.v") != nil { |
| istest = true |
| } |
| for _, flagDef := range flagDefs { |
| if istest && flagDef.name == "v" { |
| continue |
| } |
| switch v := flagDef.variable.(type) { |
| case *string: |
| flag.StringVar(v, flagDef.name, |
| flagDef.defaultValue.(string), flagDef.description) |
| case *bool: |
| flag.BoolVar(v, flagDef.name, |
| flagDef.defaultValue.(bool), flagDef.description) |
| case *int: |
| flag.IntVar(v, flagDef.name, |
| flagDef.defaultValue.(int), flagDef.description) |
| case flag.Value: |
| if flagDef.defaultValue != nil { |
| panic(fmt.Sprintf("default value not supported for flag %s", flagDef.name)) |
| } |
| flag.Var(v, flagDef.name, flagDef.description) |
| default: |
| panic("invalid flag type") |
| } |
| } |
| } |
| |
| // ConfigureLibraryLoggerFromFlags will configure the internal global logger |
| // using command line flags. It assumes that flag.Parse() has already been |
| // called to initialize the flag variables. |
| func ConfigureLibraryLoggerFromFlags() error { |
| return ConfigureLoggerFromFlags(Log) |
| } |
| |
| // ConfigureLoggerFromLogs will configure the supplied logger using |
| // command line flags. |
| func ConfigureLoggerFromFlags(l Logger) error { |
| return l.Configure( |
| LogToStderr(toStderr), |
| AlsoLogToStderr(alsoToStderr), |
| LogDir(logDir), |
| Level(verbosity), |
| StderrThreshold(stderrThreshold), |
| ModuleSpec(vmodule), |
| TraceLocation(traceLocation), |
| MaxStackBufSize(maxStackBufSize), |
| ) |
| } |
| |
| func (l *logger) String() string { |
| return l.log.String() |
| } |
| |
| // ExplicitlySetFlags returns a map of the logging command line flags and their |
| // values formatted as strings. Only the flags that were explicitly set are |
| // returned. This is intended for use when an application needs to know what |
| // value the flags were set to, for example when creating subprocesses. |
| func (l *logger) ExplicitlySetFlags() map[string]string { |
| logFlagNames := make(map[string]bool) |
| for _, flagDef := range flagDefs { |
| logFlagNames[flagDef.name] = true |
| } |
| args := make(map[string]string) |
| flag.Visit(func(f *flag.Flag) { |
| if logFlagNames[f.Name] { |
| args[f.Name] = f.Value.String() |
| } |
| }) |
| return args |
| } |