imc-vibe/backend/internal/mail/logs.go
2026-03-21 22:41:23 +01:00

88 lines
1.8 KiB
Go

package mail
import (
"bufio"
"bytes"
"context"
"os/exec"
"regexp"
"strings"
"time"
)
type LogEntry struct {
Timestamp string `json:"timestamp"`
Priority string `json:"priority"`
Message string `json:"message"`
}
func GetLogs(hours int, filter string) ([]LogEntry, error) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
args := []string{
"-u", "postfix",
"--since", formatDuration(hours),
"--no-pager",
"-o", "short=false",
}
cmd := exec.CommandContext(ctx, "journalctl", args...)
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return nil, err
}
var entries []LogEntry
scanner := bufio.NewScanner(&out)
priorityRegex := regexp.MustCompile(`\[([^\]]+)\]`)
for scanner.Scan() {
line := scanner.Text()
if filter != "" && !strings.Contains(strings.ToLower(line), strings.ToLower(filter)) {
continue
}
parts := strings.SplitN(line, " ", 4)
if len(parts) < 4 {
continue
}
timestamp := parts[0] + " " + parts[1]
matches := priorityRegex.FindStringSubmatch(parts[2])
priority := "info"
if len(matches) > 1 {
priority = matches[1]
} else if strings.Contains(parts[2], "err") {
priority = "err"
} else if strings.Contains(parts[2], "warning") || strings.Contains(parts[2], "warn") {
priority = "warning"
}
message := parts[3]
if filter != "" && !strings.Contains(strings.ToLower(message), strings.ToLower(filter)) {
continue
}
entries = append(entries, LogEntry{
Timestamp: timestamp,
Priority: priority,
Message: message,
})
}
if entries == nil {
entries = []LogEntry{}
}
return entries, nil
}
func formatDuration(hours int) string {
return time.Now().Add(-time.Duration(hours) * time.Hour).Format("15:04:05 2006-01-02")
}