Compare commits

...

38 Commits

Author SHA1 Message Date
Your Name 466a3c6076 tracking down all erroneous log messages 2024-01-01 12:00:00 -06:00
Jeff Carr c1c1b8a75e also add Enable() 2025-02-05 07:25:08 -06:00
Jeff Carr f793a05288 switch to Disabled() 2025-02-05 06:28:51 -06:00
Jeff Carr 1631c72f70 don't use STDERR anymore. also timestamps off by default
Signed-off-by: Jeff Carr <jcarr@wit.com>
2025-01-09 20:42:18 -06:00
Jeff Carr e1d7a5c2cc deprecate use of spew so package is a go primitive 2024-12-13 12:57:33 -06:00
Jeff Carr 9b12c5049e see if http.Flush works 2024-11-28 00:03:36 -06:00
Jeff Carr fe562dbf1b fix timestamp not showing up 2024-11-15 20:04:51 -06:00
Jeff Carr 56145cd22a use io.Writer 2024-11-14 04:58:57 -06:00
Jeff Carr 72d75ee478 attempt 'capture' mode 2024-11-13 21:31:55 -06:00
Jeff Carr 1bcdcfa2f4 remove debugging code 2024-11-07 05:08:42 -06:00
Jeff Carr 53adaabee0 mirroring is weird 2024-11-07 03:11:19 -06:00
Jeff Carr 889ec714e1 mirror output to stdout and http 2024-11-07 02:55:46 -06:00
Jeff Carr ef61eb494b try allowing switching to writing to http 2024-11-07 01:23:43 -06:00
Jeff Carr 2b11a4e334 Sprint()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-04 05:45:32 -06:00
Jeff Carr 52991d305f add Sprintf and Sprintln
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-04 05:11:02 -06:00
Jeff Carr 91b0564fb0 run everything through the daemon check to switch to fmt
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-10-12 16:36:44 -05:00
Jeff Carr 366bcac15c fix go vet warnings
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-10-12 16:32:08 -05:00
Jeff Carr 2cf02ee2e5 half working 'daemon mode'
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-10-12 16:21:47 -05:00
Jeff Carr 54c0947452 rethink this 2024-02-12 15:11:22 -06:00
Jeff Carr 99fbd48d0b make this quiet finally
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-07 08:45:26 -06:00
Jeff Carr fc382169a3 attempt at release automation
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-30 16:05:42 -06:00
Jeff Carr 162d2dd85b try to restore STDOUT
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-30 11:50:24 -06:00
Jeff Carr 57b20eb7d0 toolkit load release
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 12:13:05 -06:00
Jeff Carr 53f2462b32 nocui works correctly
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 09:02:42 -06:00
Jeff Carr 7371f0428f log flags gui is kinda working now
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-20 14:57:53 -06:00
Jeff Carr fce5068f04 trying to make this work again
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-20 13:42:42 -06:00
Jeff Carr 67fcbe1f5d missing Fatall()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-17 20:54:32 -06:00
Jeff Carr abb5a8dbad start fixing the logging settings
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-16 11:10:19 -06:00
Jeff Carr a71a85d5c3 prep for patches against golang master
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-15 15:54:53 -06:00
Jeff Carr 7e6b171e0d clean spew
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-14 12:27:10 -06:00
Jeff Carr 7f8cebc504 update spew path
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-14 11:54:13 -06:00
Jeff Carr 7581b8e28e This is a core GO language package
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-14 10:43:35 -06:00
Jeff Carr 8cbc668397 always must init first
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-12 16:49:24 -06:00
Jeff Carr 4f8752d9f4 go.wit.com/log flag changes
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-09 15:50:53 -06:00
Jeff Carr 6749a1d173 use Short if defined
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 17:10:59 -06:00
Jeff Carr 5fa7681956 quiet debugging on Get() and Set()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-05 20:39:56 -06:00
Jeff Carr 29db278b6a SetDefaults()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-04 15:22:08 -06:00
Jeff Carr 9b46482ad0 make a log config window
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-04 12:34:04 -06:00
22 changed files with 567 additions and 362 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.swp
go.mod
go.sum

27
LICENSE Normal file
View File

@ -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.

View File

@ -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

16
README.md Normal file
View File

@ -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

1
VERSION Normal file
View File

@ -0,0 +1 @@
0.13.18

33
args.go
View File

@ -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
View File

@ -1,10 +0,0 @@
package log
import (
golanglog "log"
)
func Bool(b bool, a ...any) {
if ! b {return}
golanglog.Println(a...)
}

5
doc.go
View File

@ -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
//

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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...)
}

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

@ -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...)
}

View File

@ -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")
}

147
reallog.go Normal file
View File

@ -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...)
}

View File

@ -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
View File

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

View File

@ -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
View File

@ -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...)
}