carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1{{define "app_errors"}}{{template "top" .}}
2{{if .Flash}}<p class="banner">{{.Flash}}</p>{{end}}
3{{if .FlashErr}}<p class="banner error">{{.FlashErr}}</p>{{end}}
4{{template "appnav" .}}
5{{template "lognav" .}}
6
7<h2 class="visually-hidden">Errors</h2>
8{{if .ErrsErr}}<p class="banner error">{{.ErrsErr}}</p>{{end}}
9<form method="get" class="small">
10 <label>from the last
11 <select name="since">
12 <option value="1h"{{if eq .ErrSince "1h"}} selected{{end}}>hour</option>
13 <option value="24h"{{if eq .ErrSince "24h"}} selected{{end}}>day</option>
14 <option value="168h"{{if eq .ErrSince "168h"}} selected{{end}}>week</option>
15 </select>
16 </label>
17 <label>source
18 <select name="source">
19 <option value=""{{if eq .ErrSource ""}} selected{{end}}>all</option>
20 <option value="log"{{if eq .ErrSource "log"}} selected{{end}}>log</option>
21 <option value="edge"{{if eq .ErrSource "edge"}} selected{{end}}>edge</option>
22 <option value="server"{{if eq .ErrSource "server"}} selected{{end}}>server</option>
23 <option value="browser"{{if eq .ErrSource "browser"}} selected{{end}}>browser</option>
24 </select>
25 </label>
26 <label>log level
27 <select name="level">
28 <option value=""{{if eq .ErrLevel ""}} selected{{end}}>setting ({{.ErrWin.LogLevel}})</option>
29 <option value="error"{{if eq .ErrLevel "error"}} selected{{end}}>error</option>
30 <option value="warn"{{if eq .ErrLevel "warn"}} selected{{end}}>warn and above</option>
31 </select>
32 </label>
33 <label>host <input name="host" value="{{.ErrHost}}" size="24"></label>
34 <button type="submit">Update</button>
35</form>
36<p class="small">Sources live: {{if .ErrWin.Sources}}{{range $i, $s := .ErrWin.Sources}}{{if $i}}, {{end}}{{$s}}{{end}}{{else}}none yet{{end}}.
37Counts are to the nearest flush. Messages are redacted for addresses and credentials before they are stored; treat that as a floor, not a guarantee.</p>
38
39{{if .ErrFP}}
40{{with .ErrWin.Records}}
41<h3>Occurrences of <code>{{$.ErrFP}}</code></h3>
42<p class="small"><a href="?since={{$.ErrSince}}{{if $.ErrSource}}&amp;source={{$.ErrSource}}{{end}}{{if $.ErrHost}}&amp;host={{$.ErrHost}}{{end}}{{if $.ErrLevel}}&amp;level={{$.ErrLevel}}{{end}}">All groups</a></p>
43{{if $.ErrWin.Truncated}}<p class="small">Showing the newest {{len $.ErrWin.Records}} occurrences of a larger window — narrow the window, or use <code>carlos errors</code> for all of them.</p>{{end}}
44{{range .}}
45<div class="tablewrap"><table>
46 <tr><th>Last</th><td>{{.Last.UTC.Format "2006-01-02 15:04:05"}}</td></tr>
47 <tr><th>Count</th><td>{{.Count}}</td></tr>
48 <tr><th>Source</th><td>{{.Source}}{{if .Kind}} / {{.Kind}}{{end}}</td></tr>
49 <tr><th>Host</th><td>{{.Host}}</td></tr>
50 {{if .Release}}<tr><th>Release</th><td>{{.Release}}</td></tr>{{end}}
51 {{if .Path}}<tr><th>Path</th><td><code>{{.Path}}</code>{{if .Status}} &rarr; {{.Status}}{{end}}</td></tr>{{end}}
52 <tr><th>Message</th><td>{{.Name}}</td></tr>
53 {{if .Stack}}<tr><th>Stack</th><td><pre>{{.Stack}}</pre></td></tr>{{end}}
54 {{if .Fields}}<tr><th>Fields</th><td>{{range $k, $v := .Fields}}<code>{{$k}}={{$v}}</code> {{end}}</td></tr>{{end}}
55 <tr><th>Logs</th><td><a href="{{$.Nav}}/apps/{{$.AppName}}/logs?since=1h&amp;host={{.Host}}">around this time</a></td></tr>
56</table></div>
57{{end}}
58{{else}}<p>No occurrences of this group in the window.</p>{{end}}
59{{else if .ErrWin.Groups}}
60{{if .ErrWin.Truncated}}<p class="small">Showing {{len .ErrWin.Groups}} groups of a larger window — counts are within what was read. Narrow the window, or use <code>carlos errors</code> for all of them.</p>{{end}}
61<div class="tablewrap">
62<table>
63 <tr><th>Last seen</th><th>First seen</th><th>Count</th><th>Source</th><th>Error</th><th>Hosts</th><th>Releases</th></tr>
64 {{range .ErrWin.Groups}}<tr>
65 <td>{{.Last.UTC.Format "2006-01-02 15:04"}}</td>
66 <td>{{.First.UTC.Format "2006-01-02 15:04"}}</td>
67 <td>{{.Count}}{{if eq .FP "_overflow"}} <span class="small" title="occurrences beyond the hourly cap on distinct errors">(overflow)</span>{{end}}</td>
68 <td>{{.Source}}{{if .Kind}} <span class="small">{{.Kind}}</span>{{end}}{{if .Level}} <span class="small">{{.Level}}</span>{{end}}</td>
69 <td><a href="?since={{$.ErrSince}}&amp;fp={{.FP}}{{if $.ErrSource}}&amp;source={{$.ErrSource}}{{end}}{{if $.ErrHost}}&amp;host={{$.ErrHost}}{{end}}{{if $.ErrLevel}}&amp;level={{$.ErrLevel}}{{end}}">{{.Name}}</a></td>
70 <td>{{range $i, $h := .Hosts}}{{if $i}}, {{end}}{{$h}}{{end}}</td>
71 <td>{{range $i, $r := .Releases}}{{if $i}}, {{end}}<code>{{$r}}</code>{{end}}</td>
72 </tr>{{end}}
73</table>
74</div>
75<p class="small">Times are UTC. The same view from a terminal: <code>carlos errors --app {{.AppName}} --since {{.ErrSince}}</code>.</p>
76{{else if not .ErrsErr}}
77<p>No errors in this window.</p>
78<p class="small">Log lines at <code>{{.ErrWin.LogLevel}}</code> and above and the app's own 500s appear here on their own (a 502, 503 or 504 is on <a href="{{.Nav}}/apps/{{.AppName}}/availability">Availability</a>); a JavaScript or server-side error needs the hook (coming in a later step). The level is set on the Settings tab. The same view from a terminal: <code>carlos errors --app {{.AppName}}</code>.</p>
79{{end}}
80{{template "bottom" .}}{{end}}
81