Fixes #7. Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
parent
e486d3df98
commit
0ce540e92d
7 changed files with 141 additions and 18 deletions
|
@ -7,18 +7,22 @@ import (
|
|||
)
|
||||
|
||||
type Config struct {
|
||||
Title string `json:"title"`
|
||||
DatabaseType string `json:"database_type"`
|
||||
DatabaseDsn string `json:"database_dsn"`
|
||||
IDLength int `json:"id_length"`
|
||||
PasswordLength int `json:"password_length"`
|
||||
ExpirationInterval int `json:"expiration_interval"`
|
||||
ListenAddress string `json:"listen_address"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
Expirations []int `json:"expirations"`
|
||||
Expiration int `json:"expiration"`
|
||||
MaxUploadSize int64 `json:"max_upload_size"`
|
||||
ShowVersion bool `json:"show_version"`
|
||||
Title string `json:"title"`
|
||||
DatabaseType string `json:"database_type"`
|
||||
DatabaseDsn string `json:"database_dsn"`
|
||||
IDLength int `json:"id_length"`
|
||||
PasswordLength int `json:"password_length"`
|
||||
ExpirationInterval int `json:"expiration_interval"`
|
||||
ListenAddress string `json:"listen_address"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
Expirations []int `json:"expirations"`
|
||||
Expiration int `json:"expiration"`
|
||||
MaxUploadSize int64 `json:"max_upload_size"`
|
||||
ShowVersion bool `json:"show_version"`
|
||||
EnableMetrics bool `json:"enable_metrics"`
|
||||
PrometheusRoute string `json:"prometheus_route"`
|
||||
PrometheusNotesMetric string `json:"prometheus_notes_metric"`
|
||||
ObservationInterval int `json:"observation_internal"`
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
|
@ -38,9 +42,13 @@ func NewConfig() *Config {
|
|||
604800, // 7 days
|
||||
18144000, // 30 days
|
||||
},
|
||||
Expiration: 604800, // 7 days
|
||||
MaxUploadSize: 10485760, // 10MiB (encoded)
|
||||
ShowVersion: false,
|
||||
Expiration: 604800, // 7 days
|
||||
MaxUploadSize: 10485760, // 10MiB (encoded)
|
||||
ShowVersion: false,
|
||||
EnableMetrics: false,
|
||||
PrometheusRoute: "/metrics",
|
||||
PrometheusNotesMetric: "collerd_notes",
|
||||
ObservationInterval: 60,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
55
src/server/metrics.go
Normal file
55
src/server/metrics.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type Metrics struct {
|
||||
logger *slog.Logger
|
||||
notes prometheus.Gauge
|
||||
db *Database
|
||||
reg *prometheus.Registry
|
||||
interval int
|
||||
}
|
||||
|
||||
func NewMetrics(logger *slog.Logger, reg *prometheus.Registry, config *Config, db *Database) (*Metrics, error) {
|
||||
l := logger.With("module", "metrics")
|
||||
m := &Metrics{
|
||||
logger: l,
|
||||
db: db,
|
||||
notes: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: config.PrometheusNotesMetric,
|
||||
}),
|
||||
reg: reg,
|
||||
interval: config.ObservationInterval,
|
||||
}
|
||||
if err := reg.Register(m.notes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go m.ObserveThread()
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *Metrics) ObserveThread() {
|
||||
m.logger.Debug("starting observations")
|
||||
for {
|
||||
m.logger.Debug("counting notes")
|
||||
var count int64
|
||||
m.db.db.Model(&Note{}).Count(&count)
|
||||
m.notes.Set(float64(count))
|
||||
m.logger.Debug("counted notes", slog.Any("count", count))
|
||||
|
||||
wording := "second"
|
||||
if m.interval > 1 {
|
||||
wording += "s"
|
||||
}
|
||||
m.logger.Debug(fmt.Sprintf("waiting for %d %s before next observation", m.interval, wording))
|
||||
time.Sleep(time.Duration(m.interval) * time.Second)
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
"git.riou.xyz/jriou/coller/internal"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
var passwordLength = internal.MIN_PASSWORD_LENGTH
|
||||
|
@ -23,6 +24,7 @@ type Server struct {
|
|||
db *Database
|
||||
config *Config
|
||||
version string
|
||||
metrics *Metrics
|
||||
}
|
||||
|
||||
func NewServer(logger *slog.Logger, db *Database, config *Config, version string) (*Server, error) {
|
||||
|
@ -44,6 +46,10 @@ func (s *Server) SetPasswordLength(length int) {
|
|||
passwordLength = length
|
||||
}
|
||||
|
||||
func (s *Server) SetMetrics(metrics *Metrics) {
|
||||
s.metrics = metrics
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"message"`
|
||||
Error string `json:"error"`
|
||||
|
@ -312,8 +318,15 @@ var templatesFS embed.FS
|
|||
func (s *Server) Start() error {
|
||||
r := mux.NewRouter().StrictSlash(true)
|
||||
|
||||
// API
|
||||
// Healthchecks
|
||||
r.HandleFunc("/health", HealthHandler)
|
||||
|
||||
// Metrics
|
||||
if s.metrics != nil && s.metrics.reg != nil {
|
||||
r.Path(s.config.PrometheusRoute).Handler(promhttp.HandlerFor(s.metrics.reg, promhttp.HandlerOpts{Registry: s.metrics.reg})).Methods("GET")
|
||||
}
|
||||
|
||||
// API
|
||||
r.Path("/api/note").Handler(&CreateNoteHandler{logger: s.logger, db: s.db, maxUploadSize: s.config.MaxUploadSize}).Methods("POST")
|
||||
r.Path("/{id:[a-zA-Z0-9]+}/{password:[a-zA-Z0-9]+}").Handler(&GetProtectedNoteHandler{logger: s.logger, db: s.db}).Methods("GET")
|
||||
r.Path("/{id:[a-zA-Z0-9]+}").Handler(&GetNoteHandler{logger: s.logger, db: s.db}).Methods("GET")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue