added screen dumps

mine
derailed 2019-05-30 08:24:17 -06:00
parent d369c0694a
commit 6aa9e18e12
4 changed files with 116 additions and 16 deletions

View File

@ -3,7 +3,10 @@ package views
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/derailed/k9s/internal/config"
"github.com/derailed/tview"
@ -21,6 +24,7 @@ type logView struct {
ansiWriter io.Writer
autoScroll bool
actions keyActions
path string
}
func newLogView(title string, parent masterView) *logView {
@ -47,13 +51,14 @@ func newLogView(title string, parent masterView) *logView {
v.AddItem(v.logs, 0, 1, true)
v.actions = keyActions{
tcell.KeyEscape: {description: "Back", action: v.backCmd, visible: true},
KeyC: {description: "Clear", action: v.clearCmd, visible: true},
KeyS: {description: "Toggle AutoScroll", action: v.toggleScrollCmd, visible: true},
KeyG: {description: "Top", action: v.topCmd, visible: false},
KeyShiftG: {description: "Bottom", action: v.bottomCmd, visible: false},
KeyF: {description: "Up", action: v.pageUpCmd, visible: false},
KeyB: {description: "Down", action: v.pageDownCmd, visible: false},
tcell.KeyEscape: newKeyAction("Back", v.backCmd, true),
KeyC: newKeyAction("Clear", v.clearCmd, true),
KeyS: newKeyAction("Toggle AutoScroll", v.toggleScrollCmd, true),
KeyG: newKeyAction("Top", v.topCmd, false),
KeyShiftG: newKeyAction("Bottom", v.bottomCmd, false),
KeyF: newKeyAction("Up", v.pageUpCmd, false),
KeyB: newKeyAction("Down", v.pageDownCmd, false),
tcell.KeyCtrlS: newKeyAction("Save", v.saveCmd, true),
}
v.logs.SetInputCapture(v.keyboard)
@ -111,6 +116,37 @@ func (v *logView) update() {
// ----------------------------------------------------------------------------
// Actions...
func (v *logView) saveCmd(evt *tcell.EventKey) *tcell.EventKey {
if err := os.MkdirAll(K9sDump, 0744); err != nil {
log.Error().Err(err).Msgf("Mkdir K9s dump")
return nil
}
now := time.Now().UnixNano()
fName := fmt.Sprintf("%s-%d.log", strings.Replace(v.path, "/", "-", -1), now)
path := filepath.Join(K9sDump, fName)
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile(path, mod, 0644)
defer func() {
if file != nil {
file.Close()
}
}()
if err != nil {
log.Error().Err(err).Msgf("LogFile create %s", path)
return nil
}
if _, err := fmt.Fprintf(file, v.logs.GetText(true)); err != nil {
log.Error().Err(err).Msgf("Log dump %s", v.path)
}
v.app.flash().infof("Log %s saved successfully!", path)
log.Debug().Msgf("Log %s saved successfully!", path)
return nil
}
func (v *logView) toggleScrollCmd(evt *tcell.EventKey) *tcell.EventKey {
v.autoScroll = !v.autoScroll
if v.autoScroll {

View File

@ -121,6 +121,7 @@ func (v *logsView) doLoad(path, co string) error {
l.logs.Clear()
fmat := skinTitle(fmt.Sprintf(logFmt, path, co), v.parent.appView().styles.Style)
l.SetTitle(fmat)
l.path = path
c := make(chan string, 10)
go func(l *logView) {

View File

@ -1,11 +1,15 @@
package views
import (
"encoding/csv"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
"github.com/derailed/k9s/internal/config"
"github.com/derailed/k9s/internal/resource"
@ -86,8 +90,7 @@ func newTableView(app *appView, title string) *tableView {
func (v *tableView) bindKeys() {
v.actions[KeyShiftI] = newKeyAction("Invert", v.sortInvertCmd, false)
v.actions[KeyShiftN] = newKeyAction("Sort Name", v.sortColCmd(0), true)
v.actions[KeyShiftA] = newKeyAction("Sort Age", v.sortColCmd(-1), true)
v.actions[tcell.KeyCtrlS] = newKeyAction("Save", v.saveCmd, true)
v.actions[KeySlash] = newKeyAction("Filter Mode", v.activateCmd, false)
v.actions[tcell.KeyEscape] = newKeyAction("Filter Reset", v.resetCmd, false)
@ -96,6 +99,9 @@ func (v *tableView) bindKeys() {
v.actions[tcell.KeyBackspace2] = newKeyAction("Erase", v.eraseCmd, false)
v.actions[tcell.KeyBackspace] = newKeyAction("Erase", v.eraseCmd, false)
v.actions[tcell.KeyDelete] = newKeyAction("Erase", v.eraseCmd, false)
v.actions[KeyShiftN] = newKeyAction("Sort Name", v.sortColCmd(0), true)
v.actions[KeyShiftA] = newKeyAction("Sort Age", v.sortColCmd(-1), true)
}
func (v *tableView) clearSelection() {
@ -133,6 +139,57 @@ func (v *tableView) setSelection() {
}
}
// K9sDump represents a directory where K9s artifacts will be persisted.
var K9sDump = filepath.Join(os.TempDir(), fmt.Sprintf("k9s-screens-%s", config.MustK9sUser()))
const (
fullFmat = "%s-%s-%d.csv"
noNSFmat = "%s-%d.csv"
)
func (v *tableView) saveCmd(evt *tcell.EventKey) *tcell.EventKey {
if err := os.MkdirAll(K9sDump, 0744); err != nil {
log.Error().Err(err).Msgf("Mkdir K9s dump")
return nil
}
ns, now := v.data.Namespace, time.Now().UnixNano()
if ns == resource.AllNamespaces {
ns = resource.AllNamespace
}
fName := fmt.Sprintf(fullFmat, v.baseTitle, ns, now)
if ns == resource.NotNamespaced {
fName = fmt.Sprintf(noNSFmat, v.baseTitle, now)
}
path := filepath.Join(K9sDump, fName)
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile(path, mod, 0644)
defer func() {
if file != nil {
file.Close()
}
}()
if err != nil {
log.Error().Err(err).Msgf("CSV create %s", path)
return nil
}
w := csv.NewWriter(file)
w.Write(v.data.Header)
for _, r := range v.data.Rows {
w.Write(r.Fields)
}
w.Flush()
if err := w.Error(); err != nil {
log.Error().Err(err).Msgf("Screen dump %s", v.baseTitle)
}
v.app.flash().infof("File %s saved successfully!", path)
log.Debug().Msgf("File %s saved successfully!", path)
return nil
}
func (v *tableView) filterCmd(evt *tcell.EventKey) *tcell.EventKey {
if v.cmdBuff.isActive() {
v.cmdBuff.setActive(false)

20
main.go
View File

@ -12,15 +12,21 @@ import (
func init() {
config.EnsurePath(config.K9sLogs, config.DefaultDirMod)
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
if file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod); err == nil {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
} else {
panic(err)
}
}
func main() {
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod)
defer func() {
if file != nil {
file.Close()
}
}()
if err != nil {
panic(err)
}
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
cmd.Execute()
}