From 5895519a2882e5fecf4a0e6d4d60933005966b7e Mon Sep 17 00:00:00 2001 From: Alextopher Date: Sat, 23 Sep 2023 21:40:19 -0400 Subject: [PATCH] remove daily health --- daily_health.go | 151 ------------------------------------------ go.mod | 4 -- go.sum | 10 --- influx.go | 70 -------------------- logging/logging.go | 46 ++++++------- scheduler/calander.go | 2 +- sync.go | 12 ++-- sync_rsync.go | 4 +- sync_script.go | 2 +- webserver.go | 61 ----------------- 10 files changed, 32 insertions(+), 330 deletions(-) delete mode 100644 daily_health.go diff --git a/daily_health.go b/daily_health.go deleted file mode 100644 index 390cb42..0000000 --- a/daily_health.go +++ /dev/null @@ -1,151 +0,0 @@ -package main - -import ( - "context" - "errors" - "fmt" - "sort" - "time" - - "github.com/COSI-Lab/Mirror/logging" - "github.com/influxdata/influxdb-client-go/v2/api" - "github.com/wcharczuk/go-chart/v2" - "github.com/wcharczuk/go-chart/v2/drawing" -) - -// QueryDailyNginxStats gets the hourly nginx statistics from influxdb -// You can paste this into the influxdb data explorer -/* -from(bucket: "public") - |> range(start: -25h, stop: now()) - |> filter(fn: (r) => r["_measurement"] == "nginx") - |> filter(fn: (r) => r["_field"] == "bytes_sent") - |> derivative(unit: 1h, nonNegative: true) -*/ -func QueryDailyNginxStats() (*api.QueryTableResult, error) { - const request = "from(bucket: \"public\") |> range(start: -25h, stop: now()) |> filter(fn: (r) => r[\"_measurement\"] == \"nginx\") |> filter(fn: (r) => r[\"_field\"] == \"bytes_sent\") |> derivative(unit: 1h, nonNegative: true)" - - // try the query at most 5 times - for i := 0; i < 5; i++ { - result, err := reader.Query(context.Background(), request) - - if err != nil { - logging.Warn("Failed to querying influxdb nginx statistics", err) - // Sleep for some time before retrying - time.Sleep(time.Duration(i) * time.Second) - continue - } - - return result, nil - } - - return nil, errors.New("Error querying influxdb") -} - -// TimeSentPair is a simple product type for storing a time and the number of bytes sent -type TimeSentPair struct { - t time.Time - sent int64 -} - -// PrepareDailySendStats prepares the daily send statistics for each distro -// -// For each distro return a slice of (time, bytes_sent) pairs for each hour in the last 24 hours -// It should be expected that the returned slices will be of length 24, but this is not guaranteed -// It is guaranteed that the returned time slices will be in chronological order -func PrepareDailySendStats() (map[string][]TimeSentPair, error) { - result, err := QueryDailyNginxStats() - if err != nil { - return nil, err - } - - // Create a map of distro -> [(time, bytes_sent)] - distroMap := make(map[string][]TimeSentPair) - - // Iterate over the results - for result.Next() { - if result.Err() == nil { - // Get the data point - dp := result.Record() - - // Get the distro short name - distro, ok := dp.ValueByKey("distro").(string) - if !ok { - logging.Warn("Error getting distro short name") - fmt.Printf("%T %v\n", distro, distro) - continue - } - - if distroMap[distro] == nil { - distroMap[distro] = make([]TimeSentPair, 0) - } - - // Get the time - t := dp.Time() - sent := int64(dp.Value().(float64)) - - // Add the data point to the map - distroMap[distro] = append(distroMap[distro], TimeSentPair{t, sent}) - } else { - logging.Warn("InitNGINXStats Flux Query Error", result.Err()) - } - } - - // Sort each slice in the map by time - for _, v := range distroMap { - sort.Slice(v, func(i, j int) bool { - return v[i].t.Before(v[j].t) - }) - } - - return distroMap, nil -} - -// CreateBarChart uses the go-chart library to create a bar chart from the given data -func CreateBarChart(timeSentPairs []TimeSentPair, project string) chart.BarChart { - style := chart.Style{ - FillColor: drawing.ColorFromHex("#00bcd4"), - StrokeColor: drawing.ColorFromHex("#00bcd4"), - StrokeWidth: 0, - } - - max := float64(0) - values := make([]chart.Value, 0) - for _, v := range timeSentPairs { - values = append(values, chart.Value{Style: style, Label: fmt.Sprint(v.t.Hour()), Value: float64(v.sent / 1000000000)}) - if float64(v.sent/1000000000) > max { - max = float64(v.sent / 1000000000) - } - } - - graph := chart.BarChart{ - Title: fmt.Sprintf("Bytes sent per hour for \"%s\" | %s", project, time.Now().Format("Jan 02 2006")), - Background: chart.Style{ - Padding: chart.Box{ - Top: 40, - Left: 10, - Right: 10, - Bottom: 20, - }, - FillColor: drawing.ColorFromHex("efefef"), - }, - YAxis: chart.YAxis{ - Range: &chart.ContinuousRange{ - Min: 0, - Max: max, - }, - ValueFormatter: func(v interface{}) string { - if vf, isFloat := v.(float64); isFloat { - return fmt.Sprintf("%0.fG", vf) - } - return "" - }, - }, - Height: 600, - Width: 600 * 16 / 9, - BarWidth: 16, - Bars: values, - } - - return graph -} diff --git a/go.mod b/go.mod index 9d496a8..b60aa38 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,6 @@ require ( github.com/joho/godotenv v1.5.1 github.com/nxadm/tail v1.4.8 github.com/pelletier/go-toml/v2 v2.1.0 - github.com/wcharczuk/go-chart/v2 v2.1.1 github.com/xeipuuv/gojsonschema v1.2.0 ) @@ -31,7 +30,6 @@ require ( github.com/antchfx/xpath v1.2.4 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/blend/go-sdk v1.20220411.3 // indirect github.com/bytedance/sonic v1.10.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect @@ -47,7 +45,6 @@ require ( github.com/go-playground/validator/v10 v10.15.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -96,7 +93,6 @@ require ( github.com/yosssi/ace v0.0.5 // indirect golang.org/x/arch v0.5.0 // indirect golang.org/x/crypto v0.13.0 // indirect - golang.org/x/image v0.12.0 // indirect golang.org/x/net v0.15.0 // indirect golang.org/x/sys v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect diff --git a/go.sum b/go.sum index 94192f9..dc83443 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,6 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7D github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/blend/go-sdk v1.20220411.3 h1:GFV4/FQX5UzXLPwWV03gP811pj7B8J2sbuq+GJQofXc= -github.com/blend/go-sdk v1.20220411.3/go.mod h1:7lnH8fTi6U4i1fArEXRyOIY2E1X4MALg09qsQqY1+ak= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= @@ -84,8 +82,6 @@ github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI= github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -233,8 +229,6 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/wcharczuk/go-chart/v2 v2.1.1 h1:2u7na789qiD5WzccZsFz4MJWOJP72G+2kUuJoSNqWnE= -github.com/wcharczuk/go-chart/v2 v2.1.1/go.mod h1:CyCAUt2oqvfhCl6Q5ZvAZwItgpQKZOkCJGb+VGv6l14= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -260,9 +254,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= -golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= -golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -318,7 +309,6 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= diff --git a/influx.go b/influx.go index 29bda82..20d4adf 100644 --- a/influx.go +++ b/influx.go @@ -4,7 +4,6 @@ import ( "context" "crypto/tls" "fmt" - "sort" "github.com/COSI-Lab/Mirror/logging" influxdb2 "github.com/influxdata/influxdb-client-go/v2" @@ -98,72 +97,3 @@ func (l *LineChart) Swap(i, j int) { func (l *LineChart) Less(i, j int) bool { return l.Times[i] < l.Times[j] } - -// QueryWeeklyNetStats gets the bytes sent and received by the server in the last week -// Aggregates the data into 1 hour intervals -func QueryWeeklyNetStats() (line *LineChart, err error) { - // You can paste this into the influxdb data explorer - /* - from(bucket: "system") - |> range(start: -7d, stop: now()) - |> filter(fn: (r) => r["_measurement"] == "net" and r["interface"] == "enp8s0") - |> filter(fn: (r) => r["_field"] == "bytes_sent" or r["_field"] == "bytes_recv") - |> aggregateWindow(every: 1h, fn: last) - |> derivative(unit: 1s, nonNegative: true) - |> yield(name: "nonnegative derivative") - */ - result, err := reader.Query(context.Background(), "from(bucket: \"system\") |> range(start: -7d, stop: now()) |> filter(fn: (r) => r[\"_measurement\"] == \"net\" and r[\"interface\"] == \"enp8s0\") |> filter(fn: (r) => r[\"_field\"] == \"bytes_sent\" or r[\"_field\"] == \"bytes_recv\") |> aggregateWindow(every: 1h, fn: last) |> derivative(unit: 1s, nonNegative: true) |> yield(name: \"nonnegative derivative\")") - - if err != nil { - return nil, err - } - - sent := make([]float64, 0) - recv := make([]float64, 0) - times := make([]int64, 0) - - for result.Next() { - if result.Err() == nil { - // Get the data point - dp := result.Record() - - // Get the field - field, ok := dp.ValueByKey("_field").(string) - if !ok { - logging.Warn("Error getting field") - fmt.Printf("%T %v\n", field, field) - continue - } - - // Get the value - value, ok := dp.ValueByKey("_value").(float64) - if !ok { - logging.Warn("Error getting value") - fmt.Printf("%T %v\n", value, value) - continue - } - - switch field { - case "bytes_sent": - sent = append(sent, value) - case "bytes_recv": - recv = append(recv, value) - times = append(times, dp.Time().Unix()) - } - } else { - logging.Warn("InitNGINXStats Flux Query Error", result.Err()) - } - } - - line = &LineChart{ - Sent: sent, - Recv: recv, - Times: times, - } - - fmt.Println(len(sent), len(recv), len(times)) - - sort.Sort(line) - - return line, nil -} diff --git a/logging/logging.go b/logging/logging.go index 6c75bb8..f1c5629 100644 --- a/logging/logging.go +++ b/logging/logging.go @@ -46,48 +46,48 @@ func (mt messageType) String() string { } } -// LogEntryT enables programmatic creation of log entries -type LogEntryT struct { +// LogEntry enables programmatic creation of log entries +type LogEntry struct { typ messageType time time.Time message string } -// NewLogEntry creates a new LogEntryT with the current time -func NewLogEntry(mt messageType, message string) LogEntryT { - return LogEntryT{ +// NewLogEntry creates a new LogEntry with the current time +func NewLogEntry(mt messageType, message string) LogEntry { + return LogEntry{ typ: mt, time: time.Now(), message: message, } } -// InfoLogEntry creates a new LogEntryT with the current time and [INFO] tag -func InfoLogEntry(message string) LogEntryT { +// InfoLogEntry creates a new LogEntry with the current time and [INFO] tag +func InfoLogEntry(message string) LogEntry { return NewLogEntry(InfoT, message) } -// WarnLogEntry creates a new LogEntryT with the current time and [WARN] tag -func WarnLogEntry(message string) LogEntryT { +// WarnLogEntry creates a new LogEntry with the current time and [WARN] tag +func WarnLogEntry(message string) LogEntry { return NewLogEntry(WarnT, message) } -// ErrorLogEntry creates a new LogEntryT with the current time and [ERROR] tag -func ErrorLogEntry(message string) LogEntryT { +// ErrorLogEntry creates a new LogEntry with the current time and [ERROR] tag +func ErrorLogEntry(message string) LogEntry { return NewLogEntry(ErrorT, message) } -// PanicLogEntry creates a new LogEntryT with the current time and [PANIC] tag -func PanicLogEntry(message string) LogEntryT { +// PanicLogEntry creates a new LogEntry with the current time and [PANIC] tag +func PanicLogEntry(message string) LogEntry { return NewLogEntry(PanicT, message) } -// SuccessLogEntry creates a new LogEntryT with the current time and [SUCCESS] tag -func SuccessLogEntry(message string) LogEntryT { +// SuccessLogEntry creates a new LogEntry with the current time and [SUCCESS] tag +func SuccessLogEntry(message string) LogEntry { return NewLogEntry(SuccessT, message) } -func (le LogEntryT) String() string { +func (le LogEntry) String() string { if le.message[len(le.message)-1] != '\n' { return fmt.Sprintf("%s %s %s\n", time.Now().Format(tm), le.typ.String(), le.message) } @@ -95,6 +95,13 @@ func (le LogEntryT) String() string { return fmt.Sprintf("%s %s %s", time.Now().Format(tm), le.typ.String(), le.message) } +// Log prints the log entry to stdout +func (le LogEntry) Log() { + logger.Lock() + fmt.Print(le.String()) + logger.Unlock() +} + func logf(mt messageType, format string, v ...interface{}) { logger.Lock() if format[len(format)-1] != '\n' { @@ -172,10 +179,3 @@ func Logf(mt messageType, format string, v ...interface{}) { func Log(mt messageType, v ...interface{}) { logln(mt, v...) } - -// LogEntry logs a LogEntryT -func LogEntry(le LogEntryT) { - logger.Lock() - fmt.Print(le.String()) - logger.Unlock() -} diff --git a/scheduler/calander.go b/scheduler/calander.go index 294e7da..c468541 100644 --- a/scheduler/calander.go +++ b/scheduler/calander.go @@ -96,7 +96,7 @@ func buildCalendar[T any](tasks []T, timesPerDay []uint) Calendar[T] { } } -// Applies a function to each task in the calendar +// ForEach applies a function to each task in the calendar func (s *Calendar[T]) ForEach(f func(*T)) { for i := range s.tasks { f(&s.tasks[i]) diff --git a/sync.go b/sync.go index dfb5e15..86bc021 100644 --- a/sync.go +++ b/sync.go @@ -23,8 +23,6 @@ const ( TaskStatusSuccess TaskStatus = iota // TaskStatusFailure indicates that the task failed to complete TaskStatusFailure - // TaskStatusTimeout indicates that the task failed to complete within the allotted time - TaskStatusTimeout // TaskStatusStopped indicates that the task was stopped before it could complete by the scheduler TaskStatusStopped ) @@ -33,7 +31,7 @@ const ( // // Each task runs in its own go-routine and the scheduler ensures that only one instance of task `Run` will be called at a time type Task interface { - Run(context context.Context, stdout io.Writer, stderr io.Writer, status chan<- logging.LogEntryT) TaskStatus + Run(context context.Context, stdout io.Writer, stderr io.Writer, status chan<- logging.LogEntry) TaskStatus } type syncResult struct { @@ -56,10 +54,10 @@ type SchedulerTask struct { short string - queue *datarithms.CircularQueue[logging.LogEntryT] + queue *datarithms.CircularQueue[logging.LogEntry] results *datarithms.CircularQueue[syncResult] - channel chan logging.LogEntryT + channel chan logging.LogEntry stdout *bufio.Writer stderr *bufio.Writer task Task @@ -87,10 +85,10 @@ func NewScheduler(ctx context.Context, config *config.File) Scheduler { continue } - q := datarithms.NewCircularQueue[logging.LogEntryT](64) + q := datarithms.NewCircularQueue[logging.LogEntry](64) results := datarithms.NewCircularQueue[syncResult](64) - channel := make(chan logging.LogEntryT, 64) + channel := make(chan logging.LogEntry, 64) go func() { for { select { diff --git a/sync_rsync.go b/sync_rsync.go index 2eddfca..ddf5b4d 100644 --- a/sync_rsync.go +++ b/sync_rsync.go @@ -93,7 +93,7 @@ func NewRSYNCTask(declaration *config.Rsync, short string) *RSYNCTask { } // Run runs the script, blocking until it finishes -func (r *RSYNCTask) Run(ctx context.Context, stdout, stderr io.Writer, status chan<- logging.LogEntryT) TaskStatus { +func (r *RSYNCTask) Run(ctx context.Context, stdout, stderr io.Writer, status chan<- logging.LogEntry) TaskStatus { status <- logging.InfoLogEntry(fmt.Sprintf("%s: Starting rsync", r.short)) for i := 0; i < len(r.stages); i++ { @@ -107,7 +107,7 @@ func (r *RSYNCTask) Run(ctx context.Context, stdout, stderr io.Writer, status ch } // RunStage runs a single stage of the rsync task -func (r *RSYNCTask) RunStage(ctx context.Context, stdout, stderr io.Writer, status chan<- logging.LogEntryT, stage int) TaskStatus { +func (r *RSYNCTask) RunStage(ctx context.Context, stdout, stderr io.Writer, status chan<- logging.LogEntry, stage int) TaskStatus { // join r.args and r.stages[stage] args := make([]string, len(r.args)) copy(args, r.args) diff --git a/sync_script.go b/sync_script.go index 4c5f07d..db42720 100644 --- a/sync_script.go +++ b/sync_script.go @@ -30,7 +30,7 @@ func NewScriptTask(declaration *config.Script, short string) *ScriptTask { } // Run runs the script, blocking until it finishes -func (s *ScriptTask) Run(ctx context.Context, stdout, stderr io.Writer, status chan<- logging.LogEntryT) TaskStatus { +func (s *ScriptTask) Run(ctx context.Context, stdout, stderr io.Writer, status chan<- logging.LogEntry) TaskStatus { status <- logging.InfoLogEntry(fmt.Sprintf("%s: Starting script", s.short)) cmd := exec.Command(s.command, s.arguments...) cmd.Stdout = stdout diff --git a/webserver.go b/webserver.go index 2aad6f9..d4dde5a 100644 --- a/webserver.go +++ b/webserver.go @@ -9,7 +9,6 @@ import ( "github.com/COSI-Lab/Mirror/config" "github.com/COSI-Lab/Mirror/logging" "github.com/gorilla/mux" - "github.com/wcharczuk/go-chart/v2" ) var tmpls *template.Template @@ -65,64 +64,6 @@ func handleProjects(w http.ResponseWriter, r *http.Request) { } } -// The /stats page -func handleStats(w http.ResponseWriter, r *http.Request) { - // get bar chart data - line, err := QueryWeeklyNetStats() - if err != nil { - logging.Warn("handleStats;", err) - return - } - - err = tmpls.ExecuteTemplate(w, "statistics.gohtml", line) - if err != nil { - logging.Warn("handleStats;", err) - } -} - -// The /stats/{project}/{statistic} endpoint -// Supported statistics: -// - daily_sent -func handleStatistics(w http.ResponseWriter, r *http.Request) { - // Get the statistic name - vars := mux.Vars(r) - project := vars["project"] - statistic := vars["statistic"] - - if project == "" || statistic == "" { - w.WriteHeader(http.StatusBadRequest) - return - } - - switch statistic { - case "daily_sent": - // Get the bar chart data - stats, err := PrepareDailySendStats() - if err != nil { - logging.Warn("handleStatistics /daily_sent", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - // Create the bar chart for the to - if data, ok := stats[project]; ok { - graph := CreateBarChart(data, project) - // render the chart as PNG - err = graph.Render(chart.PNG, w) - if err != nil { - logging.Warn("handleStatistics /daily_sent", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "image/png") - } else { - w.WriteHeader(http.StatusNotFound) - } - default: - w.WriteHeader(http.StatusBadRequest) - } -} - // handleManualSyncs is a endpoint that allows a privileged user to manually cause a project to sync // Access token is included in the query string. The http method is not considered. // @@ -200,8 +141,6 @@ func HandleWebServer(manual chan<- string, entries <-chan NGINXLogEntry) { r.HandleFunc("/home", handleHome) r.HandleFunc("/projects", handleProjects) r.HandleFunc("/history", handleHistory) - r.HandleFunc("/stats/{project}/{statistic}", handleStatistics) - r.HandleFunc("/stats", handleStats) r.HandleFunc("/sync/{project}", handleManualSyncs(manual)) r.HandleFunc("/health", handleHealth)