1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-17 09:37:02 +00:00

ui: Display server uptime, scan completion time

This commit is contained in:
James Hillyerd
2018-12-10 20:54:02 -08:00
parent 9b3049562d
commit fc5cc4d864
4 changed files with 52 additions and 35 deletions

View File

@@ -40,10 +40,8 @@ var (
func init() { func init() {
// Server uptime for status page. // Server uptime for status page.
startTime := time.Now() startTime := expvar.NewInt("startMillis")
expvar.Publish("uptime", expvar.Func(func() interface{} { startTime.Set(time.Now().UnixNano() / 1000000)
return time.Since(startTime) / time.Second
}))
// Goroutine count for status page. // Goroutine count for status page.
expvar.Publish("goroutines", expvar.Func(func() interface{} { expvar.Publish("goroutines", expvar.Func(func() interface{} {

View File

@@ -3,7 +3,6 @@ package storage
import ( import (
"container/list" "container/list"
"expvar" "expvar"
"sync"
"time" "time"
"github.com/jhillyerd/inbucket/pkg/config" "github.com/jhillyerd/inbucket/pkg/config"
@@ -12,8 +11,7 @@ import (
) )
var ( var (
retentionScanCompleted = time.Now() scanCompletedMillis = new(expvar.Int)
retentionScanCompletedMu sync.RWMutex
// History counters // History counters
expRetentionDeletesTotal = new(expvar.Int) expRetentionDeletesTotal = new(expvar.Int)
@@ -34,7 +32,7 @@ var (
func init() { func init() {
rm := expvar.NewMap("retention") rm := expvar.NewMap("retention")
rm.Set("SecondsSinceScanCompleted", expvar.Func(secondsSinceRetentionScanCompleted)) rm.Set("ScanCompletedMillis", scanCompletedMillis)
rm.Set("DeletesHist", expRetentionDeletesHist) rm.Set("DeletesHist", expRetentionDeletesHist)
rm.Set("DeletesTotal", expRetentionDeletesTotal) rm.Set("DeletesTotal", expRetentionDeletesTotal)
rm.Set("Period", expRetentionPeriod) rm.Set("Period", expRetentionPeriod)
@@ -159,7 +157,7 @@ func (rs *RetentionScanner) DoScan() error {
return err return err
} }
// Update metrics // Update metrics
setRetentionScanCompleted(time.Now()) scanCompletedMillis.Set(time.Now().UnixNano() / 1000000)
expRetainedCurrent.Set(int64(retained)) expRetainedCurrent.Set(int64(retained))
expRetainedSize.Set(storeSize) expRetainedSize.Set(storeSize)
return nil return nil
@@ -171,19 +169,3 @@ func (rs *RetentionScanner) Join() {
<-rs.retentionShutdown <-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
}

View File

@@ -1,11 +1,14 @@
module Data.Metrics exposing (Metrics, decodeIntList, decoder) module Data.Metrics exposing (Metrics, decodeIntList, decoder)
import Data.Date exposing (date)
import Json.Decode as Decode exposing (..) import Json.Decode as Decode exposing (..)
import Json.Decode.Pipeline exposing (..) import Json.Decode.Pipeline exposing (..)
import Time exposing (Posix)
type alias Metrics = type alias Metrics =
{ sysMem : Int { startTime : Posix
, sysMem : Int
, heapSize : Int , heapSize : Int
, heapUsed : Int , heapUsed : Int
, heapObjects : Int , heapObjects : Int
@@ -26,12 +29,14 @@ type alias Metrics =
, retainedCountHist : List Int , retainedCountHist : List Int
, retainedSize : Int , retainedSize : Int
, retainedSizeHist : List Int , retainedSizeHist : List Int
, scanCompleted : Posix
} }
decoder : Decoder Metrics decoder : Decoder Metrics
decoder = decoder =
succeed Metrics succeed Metrics
|> requiredAt [ "startMillis" ] date
|> requiredAt [ "memstats", "Sys" ] int |> requiredAt [ "memstats", "Sys" ] int
|> requiredAt [ "memstats", "HeapSys" ] int |> requiredAt [ "memstats", "HeapSys" ] int
|> requiredAt [ "memstats", "HeapAlloc" ] int |> requiredAt [ "memstats", "HeapAlloc" ] int
@@ -53,6 +58,7 @@ decoder =
|> requiredAt [ "retention", "RetainedHist" ] decodeIntList |> requiredAt [ "retention", "RetainedHist" ] decodeIntList
|> requiredAt [ "retention", "RetainedSize" ] int |> requiredAt [ "retention", "RetainedSize" ] int
|> requiredAt [ "retention", "SizeHist" ] decodeIntList |> requiredAt [ "retention", "SizeHist" ] decodeIntList
|> requiredAt [ "retention", "ScanCompletedMillis" ] date
{-| Decodes Inbuckets hacky comma-separated-int JSON strings. {-| Decodes Inbuckets hacky comma-separated-int JSON strings.

View File

@@ -3,6 +3,7 @@ module Page.Status exposing (Model, Msg, init, subscriptions, update, view)
import Data.Metrics as Metrics exposing (Metrics) import Data.Metrics as Metrics exposing (Metrics)
import Data.ServerConfig as ServerConfig exposing (ServerConfig) import Data.ServerConfig as ServerConfig exposing (ServerConfig)
import Data.Session as Session exposing (Session) import Data.Session as Session exposing (Session)
import DateFormat.Relative as Relative
import Filesize import Filesize
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
@@ -10,6 +11,7 @@ import Http exposing (Error)
import HttpUtil import HttpUtil
import Sparkline as Spark import Sparkline as Spark
import Svg.Attributes as SvgAttrib import Svg.Attributes as SvgAttrib
import Task
import Time exposing (Posix) import Time exposing (Posix)
@@ -18,7 +20,8 @@ import Time exposing (Posix)
type alias Model = type alias Model =
{ config : Maybe ServerConfig { now : Posix
, config : Maybe ServerConfig
, metrics : Maybe Metrics , metrics : Maybe Metrics
, xCounter : Float , xCounter : Float
, sysMem : Metric , sysMem : Metric
@@ -50,7 +53,8 @@ type alias Metric =
init : ( Model, Cmd Msg, Session.Msg ) init : ( Model, Cmd Msg, Session.Msg )
init = init =
( { config = Nothing ( { now = Time.millisToPosix 0
, config = Nothing
, metrics = Nothing , metrics = Nothing
, xCounter = 60 , xCounter = 60
, sysMem = Metric "System Memory" 0 Filesize.format graphZero initDataSet 10 , sysMem = Metric "System Memory" 0 Filesize.format graphZero initDataSet 10
@@ -62,13 +66,16 @@ init =
, smtpConnOpen = Metric "Open Connections" 0 fmtInt graphZero initDataSet 10 , smtpConnOpen = Metric "Open Connections" 0 fmtInt graphZero initDataSet 10
, smtpConnTotal = Metric "Total Connections" 0 fmtInt graphChange initDataSet 60 , smtpConnTotal = Metric "Total Connections" 0 fmtInt graphChange initDataSet 60
, smtpReceivedTotal = Metric "Messages Received" 0 fmtInt graphChange initDataSet 60 , smtpReceivedTotal = Metric "Messages Received" 0 fmtInt graphChange initDataSet 60
, smtpErrorsTotal = Metric "Messages Errors" 0 fmtInt graphChange initDataSet 60 , smtpErrorsTotal = Metric "Message Errors" 0 fmtInt graphChange initDataSet 60
, smtpWarnsTotal = Metric "Messages Warns" 0 fmtInt graphChange initDataSet 60 , smtpWarnsTotal = Metric "Message Warnings" 0 fmtInt graphChange initDataSet 60
, retentionDeletesTotal = Metric "Retention Deletes" 0 fmtInt graphChange initDataSet 60 , retentionDeletesTotal = Metric "Retention Deletes" 0 fmtInt graphChange initDataSet 60
, retainedCount = Metric "Stored Messages" 0 fmtInt graphZero initDataSet 60 , retainedCount = Metric "Stored Messages" 0 fmtInt graphZero initDataSet 60
, retainedSize = Metric "Store Size" 0 Filesize.format 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 , Session.none
) )
@@ -114,7 +121,7 @@ update session msg model =
( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) ) ( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) )
Tick time -> Tick time ->
( model, loadMetrics, Session.none ) ( { model | now = time }, loadMetrics, Session.none )
{-| Update all metrics in Model; increment xCounter. {-| Update all metrics in Model; increment xCounter.
@@ -343,9 +350,12 @@ metricPanels model =
Nothing -> Nothing ->
[ text "Loading metrics..." ] [ text "Loading metrics..." ]
Just _ -> Just metrics ->
[ framePanel "General Metrics" [ framePanel "General Metrics"
[ viewMetric model.sysMem [ textEntry "Uptime" <|
"Started "
++ Relative.relativeTime model.now metrics.startTime
, viewMetric model.sysMem
, viewMetric model.heapSize , viewMetric model.heapSize
, viewMetric model.heapUsed , viewMetric model.heapUsed
, viewMetric model.heapObjects , viewMetric model.heapObjects
@@ -360,13 +370,34 @@ metricPanels model =
, viewMetric model.smtpWarnsTotal , viewMetric model.smtpWarnsTotal
] ]
, framePanel "Storage Metrics" , framePanel "Storage Metrics"
[ viewMetric model.retentionDeletesTotal [ textEntry "Retention Scan" (retentionScan model)
, viewMetric model.retentionDeletesTotal
, viewMetric model.retainedCount , viewMetric model.retainedCount
, viewMetric model.retainedSize , 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 : String -> String -> Html Msg
textEntry name value = textEntry name value =
div [ class "metric" ] div [ class "metric" ]