github.com/wtfutil/wtf@v0.43.0/modules/logger/widget.go (about)

     1  package logger
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/rivo/tview"
     9  	log "github.com/wtfutil/wtf/logger"
    10  	"github.com/wtfutil/wtf/view"
    11  )
    12  
    13  const (
    14  	maxBufferSize int64 = 1024
    15  )
    16  
    17  type Widget struct {
    18  	view.TextWidget
    19  
    20  	filePath string
    21  	settings *Settings
    22  }
    23  
    24  func NewWidget(tviewApp *tview.Application, redrawChan chan bool, settings *Settings) *Widget {
    25  	widget := Widget{
    26  		TextWidget: view.NewTextWidget(tviewApp, redrawChan, nil, settings.Common),
    27  
    28  		filePath: log.LogFilePath(),
    29  		settings: settings,
    30  	}
    31  
    32  	return &widget
    33  }
    34  
    35  // Refresh updates the onscreen contents of the widget
    36  func (widget *Widget) Refresh() {
    37  	widget.Redraw(widget.content)
    38  }
    39  
    40  /* -------------------- Unexported Functions -------------------- */
    41  
    42  func (widget *Widget) content() (string, string, bool) {
    43  	if log.LogFileMissing() {
    44  		return widget.CommonSettings().Title, "File missing", false
    45  	}
    46  
    47  	logLines := widget.tailFile()
    48  	str := ""
    49  
    50  	for _, line := range logLines {
    51  		chunks := strings.Split(line, " ")
    52  
    53  		if len(chunks) >= 4 {
    54  			str += fmt.Sprintf(
    55  				"[green]%s[white] [yellow]%s[white] %s\n",
    56  				chunks[0],
    57  				chunks[1],
    58  				strings.Join(chunks[3:], " "),
    59  			)
    60  		}
    61  	}
    62  
    63  	return widget.CommonSettings().Title, str, false
    64  }
    65  
    66  func (widget *Widget) tailFile() []string {
    67  	file, err := os.Open(widget.filePath)
    68  	if err != nil {
    69  		return []string{}
    70  	}
    71  	defer func() { _ = file.Close() }()
    72  
    73  	stat, err := file.Stat()
    74  	if err != nil {
    75  		return []string{}
    76  	}
    77  
    78  	bufferSize := maxBufferSize
    79  	if maxBufferSize > stat.Size() {
    80  		bufferSize = stat.Size()
    81  	}
    82  
    83  	startPos := stat.Size() - bufferSize
    84  
    85  	buff := make([]byte, bufferSize)
    86  	_, err = file.ReadAt(buff, startPos)
    87  	if err != nil {
    88  		return []string{}
    89  	}
    90  
    91  	logLines := strings.Split(string(buff), "\n")
    92  
    93  	// Reverse the array of lines
    94  	// Offset by two to account for the blank line at the end
    95  	last := len(logLines) - 2
    96  	for i := 0; i < len(logLines)/2; i++ {
    97  		logLines[i], logLines[last-i] = logLines[last-i], logLines[i]
    98  	}
    99  
   100  	return logLines
   101  }