Compare commits
38 Commits
Author | SHA1 | Date |
---|---|---|
|
466a3c6076 | |
|
c1c1b8a75e | |
|
f793a05288 | |
|
1631c72f70 | |
|
e1d7a5c2cc | |
|
9b12c5049e | |
|
fe562dbf1b | |
|
56145cd22a | |
|
72d75ee478 | |
|
1bcdcfa2f4 | |
|
53adaabee0 | |
|
889ec714e1 | |
|
ef61eb494b | |
|
2b11a4e334 | |
|
52991d305f | |
|
91b0564fb0 | |
|
366bcac15c | |
|
2cf02ee2e5 | |
|
54c0947452 | |
|
99fbd48d0b | |
|
fc382169a3 | |
|
162d2dd85b | |
|
57b20eb7d0 | |
|
53f2462b32 | |
|
7371f0428f | |
|
fce5068f04 | |
|
67fcbe1f5d | |
|
abb5a8dbad | |
|
a71a85d5c3 | |
|
7e6b171e0d | |
|
7f8cebc504 | |
|
7581b8e28e | |
|
8cbc668397 | |
|
4f8752d9f4 | |
|
6749a1d173 | |
|
5fa7681956 | |
|
29db278b6a | |
|
9b46482ad0 |
|
@ -0,0 +1,3 @@
|
|||
*.swp
|
||||
go.mod
|
||||
go.sum
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
15
Makefile
15
Makefile
|
@ -1,5 +1,20 @@
|
|||
# git remote add github git@github.com:wit-go/log.git
|
||||
|
||||
all: vet
|
||||
@#GO111MODULE=off go vet -x
|
||||
@echo this go library builds ok
|
||||
|
||||
vet:
|
||||
@GO111MODULE=off go vet
|
||||
|
||||
redomod:
|
||||
rm -f go.*
|
||||
GO111MODULE= go mod init
|
||||
GO111MODULE= go mod tidy
|
||||
|
||||
goimport:
|
||||
goimports -w *.go
|
||||
|
||||
github:
|
||||
git push origin master
|
||||
git push origin devel
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
log
|
||||
|
||||
This is an attempt to modify the default golang 'log'.
|
||||
Because the 'gui' toolkit could be either ncurses or something like gtk,
|
||||
'log' is an attempt to be smart about changing STDOUT on the fly.
|
||||
|
||||
* add meaningful shortcuts like log.Info(), log.Warn(), log.Error() etc
|
||||
* add flags to enable & disable output on a per-gomodule basis
|
||||
* add http flag to switch stdout to http socket
|
||||
* compatible with changing import 'log' to import 'go.wit.com/log'
|
||||
* should also be compatible with changing import 'fmt' to import fmt 'go.wit.com/log'
|
||||
|
||||
Notes & Goals:
|
||||
|
||||
* be a complete droplet replacement for golang 'log'
|
||||
* provide an example of how the stdlib 'log' could be changed
|
33
args.go
33
args.go
|
@ -1,33 +0,0 @@
|
|||
package log
|
||||
|
||||
/*
|
||||
// disable this until it hopefully is adopted by the go lang developers
|
||||
// TODO: clean alex's dependancies
|
||||
|
||||
import (
|
||||
arg "github.com/alexflint/go-arg"
|
||||
)
|
||||
|
||||
//
|
||||
// Attempt to switch logging to syslog on linux
|
||||
//
|
||||
|
||||
var argLog ArgLog
|
||||
|
||||
// This struct can be used with the go-arg package
|
||||
type ArgLog struct {
|
||||
LogDebug bool `arg:"--log-debug" help:"show the log gui"`
|
||||
LogTmp bool `arg:"--log-tmp" help:"send all output /tmp"`
|
||||
LogStdout bool `arg:"--log-stdout" help:"send all output to STDOUT"`
|
||||
LogQuiet bool `arg:"--log-quiet" help:"suppress all output"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
arg.Register(&argLog)
|
||||
}
|
||||
|
||||
// returns true if --log-debug was passed from the command line
|
||||
func ArgDebug() bool {
|
||||
return argLog.LogDebug
|
||||
}
|
||||
*/
|
10
bool.go
10
bool.go
|
@ -1,10 +0,0 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
golanglog "log"
|
||||
)
|
||||
|
||||
func Bool(b bool, a ...any) {
|
||||
if ! b {return}
|
||||
golanglog.Println(a...)
|
||||
}
|
5
doc.go
5
doc.go
|
@ -1,4 +1,9 @@
|
|||
// Copyright 2009 The Go 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 log
|
||||
|
||||
//
|
||||
// version v1.5
|
||||
//
|
||||
|
|
15
error.go
15
error.go
|
@ -1,10 +1,13 @@
|
|||
// Copyright 2024 The Go 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 log
|
||||
|
||||
import (
|
||||
origlog "log"
|
||||
)
|
||||
|
||||
func Error(err error, a ...any) {
|
||||
origlog.Println("Error:", err)
|
||||
origlog.Println(a...)
|
||||
if ERROR.Disabled() {
|
||||
return
|
||||
}
|
||||
realPrintln("Error:", err)
|
||||
realPrintln(a...)
|
||||
}
|
||||
|
|
266
flags.go
266
flags.go
|
@ -1,109 +1,235 @@
|
|||
// Copyright 2024 The Go 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 log
|
||||
|
||||
import (
|
||||
"errors"
|
||||
/*
|
||||
Handles the on/off flags for things like log.Info() and log.Warn()
|
||||
*/
|
||||
|
||||
/*
|
||||
The original log flags:
|
||||
|
||||
log.Ldate: The date in the local time zone: YYYY/MM/DD.
|
||||
log.Ltime: The time in the local time zone: HH:MM:SS.
|
||||
log.Lmicroseconds: Microsecond resolution: HH:MM:SS.microseconds.
|
||||
log.Llongfile: Full file name and line number: /a/b/c/d.go:23.
|
||||
log.Lshortfile: Final file name element and line number: d.go:23.
|
||||
log.LUTC: If Ldate or Ltime is set, use UTC rather than the local time zone.
|
||||
log.Lmsgprefix: Move the "prefix" from the beginning of the line to before the message.
|
||||
log.LstdFlags: Initial values for the standard logger (Ldate | Ltime).
|
||||
|
||||
can be set this way:
|
||||
myLogger.SetFlags(log.Ldate | log.Ltime)
|
||||
|
||||
*/
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var INFO bool = true
|
||||
var WARN bool = true
|
||||
var ERROR bool = true
|
||||
var INFO *LogFlag // toggles log.Info()
|
||||
var VERBOSE *LogFlag // toggles log.Verbose()
|
||||
var SPEW *LogFlag // toggles log.Spew()
|
||||
|
||||
var VERBOSE bool = false
|
||||
// var SPEW bool = false
|
||||
var WARN *LogFlag // toggles log.Warn() (true by default)
|
||||
var ERROR *LogFlag // toggles log.Warn() (true by default)
|
||||
var PRINTLN *LogFlag // toggles log.Println() (true by default)
|
||||
|
||||
var SPEW LogFlag
|
||||
var always *LogFlag
|
||||
var allon bool = false
|
||||
|
||||
// writeMutex protects locks the write process
|
||||
var flagsMutex sync.Mutex
|
||||
|
||||
type LogFlag struct {
|
||||
B bool
|
||||
Name string
|
||||
Subsystem string
|
||||
Desc string
|
||||
b bool
|
||||
orig bool // used as the Default value. set at the time of Registration()
|
||||
name string
|
||||
// TODO: figure out what package is sending the Registration
|
||||
subsystem string // probably should just be forced to be the package name
|
||||
short string // string actually printed on each line
|
||||
desc string
|
||||
}
|
||||
|
||||
var registered map[string][]string
|
||||
var flags []*LogFlag
|
||||
var daemonMode bool
|
||||
var timestamps bool = false
|
||||
var httpMode http.ResponseWriter
|
||||
|
||||
func init() {
|
||||
registered = make(map[string][]string)
|
||||
full := "go.wit.com/log"
|
||||
short := "log"
|
||||
|
||||
SPEW.B = false
|
||||
SPEW.Name = "SPEW"
|
||||
SPEW.Subsystem = "log"
|
||||
SPEW.Desc = "Enable log.Spew()"
|
||||
// internally used to bypass the possibility that all the flags are off
|
||||
always = new(LogFlag)
|
||||
always.b = true
|
||||
always.orig = true
|
||||
always.subsystem = full
|
||||
always.short = short
|
||||
always.desc = "internal only"
|
||||
|
||||
// register the default flags used by this log package
|
||||
registered["log"] = []string{"SPEW","INFO", "WARN", "ERROR", "VERBOSE"}
|
||||
daemonMode = false
|
||||
|
||||
INFO = NewFlag("INFO", true, full, short, "Enable log.Info()")
|
||||
SPEW = NewFlag("SPEW", false, full, short, "Enable log.Spew()")
|
||||
WARN = NewFlag("WARN", true, full, short, "Enable log.Warn()")
|
||||
|
||||
ERROR = NewFlag("ERROR", true, full, short, "Enable log.Error()")
|
||||
PRINTLN = NewFlag("PRINTLN", true, full, short, "Enable log.Println()")
|
||||
VERBOSE = NewFlag("VERBOSE", false, full, short, "Enable log.Verbose()")
|
||||
}
|
||||
|
||||
func All(b bool) {
|
||||
Set("SPEW", b)
|
||||
Set("INFO", b)
|
||||
Set("WARN", b)
|
||||
Set("ERROR", b)
|
||||
Set("VERBOSE", b)
|
||||
// restores flag to it's default value
|
||||
func (f *LogFlag) SetDefault() {
|
||||
if !f.Ok() {
|
||||
return
|
||||
}
|
||||
f.b = f.orig
|
||||
}
|
||||
|
||||
// set all the flags
|
||||
func SetDefaults() {
|
||||
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)
|
||||
f.SetDefault()
|
||||
}
|
||||
}
|
||||
|
||||
// simply protects against panic() by making sure it exists.
|
||||
func (f *LogFlag) Ok() bool {
|
||||
if f == nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// set all the flags
|
||||
func SetAll(b bool) {
|
||||
flagsMutex.Lock()
|
||||
defer flagsMutex.Unlock()
|
||||
allon = b
|
||||
for _, f := range flags {
|
||||
f.b = 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(always, "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. maybe.
|
||||
func ProcessFlags(callback func(*LogFlag)) {
|
||||
flagsMutex.Lock()
|
||||
defer flagsMutex.Unlock()
|
||||
for _, f := range flags {
|
||||
Log(always, "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)
|
||||
// is the output flag disabled?
|
||||
// if so, don't print anything!
|
||||
func (f *LogFlag) Disabled() bool {
|
||||
if !f.Ok() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return ! f.b
|
||||
}
|
||||
|
||||
// just the opposite of Disabled()
|
||||
// both are here just for code readability
|
||||
func (f *LogFlag) Enabled() bool {
|
||||
if !f.Ok() {
|
||||
return false
|
||||
}
|
||||
return f.b
|
||||
}
|
||||
|
||||
/*
|
||||
func (f *LogFlag) Set(b bool) {
|
||||
if ! f.Ok() {}
|
||||
f.b = b
|
||||
}
|
||||
*/
|
||||
|
||||
// returns the name of the flag
|
||||
func (f *LogFlag) GetName() string {
|
||||
if !f.Ok() {
|
||||
return ""
|
||||
}
|
||||
return f.name
|
||||
}
|
||||
|
||||
// returns the subsystem of the flag
|
||||
func (f *LogFlag) GetSubsystem() string {
|
||||
if !f.Ok() {
|
||||
return ""
|
||||
}
|
||||
return f.subsystem
|
||||
}
|
||||
|
||||
// returns the description of the flag
|
||||
func (f *LogFlag) GetDesc() string {
|
||||
if !f.Ok() {
|
||||
return ""
|
||||
}
|
||||
return f.desc
|
||||
}
|
||||
|
||||
// returns the description of the flag
|
||||
func (f *LogFlag) GetDefault() bool {
|
||||
if !f.Ok() {
|
||||
return false
|
||||
}
|
||||
return f.orig
|
||||
}
|
||||
|
||||
// register a variable name from a subsystem
|
||||
// inspired by Alex Flint
|
||||
func (f *LogFlag) Register() {
|
||||
Info("log.Register() ", f)
|
||||
flags = append(flags,f)
|
||||
// set the Default value at the time of registration
|
||||
|
||||
// this is what the current log.SetFlag() function should become
|
||||
func NewFlag(name string, b bool, full, short, desc string) *LogFlag {
|
||||
flagsMutex.Lock()
|
||||
defer flagsMutex.Unlock()
|
||||
f := new(LogFlag)
|
||||
// Log(always, "log.SetFlag() ", full, short, name, b)
|
||||
if allon {
|
||||
f.b = true
|
||||
} else {
|
||||
f.b = b
|
||||
}
|
||||
f.orig = b
|
||||
f.short = short
|
||||
f.subsystem = full
|
||||
f.name = name
|
||||
f.desc = desc
|
||||
flags = append(flags, f)
|
||||
return 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) SetBool(b bool) {
|
||||
/*
|
||||
if ! f.Ok() {return}
|
||||
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)
|
||||
}
|
||||
|
|
5
go.mod
5
go.mod
|
@ -1,5 +0,0 @@
|
|||
module go.wit.com/log
|
||||
|
||||
go 1.21.4
|
||||
|
||||
require github.com/davecgh/go-spew v1.1.1
|
2
go.sum
2
go.sum
|
@ -1,2 +0,0 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
20
info.go
20
info.go
|
@ -1,15 +1,19 @@
|
|||
// Copyright 2024 The Go 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 log
|
||||
|
||||
import (
|
||||
golanglog "log"
|
||||
)
|
||||
|
||||
func Info(a ...any) {
|
||||
if ! INFO { return }
|
||||
golanglog.Println(a...)
|
||||
if INFO.Disabled() {
|
||||
return
|
||||
}
|
||||
realPrintln(a...)
|
||||
}
|
||||
|
||||
func Infof(s string, a ...any) {
|
||||
if ! INFO { return }
|
||||
golanglog.Printf(s, a...)
|
||||
if INFO.Disabled() {
|
||||
return
|
||||
}
|
||||
realPrintf(s, a...)
|
||||
}
|
||||
|
|
62
log.go
62
log.go
|
@ -1,8 +1,8 @@
|
|||
package log
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
import (
|
||||
origlog "log"
|
||||
)
|
||||
package log
|
||||
|
||||
/*
|
||||
|
||||
|
@ -16,45 +16,29 @@ Example:
|
|||
|
||||
In your package, register NETWARN:
|
||||
|
||||
var NETWARN bool
|
||||
log.Register("myNetPkg", "NETWARN", &NETWARN)
|
||||
var NETWARN *log.LogFlag
|
||||
NETWARN = log.NewFlag("NETWARN", true, "go.wit.com/log", "log", "network warnings!")
|
||||
|
||||
*/
|
||||
|
||||
func Log(x any, a ...any) {
|
||||
if x == nil { return }
|
||||
switch x.(type) {
|
||||
case bool:
|
||||
if ! x.(bool) {
|
||||
return
|
||||
}
|
||||
origlog.Println(a...)
|
||||
case LogFlag:
|
||||
var f LogFlag
|
||||
f = x.(LogFlag)
|
||||
if ! f.B {
|
||||
return
|
||||
}
|
||||
a = append([]any{f.Subsystem}, a...)
|
||||
origlog.Println(a...)
|
||||
default:
|
||||
a = append([]any{x}, a...)
|
||||
origlog.Println(a...)
|
||||
func Log(f *LogFlag, a ...any) {
|
||||
if !f.Ok() {
|
||||
// if the flag is NULL, notify the user they didn't initialize the flag
|
||||
a = append([]any{"FLAG = NULL. Normal error output. please ignore for now"}, a...)
|
||||
realPrintln(a...)
|
||||
return
|
||||
}
|
||||
if f.Disabled() {
|
||||
return
|
||||
}
|
||||
a = append([]any{f.short}, a...)
|
||||
realPrintln(a...)
|
||||
}
|
||||
|
||||
func Logf(x any, s string, a ...any) {
|
||||
if x == nil { return }
|
||||
switch x.(type) {
|
||||
case bool:
|
||||
if ! x.(bool) {
|
||||
return
|
||||
}
|
||||
case LogFlag:
|
||||
var f LogFlag
|
||||
f = x.(LogFlag)
|
||||
if ! f.B {
|
||||
return
|
||||
}
|
||||
func Logf(f *LogFlag, s string, a ...any) {
|
||||
if f.Disabled() {
|
||||
return
|
||||
}
|
||||
origlog.Printf(s, a...)
|
||||
s = f.short + " " + s
|
||||
realPrintf(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)
|
||||
}
|
||||
*/
|
71
original.go
71
original.go
|
@ -5,7 +5,7 @@ package log
|
|||
"log"
|
||||
}
|
||||
|
||||
and
|
||||
and
|
||||
|
||||
import (
|
||||
"go.wit.com/log"
|
||||
|
@ -18,22 +18,77 @@ package log
|
|||
so this package appears to work exactly like the original ones
|
||||
*/
|
||||
|
||||
import (
|
||||
origlog "log"
|
||||
)
|
||||
// TODO: fill in the other functions from "log". Is there a way to automagically do that?
|
||||
// the full list is:
|
||||
/*
|
||||
type Logger
|
||||
|
||||
// NEED THESE
|
||||
func (l *Logger) Fatal(v ...any)
|
||||
func (l *Logger) Fatalf(format string, v ...any)
|
||||
func (l *Logger) Fatalln(v ...any)
|
||||
func (l *Logger) Panic(v ...any)
|
||||
func (l *Logger) Panicf(format string, v ...any)
|
||||
func (l *Logger) Panicln(v ...any)
|
||||
func (l *Logger) Print(v ...any)
|
||||
func (l *Logger) Printf(format string, v ...any)
|
||||
func (l *Logger) Println(v ...any)
|
||||
|
||||
func Default() *Logger
|
||||
func New(out io.Writer, prefix string, flag int) *Logger
|
||||
|
||||
// what are these?
|
||||
func (l *Logger) Flags() int
|
||||
func (l *Logger) SetFlags(flag int)
|
||||
func (l *Logger) Prefix() string
|
||||
func (l *Logger) SetPrefix(prefix string)
|
||||
|
||||
// probably not this stuff
|
||||
func (l *Logger) SetOutput(w io.Writer)
|
||||
func (l *Logger) Output(calldepth int, s string) error
|
||||
func (l *Logger) Writer() io.Writer
|
||||
*/
|
||||
|
||||
func Println(a ...any) {
|
||||
origlog.Println(a...)
|
||||
if !PRINTLN.Ok() {
|
||||
return
|
||||
}
|
||||
if !PRINTLN.b {
|
||||
return
|
||||
}
|
||||
realPrintln(a...)
|
||||
}
|
||||
|
||||
func Printf(s string, a ...any) {
|
||||
origlog.Printf(s, a...)
|
||||
if !PRINTLN.Ok() {
|
||||
return
|
||||
}
|
||||
if !PRINTLN.b {
|
||||
return
|
||||
}
|
||||
realPrintf(s, a...)
|
||||
}
|
||||
|
||||
func Sprint(a ...any) string {
|
||||
return realSprint(a...)
|
||||
}
|
||||
|
||||
func Sprintf(s string, a ...any) string {
|
||||
return realSprintf(s, a...)
|
||||
}
|
||||
|
||||
func Sprintln(a ...any) string {
|
||||
return realSprintln(a...)
|
||||
}
|
||||
|
||||
func Fatalln(a ...any) {
|
||||
realFatalln(a...)
|
||||
}
|
||||
|
||||
func Fatalf(s string, a ...any) {
|
||||
origlog.Fatalf(s, a...)
|
||||
realFatalf(s, a...)
|
||||
}
|
||||
|
||||
func Fatal(s string, a ...any) {
|
||||
origlog.Fatalf(s, a...)
|
||||
realFatalf(s, a...)
|
||||
}
|
||||
|
|
22
output.go
22
output.go
|
@ -1,19 +1,29 @@
|
|||
// Copyright 2024 The Go 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 log
|
||||
|
||||
import (
|
||||
"os"
|
||||
import (
|
||||
golanglog "log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// start writing all the logging to a tmp file
|
||||
func SetTmp() {
|
||||
f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
||||
func SetTmpOLD() {
|
||||
f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
golanglog.Fatalf("error opening file: %v", err)
|
||||
realFatalf("error opening file: %v", err)
|
||||
}
|
||||
// hmm. is there a trick here or must this be in main()
|
||||
// defer f.Close()
|
||||
|
||||
golanglog.SetOutput(f)
|
||||
golanglog.Println("This is a test log entry")
|
||||
realPrintln("This is a test log entry")
|
||||
}
|
||||
|
||||
// start writing all the logging to a tmp file
|
||||
func UnsetTmp() {
|
||||
golanglog.SetOutput(os.Stdout)
|
||||
realPrintln("This is a test log entry")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package log
|
||||
|
||||
// implements 'daemon' mode so switches to fmt
|
||||
// instead of log so that timestamps are not printed twice
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
reallog "log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func DaemonMode(b bool) {
|
||||
daemonMode = b
|
||||
}
|
||||
|
||||
func Timestamps(b bool) {
|
||||
timestamps = b
|
||||
}
|
||||
|
||||
|
||||
var captureMode io.Writer
|
||||
|
||||
func CaptureMode(w io.Writer) {
|
||||
captureMode = w
|
||||
}
|
||||
|
||||
var flusher http.Flusher
|
||||
|
||||
func HttpMode(w http.ResponseWriter) {
|
||||
var ok bool
|
||||
httpMode = w
|
||||
if w == nil {
|
||||
flusher = nil
|
||||
return
|
||||
}
|
||||
flusher, ok = w.(http.Flusher)
|
||||
if !ok {
|
||||
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
|
||||
flusher = nil
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func DaemonShow() bool {
|
||||
if daemonMode {
|
||||
fmt.Println("daemonMode=true")
|
||||
return true
|
||||
} else {
|
||||
fmt.Println("daemonMode=false")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func realPrintln(a ...any) {
|
||||
if daemonMode {
|
||||
// in daemon mode, don't put timestamps on each line
|
||||
if captureMode == nil {
|
||||
fmt.Println(a...)
|
||||
} else {
|
||||
fmt.Fprintln(captureMode, a...)
|
||||
}
|
||||
} else {
|
||||
// put timestamps on each line
|
||||
if captureMode == nil {
|
||||
if timestamps {
|
||||
reallog.Println(a...)
|
||||
} else {
|
||||
fmt.Println(a...)
|
||||
}
|
||||
} else {
|
||||
// TODO: add datestamp
|
||||
fmt.Fprintln(captureMode, a...)
|
||||
}
|
||||
}
|
||||
if httpMode != nil {
|
||||
var timestamp string
|
||||
if timestamps {
|
||||
now := time.Now()
|
||||
timestamp = now.Format("2006/01/02 15:04:05") // todo: fix GO so Nov 5 1955 works here
|
||||
}
|
||||
s := timestamp + " " + fmt.Sprint(a...)
|
||||
fmt.Fprintln(httpMode, s)
|
||||
if flusher != nil {
|
||||
flusher.Flush() // Flush the data to the client
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func realPrintf(s string, a ...any) {
|
||||
if daemonMode {
|
||||
// in daemon mode, don't put timestamps on each line
|
||||
if captureMode == nil {
|
||||
fmt.Printf(s, a...)
|
||||
} else {
|
||||
fmt.Fprintf(captureMode, s, a...)
|
||||
}
|
||||
} else {
|
||||
// put timestamps on each line
|
||||
if captureMode == nil {
|
||||
if timestamps {
|
||||
reallog.Printf(s, a...)
|
||||
} else {
|
||||
fmt.Printf(s, a...)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(captureMode, s, a...)
|
||||
}
|
||||
}
|
||||
if httpMode != nil {
|
||||
var timestamp string
|
||||
if timestamps {
|
||||
now := time.Now()
|
||||
timestamp = now.Format("2006/01/02 15:04:05")
|
||||
}
|
||||
s := timestamp + " " + fmt.Sprintf(s, a...)
|
||||
fmt.Fprintln(httpMode, s)
|
||||
if flusher != nil {
|
||||
flusher.Flush() // Flush the data to the client
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func realSprint(a ...any) string {
|
||||
return fmt.Sprint(a...)
|
||||
}
|
||||
|
||||
func realSprintf(s string, a ...any) string {
|
||||
return fmt.Sprintf(s, a...)
|
||||
}
|
||||
|
||||
func realSprintln(a ...any) string {
|
||||
return fmt.Sprintln(a...)
|
||||
}
|
||||
|
||||
func realFatalln(a ...any) {
|
||||
reallog.Fatalln(a...)
|
||||
}
|
||||
|
||||
func realFatalf(s string, a ...any) {
|
||||
reallog.Fatalf(s, a...)
|
||||
}
|
||||
|
||||
func realFatal(s string, a ...any) {
|
||||
reallog.Fatalf(s, a...)
|
||||
}
|
64
sleep.go
64
sleep.go
|
@ -1,75 +1,47 @@
|
|||
// Copyright 2024 The Go 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 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.
|
||||
// a shortcut for sleep so you don't have to always change the import lines when debugging
|
||||
|
||||
log() # doesn't do anything
|
||||
log(stuff) # sends it to whatever log you define in a single place. here is the place
|
||||
*/
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
origlog "log"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
sleep() # you know what this does? sleeps for 1 second. yep. dump. easy.
|
||||
sleep(.1) # you know what this does? yes, it sleeps for 1/10th of a second
|
||||
sleep() # you know what this does? sleeps for 1 second. yep. dump. easy.
|
||||
sleep(.1) # you know what this does? yes, it sleeps for 1/10th of a second
|
||||
*/
|
||||
func Sleep(a ...any) {
|
||||
if (a == nil) {
|
||||
if a == nil {
|
||||
time.Sleep(time.Second)
|
||||
return
|
||||
}
|
||||
|
||||
origlog.Println("sleep", a[0])
|
||||
Verbose("sleep", a[0])
|
||||
|
||||
switch a[0].(type) {
|
||||
case int:
|
||||
time.Sleep(time.Duration(a[0].(int)) * time.Second)
|
||||
case float64:
|
||||
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
|
||||
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]))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
exit() # yep. exits. I guess everything must be fine
|
||||
exit(3) # I guess 3 it is then
|
||||
exit("dont like apples") # ok. I'll make a note of that
|
||||
exit() # yep. exits. I guess everything must be fine
|
||||
exit(3) # I guess 3 it is then
|
||||
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)
|
||||
//}
|
||||
|
|
37
spew.go
37
spew.go
|
@ -1,37 +0,0 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
origlog "log"
|
||||
"go.wit.com/spew"
|
||||
)
|
||||
|
||||
func Spew(b any, a ...any) {
|
||||
if ! SPEW.B { return }
|
||||
|
||||
switch b.(type) {
|
||||
case bool:
|
||||
if ! b.(bool) {
|
||||
return
|
||||
}
|
||||
origlog.Println("SPEW:", spew.Sdump(a...))
|
||||
case LogFlag:
|
||||
var f LogFlag
|
||||
f = b.(LogFlag)
|
||||
if ! f.B {
|
||||
return
|
||||
}
|
||||
origlog.Println("SPEW:", spew.Sdump(a...))
|
||||
default:
|
||||
origlog.Println("SPEW b:", spew.Sdump(b))
|
||||
origlog.Println("SPEW a:", spew.Sdump(a...))
|
||||
}
|
||||
// origlog.Println("SPEW:", spew.Sdump(a...))
|
||||
/*
|
||||
scs := spew.ConfigState{Indent: "\t", MaxDepth: 1}
|
||||
// Output using the ConfigState instance.
|
||||
v := map[string]int{"one": 1}
|
||||
scs.Printf("v: %v\n", v)
|
||||
scs.Dump(v)
|
||||
scs.Dump(a)
|
||||
*/
|
||||
}
|
14
verbose.go
14
verbose.go
|
@ -1,10 +1,12 @@
|
|||
// Copyright 2024 The Go 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 log
|
||||
|
||||
import (
|
||||
golanglog "log"
|
||||
)
|
||||
|
||||
func Verbose(a ...any) {
|
||||
if ! VERBOSE { return }
|
||||
golanglog.Println(a...)
|
||||
if VERBOSE.Disabled() {
|
||||
return
|
||||
}
|
||||
realPrintln(a...)
|
||||
}
|
||||
|
|
14
warn.go
14
warn.go
|
@ -1,10 +1,12 @@
|
|||
// Copyright 2024 The Go 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 log
|
||||
|
||||
import (
|
||||
origlog "log"
|
||||
)
|
||||
|
||||
func Warn(a ...any) {
|
||||
if ! WARN { return }
|
||||
origlog.Println(a...)
|
||||
if WARN.Disabled() {
|
||||
return
|
||||
}
|
||||
realPrintln(a...)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue