mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-23 16:13:04 +01:00
feat(loganalyzer): complete tool suite for analysing erupe logs.
This commit is contained in:
108
tools/loganalyzer/tail.go
Normal file
108
tools/loganalyzer/tail.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// runTail implements the tail command for following log files in real-time.
|
||||
//
|
||||
// The tail command mimics the Unix `tail -f` command, displaying the last N lines
|
||||
// of a log file and then continuously monitoring the file for new entries. This is
|
||||
// useful for real-time monitoring of server activity.
|
||||
//
|
||||
// The command operates in two phases:
|
||||
// 1. Initial display: Shows the last N matching entries from the file
|
||||
// 2. Follow mode: Continuously monitors for new lines and displays them as they appear
|
||||
//
|
||||
// Both phases support filtering by log level and colorized output.
|
||||
//
|
||||
// Options:
|
||||
// - f: Path to log file (default: "erupe.log")
|
||||
// - n: Number of initial lines to show (default: 10)
|
||||
// - follow: Whether to continue following the file (default: true)
|
||||
// - level: Filter by log level (info, warn, error, fatal)
|
||||
// - color: Colorize output (default: true)
|
||||
//
|
||||
// The follow mode polls the file every 100ms for new content. Use Ctrl+C to stop.
|
||||
//
|
||||
// Examples:
|
||||
// runTail([]string{}) // Show last 10 lines and follow
|
||||
// runTail([]string{"-n", "50"}) // Show last 50 lines and follow
|
||||
// runTail([]string{"-level", "error"}) // Only show errors
|
||||
// runTail([]string{"-follow=false", "-n", "20"}) // Just show last 20 lines, don't follow
|
||||
func runTail(args []string) {
|
||||
fs := flag.NewFlagSet("tail", flag.ExitOnError)
|
||||
|
||||
logFile := fs.String("f", "erupe.log", "Path to log file")
|
||||
lines := fs.Int("n", 10, "Number of initial lines to show")
|
||||
follow := fs.Bool("follow", true, "Follow the log file (like tail -f)")
|
||||
level := fs.String("level", "", "Filter by log level")
|
||||
colorize := fs.Bool("color", true, "Colorize output")
|
||||
|
||||
fs.Parse(args)
|
||||
|
||||
// First, show last N lines
|
||||
if *lines > 0 {
|
||||
entries, err := ParseLogFile(*logFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading log file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Filter by level if specified
|
||||
var filtered []*LogEntry
|
||||
for _, entry := range entries {
|
||||
if *level == "" || entry.Level == *level {
|
||||
filtered = append(filtered, entry)
|
||||
}
|
||||
}
|
||||
|
||||
// Show last N lines
|
||||
start := len(filtered) - *lines
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
|
||||
for i := start; i < len(filtered); i++ {
|
||||
fmt.Println(FormatLogEntry(filtered[i], *colorize))
|
||||
}
|
||||
}
|
||||
|
||||
// If follow is enabled, watch for new lines
|
||||
if *follow {
|
||||
file, err := os.Open(*logFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error opening log file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Seek to end of file
|
||||
file.Seek(0, 2)
|
||||
|
||||
reader := bufio.NewReader(file)
|
||||
|
||||
fmt.Fprintln(os.Stderr, "Following log file... (Ctrl+C to stop)")
|
||||
|
||||
for {
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
// No more data, wait a bit and try again
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
entry := ParseLogLine(line)
|
||||
if entry != nil {
|
||||
// Filter by level if specified
|
||||
if *level == "" || entry.Level == *level {
|
||||
fmt.Println(FormatLogEntry(entry, *colorize))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user