fix: полный production-фикс fix40 (layout, sidebar, journald, логирование)
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user