mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
Generate crash report txt and webpage
The last 100 lines of logs are now cached, and when a crash occurs, they
are saved to a file in the temp directory ("/tmp" on *nix), and pretty
HTML version is also created and opened in the browser.
* Currently only handles panics, will be included in more places soon
* Copy button and button to generate a GH issue will be added
This commit is contained in:
3
linecache/go.mod
Normal file
3
linecache/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/hrfee/jfa-go/linecache
|
||||
|
||||
go 1.16
|
||||
66
linecache/linecache.go
Normal file
66
linecache/linecache.go
Normal file
@@ -0,0 +1,66 @@
|
||||
// Package linecache provides a writer that stores n lines of text at once, overwriting old content as it reaches its capacity. Its contents can be read from with a String() method.
|
||||
package linecache
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// LineCache provides an io.Writer that stores a fixed number of lines of text.
|
||||
type LineCache struct {
|
||||
count int
|
||||
lines [][]byte
|
||||
current int
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
// NewLineCache returns a new line cache of capacity (n) lines.
|
||||
func NewLineCache(n int) *LineCache {
|
||||
return &LineCache{
|
||||
current: 0,
|
||||
count: n,
|
||||
lines: make([][]byte, n),
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes a given byte array to the cache.
|
||||
func (l *LineCache) Write(p []byte) (n int, err error) {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
lines := strings.Split(string(p), "\n")
|
||||
for _, line := range lines {
|
||||
if string(line) == "" {
|
||||
continue
|
||||
}
|
||||
if l.current == l.count {
|
||||
l.current = 0
|
||||
}
|
||||
l.lines[l.current] = []byte(line)
|
||||
l.current++
|
||||
}
|
||||
n = len(p)
|
||||
return
|
||||
}
|
||||
|
||||
// String returns a string representation of the cache contents.
|
||||
func (l *LineCache) String() string {
|
||||
i := 0
|
||||
if l.lines[l.count-1] != nil && l.current != l.count {
|
||||
i = l.current
|
||||
}
|
||||
out := ""
|
||||
for {
|
||||
if l.lines[i] == nil {
|
||||
return out
|
||||
}
|
||||
out += string(l.lines[i]) + "\n"
|
||||
i++
|
||||
if i == l.current {
|
||||
return out
|
||||
}
|
||||
if i == l.count {
|
||||
i = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
17
linecache/linecache_test.go
Normal file
17
linecache/linecache_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package linecache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
wr := NewLineCache(10)
|
||||
for i := 10; i < 50; i++ {
|
||||
fmt.Fprintln(wr, i)
|
||||
fmt.Print(strings.ReplaceAll(wr.String(), "\n", " "), "\n")
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user