將 LogQL、KQL 和 SPL 查詢遷移到 SQL
將操作查詢移至 SQL 是資料模型遷移,而不是查詢和替換練習。 LogQL 從日誌流和標籤選擇器開始,Kusto 查詢語言使用表格管道,Splunk SPL 透過命令轉換搜尋結果。 SQL 從關係開始,使選擇、分組、連線和投影變得明確。
最安全的遷移在更改語法之前保留問題和結果契約。
首先寫下語義契約
對於每個查詢,記錄:
- 它支援的決定;
- 來源和時間視窗;
- 行或事件粒度;
- 解析的欄位及其型別;
- 分組維度;
- 分子和分母;
- 空、重複、重試和遲到規則;
- 預期的列和排序順序。
在相同的有限間隔內執行舊查詢和新查詢。首先比較總數,然後比較組級結果,然後比較代表性原始行。視覺上看起來相似的結果仍然可以使用不同的分母。
共享範例事件
下面的翻譯假設每個完成的 API 請求有一個鍵入的行:
{
"timestamp": "2026-07-28T16:04:00Z",
"event_name": "api_request_completed",
"service": "checkout-api",
"route": "/v1/orders/:id",
"status_code": 503,
"latency_ms": 842,
"request_id": "req_01J...",
"release": "2026.07.28"
}
如果舊系統僅儲存 "GET /v1/orders/123 returned 503 in 842ms" 等訊息,請首先新增解析器或更改檢測。 SQL 無法恢復從未記錄過的穩定路由範本或可靠數字型別。
概念圖
| 意圖 | LogQL | KQL | SPL | SQL |
|---|---|---|---|---|
| 選擇來源 | 流選擇器 | 資料表表示式 | 索引和源搜尋 | FROM table |
| 過濾行 | 行或標籤過濾器 | where |
search 或 where |
WHERE |
| 解析欄位 | 解析器表示式 | parse、extend |
rex、spath、eval |
最好在查詢之前輸入列 |
| 選擇列 | 行格式 | project |
fields 或 table |
SELECT |
| 骨料 | 指標查詢 | summarize |
stats 或 timechart |
骨料加GROUP BY |
| 管道 | ` | ` 階段 | ` | ` 運算子 |
| 時間桶 | 範圍向量 | bin() |
timechart span= |
date_trunc() |
該資料表對映了意圖,而不是完全等同。例如,Loki標籤參與流索引和基數約束; SQL 列不會自動具有相同的儲存行為。
範例1:過濾最近的錯誤
LogQL
{service="checkout-api"} | json | status_code >= 500
KQL
ApiRequestCompleted
| where Timestamp > ago(1h)
| where Service == "checkout-api" and StatusCode >= 500
| project Timestamp, Route, StatusCode, LatencyMs, RequestId
| order by Timestamp desc
SPL
index=production service=checkout-api status_code>=500 earliest=-1h
| table _time route status_code latency_ms request_id
| sort - _time
SQL
SELECT
timestamp_utc,
route,
status_code,
latency_ms,
request_id
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '1 hour'
AND service = 'checkout-api'
AND status_code >= 500
ORDER BY timestamp_utc DESC
LIMIT 200;
顯式限制可防止探索性查詢返回無界的事件視窗。它不是彙總報告的一部分。
範例2:按路由計算錯誤率
管道語言通常使分子易於檢視,而分母則由早期階段隱含。將兩者保留在 SQL 結果中:
SELECT
route,
COUNT(*) AS requests,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
ROUND(
100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0),
2
) AS error_rate_pct
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
AND service = 'checkout-api'
GROUP BY route
ORDER BY error_rate_pct DESC, requests DESC;
不要將 LogQL count_over_time 轉換為 COUNT(*),除非您確認一個已解析的日誌條目對應於一個 SQL 行並且重試或多行訊息不會更改粒度。
範例3:建置時間表
KQL summarize ... by bin(Timestamp, 5m)、SPL timechart span=5m 和 LogQL 範圍聚合均表示時間序列。在 DataFusion SQL 中,行動式第一步是一個小時桶:
SELECT
date_trunc('hour', timestamp_utc) AS hour,
release,
COUNT(*) AS requests,
approx_percentile_cont(latency_ms, 0.95) AS p95_latency_ms
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '7 days'
GROUP BY date_trunc('hour', timestamp_utc), release
ORDER BY hour ASC, release ASC;
選擇引擎支援且適合事件量的儲存桶。當最新的儲存桶不完整時,將其排除或註釋。
範例 4:用公用資料表表示式替換管道
管道是可讀的,因為每個階段都會轉換先前的資料表。 SQL 公用資料表表示式可以保留該形狀:
WITH recent_requests AS (
SELECT *
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
AND service = 'checkout-api'
),
route_summary AS (
SELECT
route,
COUNT(*) AS requests,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors
FROM recent_requests
GROUP BY route
)
SELECT
route,
requests,
errors,
ROUND(100.0 * errors / NULLIF(requests, 0), 2) AS error_rate_pct
FROM route_summary
WHERE requests >= 100
ORDER BY error_rate_pct DESC;
根據其含義命名階段,而不是 step1 或 filtered。生成的查詢仍然易於檢視和測試。
解析是遷移風險
現有查詢可能依賴於正規表示式、JSON 提取、自動欄位發現或特定於供應商的搜尋時解析。盤點每個派生欄位:
| 派生欄位 | 新事件場 | 型別 | 切換期間的回退 |
|---|---|---|---|
| 請求方式 | method |
字串類別 | 解析舊訊息 |
| 路線範本 | route |
字串類別 | 將原始路徑對映到範本 |
| 回應碼 | status_code |
整數 | 轉換解析值 |
| 持續時間 | latency_ms |
整數 | 標準化秒或微秒 |
| 釋放 | release |
字串類別 | 從部署後設資料中豐富 |
執行雙重收集,直到鍵入的欄位在生產者中存在並且正確。不要刪除舊的解析器,因為單個 happy-path 服務匹配。
需要重新設計的供應商特定功能
某些構造不應強制進入通用 SQL:
- LogQL 流標籤和解包操作將儲存選擇與解析結合起來。
- KQL具有豐富的動態值、時間序列、異常功能。
- SPL 具有搜尋時知識物件、事務和特定於命令的行為。
- 每個系統應用不同的預設時區、空語義、限制和近似聚合演算法。
當供應商查詢是事件或資料型別的最佳工具時,保留它。目標是針對共享問題建立可靠的 SQL 事件模型,而不是語言純粹性。
請參閱 LogQL 查詢範例、Kusto 查詢運算子 和 Splunk 搜尋參考 的當前第一方參考資料。
驗證和切換
對於每個遷移的查詢:
- 凍結代表性區間;
- 比較源行計數;
- 比較不同的操作識別符號;
- 比較空值和解析失敗計數;
- 比較每個輸出組,而不僅僅是總計;
- 解釋可接受的差異;
- 至少在一個正常的流量週期中執行兩個儀表板;
- 保留舊查詢的回滾連結,直到使用者接受新結果。
使用 SQL 查詢故障排除 解決發動機和型別問題,使用 將日誌遷移到結構化事件 進行儀資料表部署,使用 SQL食譜 進行完整的合約和視覺化輸出。