diff options
Diffstat (limited to 'service')
-rw-r--r-- | service/httpd/httpd.go | 38 | ||||
-rw-r--r-- | service/scheduler/scheduler.go | 17 |
2 files changed, 51 insertions, 4 deletions
diff --git a/service/httpd/httpd.go b/service/httpd/httpd.go index aa9ceca3..36e97326 100644 --- a/service/httpd/httpd.go +++ b/service/httpd/httpd.go @@ -16,6 +16,7 @@ import ( "miniflux.app/api" "miniflux.app/config" "miniflux.app/fever" + "miniflux.app/http/request" "miniflux.app/logger" "miniflux.app/reader/feed" "miniflux.app/storage" @@ -24,6 +25,7 @@ import ( "miniflux.app/worker" "github.com/gorilla/mux" + "github.com/prometheus/client_golang/prometheus/promhttp" "golang.org/x/crypto/acme/autocert" ) @@ -186,9 +188,45 @@ func setupHandler(store *storage.Storage, feedHandler *feed.Handler, pool *worke router.HandleFunc("/healthcheck", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("OK")) }).Name("healthcheck") + router.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(version.Version)) }).Name("version") + if config.Opts.HasMetricsCollector() { + router.Handle("/metrics", promhttp.Handler()).Name("metrics") + router.Use(func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + route := mux.CurrentRoute(r) + + // Returns a 404 if the client is not authorized to access the metrics endpoint. + if route.GetName() == "metrics" && !isAllowedToAccessMetricsEndpoint(r) { + logger.Error(`[Metrics] Client not allowed: %s`, request.ClientIP(r)) + http.NotFound(w, r) + return + } + + next.ServeHTTP(w, r) + }) + }) + } + return router } + +func isAllowedToAccessMetricsEndpoint(r *http.Request) bool { + clientIP := net.ParseIP(request.ClientIP(r)) + + for _, cidr := range config.Opts.MetricsAllowedNetworks() { + _, network, err := net.ParseCIDR(cidr) + if err != nil { + logger.Fatal(`[Metrics] Unable to parse CIDR %v`, err) + } + + if network.Contains(clientIP) { + return true + } + } + + return false +} diff --git a/service/scheduler/scheduler.go b/service/scheduler/scheduler.go index 9e822705..6ec55279 100644 --- a/service/scheduler/scheduler.go +++ b/service/scheduler/scheduler.go @@ -9,6 +9,7 @@ import ( "miniflux.app/config" "miniflux.app/logger" + "miniflux.app/metric" "miniflux.app/model" "miniflux.app/storage" "miniflux.app/worker" @@ -35,8 +36,7 @@ func Serve(store *storage.Storage, pool *worker.Pool) { } func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency, batchSize int) { - c := time.Tick(time.Duration(frequency) * time.Minute) - for range c { + for range time.Tick(time.Duration(frequency) * time.Minute) { jobs, err := store.NewBatch(batchSize) if err != nil { logger.Error("[Scheduler:Feed] %v", err) @@ -48,22 +48,31 @@ func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency, batchSi } func cleanupScheduler(store *storage.Storage, frequency, archiveReadDays, archiveUnreadDays, sessionsDays int) { - c := time.Tick(time.Duration(frequency) * time.Hour) - for range c { + for range time.Tick(time.Duration(frequency) * time.Hour) { nbSessions := store.CleanOldSessions(sessionsDays) nbUserSessions := store.CleanOldUserSessions(sessionsDays) logger.Info("[Scheduler:Cleanup] Cleaned %d sessions and %d user sessions", nbSessions, nbUserSessions) + startTime := time.Now() if rowsAffected, err := store.ArchiveEntries(model.EntryStatusRead, archiveReadDays); err != nil { logger.Error("[Scheduler:ArchiveReadEntries] %v", err) } else { logger.Info("[Scheduler:ArchiveReadEntries] %d entries changed", rowsAffected) + + if config.Opts.HasMetricsCollector() { + metric.ArchiveEntriesDuration.WithLabelValues(model.EntryStatusRead).Observe(time.Since(startTime).Seconds()) + } } + startTime = time.Now() if rowsAffected, err := store.ArchiveEntries(model.EntryStatusUnread, archiveUnreadDays); err != nil { logger.Error("[Scheduler:ArchiveUnreadEntries] %v", err) } else { logger.Info("[Scheduler:ArchiveUnreadEntries] %d entries changed", rowsAffected) + + if config.Opts.HasMetricsCollector() { + metric.ArchiveEntriesDuration.WithLabelValues(model.EntryStatusUnread).Observe(time.Since(startTime).Seconds()) + } } } } |