go-cnj-helper/logger.go

224 lines
4.7 KiB
Go

package gocnjhelper
import (
"encoding/json"
"fmt"
"math/rand"
"os"
"sync"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
var (
logsClient *Client
gServiceCode string // An id to distinguish scaled servers of a service. For example, two socket servers. 1 server id = 552 , 2 server id = 123
gServiceName uint8
gServiceType uint8
gRabbitMqLoggingEnabled bool
gDebugEnabled bool
)
const (
RabbitMqQueueLogs = "cnj.logs"
ServiceNameAPI = 0
ServiceNameMailer = 1
ServiceNameStorageServer = 2
ServiceNameSSEServer = 3
ServiceNameWSServer = 4
ServiceTypeAlpha = 0
ServiceTypeBeta = 1
ServiceTypeStable = 2
messageTypeInfo = 0
messageTypeDebug = 1
messageTypeError = 2
)
func InitLogger(debug bool, colorizedOutput bool, rabbitMqLogging bool, rabbitMqConnAddr string, serviceName uint8, serviceType uint8) {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
gDebugEnabled = debug
gRabbitMqLoggingEnabled = rabbitMqLogging
if debug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
if colorizedOutput {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "15:04:05"})
}
if rabbitMqLogging {
gServiceCode = randomServiceCode()
gServiceName = serviceName
gServiceType = serviceType
logsClient = NewClient(
ExchangeSettings{},
QueueSettings{
Enabled: true,
Name: RabbitMqQueueLogs,
Durable: true,
DeleteWhenUnused: false,
Exclusive: false,
NoWait: false,
Arguments: nil,
QueuePublishSettings: QueuePublishSettings{
Mandatory: false,
Immediate: false,
DeliveryMode: DeliveryModePersistent,
ContentType: ContentTypeJson,
},
},
ChannelQosSettingsDefault,
Config{
ReconnectDelay: 1 * time.Second,
ReInitDelay: 1 * time.Second,
ResendDelay: 5 * time.Second,
},
rabbitMqConnAddr)
go startLogMessagesSender()
}
}
const numbers = "123456789"
func randomServiceCode() string {
res := make([]byte, 3)
for i := 0; i < 3; i++ {
res[i] = numbers[rand.New(rand.NewSource(time.Now().UnixNano())).Intn(len(numbers))]
}
return string(res)
}
func LogInfo(msg string) {
log.Info().Msg(msg)
pushLogMessage(messageTypeInfo, msg)
}
func LogInfof(format string, v ...interface{}) {
log.Info().Msgf(format, v)
pushLogMessage(messageTypeInfo, fmt.Sprintf(format, v...))
}
func LogDebug(msg string) {
log.Debug().Msg(msg)
pushLogMessage(messageTypeDebug, msg)
}
func LogDebugf(format string, v ...interface{}) {
log.Debug().Msgf(format, v)
pushLogMessage(messageTypeDebug, fmt.Sprintf(format, v...))
}
func LogError(msg string) {
log.Error().Msg(msg)
pushLogMessage(messageTypeError, msg)
}
func LogErrorf(format string, v ...interface{}) {
log.Error().Msgf(format, v)
pushLogMessage(messageTypeError, fmt.Sprintf(format, v...))
}
func LogFatal(msg string) {
pushLogMessage(messageTypeError, msg)
log.Fatal().Msg(msg)
}
func LogFatalf(format string, v ...interface{}) {
pushLogMessage(messageTypeError, fmt.Sprintf(format, v...))
log.Fatal().Msgf(format, v)
}
type RabbitMqLogMessage struct {
ServiceCode string
MessageType uint8
ServiceName uint8
ServiceType uint8
Msg string
Timestamp int64
}
var logMessages []RabbitMqLogMessage
var muLM sync.RWMutex
func addLogMessage(rabbitMqLogMessage RabbitMqLogMessage) {
muLM.Lock()
logMessages = append(logMessages, rabbitMqLogMessage)
muLM.Unlock()
}
func getLogMessages() []RabbitMqLogMessage {
muLM.RLock()
defer muLM.RUnlock()
return logMessages
}
func clearLogMessages() {
muLM.Lock()
logMessages = nil
muLM.Unlock()
}
func startLogMessagesSender() {
ticker := time.NewTicker(time.Millisecond * 500)
for range ticker.C {
msgs := getLogMessages()
if len(msgs) == 0 {
continue
}
marshaledMessages, err := json.Marshal(msgs)
if err != nil {
log.Error().Msgf("Failed to marshal rabbitMqLogMessages, err: %s", err)
continue
}
if err := logsClient.PushQueueMessage(marshaledMessages); err != nil {
log.Error().Msgf("Failed to push log messages, err: %s", err)
continue
}
clearLogMessages()
}
}
func pushLogMessage(messageType uint8, logMsg string) {
if !gRabbitMqLoggingEnabled || !gDebugEnabled && messageType == messageTypeDebug {
return
}
rabbitMqLogMessage := RabbitMqLogMessage{
ServiceCode: gServiceCode, // could be 552
MessageType: messageType, // could be debug, info
ServiceName: gServiceName, // could be API
ServiceType: gServiceType, // could be alpha
Msg: logMsg,
Timestamp: time.Now().UnixMilli(),
}
addLogMessage(rabbitMqLogMessage)
}