oc-scheduler -> scheduling + logs

This commit is contained in:
mr
2026-04-08 10:05:27 +02:00
parent f8a6e69ef3
commit 1d63d31442
21 changed files with 4605 additions and 139 deletions

View File

@@ -5,10 +5,12 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"cloud.o-forge.io/core/oc-lib/config"
beego "github.com/beego/beego/v2/server/web"
gorillaws "github.com/gorilla/websocket"
)
// Operations about workflow
@@ -84,3 +86,91 @@ func (o *LokiController) GetLogs() {
o.Data["json"] = map[string]string{"error": "Query error"}
o.ServeJSON()
}
// LogsStreamHandler streams Loki logs over WebSocket.
//
// The client sends one JSON message with the same format as GetLogs:
//
// {"start": "<unix-seconds>", "label1": "val1", ...}
//
// The server connects to Loki's /loki/api/v1/tail WebSocket endpoint and
// forwards every message it receives until the client disconnects.
func LogsStreamHandler(w http.ResponseWriter, r *http.Request) {
conn, err := wsUpgrader.Upgrade(w, r, nil)
if err != nil {
return
}
defer conn.Close()
var query map[string]interface{}
if err := conn.ReadJSON(&query); err != nil {
return
}
start := fmt.Sprintf("%v", query["start"])
if len(start) > 10 {
start = start[:10]
}
var labels []string
for k, v := range query {
if k == "start" || k == "end" {
continue
}
labels = append(labels, fmt.Sprintf("%v=\"%v\"", k, v))
}
if len(labels) == 0 || len(start) < 10 {
_ = conn.WriteJSON(map[string]string{"error": "missing start or query labels"})
return
}
// Build Loki tail WS URL (http→ws, https→wss).
lokiBase := config.GetConfig().LokiUrl
lokiBase = strings.Replace(lokiBase, "https://", "wss://", 1)
lokiBase = strings.Replace(lokiBase, "http://", "ws://", 1)
lokiURL := lokiBase + "/loki/api/v1/tail?" + url.Values{
"query": {"{" + strings.Join(labels, ", ") + "}"},
"start": {start + "000000000"}, // seconds → nanoseconds
}.Encode()
lokiConn, _, err := gorillaws.DefaultDialer.Dial(lokiURL, nil)
if err != nil {
_ = conn.WriteJSON(map[string]string{"error": "loki: " + err.Error()})
return
}
defer lokiConn.Close()
errCh := make(chan error, 2)
// Forward Loki → client.
go func() {
for {
_, msg, err := lokiConn.ReadMessage()
if err != nil {
errCh <- err
return
}
var result map[string]interface{}
if json.Unmarshal(msg, &result) == nil {
if err := conn.WriteJSON(result); err != nil {
errCh <- err
return
}
}
}
}()
// Detect client disconnect (read pump).
go func() {
for {
if _, _, err := conn.ReadMessage(); err != nil {
errCh <- err
return
}
}
}()
<-errCh
}