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) }