truckstop/logtr/log.go

139 lines
2.3 KiB
Go

package logtr
import (
"encoding/json"
"errors"
"fmt"
"io"
"log"
"os"
"strings"
"sync"
"time"
)
type Level int
const (
VERBOSE = Level(7)
DEBUG = Level(8)
INFO = Level(9)
ERROR = Level(10)
SOS = Level(15)
)
type SOSer interface {
Send(string) error
}
func (l Level) MarshalJSON() ([]byte, error) {
return json.Marshal(l.String())
}
func (l *Level) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
s = strings.TrimSpace(s)
s = strings.ToUpper(s)
if len(s) > 3 {
s = s[:3]
}
for i := 0; i < int(SOS)+5; i++ {
l2 := Level(i)
if l2.String() == s {
*l = l2
return nil
}
}
return errors.New("unknown log level: " + s)
}
var logger io.Writer = os.Stderr
var loggerPath string = ""
var lock = &sync.Mutex{}
var level Level = INFO
var ansoser SOSer = nil
func SetLogpath(p string) {
lock.Lock()
defer lock.Unlock()
if p == loggerPath {
return
}
f, err := os.OpenFile(p, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
logger = f
loggerPath = p
}
func SetSOSer(another SOSer) {
lock.Lock()
defer lock.Unlock()
ansoser = another
}
func SetLevel(l Level) {
lock.Lock()
defer lock.Unlock()
level = l
}
func logf(l Level, format string, args []interface{}) {
format = fmt.Sprintf("%v: %v: %s\n", time.Now().Format("15:04:05"), l.String(), strings.TrimSpace(format))
cLevel := level
cAnsoser := ansoser
if l >= cLevel {
fmt.Fprintf(os.Stderr, format, args...)
}
fmt.Fprintf(logger, format, args...)
log.Printf("l==sos=%v, ansoser!=nil=%v", l == SOS, ansoser != nil)
if l == SOS && cAnsoser != nil {
cAnsoser.Send(fmt.Sprintf(format, args...))
}
}
func SOSf(format string, args ...interface{}) {
logf(SOS, format, args)
}
func Infof(format string, args ...interface{}) {
logf(INFO, format, args)
}
func Printf(format string, args ...interface{}) {
Infof(format, args...)
}
func Debugf(format string, args ...interface{}) {
logf(DEBUG, format, args)
}
func Verbosef(format string, args ...interface{}) {
logf(VERBOSE, format, args)
}
func Errorf(format string, args ...interface{}) {
logf(ERROR, format, args)
}
func (l Level) String() string {
switch l {
case ERROR:
return "ERR"
case INFO:
return "INF"
case DEBUG:
return "DEB"
case VERBOSE:
return "VER"
case SOS:
return "SOS"
default:
return "?"
}
}