feat: support clash premium's structured log stream (#735)
* feat: support clash premium's structured log stream New version of Clash for Windows uses `ws://external-controller/logs?token=&level=info&format=structured` to get real time log. When Clash Premium Core reveices `format=structured`, it returns a different form of JSON log entry. Supporting this feature will allow better Clash for Windows integration Signed-off-by: Misty <gyc990326@gmail.com>
This commit is contained in:
parent
0ed3c5a5ec
commit
10e7c533d7
1 changed files with 36 additions and 5 deletions
|
@ -293,6 +293,16 @@ type Log struct {
|
|||
Type string `json:"type"`
|
||||
Payload string `json:"payload"`
|
||||
}
|
||||
type LogStructuredField struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
type LogStructured struct {
|
||||
Time string `json:"time"`
|
||||
Level string `json:"level"`
|
||||
Message string `json:"message"`
|
||||
Fields []LogStructuredField `json:"fields"`
|
||||
}
|
||||
|
||||
func getLogs(w http.ResponseWriter, r *http.Request) {
|
||||
levelText := r.URL.Query().Get("level")
|
||||
|
@ -300,6 +310,12 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
|
|||
levelText = "info"
|
||||
}
|
||||
|
||||
formatText := r.URL.Query().Get("format")
|
||||
isStructured := false
|
||||
if formatText == "structured" {
|
||||
isStructured = true
|
||||
}
|
||||
|
||||
level, ok := log.LogLevelMapping[levelText]
|
||||
if !ok {
|
||||
render.Status(r, http.StatusBadRequest)
|
||||
|
@ -342,12 +358,27 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
buf.Reset()
|
||||
|
||||
if !isStructured {
|
||||
if err := json.NewEncoder(buf).Encode(Log{
|
||||
Type: logM.Type(),
|
||||
Payload: logM.Payload,
|
||||
}); err != nil {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
newLevel := logM.Type()
|
||||
if newLevel == "warning" {
|
||||
newLevel = "warn"
|
||||
}
|
||||
if err := json.NewEncoder(buf).Encode(LogStructured{
|
||||
Time: time.Now().Format(time.TimeOnly),
|
||||
Level: newLevel,
|
||||
Message: logM.Payload,
|
||||
Fields: []LogStructuredField{},
|
||||
}); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
if wsConn == nil {
|
||||
|
|
Loading…
Reference in a new issue