clogviewr

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2022 License: MIT Imports: 14 Imported by: 0

README

LogView widget for tview/cview

LogView widget for tview.

It will also work with cview, just replace import github.com/rivo/tview with gitlab.com/rivo/cview.

Rationale

cview/tview TextView widget tries to recalculate highlighting and wrapping on every new line appended to the widget. Batch appends helps a little, but I was not able to achieve acceptable performance even when the line count in TextView's buffer was set to as little as 500.

LogView is designed for logs, so it supports very fast append operation and takes special care to calculate highlighting and line wrapping only once for each log event added.

LogView operates on LogEvent structures, not on text lines, this allows keeping track of which line belongs to which event even with wrapping enabled and easy navigation to specific log event by its ID or timestamp.

Capabilities

LogView supports:

  • tailing logs
  • limiting the number of log events stored in log view
  • highlighting error/warning events (with customizable colors)
  • custom highlighting of parts of log messages
  • scrolling to event id
  • scrolling to timestamp
  • optional display of log event source and timestamp separately from main message
  • keyboard and mouse scrolling
  • selection of log event with a keyboard or mouse with a callback on selection change
  • merging of continuation events (i.e. multiline java stack-traces can be treated as one log event)
  • velocity graph

Performance notes

LogView attempts to minimize the number of calculations performed. For each log event, the line wrapping and colour highlighting are calculated only once, at the moment the event is appended to the log view. This allows for very fast appends, but also means the whole log view can become stale if widget size or colour settings change.

Widget size changes are handled automatically. If line wrapping is disabled, then no additional work has to be done, otherwise line wrapping are recalculated as needed.

Recalculating highlights changes is a more expensive operation, so it is not handled automatically. To force recalculation of highlights for all the log events call LogView.RefreshHighlighs() method.

Changes to any of the highlights or default Log view style would require recalculation. Changes to the background colour of current event or error and warning level events do not require recalculation.

Event Message Highlighting

LogView doesn't use tview color tags, mostly because they are an unnecessary step in colorizing event message. LogView accepts regular expression to extract parts of the log message and apply styles to them.

Named capture groups define parts of the message that should be highlighted, and the name of the group defines the colors.

Group name must match foreground_background pattern. Background color is optional and colors must match names of "extended" web colors. Defining colors in hex is not yet supported.

Note: Regular expression syntax for color highlighting is different from standard Go regexp syntax, you can use lookahead and lookbehind but setting regexp flags within expression (i.e. (?iU)) is not supported. Using lookahead/behind can be a significant performance hit though. A general rule is to try to stick to the simplest expressions possible. Use non-capturing groups for everything, except for the things you need highlighted.

See regexp2 readme for more details.

Examples (note the use of non-capturing groups):

Match time tokens like 2021-03-05 or 12:23:44.332 and highlight them with "lavender" color

(?P<lavender>\d{2}(?:[:.-]\d{2,3})+) 

Match debug level as a separate word and highlight it as white on reddish color

(?:\b(?P<white_lightsalmon>info|warning|error|trace|debug)\b) 

LogVelocityView Widget

Log velocity widget displays bar chart of number of log events per time period. Widget can show count for all events or only events of the certain level.

Note. Many fonts will have weird line gaps in the block characters. Hack is one of the best in this regard.

Documentation

Index

Constants

View Source
const (
	// LogLevelInfo is default log
	LogLevelInfo = LogLevel(iota)
	// LogLevelWarning is the level for warnings
	LogLevelWarning
	// LogLevelError is the level for errors
	LogLevelError
	// LogLevelAll is used for building histograms only as a placeholder for all log levels
	LogLevelAll
)

Variables

View Source
var Keys = Key{
	Cancel: []string{"Escape"},

	Select:  []string{"Enter", "Ctrl+J"},
	Select2: []string{"Space"},

	MoveUp:     []string{"Up"},
	MoveUp2:    []string{"k"},
	MoveDown:   []string{"Down"},
	MoveDown2:  []string{"j"},
	MoveLeft:   []string{"Left"},
	MoveLeft2:  []string{"h"},
	MoveRight:  []string{"Right"},
	MoveRight2: []string{"l"},

	MoveFirst:  []string{"Home", "Ctrl+A"},
	MoveFirst2: []string{"g"},
	MoveLast:   []string{"End", "Ctrl+E"},
	MoveLast2:  []string{"G"},

	MovePreviousField: []string{"Backtab"},
	MoveNextField:     []string{"Tab"},
	MovePreviousPage:  []string{"PageUp", "Ctrl+B"},
	MoveNextPage:      []string{"PageDown", "Ctrl+F"},

	ShowContextMenu: []string{"Alt+Enter"},
}

Keys defines the keyboard shortcuts of an application. Secondary shortcuts apply when not focusing a text input.

Functions

func Details

func Details(evt *LogEvent) (text string)

func HitShortcut

func HitShortcut(event *tcell.EventKey, keybindings ...[]string) bool

HitShortcut returns whether the EventKey provided is present in one or more sets of keybindings.

Types

type AppMode

type AppMode int
const (
	ExitModal AppMode = iota
	InfoDialogModal
	CommandEntry
	LogViewer
)

type CmdExecFunc

type CmdExecFunc func(string)

type Key

type Key struct {
	Cancel []string

	Select  []string
	Select2 []string

	MoveUp     []string
	MoveUp2    []string
	MoveDown   []string
	MoveDown2  []string
	MoveLeft   []string
	MoveLeft2  []string
	MoveRight  []string
	MoveRight2 []string

	MoveFirst  []string
	MoveFirst2 []string
	MoveLast   []string
	MoveLast2  []string

	MovePreviousField []string
	MoveNextField     []string
	MovePreviousPage  []string
	MoveNextPage      []string

	ShowContextMenu []string
}

Key defines the keyboard shortcuts of an application. Secondary shortcuts apply when not focusing a text input.

type LogEvent

type LogEvent struct {
	EventID   string
	Source    string
	Timestamp time.Time
	Level     LogLevel
	Message   string
	Data      interface{}
}

LogEvent that can be added to LogView. Contains following fields:

- EventID - a string identifier of the event, used in event handlers, may contain only ASCII characters

- Source - a source that produced the event, may contain only ASCII characters

- Timestamp - an instant when the event was created/ingested

- Level - the severity level of an event. Can be used to highlight errors and warnings

- Message - the event contents

func NewLogEvent

func NewLogEvent(eventID string, message string) *LogEvent

type LogLevel

type LogLevel uint

LogLevel represents the log level LogView recognizes three log levels: Info, Warning and Error Warning and Error events can be highlighted

type LogVelocityView

type LogVelocityView struct {
	*gui.Box

	sync.RWMutex
	// contains filtered or unexported fields
}

LogVelocityView is a bar chart to display number of log events per time period

func NewLogVelocityView

func NewLogVelocityView(bucketWidth time.Duration) *LogVelocityView

NewLogVelocityView creates a new log velocity view with a defined bucket time frame

func (*LogVelocityView) AppendLogEvent

func (lh *LogVelocityView) AppendLogEvent(event *LogEvent)

AppendLogEvents adds event to a velocity chart

func (*LogVelocityView) AutoScale

func (lh *LogVelocityView) AutoScale(from, to time.Time)

func (*LogVelocityView) Clear

func (lh *LogVelocityView) Clear()

Clear resets all the statistics. Bucket width and anchor do not change

func (*LogVelocityView) ClearAnchor

func (lh *LogVelocityView) ClearAnchor()

ClearAnchor removes the max time for the time axis. Max time will be equal to the current time

func (*LogVelocityView) Draw

func (lh *LogVelocityView) Draw(screen tcell.Screen)

Draw draws this primitive onto the screen.

func (*LogVelocityView) GetAnchor

func (lh *LogVelocityView) GetAnchor() *time.Time

func (*LogVelocityView) GetShowLogLevel

func (lh *LogVelocityView) GetShowLogLevel() LogLevel

GetShowLogLevel returns the log level of events that are be displayed in the velocity view

func (*LogVelocityView) ScaleFor

func (lh *LogVelocityView) ScaleFor(duration time.Duration)

func (*LogVelocityView) SetAnchor

func (lh *LogVelocityView) SetAnchor(newAnchor time.Time)

SetAnchor sets the max time for the time axis

func (*LogVelocityView) SetShowLogLevel

func (lh *LogVelocityView) SetShowLogLevel(logLevel LogLevel)

SetShowLogLevel sets the log level of events that should be displayed in the velocity view

Supported values are:

  • LogLevelInfo - show all events but warning and errors

  • LogLevelWarning

  • LogLevelError

  • LogLevelAll - show all events

type LogView

type LogView struct {
	*gui.Box

	sync.RWMutex
	// contains filtered or unexported fields
}

LogView is a Box that displays log events

LogView doesn't have border or scroll bars to allow easier copy-paste of events.

func NewLogView

func NewLogView() *LogView

NewLogView returns a new log view.

func (*LogView) AppendEvent

func (lv *LogView) AppendEvent(logEvent *LogEvent)

AppendEvent appends an event to the log view If possible use AppendEvents to add multiple events at once

func (*LogView) AppendEvents

func (lv *LogView) AppendEvents(events []*LogEvent)

AppendEvents appends multiple events in a single batch improving performance

func (*LogView) Clear

func (lv *LogView) Clear()

Clear deletes all events from the log view

func (*LogView) Draw

func (lv *LogView) Draw(screen tcell.Screen)

Draw draws this primitive onto the screen.

func (*LogView) EventCount

func (lv *LogView) EventCount() uint

EventCount returns the number of log events in the log view

func (*LogView) FindMatchingEvent

func (lv *LogView) FindMatchingEvent(lastEventId string, predicate func(event *LogEvent) bool) *LogEvent

FindMatchingEvent searches for a event that matches a given predicate First event to be matched is the one after the event id equal to lastEventId. If the lastEventId is an empty string, the search will start from the first event in the log view.

If no such event can be found it will return nil

func (*LogView) FindTotalMatches

func (lv *LogView) FindTotalMatches(predicate func(event *LogEvent) bool) int

func (*LogView) Focus

func (lv *LogView) Focus(_ func(p gui.Primitive))

Focus is called when this primitive receives focus.

func (*LogView) GetCurrentEvent

func (lv *LogView) GetCurrentEvent() *LogEvent

GetCurrentEvent returns the currently selected event

func (*LogView) GetEventCount

func (lv *LogView) GetEventCount() uint

GetEventCount returns number of events in the log view

func (*LogView) GetFirstEvent

func (lv *LogView) GetFirstEvent() *LogEvent

GetFirstEvent returns the first event in the log view

func (*LogView) GetFocusable

func (lv *LogView) GetFocusable() gui.Focusable

func (*LogView) GetHeight

func (lv *LogView) GetHeight() int

GetHeight returns the width of the list view

func (*LogView) GetMaxEvents

func (lv *LogView) GetMaxEvents() uint

GetMaxEvents returns a maximum number of events that log view will hold

func (*LogView) GetNewEventMatchingRegex

func (lv *LogView) GetNewEventMatchingRegex() string

GetNewEventMatchingRegex gets the regular expression used for detecting continuation events.

func (*LogView) GetSourceClipLength

func (lv *LogView) GetSourceClipLength() int

GetSourceClipLength returns the current maximum length of event source that would be displayed

func (*LogView) GetTimestampFormat

func (lv *LogView) GetTimestampFormat() string

GetTimestampFormat returns the format used to display timestamps

func (*LogView) GetVisible

func (lv *LogView) GetVisible() bool

GetVisible returns a value indicating whether or not the box is visible.

func (*LogView) GetWidth

func (lv *LogView) GetWidth() int

GetWidth returns the width of the list view

func (*LogView) HasFocus

func (lv *LogView) HasFocus() bool

HasFocus returns whether or not this primitive has focus.

func (*LogView) InputHandler

func (lv *LogView) InputHandler() func(event *tcell.EventKey, setFocus func(p gui.Primitive))

InputHandler returns the handler for this primitive.

func (*LogView) IsConcatenateEventsEnabled

func (lv *LogView) IsConcatenateEventsEnabled() bool

IsConcatenateEventsEnabled returns the status of event concatenation

func (*LogView) IsFollowing

func (lv *LogView) IsFollowing() bool

IsFollowing returns whether the following mode is enabled. Following mode automatically scrolls log view up as new events are appended. Last event is always in the view.

func (*LogView) IsHighlightCurrentEventEnabled

func (lv *LogView) IsHighlightCurrentEventEnabled() bool

IsHighlightCurrentEventEnabled returns the status background color highlighting for currently selected event

func (*LogView) IsHighlightingEnabled

func (lv *LogView) IsHighlightingEnabled() bool

IsHighlightingEnabled returns the status of event message highlighting

func (*LogView) IsLevelHighlightingEnabled

func (lv *LogView) IsLevelHighlightingEnabled() bool

IsLevelHighlightingEnabled returns the status of background color highlighting for events based on severity level

func (*LogView) IsLineWrapEnabled

func (lv *LogView) IsLineWrapEnabled() bool

IsLineWrapEnabled returns the current status of line wrap

func (*LogView) IsShowSource

func (lv *LogView) IsShowSource() bool

IsShowSource returns whether the showing of event source is enabled

func (*LogView) IsShowTimestamp

func (lv *LogView) IsShowTimestamp() bool

IsShowTimestamp returns whether the showing of event source is enabled

func (*LogView) MouseHandler

func (lv *LogView) MouseHandler() func(action gui.MouseAction, event *tcell.EventMouse, setFocus func(p gui.Primitive)) (consumed bool, capture gui.Primitive)

MouseHandler returns the mouse handler for this primitive.

func (*LogView) RefreshHighlights

func (lv *LogView) RefreshHighlights()

RefreshHighlights forces recalculation of highlight patterns for all events in the log view. LogView calculates highlight spans once for each event when the event is appended. Any changes in highlighting will not be applied to the events that are already in the log view. To apply changes to all the events call this function. Warning: this might be a rather expensive operation

func (*LogView) ScrollPageDown

func (lv *LogView) ScrollPageDown()

ScrollPageDown scrolls the log view one screen down

This will enable auto follow if the last line has been reached

func (*LogView) ScrollPageUp

func (lv *LogView) ScrollPageUp()

ScrollPageUp scrolls the log view one screen up

This does not disables following.

func (*LogView) ScrollToBottom

func (lv *LogView) ScrollToBottom()

ScrollToBottom scrolls the log view to the last event

This does not automatically enables following. User SetFollowing function to enable it

func (*LogView) ScrollToEventID

func (lv *LogView) ScrollToEventID(eventID string) bool

ScrollToEventID scrolls to the first event with a matching eventID If no such event is found it will not scroll and return false.

Current event will be updated to the found event

func (*LogView) ScrollToTimestamp

func (lv *LogView) ScrollToTimestamp(timestamp time.Time) bool

ScrollToTimestamp scrolls to the first event with a timestamp equal to or greater than given. If no event satisfies that condition it will not scroll and return false.

Current event will be updated to the found event

func (*LogView) ScrollToTop

func (lv *LogView) ScrollToTop()

ScrollToTop scrolls the log view to the first event

This does not automatically enables following. User SetFollowing function to enable it

func (*LogView) SelectNextEvent

func (lv *LogView) SelectNextEvent()

SelectNextEvent selects the next event in the log view

func (*LogView) SelectPrevEvent

func (lv *LogView) SelectPrevEvent()

SelectPrevEvent selects the previous event in the log view

func (*LogView) SetBorder

func (lv *LogView) SetBorder(_ bool)

SetBorder does nothing

func (*LogView) SetConcatenateEvents

func (lv *LogView) SetConcatenateEvents(enabled bool)

SetConcatenateEvents enables/disables event concatenation

Events with a message that do not match regular expression set by SetNewEventMatcher are appended to the previous event

func (*LogView) SetCurrentBgColor

func (lv *LogView) SetCurrentBgColor(color tcell.Color)

SetCurrentBgColor sets the background color to highlight currently selected event

func (*LogView) SetErrorBgColor

func (lv *LogView) SetErrorBgColor(bgColor tcell.Color)

SetErrorColor sets the background color for events with level == LogLevelError. Event level highlighting can be turned on and off with SetLevelHighlighting function.

Changing error color will do nothing to the events that are already in the log view. To update highlighting of all events use RefreshHighlights. Be warned: this is an expensive operation

func (*LogView) SetEventLimit

func (lv *LogView) SetEventLimit(limit uint)

SetEventLimit sets the limit to number of log event held by log view.

To disable limit set it to zero.

func (*LogView) SetFollowing

func (lv *LogView) SetFollowing(follow bool)

SetFollowing enables/disables following mode. Following mode automatically scrolls log view up as new events are appended. Last event is always in the view

Enabling following will automatically scroll to the last event

func (*LogView) SetHighlightCurrentEvent

func (lv *LogView) SetHighlightCurrentEvent(enabled bool)

SetHighlightCurrentEvent enables background color highlighting for currently selected event

func (*LogView) SetHighlightPattern

func (lv *LogView) SetHighlightPattern(pattern string)

SetHighlightPattern sets new regular expression pattern to find spans that need to be highlighted setting this to nil disables highlighting.

pattern is a regular expression where each matching named capturing group can be highlighted with a different color. Colors for any given group name can be set with SetHighlightColor, SetHighlightColorFg, SetHighlightColorBg

Note: Updating pattern doesn't changes highlighting for previously appended events Call RefreshHighlights() to force updating highlighting for all events in the log view.

func (*LogView) SetHighlighting

func (lv *LogView) SetHighlighting(enable bool)

SetHighlighting enables/disables event message highlighting according to the pattern set by SetHighlightPattern.

Events appended when this setting was disabled will not be highlighted until RefreshHighlights function is called.

func (*LogView) SetLevelHighlighting

func (lv *LogView) SetLevelHighlighting(enabled bool)

SetLevelHighlighting enables background color highlighting for events based on severity level

func (*LogView) SetLineWrap

func (lv *LogView) SetLineWrap(enabled bool)

SetLineWrap enables/disables the line wrap. Disabling line wrap may increase performance

func (*LogView) SetMaxEvents

func (lv *LogView) SetMaxEvents(limit uint)

SetMaxEvents sets a maximum number of events that log view will hold

func (*LogView) SetNewEventMatchingRegex

func (lv *LogView) SetNewEventMatchingRegex(regex string)

SetNewEventMatcher sets the regular expression to use for detecting continuation events.

If event message matches provided regular expression it is treated as a new event, otherwise it is appended to a previous line. All attributes of appended event are discarded.

If line wrapping is enabled, event will be split into original lines

For examples typical Java exception looks like IllegalArgumentException: No nulls please

	   caused by NullPointerException
    at org.some.java.package.Class
    at org.another.java.package

Each line might be a new log event, but it makes sense to treat whole stack trace as as a single event.

func (*LogView) SetOnCurrentChange

func (lv *LogView) SetOnCurrentChange(listener OnCurrentChanged)

SetOnCurrentChange sets a listener that will be called every time the current event is changed

If current event highlighting is disabled, listener will not be called.

func (*LogView) SetShowSource

func (lv *LogView) SetShowSource(enabled bool)

SetShowSource enables/disables the displaying of event source

Event Source is displayed to the left of the actual event message with style defined by SetSourceStyle and is clipped to the length set by SetSourceClipLength (6 characters is the default)

func (*LogView) SetShowTimestamp

func (lv *LogView) SetShowTimestamp(enabled bool)

SetShowTimestamp enables/disables the displaying of event timestamp

Event timestamp is displayed to the left of the actual event message with the format defined by SetTimestampFormat

func (*LogView) SetSourceClipLength

func (lv *LogView) SetSourceClipLength(length int)

SetSourceClipLength sets the maximum length of event source that would be displayed if SetShowSource is on

func (*LogView) SetSourceStyle

func (lv *LogView) SetSourceStyle(style tcell.Style)

SetSourceStyle sets the style for displaying event source

func (*LogView) SetTextStyle

func (lv *LogView) SetTextStyle(style tcell.Style)

SetTextStyle sets the default style for the log messages

func (*LogView) SetTimestampFormat

func (lv *LogView) SetTimestampFormat(format string)

SetTimestampFormat sets the format for displaying the event timestamp.

Default is 15:04:05.000

func (*LogView) SetTimestampStyle

func (lv *LogView) SetTimestampStyle(style tcell.Style)

SetTimestampStyle sets the style for displaying event timestamp

func (*LogView) SetVisible

func (lv *LogView) SetVisible(v bool)

SetVisible sets the flag indicating whether or not the box is visible.

func (*LogView) SetWarningBgColor

func (lv *LogView) SetWarningBgColor(bgColor tcell.Color)

SetWarningColor sets the background color for events with level == LogLevelWarning. Event level highlighting can be turned on and off with SetLevelHighlighting function.

Changing warning color will do nothing to the events that are already in the log view. To update highlighting of all events use RefreshHighlights. Be warned: this is an expensive operation

type OnCurrentChanged

type OnCurrentChanged func(current *LogEvent)

OnCurrentChanged is an event time that is fired when current log event is changed

type UI

type UI struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func CreateAppUI

func CreateAppUI() *UI

CreateAppUI creates base UI layout

func (*UI) AppendEvent

func (ui *UI) AppendEvent(event *LogEvent)

func (*UI) GetCommandHistory

func (ui *UI) GetCommandHistory() []string

func (*UI) HandleGotoLine

func (ui *UI) HandleGotoLine(s string)

func (*UI) HandleSearch

func (ui *UI) HandleSearch(s string)

func (*UI) IsCommandEntryVisible

func (ui *UI) IsCommandEntryVisible() bool

func (*UI) IsExitModalVisible

func (ui *UI) IsExitModalVisible() bool

func (*UI) IsInfoDialogModalVisible

func (ui *UI) IsInfoDialogModalVisible() bool

func (*UI) IsLogViewerVisible

func (ui *UI) IsLogViewerVisible() bool

func (*UI) Run

func (ui *UI) Run()

Run starts the application event loop

func (*UI) SetAnchor

func (ui *UI) SetAnchor(lastTime time.Time)

func (*UI) SetDetailsGenerator

func (ui *UI) SetDetailsGenerator(g func(evt *LogEvent) string)

func (*UI) SetErrorBgColor

func (ui *UI) SetErrorBgColor(c tcell.Color)

func (*UI) SetExecuteCmdFunc

func (ui *UI) SetExecuteCmdFunc(f CmdExecFunc)

func (*UI) SetHighlightCurrentEvent

func (ui *UI) SetHighlightCurrentEvent(b bool)

func (*UI) SetHighlightPattern

func (ui *UI) SetHighlightPattern(pattern string)

func (*UI) SetHighlighting

func (ui *UI) SetHighlighting(b bool)

func (*UI) SetInputFieldLabel

func (ui *UI) SetInputFieldLabel(s string)

func (*UI) SetLevelHighlighting

func (ui *UI) SetLevelHighlighting(b bool)

func (*UI) SetShowTimestamp

func (ui *UI) SetShowTimestamp(b bool)

func (*UI) SetStatusViewText

func (ui *UI) SetStatusViewText(message string)

func (*UI) SetStatusViewTextColor

func (ui *UI) SetStatusViewTextColor(color tcell.Color)

func (*UI) SetTitle

func (ui *UI) SetTitle(s string)

func (*UI) SetTitleAlign

func (ui *UI) SetTitleAlign(s int)

func (*UI) SetTitleColor

func (ui *UI) SetTitleColor(s tcell.Color)

func (*UI) SetWarningBgColor

func (ui *UI) SetWarningBgColor(c tcell.Color)

func (*UI) ShowDetailsModal

func (ui *UI) ShowDetailsModal(title, message string)

func (*UI) ShowExitModal

func (ui *UI) ShowExitModal()

func (*UI) ShowInputField

func (ui *UI) ShowInputField()

func (*UI) ShowLogEventDetails

func (ui *UI) ShowLogEventDetails(evt *LogEvent)

func (*UI) ShowLogViewer

func (ui *UI) ShowLogViewer()

func (*UI) Stop

func (ui *UI) Stop()

Stop the UI

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL