Rename the collector-picker concept to 'collector' throughout the frontend so it no longer collides with the ipng_source_tag group-by (which is labelled 'source'). Affects PageData.Collector, the raw JSON output key, template labels, and tests. Proto Source field is untouched (wire-level name used by CLI and aggregator too). Shrink tab padding/gap/font-size and add window:/filter: labels so the four tab rows (window, filter, collector, tor) line up and 7+ collectors fit on one line at the 1100px body width. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
98 lines
2.8 KiB
HTML
98 lines
2.8 KiB
HTML
{{define "content"}}
|
||
<h1>nginx-logtail</h1>
|
||
|
||
<div class="tabs">
|
||
<span class="tabs-label">window:</span>
|
||
{{- range .Windows}}
|
||
<a href="{{.URL}}"{{if .Active}} class="active"{{end}}>{{.Label}}</a>
|
||
{{- end}}
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<span class="tabs-label">filter:</span>
|
||
{{- range .GroupBys}}
|
||
<a href="{{.URL}}"{{if .Active}} class="active"{{end}}>{{.Label}}</a>
|
||
{{- end}}
|
||
</div>
|
||
|
||
{{if .Targets}}<div class="tabs tabs-targets">
|
||
<span class="tabs-label">collector:</span>
|
||
{{- range .Targets}}
|
||
<a href="{{.URL}}"{{if .Active}} class="active"{{end}}>{{.Label}}</a>
|
||
{{- end}}
|
||
</div>{{end}}
|
||
|
||
<div class="tabs tabs-tor">
|
||
<span class="tabs-label">tor:</span>
|
||
{{- range .TorTabs}}
|
||
<a href="{{.URL}}"{{if .Active}} class="active"{{end}}>{{.Label}}</a>
|
||
{{- end}}
|
||
</div>
|
||
|
||
<form class="filter-form" method="get" action="/">
|
||
<input type="hidden" name="target" value="{{.Params.Target}}">
|
||
<input type="hidden" name="w" value="{{.Params.WindowS}}">
|
||
<input type="hidden" name="by" value="{{.Params.GroupByS}}">
|
||
<input type="hidden" name="n" value="{{.Params.N}}">
|
||
<input class="filter-input" type="text" name="q" value="{{.FilterExpr}}" placeholder="status>=400 AND website!~=^gouda.* AND uri~=^/ct/v1/ AND is_tor=0 AND asn=8298">
|
||
<button type="submit">filter</button>
|
||
{{- if .FilterExpr}} <a class="clear" href="{{.ClearFilterURL}}">× clear</a>{{end}}
|
||
</form>
|
||
{{- if .FilterErr}}<div class="filter-err">{{.FilterErr}}</div>{{end}}
|
||
|
||
{{if .Breadcrumbs}}
|
||
<div class="crumbs">
|
||
<span class="label">Filters:</span>
|
||
{{- range .Breadcrumbs}}
|
||
<span>{{.Text}}<a href="{{.RemoveURL}}" title="remove filter">×</a></span>
|
||
{{- end}}
|
||
</div>
|
||
{{end}}
|
||
|
||
{{if .Error}}
|
||
<div class="error">{{.Error}}</div>
|
||
{{else}}
|
||
|
||
{{if .Sparkline}}
|
||
<div class="sparkline">
|
||
<small>{{.Params.WindowS}} trend · by {{.Params.GroupByS}}{{if .Collector}} · collector: {{.Collector}}{{end}}</small>
|
||
{{.Sparkline}}
|
||
</div>
|
||
{{end}}
|
||
|
||
{{if .Entries}}
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th class="rank">#</th>
|
||
<th>LABEL</th>
|
||
<th class="num">COUNT</th>
|
||
<th class="num">%</th>
|
||
<th>BAR</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{{- range .Entries}}
|
||
<tr>
|
||
<td class="rank">{{.Rank}}</td>
|
||
<td><a href="{{.DrillURL}}">{{.Label}}</a></td>
|
||
<td class="num">{{fmtCount .Count}}</td>
|
||
<td class="num">{{printf "%.0f" .Pct}}%</td>
|
||
<td class="bar"><meter value="{{printf "%.0f" .Pct}}" max="100"></meter></td>
|
||
</tr>
|
||
{{- end}}
|
||
</tbody>
|
||
</table>
|
||
{{else}}
|
||
<p class="nodata">(no data yet — ring buffer may still be filling)</p>
|
||
{{end}}
|
||
|
||
{{end}}
|
||
|
||
<footer>
|
||
{{- if .Collector}}collector: {{.Collector}} · {{end -}}
|
||
{{fmtCount .TotalCount}} requests · {{.Params.WindowS}} window · by {{.Params.GroupByS}}
|
||
{{- if gt .RefreshSecs 0}} · auto-refresh {{.RefreshSecs}}s{{end}}
|
||
</footer>
|
||
{{end}}
|