Web dashboard, task release, logs api

This commit is contained in:
simon987
2019-01-21 20:16:30 -05:00
parent 0346dd8b6b
commit cbd32daf02
65 changed files with 13430 additions and 114 deletions

View File

@@ -2,7 +2,6 @@ package api
import (
"encoding/json"
"fmt"
"github.com/Sirupsen/logrus"
"github.com/valyala/fasthttp"
)
@@ -11,7 +10,6 @@ type Request struct {
Ctx *fasthttp.RequestCtx
}
func (r *Request) OkJson(object interface{}) {
resp, err := json.Marshal(object)
@@ -26,8 +24,9 @@ func (r *Request) Json(object interface{}, code int) {
resp, err := json.Marshal(object)
if err != nil {
fmt.Fprint(r.Ctx,"Error during json encoding of error")
logrus.Error("Error during json encoding of error")
logrus.WithError(err).WithFields(logrus.Fields{
"code": code,
}).Error("Error during json encoding of object")
}
r.Ctx.Response.SetStatusCode(code)

View File

@@ -5,41 +5,56 @@ import (
"github.com/Sirupsen/logrus"
"github.com/valyala/fasthttp"
"src/task_tracker/config"
"src/task_tracker/storage"
"time"
)
type RequestHandler func(*Request)
type LogEntry struct {
type GetLogRequest struct {
Level logrus.Level `json:"level"`
Since int64 `json:"since"`
}
type LogRequest struct {
Scope string `json:"scope"`
Message string `json:"Message"`
TimeStamp int64 `json:"timestamp"`
}
func (e *LogEntry) Time() time.Time {
type GetLogResponse struct {
Ok bool `json:"ok"`
Message string `json:"message"`
Logs *[]storage.LogEntry `json:"logs"`
}
func (e *LogRequest) Time() time.Time {
t := time.Unix(e.TimeStamp, 0)
return t
}
func LogRequest(h RequestHandler) fasthttp.RequestHandler {
func LogRequestMiddleware(h RequestHandler) fasthttp.RequestHandler {
return fasthttp.RequestHandler(func(ctx *fasthttp.RequestCtx) {
logrus.WithFields(logrus.Fields{
"path": string(ctx.Path()),
}).Info(string(ctx.Method()))
"path": string(ctx.Path()),
"header": ctx.Request.Header.String(),
}).Trace(string(ctx.Method()))
h(&Request{Ctx: ctx})
})
}
func SetupLogger() {
func (api *WebAPI) SetupLogger() {
logrus.SetLevel(config.Cfg.LogLevel)
api.Database.SetupLoggerHook()
}
func parseLogEntry(r *Request) *LogEntry {
func parseLogEntry(r *Request) *LogRequest {
entry := LogEntry{}
entry := LogRequest{}
if r.GetJson(&entry) {
if len(entry.Message) == 0 {
@@ -89,3 +104,42 @@ func LogError(r *Request) {
"scope": entry.Scope,
}).WithTime(entry.Time()).Error(entry.Message)
}
func (api *WebAPI) GetLog(r *Request) {
req := &GetLogRequest{}
if r.GetJson(req) {
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
}

View File

@@ -30,9 +30,8 @@ func Index(r *Request) {
func New() *WebAPI {
SetupLogger()
api := new(WebAPI)
api.Database = &storage.Database{}
api.router = &fasthttprouter.Router{}
@@ -41,24 +40,28 @@ func New() *WebAPI {
Name: info.Name,
}
api.router.GET("/", LogRequest(Index))
api.router.GET("/", LogRequestMiddleware(Index))
api.router.POST("/log/trace", LogRequest(LogTrace))
api.router.POST("/log/info", LogRequest(LogInfo))
api.router.POST("/log/warn", LogRequest(LogWarn))
api.router.POST("/log/error", LogRequest(LogError))
api.router.POST("/log/trace", LogRequestMiddleware(LogTrace))
api.router.POST("/log/info", LogRequestMiddleware(LogInfo))
api.router.POST("/log/warn", LogRequestMiddleware(LogWarn))
api.router.POST("/log/error", LogRequestMiddleware(LogError))
api.router.POST("/worker/create", LogRequest(api.WorkerCreate))
api.router.GET("/worker/get/:id", LogRequest(api.WorkerGet))
api.router.POST("/worker/create", LogRequestMiddleware(api.WorkerCreate))
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.WorkerGet))
api.router.POST("/project/create", LogRequest(api.ProjectCreate))
api.router.GET("/project/get/:id", LogRequest(api.ProjectGet))
api.router.POST("/project/create", LogRequestMiddleware(api.ProjectCreate))
api.router.GET("/project/get/:id", LogRequestMiddleware(api.ProjectGet))
api.router.GET("/project/stats/:id", LogRequestMiddleware(api.ProjectGetStats))
api.router.POST("/task/create", LogRequest(api.TaskCreate))
api.router.GET("/task/get/:project", LogRequest(api.TaskGetFromProject))
api.router.GET("/task/get", LogRequest(api.TaskGet))
api.router.POST("/task/create", LogRequestMiddleware(api.TaskCreate))
api.router.GET("/task/get/:project", LogRequestMiddleware(api.TaskGetFromProject))
api.router.GET("/task/get", LogRequestMiddleware(api.TaskGet))
api.router.POST("/task/release", LogRequestMiddleware(api.TaskRelease))
api.router.POST("/git/receivehook", LogRequest(api.ReceiveGitWebHook))
api.router.POST("/git/receivehook", LogRequestMiddleware(api.ReceiveGitWebHook))
api.router.POST("/logs", LogRequestMiddleware(api.GetLog))
return api
}

View File

@@ -12,6 +12,7 @@ type CreateProjectRequest struct {
GitRepo string `json:"git_repo"`
Version string `json:"version"`
Priority int64 `json:"priority"`
Motd string `json:"motd"`
}
type CreateProjectResponse struct {
@@ -26,6 +27,12 @@ type GetProjectResponse struct {
Project *storage.Project `json:"project,omitempty"`
}
type GetProjectStatsResponse struct {
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
Stats *storage.ProjectStats `json:"stats,omitempty"`
}
func (api *WebAPI) ProjectCreate(r *Request) {
createReq := &CreateProjectRequest{}
@@ -37,6 +44,7 @@ func (api *WebAPI) ProjectCreate(r *Request) {
CloneUrl: createReq.CloneUrl,
GitRepo: createReq.GitRepo,
Priority: createReq.Priority,
Motd: createReq.Motd,
}
if isValidProject(project) {
@@ -52,6 +60,9 @@ func (api *WebAPI) ProjectCreate(r *Request) {
Ok: true,
Id: id,
})
logrus.WithFields(logrus.Fields{
"project": project,
}).Debug("Created project")
}
} else {
logrus.WithFields(logrus.Fields{
@@ -94,3 +105,23 @@ func (api *WebAPI) ProjectGet(r *Request) {
}, 404)
}
}
func (api *WebAPI) ProjectGetStats(r *Request) {
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
handleErr(err, r)
stats := api.Database.GetProjectStats(id)
if stats != nil && stats.Project != nil {
r.OkJson(GetProjectStatsResponse{
Ok: true,
Stats: stats,
})
} else {
r.Json(GetProjectStatsResponse{
Ok: false,
Message: "Project not found",
}, 404)
}
}

View File

@@ -15,6 +15,17 @@ type CreateTaskRequest struct {
Priority int64 `json:"priority"`
}
type ReleaseTaskRequest struct {
TaskId int64 `json:"task_id"`
Success bool `json:"success"`
WorkerId *uuid.UUID `json:"worker_id"`
}
type ReleaseTaskResponse struct {
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
}
type CreateTaskResponse struct {
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
@@ -137,3 +148,33 @@ func (api WebAPI) workerFromQueryArgs(r *Request) (*storage.Worker, error) {
return worker, nil
}
func (api *WebAPI) TaskRelease(r *Request) {
req := ReleaseTaskRequest{}
if r.GetJson(req) {
res := api.Database.ReleaseTask(req.TaskId, req.WorkerId, req.Success)
response := ReleaseTaskResponse{
Ok: res,
}
if !res {
response.Message = "Could not find a task with the specified Id assigned to this workerId"
logrus.WithFields(logrus.Fields{
"releaseTaskRequest": req,
"taskUpdated": res,
}).Warn("Release task: NOT FOUND")
} else {
logrus.WithFields(logrus.Fields{
"releaseTaskRequest": req,
"taskUpdated": res,
}).Trace("Release task")
}
r.OkJson(response)
}
}