fix(log): ES 7.2.0 time format .SSSZ + index dropdown + demo always visible

- ES query 502 fix: remove +00:00 conversion, use native .SSSZ format
  (ES 7.2.0 date_time = strict_date_optional_time only, rejects +00:00/epoch)
- parseLogTime: use time.RFC3339Nano for fractional seconds
- new API GET /log-datasources/indices to list ES indices via proxy
- LogDatasourceDialog: add '获取索引' button + Select dropdown for ES
- LogDatasourcePage: always show demo sources alongside real ones
This commit is contained in:
attacker committed 2026-06-27 09:45:21 +00:00
1 parent 2e179ef7f4
commit a04d815efe
7 files changed
+308 -15

No files matched your search

+47
View File
@@ -3,6 +3,7 @@ package controller
import (
"crypto/tls"
"encoding/base64"
"encoding/json"
"io"
"net/http"
"strings"
@@ -168,6 +169,52 @@ func (h *LogDSHandler) TestConnection(c *gin.Context) {
c.JSON(200, model.Response{Code: 200, Message: "连接成功", Data: map[string]string{"status": "ok"}})
}
// ListIndices GET /api/v1/log-datasources/indices?url=...&type=elasticsearch
// 通过代理查询 ES 集群的索引列表 // Logan.Li
func (h *LogDSHandler) ListIndices(c *gin.Context) {
esURL := c.Query("url")
if esURL == "" {
c.JSON(400, model.Response{Code: 400, Message: "url 参数必填"})
return
}
basicAuth := c.Query("basic_auth") == "true"
user := c.Query("basic_auth_user")
pass := c.Query("basic_auth_pass")
skipTLS := c.Query("skip_tls_verify") == "true"
client := newLogHTTPClient(skipTLS, 10*time.Second)
target := strings.TrimRight(esURL, "/") + "/_cat/indices?format=json&h=index"
httpReq, err := http.NewRequest(http.MethodGet, target, nil)
if err != nil {
c.JSON(502, model.Response{Code: 502, Message: err.Error()})
return
}
applyLogDSAuth(httpReq, basicAuth, user, pass)
resp, err := client.Do(httpReq)
if err != nil {
c.JSON(502, model.Response{Code: 502, Message: "查询索引失败: " + err.Error()})
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 {
c.JSON(502, model.Response{Code: 502, Message: "ES 错误: " + string(body)})
return
}
var raw []map[string]interface{}
if err := json.Unmarshal(body, &raw); err != nil {
c.JSON(502, model.Response{Code: 502, Message: "解析索引列表失败"})
return
}
indices := make([]string, 0, len(raw))
for _, entry := range raw {
if idx, ok := entry["index"].(string); ok {
indices = append(indices, idx)
}
}
c.JSON(200, model.Response{Code: 200, Data: indices})
}
func testLogDSConnection(req model.TestLogDSReq) (bool, string) {
client := newLogHTTPClient(req.SkipTLSVerify, 10*time.Second)
url := strings.TrimRight(req.URL, "/")