summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/httpd/httpd.go38
-rw-r--r--service/scheduler/scheduler.go17
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())
+ }
}
}
}