task_tracker/api/log.go
2019-02-11 20:10:33 -05:00

205 lines
4.1 KiB
Go

package api
import (
"encoding/json"
"errors"
"github.com/Sirupsen/logrus"
"github.com/simon987/task_tracker/config"
"github.com/simon987/task_tracker/storage"
"github.com/valyala/fasthttp"
"time"
)
type RequestHandler func(*Request)
type GetLogRequest struct {
Level storage.LogLevel `json:"level"`
Since int64 `json:"since"`
}
type LogRequest struct {
Scope string `json:"scope"`
Message string `json:"Message"`
TimeStamp int64 `json:"timestamp"`
worker *storage.Worker
}
type GetLogResponse struct {
Ok bool `json:"ok"`
Message string `json:"message"`
Logs *[]storage.LogEntry `json:"logs"`
}
type LogResponse struct {
Ok bool `json:"ok"`
Message string `json:"message"`
}
func (e *LogRequest) Time() time.Time {
t := time.Unix(e.TimeStamp, 0)
return t
}
func LogRequestMiddleware(h RequestHandler) fasthttp.RequestHandler {
return fasthttp.RequestHandler(func(ctx *fasthttp.RequestCtx) {
ctx.Response.Header.Add("Access-Control-Allow-Headers", "Content-Type")
ctx.Response.Header.Add("Access-Control-Allow-Methods", "GET, POST, OPTION")
ctx.Response.Header.Add("Access-Control-Allow-Origin", "*")
logrus.WithFields(logrus.Fields{
"path": string(ctx.Path()),
"header": ctx.Request.Header.String(),
}).Trace(string(ctx.Method()))
h(&Request{Ctx: ctx})
})
}
func (api *WebAPI) SetupLogger() {
logrus.SetLevel(config.Cfg.LogLevel)
api.Database.SetupLoggerHook()
}
func (api *WebAPI) parseLogEntry(r *Request) (*LogRequest, error) {
worker, err := api.validateSignature(r)
if err != nil {
return nil, err
}
entry := LogRequest{}
err = json.Unmarshal(r.Ctx.Request.Body(), &entry)
if err != nil {
return nil, err
}
if len(entry.Message) == 0 {
return nil, errors.New("invalid message")
} else if len(entry.Scope) == 0 {
return nil, errors.New("invalid scope")
} else if entry.TimeStamp <= 0 {
return nil, errors.New("invalid timestamp")
}
entry.worker = worker
return &entry, nil
}
func (api *WebAPI) LogTrace(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
logrus.WithFields(logrus.Fields{
"scope": entry.Scope,
"worker": entry.worker.Id,
}).WithTime(entry.Time()).Trace(entry.Message)
}
func (api *WebAPI) LogInfo(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
logrus.WithFields(logrus.Fields{
"scope": entry.Scope,
"worker": entry.worker.Id,
}).WithTime(entry.Time()).Info(entry.Message)
}
func (api *WebAPI) LogWarn(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
logrus.WithFields(logrus.Fields{
"scope": entry.Scope,
"worker": entry.worker.Id,
}).WithTime(entry.Time()).Warn(entry.Message)
}
func (api *WebAPI) LogError(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
logrus.WithFields(logrus.Fields{
"scope": entry.Scope,
"worker": entry.worker.Id,
}).WithTime(entry.Time()).Error(entry.Message)
}
func (api *WebAPI) GetLog(r *Request) {
req := &GetLogRequest{}
err := json.Unmarshal(r.Ctx.Request.Body(), req)
if err != nil {
r.Json(GetLogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
if req.isValid() {
logs := api.Database.GetLogs(req.Since, req.Level)
logrus.WithFields(logrus.Fields{
"getLogRequest": req,
"logCount": len(*logs),
}).Trace("Get log request")
r.OkJson(GetLogResponse{
Ok: true,
Logs: logs,
})
} else {
logrus.WithFields(logrus.Fields{
"getLogRequest": req,
}).Warn("Invalid log request")
r.Json(GetLogResponse{
Ok: false,
Message: "Invalid log request",
}, 400)
}
}
func (r GetLogRequest) isValid() bool {
if r.Since <= 0 {
return false
}
return true
}