50 lines
1.1 KiB
Go
50 lines
1.1 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Entry struct {
|
|
Timestamp string
|
|
Hostname string
|
|
WorkingDir string
|
|
Command string
|
|
}
|
|
|
|
// ParseLine parses a log line in "TIMESTAMP HOSTNAME DIR COMMAND..." format.
|
|
func ParseLine(line string) (Entry, error) {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
return Entry{}, fmt.Errorf("empty line")
|
|
}
|
|
|
|
// Split into at most 4 parts: timestamp, hostname, dir, command(rest)
|
|
parts := strings.SplitN(line, " ", 4)
|
|
if len(parts) < 4 {
|
|
return Entry{}, fmt.Errorf("malformed line: %q", line)
|
|
}
|
|
|
|
ts := parts[0]
|
|
if _, err := time.Parse(time.RFC3339, ts); err != nil {
|
|
return Entry{}, fmt.Errorf("invalid timestamp %q: %w", ts, err)
|
|
}
|
|
|
|
if parts[1] == "" || parts[2] == "" || parts[3] == "" {
|
|
return Entry{}, fmt.Errorf("empty field in line: %q", line)
|
|
}
|
|
|
|
return Entry{
|
|
Timestamp: ts,
|
|
Hostname: parts[1],
|
|
WorkingDir: parts[2],
|
|
Command: parts[3],
|
|
}, nil
|
|
}
|
|
|
|
// Format returns the entry in log format: "TIMESTAMP HOSTNAME DIR COMMAND"
|
|
func (e Entry) Format() string {
|
|
return fmt.Sprintf("%s %s %s %s", e.Timestamp, e.Hostname, e.WorkingDir, e.Command)
|
|
}
|