mirror of
https://github.com/makeplane/plane.git
synced 2026-07-12 21:40:18 +02:00
* feat: added build meta data to monitor * feat: added versioning to prime-monitor * feat: added logger package for prime-monitor * feat: implemented logging in cmd * feat: implemented moduled monorepo architecture * feat: added cron package for healthcheck * feat: added constants and modules for healthcheck * feat: added environment service getter method * feat: added environment service parser for parsing the recieved keys * feat: added environment service provider method * feat: added retry based executer for the test methods * feat: added http health check method and placeholders for redis & pg * feat: added tests for healthcheck methods * feat: added PerformHealthCheck Controller Method for execution of healthcheck controller * feat: added healthcheck test file for testing the healthcheck * feat: added healthcheck to work file * feat: added readme for healthcheck package * feat: created healthcheck register for prime scheduler * feat: added cron command for running cron subpart of monitor * feat: added prime schedule handler for cron * feat: added start command for starting up prime scheduler * feat: added build utility files for monitor * fix: goreleaser builds * feat: removed Redis method from healthcheck methods * feat: added docker file for building prime-monitor * feat: added flag for adding healthcheck duration for cron start * chore: removed redis as a healthcheck method * chore: modified actions to build monitor on branch build and docker images * feat: added monitor service in docker compose caddy * feat: added description for HealthCheckJob * fix: status code issue for reachable and non reachable * feat: added api package for connecting with prime api * feat: modified cmd package to report healthcheck status to prime * feat: added api types inside prime-monitor * feat: added message field for meta while status reporting * fix: modified constants for environment variables * feat: added monitor readme * fix: build-branch monitor content shift to build-branch-ee * chore: added build args on release * feat: remove version meta data from cli * fix: docker file changed to fix the build to default * fix: removed build flags from github branch build * fix: moved cron start to root level start cmd * fix: passed the recieved machine signature to api headers * feat: optimised docker build for monitor
228 lines
4.8 KiB
Go
228 lines
4.8 KiB
Go
package logger
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"log/slog"
|
|
)
|
|
|
|
const (
|
|
timeFormat = "[15:04:05.000]"
|
|
|
|
reset = "\033[0m"
|
|
|
|
black = 30
|
|
red = 31
|
|
green = 32
|
|
yellow = 33
|
|
blue = 34
|
|
magenta = 35
|
|
cyan = 36
|
|
lightGray = 37
|
|
darkGray = 90
|
|
lightRed = 91
|
|
lightGreen = 92
|
|
lightYellow = 93
|
|
lightBlue = 94
|
|
lightMagenta = 95
|
|
lightCyan = 96
|
|
white = 97
|
|
)
|
|
|
|
func colorize(colorCode int, v string) string {
|
|
return fmt.Sprintf("\033[%sm%s%s", strconv.Itoa(colorCode), v, reset)
|
|
}
|
|
|
|
type Handler struct {
|
|
h slog.Handler
|
|
r func([]string, slog.Attr) slog.Attr
|
|
b *bytes.Buffer
|
|
m *sync.Mutex
|
|
}
|
|
|
|
func (h *Handler) Enabled(ctx context.Context, level slog.Level) bool {
|
|
return h.h.Enabled(ctx, level)
|
|
}
|
|
|
|
func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
|
return &Handler{h: h.h.WithAttrs(attrs), b: h.b, r: h.r, m: h.m}
|
|
}
|
|
|
|
func (h *Handler) WithGroup(name string) slog.Handler {
|
|
return &Handler{h: h.h.WithGroup(name), b: h.b, r: h.r, m: h.m}
|
|
}
|
|
|
|
func (h *Handler) computeAttrs(
|
|
ctx context.Context,
|
|
r slog.Record,
|
|
) (map[string]any, error) {
|
|
h.m.Lock()
|
|
defer func() {
|
|
h.b.Reset()
|
|
h.m.Unlock()
|
|
}()
|
|
if err := h.h.Handle(ctx, r); err != nil {
|
|
return nil, fmt.Errorf("error when calling inner handler's Handle: %w", err)
|
|
}
|
|
|
|
var attrs map[string]any
|
|
err := json.Unmarshal(h.b.Bytes(), &attrs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error when unmarshaling inner handler's Handle result: %w", err)
|
|
}
|
|
return attrs, nil
|
|
}
|
|
|
|
func (h *Handler) Handle(ctx context.Context, r slog.Record) error {
|
|
|
|
var level string
|
|
levelAttr := slog.Attr{
|
|
Key: slog.LevelKey,
|
|
Value: slog.AnyValue(r.Level),
|
|
}
|
|
if h.r != nil {
|
|
levelAttr = h.r([]string{}, levelAttr)
|
|
}
|
|
|
|
if !levelAttr.Equal(slog.Attr{}) {
|
|
level = levelAttr.Value.String() + ":"
|
|
|
|
if r.Level <= slog.LevelDebug {
|
|
level = colorize(lightGray, level)
|
|
} else if r.Level <= slog.LevelInfo {
|
|
level = colorize(cyan, level)
|
|
} else if r.Level < slog.LevelWarn {
|
|
level = colorize(lightBlue, level)
|
|
} else if r.Level < slog.LevelError {
|
|
level = colorize(lightYellow, level)
|
|
} else if r.Level <= slog.LevelError+1 {
|
|
level = colorize(lightRed, level)
|
|
} else if r.Level > slog.LevelError+1 {
|
|
level = colorize(lightMagenta, level)
|
|
}
|
|
}
|
|
|
|
var timestamp string
|
|
timeAttr := slog.Attr{
|
|
Key: slog.TimeKey,
|
|
Value: slog.StringValue(r.Time.Format(timeFormat)),
|
|
}
|
|
if h.r != nil {
|
|
timeAttr = h.r([]string{}, timeAttr)
|
|
}
|
|
if !timeAttr.Equal(slog.Attr{}) {
|
|
timestamp = colorize(lightGray, timeAttr.Value.String())
|
|
}
|
|
|
|
var msg string
|
|
msgAttr := slog.Attr{
|
|
Key: slog.MessageKey,
|
|
Value: slog.StringValue(r.Message),
|
|
}
|
|
if h.r != nil {
|
|
msgAttr = h.r([]string{}, msgAttr)
|
|
}
|
|
if !msgAttr.Equal(slog.Attr{}) {
|
|
msg = colorize(white, msgAttr.Value.String())
|
|
}
|
|
|
|
attrs, err := h.computeAttrs(ctx, r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
bytes, err := json.MarshalIndent(attrs, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("error when marshaling attrs: %w", err)
|
|
}
|
|
|
|
out := strings.Builder{}
|
|
if len(timestamp) > 0 {
|
|
out.WriteString(timestamp)
|
|
out.WriteString(" ")
|
|
}
|
|
if len(level) > 0 {
|
|
out.WriteString(level)
|
|
out.WriteString(" ")
|
|
}
|
|
if len(msg) > 0 {
|
|
out.WriteString(msg)
|
|
out.WriteString(" ")
|
|
}
|
|
if len(bytes) > 0 {
|
|
out.WriteString(colorize(darkGray, string(bytes)))
|
|
}
|
|
fmt.Println(out.String())
|
|
|
|
return nil
|
|
}
|
|
|
|
func suppressDefaults(
|
|
next func([]string, slog.Attr) slog.Attr,
|
|
) func([]string, slog.Attr) slog.Attr {
|
|
return func(groups []string, a slog.Attr) slog.Attr {
|
|
if a.Key == slog.TimeKey ||
|
|
a.Key == slog.LevelKey ||
|
|
a.Key == slog.MessageKey {
|
|
return slog.Attr{}
|
|
}
|
|
if next == nil {
|
|
return a
|
|
}
|
|
return next(groups, a)
|
|
}
|
|
}
|
|
|
|
func NewHandler(opts *slog.HandlerOptions) *Handler {
|
|
if opts == nil {
|
|
opts = &slog.HandlerOptions{}
|
|
}
|
|
b := &bytes.Buffer{}
|
|
return &Handler{
|
|
b: b,
|
|
h: slog.NewJSONHandler(b, &slog.HandlerOptions{
|
|
Level: opts.Level,
|
|
AddSource: opts.AddSource,
|
|
ReplaceAttr: suppressDefaults(opts.ReplaceAttr),
|
|
}),
|
|
r: opts.ReplaceAttr,
|
|
m: &sync.Mutex{},
|
|
}
|
|
}
|
|
|
|
func (h *Handler) GetSlogHandler() slog.Handler {
|
|
return h.h
|
|
}
|
|
|
|
// New methods for simpler logging API
|
|
func (h *Handler) log(ctx context.Context, level slog.Level, msg string) {
|
|
r := slog.Record{
|
|
Time: time.Now(),
|
|
Level: level,
|
|
Message: msg,
|
|
}
|
|
h.Handle(ctx, r)
|
|
}
|
|
|
|
func (h *Handler) Info(ctx context.Context, msg string) {
|
|
h.log(ctx, slog.LevelInfo, msg)
|
|
}
|
|
|
|
func (h *Handler) Error(ctx context.Context, msg string, attrs ...slog.Attr) {
|
|
h.log(ctx, slog.LevelError, msg)
|
|
}
|
|
|
|
func (h *Handler) Warning(ctx context.Context, msg string, attrs ...slog.Attr) {
|
|
h.log(ctx, slog.LevelWarn, msg)
|
|
}
|
|
|
|
func (h *Handler) Debug(ctx context.Context, msg string, attrs ...slog.Attr) {
|
|
h.log(ctx, slog.LevelDebug, msg)
|
|
}
|