initial commit
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
{{define "content"}}
|
||||
{{$c := .Data.Stats}}{{$csrf := .CSRF}}
|
||||
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-4">
|
||||
<div>
|
||||
<h1 class="page-title">Cache</h1>
|
||||
<p class="text-body-secondary mb-0">Responses held in memory to answer repeat queries instantly.</p>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<a href="/settings/cache" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="bi bi-gear me-1"></i>Cache settings
|
||||
</a>
|
||||
{{template "confirmform" dict
|
||||
"Action" "/cache/flush" "CSRF" $csrf
|
||||
"Label" "Flush entire cache" "Icon" "bi-trash"
|
||||
"Class" "btn btn-sm btn-danger"
|
||||
"Message" "Flush every cached response? Queries will go back upstream until the cache refills."}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if not $c.Enabled}}
|
||||
<div class="alert alert-secondary d-flex align-items-center gap-2">
|
||||
<i class="bi bi-info-circle"></i>
|
||||
<div>The cache is turned off. Every recursive query is forwarded upstream.</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
{{template "stat" dict "Label" "Entries" "Value" (num $c.Entries) "Icon" "bi-database"
|
||||
"Sub" (printf "limit %s" (num $c.MaxEntries))}}
|
||||
{{template "stat" dict "Label" "Hit rate" "Value" (pct $c.HitRate) "Icon" "bi-lightning-charge" "Tone" "success"}}
|
||||
{{template "stat" dict "Label" "Hits" "Value" (num $c.Hits) "Icon" "bi-check-circle" "Tone" "success"
|
||||
"Sub" (printf "%s served stale" (num $c.StaleHits))}}
|
||||
{{template "stat" dict "Label" "Misses" "Value" (num $c.Misses) "Icon" "bi-x-circle"}}
|
||||
{{template "stat" dict "Label" "Memory estimate" "Value" (bytes $c.Bytes) "Icon" "bi-memory"}}
|
||||
{{template "stat" dict "Label" "Insertions" "Value" (num $c.Insertions) "Icon" "bi-box-arrow-in-down"}}
|
||||
{{template "stat" dict "Label" "Evictions" "Value" (num $c.Evictions) "Icon" "bi-box-arrow-up"
|
||||
"Sub" "least recently used first"}}
|
||||
{{template "stat" dict "Label" "Expirations" "Value" (num $c.Expirations) "Icon" "bi-hourglass-bottom"}}
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header d-flex flex-wrap justify-content-between align-items-center gap-2">
|
||||
<span>Cached entries</span>
|
||||
<span class="small text-body-secondary">
|
||||
TTL clamped to {{$c.MinTTL}}–{{$c.MaxTTL}}s · negative {{$c.NegativeTTL}}s
|
||||
{{if $c.ServeStale}}· serves stale for {{$c.StaleTTL}}s{{end}}
|
||||
{{if $c.Prefetch}}· prefetch on{{end}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="get" data-autosubmit class="row g-2 align-items-center mb-3">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
||||
<input type="search" class="form-control" name="q" value="{{.Data.Search}}"
|
||||
placeholder="Search cached names..." aria-label="Search cached entries">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<noscript><button class="btn btn-sm btn-outline-secondary" type="submit">Search</button></noscript>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{{if .Data.Entries}}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle table-compact">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th><th>Type</th><th>Result</th>
|
||||
<th class="text-end">Answers</th><th class="text-end">TTL left</th>
|
||||
<th class="text-end">Size</th><th>Cached</th><th class="row-actions">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Data.Entries}}
|
||||
<tr {{if .Stale}}class="is-disabled"{{end}}>
|
||||
<td class="mono truncate-cell" title="{{.Name}}">{{trimDot .Name}}</td>
|
||||
<td>
|
||||
<span class="type-chip {{typeBadge .Type}}">{{.Type}}</span>
|
||||
{{if .DO}}<span class="badge text-bg-light text-dark ms-1" title="DNSSEC answer">+do</span>{{end}}
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {{rcodeBadge .Rcode}}">{{.Rcode}}</span>
|
||||
{{if .Negative}}<span class="badge text-bg-light text-dark ms-1">negative</span>{{end}}
|
||||
</td>
|
||||
<td class="text-end">{{.Answers}}</td>
|
||||
<td class="text-end">
|
||||
{{if .Stale}}<span class="text-warning">stale</span>{{else}}{{.TTL}}s{{end}}
|
||||
</td>
|
||||
<td class="text-end small text-body-secondary">{{bytes .Size}}</td>
|
||||
<td class="small text-body-secondary">{{timeAgo .Stored}}</td>
|
||||
<td class="row-actions">
|
||||
{{template "confirmform" dict
|
||||
"Action" "/cache/delete" "CSRF" $csrf
|
||||
"Icon" "bi-trash" "Title" "Remove this entry"
|
||||
"Fields" (dict "name" .Name "type" .Type "dnssec" (boolstr .DO))
|
||||
"Message" (printf "Remove the cached %s answer for %s?" .Type (trimDot .Name))}}
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{template "pagination" dict "P" .Data.Pagination "Q" .Query}}
|
||||
|
||||
{{else if .Data.Search}}
|
||||
{{template "empty" dict "Icon" "bi-search" "Title" "Nothing cached matches that name"
|
||||
"Message" "The entry may have expired, or the name may never have been queried."}}
|
||||
{{else}}
|
||||
{{template "empty" dict "Icon" "bi-lightning-charge" "Title" "The cache is empty"
|
||||
"Message" "Recursive answers are cached here as clients query them."}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user