add logging service for service-wide logging
This commit is contained in:
parent
5fa4371b33
commit
0508a4867e
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bdlm/log"
|
||||
"github.com/satori/go.uuid"
|
||||
"github.com/streadway/amqp"
|
||||
|
||||
srv "dev.sum7.eu/genofire/microservices-collection/logging"
|
||||
)
|
||||
|
||||
const ServiceName = "eu.sum7.log-cmd"
|
||||
|
||||
var ServiceID = uuid.Must(uuid.NewV4())
|
||||
|
||||
func main() {
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
DisableTimestamp: true,
|
||||
})
|
||||
|
||||
logLevel, err := strconv.ParseUint(os.Args[1], 10, 32)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse LogLevel: %s", err)
|
||||
}
|
||||
logMessage := srv.LogMessage{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
Time: time.Now(),
|
||||
Level: uint32(logLevel),
|
||||
Message: strings.Join(os.Args[2:], " "),
|
||||
}
|
||||
body, err := json.Marshal(logMessage)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse LogLevel: %s", err)
|
||||
}
|
||||
|
||||
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to RabbitMQ: %s", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
ch, err := conn.Channel()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open a channel: %s", err)
|
||||
}
|
||||
defer ch.Close()
|
||||
|
||||
if err = srv.ExchangeDeclare(ch); err != nil {
|
||||
log.Fatalf("Failed to declare an exchange: %s", err)
|
||||
}
|
||||
|
||||
err = ch.Publish(
|
||||
srv.EXCHANGE,
|
||||
fmt.Sprintf("%d.%s", logLevel, ServiceName),
|
||||
false,
|
||||
false,
|
||||
amqp.Publishing{
|
||||
ContentType: "application/json",
|
||||
DeliveryMode: amqp.Persistent,
|
||||
Body: body,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to publish log message: %s", err)
|
||||
}
|
||||
|
||||
log.Printf(" [x] Sent %s", body)
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/bdlm/log"
|
||||
"github.com/bdlm/std/logger"
|
||||
"github.com/streadway/amqp"
|
||||
|
||||
"dev.sum7.eu/genofire/microservices-collection/lib"
|
||||
srv "dev.sum7.eu/genofire/microservices-collection/logging"
|
||||
)
|
||||
|
||||
var logRecieved = false
|
||||
|
||||
func main() {
|
||||
flag.BoolVar(&logRecieved, "recieved", logRecieved, "show recieved log on console")
|
||||
flag.Parse()
|
||||
lib.LogUpdateConfig()
|
||||
|
||||
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to RabbitMQ: %s", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
ch, err := conn.Channel()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open a channel: %s", err)
|
||||
}
|
||||
defer ch.Close()
|
||||
|
||||
if err = srv.ExchangeDeclare(ch); err != nil {
|
||||
log.Fatalf("Failed to declare an exchange: %s", err)
|
||||
}
|
||||
|
||||
q, err := ch.QueueDeclare(
|
||||
"", // name
|
||||
false, // durable
|
||||
false, // delete when usused
|
||||
true, // exclusive
|
||||
false, // no-wait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to declare a queue: %s", err)
|
||||
}
|
||||
|
||||
err = ch.QueueBind(
|
||||
q.Name, // queue name
|
||||
"", // routing key
|
||||
srv.EXCHANGE, // exchange
|
||||
false,
|
||||
nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to bind a queue: %s", err)
|
||||
}
|
||||
|
||||
msgs, err := ch.Consume(
|
||||
q.Name, // queue
|
||||
"", // consumer
|
||||
true, // auto-ack
|
||||
false, // exclusive
|
||||
false, // no-local
|
||||
false, // no-wait
|
||||
nil, // args
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to register a consumer: %s", err)
|
||||
}
|
||||
|
||||
loggerRecieved := log.New()
|
||||
loggerRecieved.SetLevel(logger.Trace)
|
||||
|
||||
go func() {
|
||||
for d := range msgs {
|
||||
var logMessage *srv.LogMessage
|
||||
if err := json.Unmarshal([]byte(d.Body), &logMessage); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
//TODO write to Database (to get last values for web client)
|
||||
|
||||
// output to console
|
||||
if !logRecieved {
|
||||
continue
|
||||
}
|
||||
e := &log.Entry{
|
||||
Logger: loggerRecieved,
|
||||
Time: logMessage.Time,
|
||||
Data: logMessage.Data,
|
||||
}
|
||||
e = e.WithFields(map[string]interface{}{
|
||||
"service_name": logMessage.ServiceName,
|
||||
"service_id": logMessage.ServiceID,
|
||||
"log_level": logMessage.Level,
|
||||
})
|
||||
lvl := logger.Level(uint32(logMessage.Level))
|
||||
if lvl >= logger.Trace {
|
||||
e.Debug(fmt.Sprintf("[trace] %s", logMessage.Message))
|
||||
} else if lvl >= logger.Debug {
|
||||
e.Debug(logMessage.Message)
|
||||
} else if lvl >= logger.Info {
|
||||
e.Info(logMessage.Message)
|
||||
} else if lvl >= logger.Warn {
|
||||
e.Warn(logMessage.Message)
|
||||
} else if lvl >= logger.Error {
|
||||
e.Error(logMessage.Message)
|
||||
} else if lvl >= logger.Panic {
|
||||
e.Error(fmt.Sprintf("[panic] %s", logMessage.Message))
|
||||
} else if lvl >= logger.Fatal {
|
||||
e.Error(fmt.Sprintf("[fatal] %s", logMessage.Message))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
log.Debug("started")
|
||||
|
||||
// Wait for INT/TERM
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-sigs
|
||||
log.WithField("recieved", sig).Info("stopped")
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package logging
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/bdlm/log"
|
||||
"github.com/satori/go.uuid"
|
||||
"github.com/streadway/amqp"
|
||||
)
|
||||
|
||||
const EXCHANGE = "sum7.logging"
|
||||
|
||||
func ExchangeDeclare(ch *amqp.Channel) error {
|
||||
return ch.ExchangeDeclare(
|
||||
EXCHANGE,
|
||||
"direct",
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
type LogMessage struct {
|
||||
ServiceName string `json:"sname"`
|
||||
ServiceID uuid.UUID `json:"sid"`
|
||||
Time time.Time `json:"time"`
|
||||
Level uint32 `json:"level"`
|
||||
Message string `json:"message"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
func LogMessageFromEntry(sname string, sid uuid.UUID, e *log.Entry) *LogMessage {
|
||||
return &LogMessage{
|
||||
ServiceName: sname,
|
||||
ServiceID: sid,
|
||||
Time: e.Time,
|
||||
Level: uint32(e.Level),
|
||||
Message: e.Message,
|
||||
Data: e.Data,
|
||||
}
|
||||
}
|
Reference in New Issue