1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-19 18:47:03 +00:00

Metrics improvements

- Label graphs by their duration, not update period
- Extend to 60 units so they are either 10 minutes or an hour of data
- Improvements to retention information
- Change javascript calculations, fixes #9 (I hope)
This commit is contained in:
James Hillyerd
2012-11-14 17:22:25 -08:00
parent 2ba9eaa779
commit afe14da506
5 changed files with 48 additions and 21 deletions

View File

@@ -104,11 +104,12 @@ func metricsTicker(t *time.Ticker) {
}
}
// pushMetric adds the metric to the end of the list and returns a comma
// separated string of the previous 50 entries
// pushMetric adds the metric to the end of the list and returns a comma separated string of the
// previous 61 entries. We return 61 instead of 60 (an hour) because the chart on the client
// tracks deltas between these values - there is nothing to compare the first value against.
func pushMetric(history *list.List, ev expvar.Var) string {
history.PushBack(ev.String())
if history.Len() > 50 {
if history.Len() > 61 {
history.Remove(history.Front())
}
return JoinStringList(history)

View File

@@ -13,6 +13,7 @@ var retentionScanCompleted time.Time
var retentionScanCompletedMu sync.RWMutex
var expRetentionDeletesTotal = new(expvar.Int)
var expRetentionPeriod = new(expvar.Int)
// History of certain stats
var retentionDeletesHist = list.New()
@@ -22,6 +23,7 @@ var expRetentionDeletesHist = new(expvar.String)
func StartRetentionScanner(ds DataStore) {
cfg := config.GetDataStoreConfig()
expRetentionPeriod.Set(int64(cfg.RetentionMinutes * 60))
if cfg.RetentionMinutes > 0 {
// Retention scanning enabled
log.Info("Retention configured for %v minutes", cfg.RetentionMinutes)
@@ -109,4 +111,5 @@ func init() {
rm.Set("SecondsSinceScanCompleted", expvar.Func(secondsSinceRetentionScanCompleted))
rm.Set("DeletesHist", expRetentionDeletesHist)
rm.Set("DeletesTotal", expRetentionDeletesTotal)
rm.Set("Period", expRetentionPeriod)
}

View File

@@ -325,7 +325,7 @@ table.metrics {
}
.metrics td.sparkline {
width: 170px;
width: 200px;
}
#emailAttachments {

View File

@@ -42,8 +42,8 @@
h = new Array(0)
}
// Prevent array from growing
if (h.length >= 50) {
h = h.slice(1,50)
if (h.length >= 60) {
h = h.slice(1,60)
}
h.push(parseInt(value))
dataHist[name] = h
@@ -61,6 +61,10 @@
h[i] = t-prev
prev = t
}
// First value will always be zero
if (h.length > 0) {
h = h.slice(1)
}
el = $('#s-' + name)
if (el) {
el.sparkline(h)
@@ -86,6 +90,7 @@
// Non graphing
metric('uptime', data.uptime, timeFilter, false)
metric('retentionScanCompleted', data.retention.SecondsSinceScanCompleted, timeFilter, false)
metric('retentionPeriod', data.retention.Period, timeFilter, false)
// JavaScript history
metric('memstatsSys', data.memstats.Sys, sizeFilter, true)
@@ -114,7 +119,7 @@
function aboutInit() {
loadMetrics()
setInterval(loadMetrics, 5000)
setInterval(loadMetrics, 10000)
}
$(document).ready(aboutInit)
@@ -131,9 +136,8 @@
{{define "content"}}
<h2>Inbucket Status</h2>
<p>Metrics are polled every 5 seconds. Inbucket does not keep history for the
graphs labeled <em>(5s)</em>, but your web browser will chart the last 50
values over time.</p>
<p>Metrics are polled every 10 seconds. Inbucket does not keep history for the
10 minute graphs, but your web browser will accumulate the data over time.</p>
<div class="box">
<h3>General Metrics</h3>
@@ -146,25 +150,25 @@ values over time.</p>
<th>System Memory:</th>
<td><span id="m-memstatsSys">.</span></td>
<td class="sparkline"><span id="s-memstatsSys">.</span></td>
<td>(5s)</td>
<td>(10min)</td>
</tr>
<tr>
<th>Heap Size:</th>
<td><span id="m-memstatsHeapSys">.</span></td>
<td class="sparkline"><span id="s-memstatsHeapSys">.</span></td>
<td>(5s)</td>
<td>(10min)</td>
</tr>
<tr>
<th>Heap In-Use:</th>
<td><span id="m-memstatsHeapAlloc">.</span></td>
<td class="sparkline"><span id="s-memstatsHeapAlloc">.</span></td>
<td>(5s)</td>
<td>(10min)</td>
</tr>
<tr>
<th>Heap # Objects:</th>
<td><span id="m-memstatsHeapObjects">.</span></td>
<td class="sparkline"><span id="s-memstatsHeapObjects">.</span></td>
<td>(5s)</td>
<td>(10min)</td>
</tr>
</table>
<p class="last">&nbsp;</p>
@@ -176,31 +180,31 @@ values over time.</p>
<th>Current Connections:</th>
<td><span id="m-smtpConnectsCurrent">.</span></td>
<td class="sparkline"><span id="s-smtpConnectsCurrent">.</span></td>
<td>(5s)</td>
<td>(10min)</td>
</tr>
<tr>
<th>Total Connections:</th>
<td><span id="m-smtpConnectsTotal">.</span></td>
<td class="sparkline"><span id="s-smtpConnectsTotal">.</span></td>
<td>(60s)</td>
<td>(60min)</td>
</tr>
<tr>
<th>Messages Delivered:</th>
<td><span id="m-smtpDeliveredTotal">.</span></td>
<td class="sparkline"><span id="s-smtpDeliveredTotal">.</span></td>
<td>(60s)</td>
<td>(60min)</td>
</tr>
<tr>
<th>Errors Logged:</th>
<td><span id="m-smtpErrorsTotal">.</span></td>
<td class="sparkline"><span id="s-smtpErrorsTotal"></span></td>
<td>(60s)</td>
<td>(60min)</td>
</tr>
<tr>
<th>Warnings Logged:</th>
<td><span id="m-smtpWarnsTotal">.</span></td>
<td class="sparkline"><span id="s-smtpWarnsTotal"></span></td>
<td>(60s)</td>
<td>(60min)</td>
</tr>
</table>
<p class="last">&nbsp;</p>
@@ -208,15 +212,31 @@ values over time.</p>
<div class="box">
<h3>Data Store Metrics</h3>
<table class="metrics">
<tr>
<th>Retention Period:</th>
<td colspan="3">
{{if .retentionMinutes}}
<span id="m-retentionPeriod">.</span>
{{else}}
Disabled
{{end}}
</td>
</tr>
<tr>
<th>Retention Scan:</th>
<td colspan="3">Completed <span id="m-retentionScanCompleted">.</span> ago</td>
<td colspan="3">
{{if .retentionMinutes}}
Completed <span id="m-retentionScanCompleted">.</span> ago
{{else}}
Disabled
{{end}}
</td>
</tr>
<tr>
<th>Retention Deletes:</th>
<td><span id="m-retentionDeletesTotal">.</span></td>
<td class="sparkline"><span id="s-retentionDeletesTotal"></span></td>
<td>(60s)</td>
<td>(60min)</td>
</tr>
</table>
<p class="last">&nbsp;</p>

View File

@@ -1,6 +1,7 @@
package web
import (
"github.com/jhillyerd/inbucket/config"
"net/http"
)
@@ -11,7 +12,9 @@ func RootIndex(w http.ResponseWriter, req *http.Request, ctx *Context) (err erro
}
func RootStatus(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) {
retentionMinutes := config.GetDataStoreConfig().RetentionMinutes
return RenderTemplate("root/status.html", w, map[string]interface{}{
"ctx": ctx,
"retentionMinutes": retentionMinutes,
})
}