Files
gocommon/logger/logger.go

160 lines
3.2 KiB
Go

package logger
import (
"fmt"
"log"
"os"
"runtime"
"runtime/debug"
"strconv"
"strings"
"repositories.action2quare.com/ayo/gocommon/flagx"
)
var stdlogger *log.Logger
var _ = flagx.Int("logprefix", 3, "0 : no_prefix, 1 : date, 2 : time, 3 : datetime")
func init() {
binpath, _ := os.Executable()
outWriter := os.Stdout
args := os.Args
logprefix := 3
for _, arg := range args {
if strings.HasPrefix(arg, "-logprefix=") {
logprefix, _ = strconv.Atoi(arg[11:])
break
}
}
pid := fmt.Sprintf("[%d]", os.Getpid())
outWriter.Write([]byte(strings.Join(append([]string{pid, binpath}, args...), " ")))
if logprefix < 4 {
stdlogger = log.New(outWriter, "", logprefix)
} else {
stdlogger = log.New(outWriter, "", log.LstdFlags)
}
}
func Println(v ...interface{}) {
stdlogger.Output(2, fmt.Sprintln(v...))
}
func Printf(format string, v ...interface{}) {
stdlogger.Output(2, fmt.Sprintf(format, v...))
}
func Error(v ...interface{}) {
stdlogger.Output(2, fmt.Sprintln(v...))
stdlogger.Output(2, string(debug.Stack()))
}
func Errorf(format string, v ...interface{}) {
stdlogger.Output(2, fmt.Sprintf(format, v...))
stdlogger.Output(2, string(debug.Stack()))
}
func Fatal(v ...interface{}) {
stdlogger.Output(2, fmt.Sprint(v...))
stdlogger.Output(2, string(debug.Stack()))
os.Exit(1)
}
func Fatalln(v ...interface{}) {
stdlogger.Output(2, fmt.Sprintln(v...))
stdlogger.Output(2, string(debug.Stack()))
os.Exit(1)
}
func Panic(v ...interface{}) {
s := fmt.Sprint(v...)
stdlogger.Output(2, s)
stdlogger.Output(2, string(debug.Stack()))
panic(s)
}
func Panicf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
stdlogger.Output(2, s)
stdlogger.Output(2, string(debug.Stack()))
panic(s)
}
func Panicln(v ...interface{}) {
s := fmt.Sprintln(v...)
stdlogger.Output(2, s)
stdlogger.Output(2, string(debug.Stack()))
panic(s)
}
type errWithCallstack struct {
inner error
frames []*runtime.Frame
}
func (ecs *errWithCallstack) Error() string {
if ecs.frames == nil {
return ecs.inner.Error()
}
out := make([]string, 0, len(ecs.frames)+1)
out = append(out, ecs.inner.Error())
for i := len(ecs.frames) - 1; i >= 0; i-- {
frame := ecs.frames[i]
out = append(out, fmt.Sprintf("%s\n\t%s:%d", frame.Function, frame.File, frame.Line))
}
return strings.Join(out, "\n")
}
func ErrorWithCallStack(err error) error {
var frames []*runtime.Frame
if recur, ok := err.(*errWithCallstack); ok {
err = recur.inner
frames = recur.frames
}
pc, _, _, ok := runtime.Caller(1)
if ok {
curframes := runtime.CallersFrames([]uintptr{pc})
f, _ := curframes.Next()
frames = append(frames, &f)
}
return &errWithCallstack{
inner: err,
frames: frames,
}
}
func ErrorSmallStack() {
buf := make([]byte, 1024)
n := runtime.Stack(buf, false)
if n < len(buf) {
buf = buf[:n]
}
Error(string(buf))
}
func RecoverAndErrorSmallStack(r any) any {
if r != nil {
pc := make([]uintptr, 10)
runtime.Callers(1, pc)
curframes := runtime.CallersFrames(pc)
var out []string
for {
frame, more := curframes.Next()
out = append(out, fmt.Sprintf("%s\n\t%s:%d", frame.Function, frame.File, frame.Line))
if !more {
break
}
}
Error(strings.Join(out, "\n"))
}
return r
}