mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
ui: Display server uptime, scan completion time
This commit is contained in:
@@ -40,10 +40,8 @@ var (
|
||||
|
||||
func init() {
|
||||
// Server uptime for status page.
|
||||
startTime := time.Now()
|
||||
expvar.Publish("uptime", expvar.Func(func() interface{} {
|
||||
return time.Since(startTime) / time.Second
|
||||
}))
|
||||
startTime := expvar.NewInt("startMillis")
|
||||
startTime.Set(time.Now().UnixNano() / 1000000)
|
||||
|
||||
// Goroutine count for status page.
|
||||
expvar.Publish("goroutines", expvar.Func(func() interface{} {
|
||||
|
||||
@@ -3,7 +3,6 @@ package storage
|
||||
import (
|
||||
"container/list"
|
||||
"expvar"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/jhillyerd/inbucket/pkg/config"
|
||||
@@ -12,8 +11,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
retentionScanCompleted = time.Now()
|
||||
retentionScanCompletedMu sync.RWMutex
|
||||
scanCompletedMillis = new(expvar.Int)
|
||||
|
||||
// History counters
|
||||
expRetentionDeletesTotal = new(expvar.Int)
|
||||
@@ -34,7 +32,7 @@ var (
|
||||
|
||||
func init() {
|
||||
rm := expvar.NewMap("retention")
|
||||
rm.Set("SecondsSinceScanCompleted", expvar.Func(secondsSinceRetentionScanCompleted))
|
||||
rm.Set("ScanCompletedMillis", scanCompletedMillis)
|
||||
rm.Set("DeletesHist", expRetentionDeletesHist)
|
||||
rm.Set("DeletesTotal", expRetentionDeletesTotal)
|
||||
rm.Set("Period", expRetentionPeriod)
|
||||
@@ -159,7 +157,7 @@ func (rs *RetentionScanner) DoScan() error {
|
||||
return err
|
||||
}
|
||||
// Update metrics
|
||||
setRetentionScanCompleted(time.Now())
|
||||
scanCompletedMillis.Set(time.Now().UnixNano() / 1000000)
|
||||
expRetainedCurrent.Set(int64(retained))
|
||||
expRetainedSize.Set(storeSize)
|
||||
return nil
|
||||
@@ -171,19 +169,3 @@ func (rs *RetentionScanner) Join() {
|
||||
<-rs.retentionShutdown
|
||||
}
|
||||
}
|
||||
|
||||
func setRetentionScanCompleted(t time.Time) {
|
||||
retentionScanCompletedMu.Lock()
|
||||
defer retentionScanCompletedMu.Unlock()
|
||||
retentionScanCompleted = t
|
||||
}
|
||||
|
||||
func getRetentionScanCompleted() time.Time {
|
||||
retentionScanCompletedMu.RLock()
|
||||
defer retentionScanCompletedMu.RUnlock()
|
||||
return retentionScanCompleted
|
||||
}
|
||||
|
||||
func secondsSinceRetentionScanCompleted() interface{} {
|
||||
return time.Since(getRetentionScanCompleted()) / time.Second
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
module Data.Metrics exposing (Metrics, decodeIntList, decoder)
|
||||
|
||||
import Data.Date exposing (date)
|
||||
import Json.Decode as Decode exposing (..)
|
||||
import Json.Decode.Pipeline exposing (..)
|
||||
import Time exposing (Posix)
|
||||
|
||||
|
||||
type alias Metrics =
|
||||
{ sysMem : Int
|
||||
{ startTime : Posix
|
||||
, sysMem : Int
|
||||
, heapSize : Int
|
||||
, heapUsed : Int
|
||||
, heapObjects : Int
|
||||
@@ -26,12 +29,14 @@ type alias Metrics =
|
||||
, retainedCountHist : List Int
|
||||
, retainedSize : Int
|
||||
, retainedSizeHist : List Int
|
||||
, scanCompleted : Posix
|
||||
}
|
||||
|
||||
|
||||
decoder : Decoder Metrics
|
||||
decoder =
|
||||
succeed Metrics
|
||||
|> requiredAt [ "startMillis" ] date
|
||||
|> requiredAt [ "memstats", "Sys" ] int
|
||||
|> requiredAt [ "memstats", "HeapSys" ] int
|
||||
|> requiredAt [ "memstats", "HeapAlloc" ] int
|
||||
@@ -53,6 +58,7 @@ decoder =
|
||||
|> requiredAt [ "retention", "RetainedHist" ] decodeIntList
|
||||
|> requiredAt [ "retention", "RetainedSize" ] int
|
||||
|> requiredAt [ "retention", "SizeHist" ] decodeIntList
|
||||
|> requiredAt [ "retention", "ScanCompletedMillis" ] date
|
||||
|
||||
|
||||
{-| Decodes Inbuckets hacky comma-separated-int JSON strings.
|
||||
|
||||
@@ -3,6 +3,7 @@ module Page.Status exposing (Model, Msg, init, subscriptions, update, view)
|
||||
import Data.Metrics as Metrics exposing (Metrics)
|
||||
import Data.ServerConfig as ServerConfig exposing (ServerConfig)
|
||||
import Data.Session as Session exposing (Session)
|
||||
import DateFormat.Relative as Relative
|
||||
import Filesize
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
@@ -10,6 +11,7 @@ import Http exposing (Error)
|
||||
import HttpUtil
|
||||
import Sparkline as Spark
|
||||
import Svg.Attributes as SvgAttrib
|
||||
import Task
|
||||
import Time exposing (Posix)
|
||||
|
||||
|
||||
@@ -18,7 +20,8 @@ import Time exposing (Posix)
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ config : Maybe ServerConfig
|
||||
{ now : Posix
|
||||
, config : Maybe ServerConfig
|
||||
, metrics : Maybe Metrics
|
||||
, xCounter : Float
|
||||
, sysMem : Metric
|
||||
@@ -50,7 +53,8 @@ type alias Metric =
|
||||
|
||||
init : ( Model, Cmd Msg, Session.Msg )
|
||||
init =
|
||||
( { config = Nothing
|
||||
( { now = Time.millisToPosix 0
|
||||
, config = Nothing
|
||||
, metrics = Nothing
|
||||
, xCounter = 60
|
||||
, sysMem = Metric "System Memory" 0 Filesize.format graphZero initDataSet 10
|
||||
@@ -62,13 +66,16 @@ init =
|
||||
, smtpConnOpen = Metric "Open Connections" 0 fmtInt graphZero initDataSet 10
|
||||
, smtpConnTotal = Metric "Total Connections" 0 fmtInt graphChange initDataSet 60
|
||||
, smtpReceivedTotal = Metric "Messages Received" 0 fmtInt graphChange initDataSet 60
|
||||
, smtpErrorsTotal = Metric "Messages Errors" 0 fmtInt graphChange initDataSet 60
|
||||
, smtpWarnsTotal = Metric "Messages Warns" 0 fmtInt graphChange initDataSet 60
|
||||
, smtpErrorsTotal = Metric "Message Errors" 0 fmtInt graphChange initDataSet 60
|
||||
, smtpWarnsTotal = Metric "Message Warnings" 0 fmtInt graphChange initDataSet 60
|
||||
, retentionDeletesTotal = Metric "Retention Deletes" 0 fmtInt graphChange initDataSet 60
|
||||
, retainedCount = Metric "Stored Messages" 0 fmtInt graphZero initDataSet 60
|
||||
, retainedSize = Metric "Store Size" 0 Filesize.format graphZero initDataSet 60
|
||||
}
|
||||
, Cmd.batch [ loadServerConfig, loadMetrics ]
|
||||
, Cmd.batch
|
||||
[ Task.perform Tick Time.now
|
||||
, loadServerConfig
|
||||
]
|
||||
, Session.none
|
||||
)
|
||||
|
||||
@@ -114,7 +121,7 @@ update session msg model =
|
||||
( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) )
|
||||
|
||||
Tick time ->
|
||||
( model, loadMetrics, Session.none )
|
||||
( { model | now = time }, loadMetrics, Session.none )
|
||||
|
||||
|
||||
{-| Update all metrics in Model; increment xCounter.
|
||||
@@ -343,9 +350,12 @@ metricPanels model =
|
||||
Nothing ->
|
||||
[ text "Loading metrics..." ]
|
||||
|
||||
Just _ ->
|
||||
Just metrics ->
|
||||
[ framePanel "General Metrics"
|
||||
[ viewMetric model.sysMem
|
||||
[ textEntry "Uptime" <|
|
||||
"Started "
|
||||
++ Relative.relativeTime model.now metrics.startTime
|
||||
, viewMetric model.sysMem
|
||||
, viewMetric model.heapSize
|
||||
, viewMetric model.heapUsed
|
||||
, viewMetric model.heapObjects
|
||||
@@ -360,13 +370,34 @@ metricPanels model =
|
||||
, viewMetric model.smtpWarnsTotal
|
||||
]
|
||||
, framePanel "Storage Metrics"
|
||||
[ viewMetric model.retentionDeletesTotal
|
||||
[ textEntry "Retention Scan" (retentionScan model)
|
||||
, viewMetric model.retentionDeletesTotal
|
||||
, viewMetric model.retainedCount
|
||||
, viewMetric model.retainedSize
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
retentionScan : Model -> String
|
||||
retentionScan model =
|
||||
case ( model.config, model.metrics ) of
|
||||
( Just config, Just metrics ) ->
|
||||
case config.storageConfig.retentionPeriod of
|
||||
"" ->
|
||||
"Disabled"
|
||||
|
||||
_ ->
|
||||
case Time.posixToMillis metrics.scanCompleted of
|
||||
0 ->
|
||||
"Not completed"
|
||||
|
||||
_ ->
|
||||
"Completed " ++ Relative.relativeTime model.now metrics.scanCompleted
|
||||
|
||||
( _, _ ) ->
|
||||
"No data"
|
||||
|
||||
|
||||
textEntry : String -> String -> Html Msg
|
||||
textEntry name value =
|
||||
div [ class "metric" ]
|
||||
|
||||
Reference in New Issue
Block a user