Skip to content

Instantly share code, notes, and snippets.

@MichaelMonashev
Created May 18, 2020 18:33
Show Gist options
  • Save MichaelMonashev/c2c09c4b49dde849c79d65ca1d957383 to your computer and use it in GitHub Desktop.
Save MichaelMonashev/c2c09c4b49dde849c79d65ca1d957383 to your computer and use it in GitHub Desktop.
Golang async logger
package warn
import (
"errors"
"fmt"
"io"
"log"
"os"
"path/filepath"
"runtime"
"runtime/debug"
"sync/atomic"
"time"
)
var logFile = os.Stderr
var logFilePath string
var rotateLog uint32
var ch = make(chan []interface{}, 10000)
var pid = os.Getpid()
func Errorln(a ...interface{}) error {
return errors.New(fmt.Sprintln(a...))
}
func Log(a ...interface{}) {
//fmt.Fprintln(os.Stderr, a...)
//return
select {
case ch <- a:
default:
}
}
func Warn(a ...interface{}) {
pc, file, line, ok := runtime.Caller(1)
if ok {
Log(fmt.Sprintf("%s[%s:%d]", runtime.FuncForPC(pc).Name(), file, line), a)
} else {
Log(a)
}
}
func RunIt() {
for a := range ch {
fmt.Fprint(logFile, time.Now().Format("02 Jan 15:04:05.000 "), pid, " ")
fmt.Fprintln(logFile, a...)
// переоткрываем лог-файл
if atomic.LoadUint32(&rotateLog) > 0 {
atomic.StoreUint32(&rotateLog, 0)
cleanedPath := filepath.Clean(logFilePath)
f, err := os.OpenFile(cleanedPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
Fatal(err)
}
if logFile != os.Stderr {
logFile.Close()
}
logFile = f // тут race c Close(), но может случиться только при остановке, так что не страшно
}
}
}
func Close() {
close(ch)
if logFile != os.Stderr {
logFile.Close()
}
}
func SetOutput(path string) {
if path != "" {
logFilePath = path
ReopenLog()
}
}
func ReopenLog() {
atomic.StoreUint32(&rotateLog, 1)
}
func Fatal(a ...interface{}) {
fmt.Fprintln(logFile, a...)
fmt.Fprintln(logFile, string(debug.Stack()))
time.Sleep(time.Second) // чтобы успело в лог записаться.
os.Exit(1)
}
type writer struct {
io.Writer
}
func (w *writer) Write(p []byte) (int, error) {
Warn(string(p))
return len(p), nil
}
var w *writer
var logger = log.New(w, "net/http ", 0)
func GetLogger() *log.Logger {
return logger
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment