yt-logger-go/ytlogget.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",
)
}