Files
HY2XS_flamy/apps/service/journal.go
T

121 lines
2.4 KiB
Go

package service
import (
"bufio"
"encoding/json"
"fmt"
"hy2xs-admin/model/vo"
"hy2xs-admin/util"
"strconv"
"strings"
"time"
)
type journalctlLogLine struct {
Message string `json:"MESSAGE"`
Priority string `json:"PRIORITY"`
RealtimeTimestamp string `json:"__REALTIME_TIMESTAMP"`
}
func ReadHysteriaJournalLogs(numLine int) ([]vo.LogHysteria2Vo, int, error) {
lines := 100
if numLine > 0 {
lines = numLine
}
output, err := util.Exec(fmt.Sprintf("journalctl --no-pager -u hysteria-server.service -n %d -o json", lines))
if err != nil {
return nil, 0, err
}
result := make([]vo.LogHysteria2Vo, 0, lines)
scanner := bufio.NewScanner(strings.NewReader(output))
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" {
continue
}
item := journalctlLogLine{}
if err = json.Unmarshal([]byte(line), &item); err != nil {
continue
}
result = append(result, parseHysteriaJournalRecord(item))
}
if scanErr := scanner.Err(); scanErr != nil {
return nil, 0, scanErr
}
return result, len(result), nil
}
func ExportHysteriaJournalLogs(numLine int) (string, error) {
lines := 5000
if numLine > 0 {
lines = numLine
}
return util.Exec(fmt.Sprintf("journalctl --no-pager -u hysteria-server.service -n %d -o short-iso", lines))
}
func parseHysteriaJournalRecord(item journalctlLogLine) vo.LogHysteria2Vo {
fallbackTime := convertJournalTimestamp(item.RealtimeTimestamp)
fallbackLevel := mapJournalPriorityToLevel(item.Priority)
if strings.TrimSpace(item.Message) == "" {
return vo.LogHysteria2Vo{
Level: fallbackLevel,
Msg: "",
Time: fallbackTime,
}
}
parsed := vo.LogHysteria2Vo{}
if err := json.Unmarshal([]byte(item.Message), &parsed); err == nil {
if parsed.Level == "" {
parsed.Level = fallbackLevel
}
if parsed.Time == "" {
parsed.Time = fallbackTime
}
if parsed.Msg == "" {
parsed.Msg = item.Message
}
return parsed
}
return vo.LogHysteria2Vo{
Level: fallbackLevel,
Msg: item.Message,
Time: fallbackTime,
}
}
func convertJournalTimestamp(raw string) string {
if raw == "" {
return ""
}
us, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
return ""
}
t := time.UnixMicro(us)
return t.Format("2006-01-02 15:04:05")
}
func mapJournalPriorityToLevel(priority string) string {
switch strings.TrimSpace(priority) {
case "0", "1", "2", "3":
return "error"
case "4":
return "warn"
default:
return "info"
}
}