121 lines
2.4 KiB
Go
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"
|
|
}
|
|
}
|
|
|