♻️ Refactored tracing system to cost less memory
This commit is contained in:
parent
5ccbc592b7
commit
ee8b7e5660
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
/letsencrypt
|
/letsencrypt
|
||||||
/certs
|
/certs
|
||||||
/dist
|
/dist
|
||||||
|
/logs
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
@ -3,7 +3,7 @@ FROM golang:alpine as roadsign-server
|
|||||||
|
|
||||||
WORKDIR /source
|
WORKDIR /source
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -buildvcs -o /dist ./pkg/cmd/server/main.go
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -buildvcs -o /dist ./pkg/cmd/main.go
|
||||||
|
|
||||||
# Runtime
|
# Runtime
|
||||||
FROM golang:alpine
|
FROM golang:alpine
|
||||||
|
@ -24,9 +24,10 @@ id = "example-region"
|
|||||||
|
|
||||||
[[locations]]
|
[[locations]]
|
||||||
id = "example"
|
id = "example"
|
||||||
host = ["localhost:8000"]
|
hosts = ["localhost:8000"]
|
||||||
path = ["/"]
|
paths = ["/"]
|
||||||
[[locations.destinations]]
|
[[locations.destinations]]
|
||||||
id = "example-destination"
|
id = "example-destination"
|
||||||
uri = "https://example.com"
|
uri = "https://example.com"
|
||||||
helmet = { x_frame_options = "SAMEORIGIN" }
|
helmet = { x_frame_options = "SAMEORIGIN" }
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@ -28,6 +28,7 @@ require (
|
|||||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
golang.org/x/net v0.29.0 // indirect
|
golang.org/x/net v0.29.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
2
go.sum
2
go.sum
@ -169,6 +169,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
|
|||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -44,6 +44,9 @@ func main() {
|
|||||||
log.Warn().Msgf("RoadSign auto generated api credential is %s", credential)
|
log.Warn().Msgf("RoadSign auto generated api credential is %s", credential)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize access logging
|
||||||
|
navi.InitializeLogging()
|
||||||
|
|
||||||
// Load & init navigator
|
// Load & init navigator
|
||||||
if err := navi.ReadInConfig(viper.GetString("paths.configs")); err != nil {
|
if err := navi.ReadInConfig(viper.GetString("paths.configs")); err != nil {
|
||||||
log.Panic().Err(err).Msg("An error occurred when loading configurations.")
|
log.Panic().Err(err).Msg("An error occurred when loading configurations.")
|
@ -16,9 +16,7 @@ func ReadInConfig(root string) error {
|
|||||||
instance := &RoadApp{
|
instance := &RoadApp{
|
||||||
Regions: make([]*Region, 0),
|
Regions: make([]*Region, 0),
|
||||||
Metrics: &RoadMetrics{
|
Metrics: &RoadMetrics{
|
||||||
Traces: make([]RoadTrace, 0),
|
|
||||||
Traffic: make(map[string]int64),
|
Traffic: make(map[string]int64),
|
||||||
TrafficFrom: make(map[string]int64),
|
|
||||||
TotalTraffic: 0,
|
TotalTraffic: 0,
|
||||||
StartupAt: time.Now(),
|
StartupAt: time.Now(),
|
||||||
},
|
},
|
||||||
|
20
pkg/navi/logging.go
Normal file
20
pkg/navi/logging.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package navi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var accessLogger *log.Logger
|
||||||
|
|
||||||
|
func InitializeLogging() {
|
||||||
|
accessLogger = log.New(&lumberjack.Logger{
|
||||||
|
Filename: viper.GetString("logging.access"),
|
||||||
|
MaxSize: 10,
|
||||||
|
MaxBackups: 3,
|
||||||
|
MaxAge: 30,
|
||||||
|
Compress: true,
|
||||||
|
}, "", 0)
|
||||||
|
}
|
@ -1,15 +1,16 @@
|
|||||||
package navi
|
package navi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/viper"
|
"bufio"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RoadMetrics struct {
|
type RoadMetrics struct {
|
||||||
Traces []RoadTrace `json:"-"`
|
|
||||||
|
|
||||||
Traffic map[string]int64 `json:"traffic"`
|
Traffic map[string]int64 `json:"traffic"`
|
||||||
TrafficFrom map[string]int64 `json:"traffic_from"`
|
|
||||||
TotalTraffic int64 `json:"total_traffic"`
|
TotalTraffic int64 `json:"total_traffic"`
|
||||||
StartupAt time.Time `json:"startup_at"`
|
StartupAt time.Time `json:"startup_at"`
|
||||||
}
|
}
|
||||||
@ -42,22 +43,28 @@ func (v *RoadMetrics) AddTrace(trace RoadTrace) {
|
|||||||
} else {
|
} else {
|
||||||
v.Traffic[trace.Region]++
|
v.Traffic[trace.Region]++
|
||||||
}
|
}
|
||||||
if _, ok := v.TrafficFrom[trace.IpAddress]; !ok {
|
|
||||||
v.TrafficFrom[trace.IpAddress] = 0
|
|
||||||
} else {
|
|
||||||
v.TrafficFrom[trace.IpAddress]++
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Traces = append(v.Traces, trace)
|
raw, _ := jsoniter.Marshal(trace)
|
||||||
|
accessLogger.Println(string(raw))
|
||||||
// Garbage recycle
|
}
|
||||||
if len(v.Traffic) > viper.GetInt("performance.traces_limit") {
|
|
||||||
clear(v.Traffic)
|
func (v *RoadMetrics) ReadTrace() []RoadTrace {
|
||||||
}
|
fp := viper.GetString("logging.access")
|
||||||
if len(v.TrafficFrom) > viper.GetInt("performance.traces_limit") {
|
file, err := os.Open(fp)
|
||||||
clear(v.TrafficFrom)
|
if err != nil {
|
||||||
}
|
return nil
|
||||||
if len(v.Traces) > viper.GetInt("performance.traces_limit") {
|
}
|
||||||
clear(v.Traces)
|
defer file.Close()
|
||||||
}
|
|
||||||
|
var out []RoadTrace
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
var entry RoadTrace
|
||||||
|
if err := jsoniter.Unmarshal([]byte(line), &entry); err == nil {
|
||||||
|
out = append(out, entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,5 @@ func getTraffic(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTraces(c *fiber.Ctx) error {
|
func getTraces(c *fiber.Ctx) error {
|
||||||
return c.JSON(navi.R.Metrics.Traces)
|
return c.JSON(navi.R.Metrics.ReadTrace())
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package sideload
|
package sideload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.solsynth.dev/goatworks/roadsign/pkg/navi"
|
"git.solsynth.dev/goatworks/roadsign/pkg/navi"
|
||||||
"git.solsynth.dev/goatworks/roadsign/pkg/warden"
|
"git.solsynth.dev/goatworks/roadsign/pkg/warden"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getStats(c *fiber.Ctx) error {
|
func getStats(c *fiber.Ctx) error {
|
||||||
@ -27,7 +28,6 @@ func getStats(c *fiber.Ctx) error {
|
|||||||
"uptime": time.Since(navi.R.Metrics.StartupAt).Milliseconds(),
|
"uptime": time.Since(navi.R.Metrics.StartupAt).Milliseconds(),
|
||||||
"traffic": fiber.Map{
|
"traffic": fiber.Map{
|
||||||
"total": navi.R.Metrics.TotalTraffic,
|
"total": navi.R.Metrics.TotalTraffic,
|
||||||
"unique_client": len(navi.R.Metrics.TrafficFrom),
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ force_https = false
|
|||||||
max_body_size = 549_755_813_888 # 512 GiB
|
max_body_size = 549_755_813_888 # 512 GiB
|
||||||
max_qps = -1
|
max_qps = -1
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
access = "./logs/access.log"
|
||||||
|
|
||||||
[paths]
|
[paths]
|
||||||
configs = "./config"
|
configs = "./config"
|
||||||
|
|
||||||
@ -29,8 +32,7 @@ request_logging = true
|
|||||||
capture_traces = true
|
capture_traces = true
|
||||||
|
|
||||||
[performance]
|
[performance]
|
||||||
low_memory = true
|
low_memory = false
|
||||||
traces_limit = 256
|
|
||||||
prefork = false
|
prefork = false
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
|
Loading…
Reference in New Issue
Block a user