348 lines
8.8 KiB
Go
348 lines
8.8 KiB
Go
package ytlogger
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.ymnuktech.ru/ymnuk/yt-logger-go/log"
|
|
)
|
|
|
|
type Priority int32
|
|
|
|
const (
|
|
|
|
// From /usr/include/sys/syslog.h.
|
|
// These are the same on Linux, BSD, and OS X.
|
|
LOG_EMERG Priority = iota
|
|
LOG_ALERT
|
|
LOG_CRIT
|
|
LOG_ERR
|
|
LOG_WARNING
|
|
LOG_NOTICE
|
|
LOG_INFO
|
|
LOG_DEBUG
|
|
)
|
|
|
|
const (
|
|
ColorReset = "\033[0m"
|
|
ColorRed = "\033[31m"
|
|
ColorGreen = "\033[32m"
|
|
ColorYellow = "\033[33m"
|
|
ColorBlue = "\033[34m"
|
|
ColorMagenta = "\033[35m"
|
|
ColorCyan = "\033[36m"
|
|
ColorWhite = "\033[37m"
|
|
ColorBlueBold = "\033[34;1m"
|
|
ColorMagentaBold = "\033[35;1m"
|
|
ColorRedBold = "\033[31;1m"
|
|
ColorYellowBold = "\033[33;1m"
|
|
ColorGreenBold = "\033[32;1m"
|
|
)
|
|
|
|
// Тип функции логирования в консоль
|
|
type LogF func(pkg *log.Pkg)
|
|
|
|
// Логер
|
|
type YTLogger struct {
|
|
logLevel Priority
|
|
streamMsg chan *log.Pkg
|
|
logF LogF
|
|
}
|
|
|
|
// Создать логер
|
|
func NewYTLogger(level Priority, queueLen int, f LogF) (logger *YTLogger) {
|
|
if queueLen <= 0 {
|
|
queueLen = 1
|
|
}
|
|
logger = &YTLogger{
|
|
logLevel: level,
|
|
streamMsg: make(chan *log.Pkg, queueLen),
|
|
logF: f,
|
|
}
|
|
go logger.worker()
|
|
return
|
|
}
|
|
|
|
// Изменение уровня логирования
|
|
func (l *YTLogger) LogMode(level Priority) *YTLogger {
|
|
newlogger := *l
|
|
newlogger.logLevel = level
|
|
return &newlogger
|
|
}
|
|
|
|
// Изменение функции логирования
|
|
func (l *YTLogger) LogFunc(f LogF) *YTLogger {
|
|
newlogger := *l
|
|
newlogger.logF = f
|
|
return &newlogger
|
|
}
|
|
|
|
// Завершить логер
|
|
func (yt *YTLogger) Shutdown() {
|
|
close(yt.streamMsg)
|
|
}
|
|
|
|
// Обработчик пакетов событий
|
|
func (yt *YTLogger) worker() {
|
|
for {
|
|
var pkg *log.Pkg
|
|
var ok bool
|
|
if pkg, ok = <-yt.streamMsg; !ok {
|
|
break
|
|
}
|
|
if pkg == nil {
|
|
continue
|
|
}
|
|
if yt.logF != nil {
|
|
yt.logF(pkg)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Подготовка пакета
|
|
func (yt *YTLogger) preparePkg(level Priority, funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) (pkg *log.Pkg) {
|
|
if funcName == nil {
|
|
funcName = &[]string{""}[0]
|
|
}
|
|
if callID == nil {
|
|
callID = &[]string{""}[0]
|
|
}
|
|
if callPrevID == nil {
|
|
callPrevID = &[]string{""}[0]
|
|
}
|
|
if callFrom == nil {
|
|
callFrom = &[]string{""}[0]
|
|
}
|
|
if callResponseID == nil {
|
|
callResponseID = &[]string{""}[0]
|
|
}
|
|
if timeStart == nil {
|
|
timeStart = &[]time.Time{time.Now()}[0]
|
|
}
|
|
if timeEnd == nil {
|
|
timeEnd = &[]time.Time{time.Now()}[0]
|
|
}
|
|
|
|
if path == nil {
|
|
path = &[]string{""}[0]
|
|
}
|
|
|
|
if errCode == nil {
|
|
errCode = &[]int32{0}[0]
|
|
}
|
|
if err == nil {
|
|
err = &[]string{""}[0]
|
|
}
|
|
if callResponseID == nil {
|
|
callResponseID = &[]string{""}[0]
|
|
}
|
|
|
|
if statusCode == nil {
|
|
statusCode = &[]int32{0}[0]
|
|
}
|
|
if size == nil {
|
|
size = &[]int64{0}[0]
|
|
}
|
|
|
|
if msg == nil {
|
|
msg = &[]string{""}[0]
|
|
}
|
|
|
|
pkg = &log.Pkg{
|
|
LogLevel: int32(level),
|
|
TimeStart: &log.Time{
|
|
Time: timeStart.Unix(),
|
|
Nano: int64(timeStart.Nanosecond()),
|
|
},
|
|
TimeEnd: &log.Time{
|
|
Time: timeEnd.Unix(),
|
|
Nano: int64(timeEnd.Nanosecond()),
|
|
},
|
|
Metadata: &log.Metadata{
|
|
FuncName: *funcName,
|
|
CallID: *callID,
|
|
CallPrevID: *callPrevID,
|
|
CallFrom: *callFrom,
|
|
CallResponseID: *callResponseID,
|
|
},
|
|
Path: *path,
|
|
Status: &log.Status{
|
|
StatusCode: int32(*statusCode),
|
|
Size: *size,
|
|
Msg: *msg,
|
|
},
|
|
Err: &log.Error{
|
|
ErrCode: *errCode,
|
|
Err: *err,
|
|
},
|
|
}
|
|
return
|
|
}
|
|
|
|
func (yt *YTLogger) Any(pkg *log.Pkg) {
|
|
if pkg != nil {
|
|
yt.streamMsg <- pkg
|
|
}
|
|
}
|
|
|
|
// Чрезвычайная ситуация
|
|
func (yt *YTLogger) Emerg(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_EMERG {
|
|
yt.streamMsg <- yt.preparePkg(LOG_EMERG, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Тревожная ситуация
|
|
func (yt *YTLogger) Alert(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_ALERT {
|
|
yt.streamMsg <- yt.preparePkg(LOG_ALERT, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Критическая ситуация
|
|
func (yt *YTLogger) Crit(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_CRIT {
|
|
yt.streamMsg <- yt.preparePkg(LOG_CRIT, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Ошибка
|
|
func (yt *YTLogger) Err(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_ERR {
|
|
yt.streamMsg <- yt.preparePkg(LOG_ERR, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Предупреждение
|
|
func (yt *YTLogger) Warning(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_WARNING {
|
|
yt.streamMsg <- yt.preparePkg(LOG_WARNING, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Уведомление
|
|
func (yt *YTLogger) Notice(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_NOTICE {
|
|
yt.streamMsg <- yt.preparePkg(LOG_NOTICE, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Информация
|
|
func (yt *YTLogger) Info(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_INFO {
|
|
yt.streamMsg <- yt.preparePkg(LOG_INFO, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Отладка
|
|
func (yt *YTLogger) Debug(funcName, callID, callPrevID, callFrom, callResponseID *string, timeStart, timeEnd *time.Time, path *string, errCode *int32, err *string, statusCode *int32, size *int64, msg *string) {
|
|
if yt.logLevel >= LOG_DEBUG {
|
|
yt.streamMsg <- yt.preparePkg(LOG_DEBUG, funcName, callID, callPrevID, callFrom, callResponseID, timeStart, timeEnd, path, errCode, err, statusCode, size, msg)
|
|
}
|
|
}
|
|
|
|
// Логирования в консоль
|
|
func LogConsole(pkg *log.Pkg) {
|
|
if pkg == nil {
|
|
return
|
|
}
|
|
var color string
|
|
var level string
|
|
switch Priority(pkg.LogLevel) {
|
|
case LOG_EMERG:
|
|
level = "emerg"
|
|
color = ColorMagenta
|
|
case LOG_ALERT:
|
|
level = "alert"
|
|
color = ColorMagentaBold
|
|
case LOG_CRIT:
|
|
level = "crit"
|
|
color = ColorRedBold
|
|
case LOG_ERR:
|
|
level = "err"
|
|
color = ColorRed
|
|
case LOG_WARNING:
|
|
level = "warning"
|
|
color = ColorYellowBold
|
|
case LOG_NOTICE:
|
|
level = "notice"
|
|
color = ColorYellow
|
|
case LOG_INFO:
|
|
level = "info"
|
|
color = ColorGreenBold
|
|
case LOG_DEBUG:
|
|
level = "debug"
|
|
color = ColorGreen
|
|
default:
|
|
return
|
|
}
|
|
var timeStartStr string
|
|
if pkg.TimeStart != nil {
|
|
timeStartStr = time.Unix(pkg.TimeStart.Time, pkg.TimeStart.Nano).Format(time.RFC3339Nano)
|
|
} else {
|
|
timeStartStr = "-"
|
|
}
|
|
|
|
var timeEndStr string
|
|
if pkg.TimeEnd != nil {
|
|
timeEndStr = time.Unix(pkg.TimeStart.Time, pkg.TimeStart.Nano).Format(time.RFC3339Nano)
|
|
} else {
|
|
timeEndStr = "-"
|
|
}
|
|
|
|
if pkg.Path == "" {
|
|
pkg.Path = "-"
|
|
}
|
|
|
|
var msg string
|
|
if pkg.Status == nil {
|
|
msg = "-"
|
|
} else if pkg.Status.Msg == "" {
|
|
msg = "-"
|
|
} else {
|
|
msg = pkg.Status.Msg
|
|
}
|
|
if pkg.Path == "" {
|
|
pkg.Path = "-"
|
|
}
|
|
|
|
var funcName string
|
|
var callID string
|
|
var callFrom string
|
|
if pkg.Metadata == nil {
|
|
funcName = "-"
|
|
callID = "-"
|
|
callFrom = "-"
|
|
} else {
|
|
if pkg.Metadata.FuncName == "" {
|
|
funcName = "-"
|
|
} else {
|
|
funcName = pkg.Metadata.FuncName
|
|
}
|
|
if pkg.Metadata.CallID == "" {
|
|
callID = "-"
|
|
} else {
|
|
callID = pkg.Metadata.CallID
|
|
}
|
|
if pkg.Metadata.CallFrom == "" {
|
|
callFrom = "-"
|
|
} else {
|
|
callFrom = pkg.Metadata.CallFrom
|
|
}
|
|
}
|
|
|
|
fmt.Printf("%s[%s]%s %s %s %s %s %s %s %s%s",
|
|
color,
|
|
level,
|
|
ColorReset,
|
|
timeStartStr,
|
|
timeEndStr,
|
|
funcName,
|
|
callID,
|
|
callFrom,
|
|
pkg.Path,
|
|
msg,
|
|
"\n",
|
|
)
|
|
}
|