make a log config window
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
6b25784508
commit
9b46482ad0
1
error.go
1
error.go
|
@ -5,6 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Error(err error, a ...any) {
|
func Error(err error, a ...any) {
|
||||||
|
if ! ERROR.B { return }
|
||||||
origlog.Println("Error:", err)
|
origlog.Println("Error:", err)
|
||||||
origlog.Println(a...)
|
origlog.Println(a...)
|
||||||
}
|
}
|
||||||
|
|
159
flags.go
159
flags.go
|
@ -1,17 +1,22 @@
|
||||||
package log
|
package log
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handles the on/off flags for things like log.Info() and log.Warn()
|
||||||
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var INFO bool = true
|
var INFO LogFlag
|
||||||
var WARN bool = true
|
var VERBOSE LogFlag
|
||||||
var ERROR bool = true
|
|
||||||
|
|
||||||
var VERBOSE bool = false
|
|
||||||
// var SPEW bool = false
|
|
||||||
|
|
||||||
var SPEW LogFlag
|
var SPEW LogFlag
|
||||||
|
var WARN LogFlag
|
||||||
|
var ERROR LogFlag
|
||||||
|
var PRINTLN LogFlag
|
||||||
|
|
||||||
|
// writeMutex protects locks the write process
|
||||||
|
var flagsMutex sync.Mutex
|
||||||
|
|
||||||
type LogFlag struct {
|
type LogFlag struct {
|
||||||
B bool
|
B bool
|
||||||
|
@ -20,90 +25,124 @@ type LogFlag struct {
|
||||||
Desc string
|
Desc string
|
||||||
}
|
}
|
||||||
|
|
||||||
var registered map[string][]string
|
|
||||||
var flags []*LogFlag
|
var flags []*LogFlag
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registered = make(map[string][]string)
|
INFO.B = false
|
||||||
|
INFO.Name = "INFO"
|
||||||
|
INFO.Subsystem = "log"
|
||||||
|
INFO.Desc = "Enable log.Info()"
|
||||||
|
INFO.Register()
|
||||||
|
|
||||||
SPEW.B = false
|
SPEW.B = false
|
||||||
SPEW.Name = "SPEW"
|
SPEW.Name = "SPEW"
|
||||||
SPEW.Subsystem = "log"
|
SPEW.Subsystem = "log"
|
||||||
SPEW.Desc = "Enable log.Spew()"
|
SPEW.Desc = "Enable log.Spew()"
|
||||||
|
SPEW.Register()
|
||||||
|
|
||||||
// register the default flags used by this log package
|
VERBOSE.B = false
|
||||||
registered["log"] = []string{"SPEW","INFO", "WARN", "ERROR", "VERBOSE"}
|
VERBOSE.Name = "VERBOSE"
|
||||||
|
VERBOSE.Subsystem = "log"
|
||||||
|
VERBOSE.Desc = "Enable log.Verbose()"
|
||||||
|
VERBOSE.Register()
|
||||||
|
|
||||||
|
WARN.B = true
|
||||||
|
WARN.Name = "WARN"
|
||||||
|
WARN.Subsystem = "log"
|
||||||
|
WARN.Desc = "Enable log.Warn()"
|
||||||
|
WARN.Register()
|
||||||
|
|
||||||
|
ERROR.B = true
|
||||||
|
ERROR.Name = "ERROR"
|
||||||
|
ERROR.Subsystem = "log"
|
||||||
|
ERROR.Desc = "Enable log.Error()"
|
||||||
|
ERROR.Register()
|
||||||
|
|
||||||
|
PRINTLN.B = true
|
||||||
|
PRINTLN.Name = "PRINTLN"
|
||||||
|
PRINTLN.Subsystem = "log"
|
||||||
|
PRINTLN.Desc = "Enable log.Println()"
|
||||||
|
PRINTLN.Register()
|
||||||
}
|
}
|
||||||
|
|
||||||
func All(b bool) {
|
// set all the flags
|
||||||
Set("SPEW", b)
|
func SetAll(b bool) {
|
||||||
Set("INFO", b)
|
flagsMutex.Lock()
|
||||||
Set("WARN", b)
|
defer flagsMutex.Unlock()
|
||||||
Set("ERROR", b)
|
|
||||||
Set("VERBOSE", b)
|
|
||||||
for _, f := range flags {
|
for _, f := range flags {
|
||||||
Warn("All() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
|
|
||||||
f.B = b
|
f.B = b
|
||||||
Warn("All() f.B is now", f.B)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this bypasses all checks and _always_ logs the info to STDOUT
|
// this bypasses all checks and _always_ logs the info to STDOUT
|
||||||
// is this a bad idea? Probably not....
|
// is this a bad idea? Probably not....
|
||||||
func ListFlags() map[string][]string {
|
// TODO: returning []*LogFlag is not safe and access must be locked
|
||||||
Log(true, "ListFlags() registered =", registered)
|
// but this is only used by the log debugging window at this time
|
||||||
|
func ShowFlags() []*LogFlag {
|
||||||
|
flagsMutex.Lock()
|
||||||
|
defer flagsMutex.Unlock()
|
||||||
for _, f := range flags {
|
for _, f := range flags {
|
||||||
Log(true, "ListFlags() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
|
Log(true, "ShowFlags() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return registered
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func Set(flag string, b bool) {
|
// TODO, switch to this
|
||||||
switch flag {
|
func ProcessFlags(callback func(*LogFlag)) {
|
||||||
case "INFO":
|
flagsMutex.Lock()
|
||||||
INFO = b
|
defer flagsMutex.Unlock()
|
||||||
case "WARN":
|
for _, f := range flags {
|
||||||
WARN = b
|
Log(true, "ProcessFlags() run callback(f) here on", f)
|
||||||
case "SPEW":
|
callback(f)
|
||||||
SPEW.B = b
|
|
||||||
case "ERROR":
|
|
||||||
ERROR = b
|
|
||||||
case "VERBOSE":
|
|
||||||
VERBOSE = b
|
|
||||||
default:
|
|
||||||
Error(errors.New("unknown flag"), "Flag name sent:", flag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(flag string) bool {
|
|
||||||
switch flag {
|
|
||||||
case "INFO":
|
|
||||||
return INFO
|
|
||||||
case "WARN":
|
|
||||||
return WARN
|
|
||||||
case "SPEW":
|
|
||||||
return SPEW.B
|
|
||||||
case "ERROR":
|
|
||||||
return ERROR
|
|
||||||
case "VERBOSE":
|
|
||||||
return VERBOSE
|
|
||||||
default:
|
|
||||||
Error(errors.New("unknown flag"), "Flag name sent:", flag)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// register a variable name from a subsystem
|
// register a variable name from a subsystem
|
||||||
// inspired by Alex Flint
|
// inspired by Alex Flint
|
||||||
func (f *LogFlag) Register() {
|
func (f *LogFlag) Register() {
|
||||||
|
flagsMutex.Lock()
|
||||||
|
defer flagsMutex.Unlock()
|
||||||
Info("log.Register() ", f)
|
Info("log.Register() ", f)
|
||||||
flags = append(flags,f)
|
flags = append(flags,f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// register a variable name from a subsystem
|
func (f *LogFlag) Set(b bool) {
|
||||||
// this is used for custom log flags
|
flagsMutex.Lock()
|
||||||
func Register(subsystem string, name string, b *bool) {
|
defer flagsMutex.Unlock()
|
||||||
Info("log.Register() got subsystem", subsystem, "with name =", name, "bool value =", b)
|
Info("Set() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
|
||||||
registered[subsystem] = append(registered[subsystem], name)
|
f.B = b
|
||||||
|
Info("Set() f.B is now", f.B)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Set(subsystem string, name string, b bool) {
|
||||||
|
flagsMutex.Lock()
|
||||||
|
defer flagsMutex.Unlock()
|
||||||
|
Info("Set() TODO find var:", "(" + subsystem + ")", name, "=", b)
|
||||||
|
for _, f := range flags {
|
||||||
|
Log(true, "Set() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
|
||||||
|
if (subsystem == f.Subsystem) && (name == f.Name) {
|
||||||
|
Log(true, "Set() FOUND ", f)
|
||||||
|
f.B = b
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get(subsystem string, name string) bool {
|
||||||
|
flagsMutex.Lock()
|
||||||
|
defer flagsMutex.Unlock()
|
||||||
|
Info("Get() TODO find var:", "(" + subsystem + ")", name)
|
||||||
|
for _, f := range flags {
|
||||||
|
Log(true, "Get() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
|
||||||
|
if (subsystem == f.Subsystem) && (name == f.Name) {
|
||||||
|
Log(true, "Get() FOUND ", f)
|
||||||
|
return f.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
4
info.go
4
info.go
|
@ -5,11 +5,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Info(a ...any) {
|
func Info(a ...any) {
|
||||||
if ! INFO { return }
|
if ! INFO.B { return }
|
||||||
golanglog.Println(a...)
|
golanglog.Println(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Infof(s string, a ...any) {
|
func Infof(s string, a ...any) {
|
||||||
if ! INFO { return }
|
if ! INFO.B { return }
|
||||||
golanglog.Printf(s, a...)
|
golanglog.Printf(s, a...)
|
||||||
}
|
}
|
||||||
|
|
80
notes.go
80
notes.go
|
@ -1,80 +0,0 @@
|
||||||
package log
|
|
||||||
|
|
||||||
/*
|
|
||||||
var argv struct {
|
|
||||||
Foo string
|
|
||||||
Bar bool
|
|
||||||
User string `arg:"env:USER"`
|
|
||||||
Demo bool `help:"run a demo"`
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
var f1 *os.File
|
|
||||||
var f2 *os.File
|
|
||||||
var err error
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* from gocron:
|
|
||||||
|
|
||||||
// DefaultLogger is used by Cron if none is specified.
|
|
||||||
var DefaultLogger Logger = PrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags))
|
|
||||||
|
|
||||||
// DiscardLogger can be used by callers to discard all log messages.
|
|
||||||
var DiscardLogger Logger = PrintfLogger(log.New(ioutil.Discard, "", 0))
|
|
||||||
|
|
||||||
// Logger is the interface used in this package for logging, so that any backend
|
|
||||||
// can be plugged in. It is a subset of the github.com/go-logr/logr interface.
|
|
||||||
type Logger interface {
|
|
||||||
// Info logs routine messages about cron's operation.
|
|
||||||
Info(msg string, keysAndValues ...interface{})
|
|
||||||
// Error logs an error condition.
|
|
||||||
Error(err error, msg string, keysAndValues ...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// fmt.Println(argv.Foo, args.Bar, args.User)
|
|
||||||
/*
|
|
||||||
// from: https://github.com/robfig/cron/blob/master/logger.go
|
|
||||||
log.Println()
|
|
||||||
log.Println("STDOUT is now at /tmp/guilogfile")
|
|
||||||
log.Println("STDOUT is now at /tmp/guilogfile")
|
|
||||||
log.Println()
|
|
||||||
f1, err = os.OpenFile(outfile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("error opening file: %v", err)
|
|
||||||
}
|
|
||||||
// hmm. is there a trick here or must this be in main()
|
|
||||||
// defer f.Close()
|
|
||||||
|
|
||||||
log.SetOutput(f1)
|
|
||||||
log.Println("This is a test log entry")
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
func captureSTDOUT() {
|
|
||||||
f2, _ = os.OpenFile("/tmp/my.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
|
|
||||||
multiWriter := io.MultiWriter(os.Stderr, f2)
|
|
||||||
rd, wr, err := os.Pipe()
|
|
||||||
if err != nil {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// overwrite os.Stdout
|
|
||||||
os.Stderr = wr
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
scanner := bufio.NewScanner(rd)
|
|
||||||
for scanner.Scan() {
|
|
||||||
stdoutLine := scanner.Text()
|
|
||||||
multiWriter.Write([]byte(stdoutLine + "\n"))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fmt.Println("foobar")
|
|
||||||
|
|
||||||
// hacky sleep to ensure the go routine can write before program exits
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -18,15 +18,19 @@ package log
|
||||||
so this package appears to work exactly like the original ones
|
so this package appears to work exactly like the original ones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: fill in the other functions from "log". Is there a way to automagically do that?
|
||||||
|
|
||||||
import (
|
import (
|
||||||
origlog "log"
|
origlog "log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Println(a ...any) {
|
func Println(a ...any) {
|
||||||
|
if ! PRINTLN.B { return }
|
||||||
origlog.Println(a...)
|
origlog.Println(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Printf(s string, a ...any) {
|
func Printf(s string, a ...any) {
|
||||||
|
if ! PRINTLN.B { return }
|
||||||
origlog.Printf(s, a...)
|
origlog.Printf(s, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
sleep.go
40
sleep.go
|
@ -1,44 +1,12 @@
|
||||||
package log
|
package log
|
||||||
//
|
|
||||||
// version v1.2
|
|
||||||
//
|
|
||||||
// I like things to be easy.
|
|
||||||
//
|
|
||||||
// this means all the log settings are in one place. it should allow
|
|
||||||
// things to be over-ridden externally to the library
|
|
||||||
// but still allow command line --args to pass debugging settings
|
|
||||||
//
|
|
||||||
// I also have a generic sleep() and exit() in here because it's simple
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
//
|
|
||||||
// log("something", foo, bar)
|
|
||||||
// var DEBUG bool = true
|
|
||||||
// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing
|
|
||||||
//
|
|
||||||
|
|
||||||
/*
|
// a shortcut for sleep so you don't have to always change the import lines when debugging
|
||||||
I've spent, am spending, too much time thinking about 'logging'. 'log', 'logrus', 'zap', whatever.
|
|
||||||
I'm not twitter. i don't give a fuck about how many nanoseconds it takes to log. Anyway, this
|
|
||||||
implementation is probably faster than all of those because you just set one bool to FALSE
|
|
||||||
and it all stops.
|
|
||||||
Sometimes I need to capture to stdout, sometimes stdout can't
|
|
||||||
work because it doesn't exist for the user. This whole thing is a PITA. Then it's spread
|
|
||||||
over 8 million references in every .go file. I'm tapping out and putting
|
|
||||||
it in one place. here it is. Also, this makes having debug levels really fucking easy.
|
|
||||||
You can define whatever level of logging you want from anywhere (command line) etc.
|
|
||||||
|
|
||||||
log() # doesn't do anything
|
|
||||||
log(stuff) # sends it to whatever log you define in a single place. here is the place
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
origlog "log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -51,7 +19,7 @@ func Sleep(a ...any) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
origlog.Println("sleep", a[0])
|
Info("sleep", a[0])
|
||||||
|
|
||||||
switch a[0].(type) {
|
switch a[0].(type) {
|
||||||
case int:
|
case int:
|
||||||
|
@ -59,7 +27,7 @@ func Sleep(a ...any) {
|
||||||
case float64:
|
case float64:
|
||||||
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
|
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
|
||||||
default:
|
default:
|
||||||
origlog.Println("sleep a[0], type = ", a[0], reflect.TypeOf(a[0]))
|
Info("sleep a[0], type = ", a[0], reflect.TypeOf(a[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +37,7 @@ func Sleep(a ...any) {
|
||||||
exit("dont like apples") # ok. I'll make a note of that
|
exit("dont like apples") # ok. I'll make a note of that
|
||||||
*/
|
*/
|
||||||
func Exit(a ...any) {
|
func Exit(a ...any) {
|
||||||
Error(errors.New("Exit"), a)
|
Error(errors.New("log.Exit()"), a)
|
||||||
//if (a) {
|
//if (a) {
|
||||||
// os.Exit(a)
|
// os.Exit(a)
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -5,6 +5,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Verbose(a ...any) {
|
func Verbose(a ...any) {
|
||||||
if ! VERBOSE { return }
|
if ! VERBOSE.B { return }
|
||||||
golanglog.Println(a...)
|
golanglog.Println(a...)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue