Skip to content

Commit

Permalink
feat: support clash premium's structured log stream (#735)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
NyaMisty authored and github-actions[bot] committed Dec 2, 2023
1 parent 2442ffb commit aa30d90
Showing 1 changed file with 36 additions and 5 deletions.
41 changes: 36 additions & 5 deletions hub/route/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,29 @@ 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")
if levelText == "" {
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)
Expand Down Expand Up @@ -342,11 +358,26 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
}
buf.Reset()

if err := json.NewEncoder(buf).Encode(Log{
Type: logM.Type(),
Payload: logM.Payload,
}); err != nil {
break
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
Expand Down

0 comments on commit aa30d90

Please sign in to comment.