make a log config window

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-01-04 12:34:04 -06:00
parent 6b25784508
commit 9b46482ad0
8 changed files with 112 additions and 180 deletions

View File

@ -5,6 +5,7 @@ import (
)
func Error(err error, a ...any) {
if ! ERROR.B { return }
origlog.Println("Error:", err)
origlog.Println(a...)
}

159
flags.go
View File

@ -1,17 +1,22 @@
package log
/*
Handles the on/off flags for things like log.Info() and log.Warn()
*/
import (
"errors"
"sync"
)
var INFO bool = true
var WARN bool = true
var ERROR bool = true
var VERBOSE bool = false
// var SPEW bool = false
var INFO LogFlag
var VERBOSE 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 {
B bool
@ -20,90 +25,124 @@ type LogFlag struct {
Desc string
}
var registered map[string][]string
var flags []*LogFlag
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.Name = "SPEW"
SPEW.Subsystem = "log"
SPEW.Desc = "Enable log.Spew()"
SPEW.Register()
// register the default flags used by this log package
registered["log"] = []string{"SPEW","INFO", "WARN", "ERROR", "VERBOSE"}
VERBOSE.B = false
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("SPEW", b)
Set("INFO", b)
Set("WARN", b)
Set("ERROR", b)
Set("VERBOSE", b)
// set all the flags
func SetAll(b bool) {
flagsMutex.Lock()
defer flagsMutex.Unlock()
for _, f := range flags {
Warn("All() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
f.B = b
Warn("All() f.B is now", f.B)
}
}
// this bypasses all checks and _always_ logs the info to STDOUT
// is this a bad idea? Probably not....
func ListFlags() map[string][]string {
Log(true, "ListFlags() registered =", registered)
// TODO: returning []*LogFlag is not safe and access must be locked
// 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 {
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) {
switch flag {
case "INFO":
INFO = b
case "WARN":
WARN = b
case "SPEW":
SPEW.B = b
case "ERROR":
ERROR = b
case "VERBOSE":
VERBOSE = b
default:
Error(errors.New("unknown flag"), "Flag name sent:", flag)
// TODO, switch to this
func ProcessFlags(callback func(*LogFlag)) {
flagsMutex.Lock()
defer flagsMutex.Unlock()
for _, f := range flags {
Log(true, "ProcessFlags() run callback(f) here on", f)
callback(f)
}
}
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
// inspired by Alex Flint
func (f *LogFlag) Register() {
flagsMutex.Lock()
defer flagsMutex.Unlock()
Info("log.Register() ", f)
flags = append(flags,f)
}
// register a variable name from a subsystem
// this is used for custom log flags
func Register(subsystem string, name string, b *bool) {
Info("log.Register() got subsystem", subsystem, "with name =", name, "bool value =", b)
registered[subsystem] = append(registered[subsystem], name)
func (f *LogFlag) Set(b bool) {
flagsMutex.Lock()
defer flagsMutex.Unlock()
Info("Set() ", "(" + f.Subsystem + ")", f.Name, "=", f.B, ":", f.Desc)
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
}

View File

@ -5,11 +5,11 @@ import (
)
func Info(a ...any) {
if ! INFO { return }
if ! INFO.B { return }
golanglog.Println(a...)
}
func Infof(s string, a ...any) {
if ! INFO { return }
if ! INFO.B { return }
golanglog.Printf(s, a...)
}

View File

@ -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)
}
*/

View File

@ -18,15 +18,19 @@ package log
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 (
origlog "log"
)
func Println(a ...any) {
if ! PRINTLN.B { return }
origlog.Println(a...)
}
func Printf(s string, a ...any) {
if ! PRINTLN.B { return }
origlog.Printf(s, a...)
}

View File

@ -1,44 +1,12 @@
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
//
/*
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
*/
// a shortcut for sleep so you don't have to always change the import lines when debugging
import (
"os"
"time"
"errors"
"reflect"
origlog "log"
)
/*
@ -51,7 +19,7 @@ func Sleep(a ...any) {
return
}
origlog.Println("sleep", a[0])
Info("sleep", a[0])
switch a[0].(type) {
case int:
@ -59,7 +27,7 @@ func Sleep(a ...any) {
case float64:
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
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
*/
func Exit(a ...any) {
Error(errors.New("Exit"), a)
Error(errors.New("log.Exit()"), a)
//if (a) {
// os.Exit(a)
//}

View File

@ -5,6 +5,6 @@ import (
)
func Verbose(a ...any) {
if ! VERBOSE { return }
if ! VERBOSE.B { return }
golanglog.Println(a...)
}

View File

@ -5,6 +5,6 @@ import (
)
func Warn(a ...any) {
if ! WARN { return }
if ! WARN.B { return }
origlog.Println(a...)
}