Migrar consultas LogQL, KQL y SPL a SQL
Mover una consulta operativa a SQL es una migración del modelo de datos, no un ejercicio de búsqueda y reemplazo. LogQL comienza con flujos de registro y selectores de etiquetas, Kusto Query Language utiliza una canalización tabular y Splunk SPL transforma los resultados de búsqueda mediante comandos. SQL comienza con relaciones y hace explícitas la selección, agrupación, uniones y proyección.
La migración más segura conserva el contrato de pregunta y resultado antes de cambiar la sintaxis.
Primero escribe el contrato semántico.
Para cada consulta, registre:
- la decisión que apoya;
- la fuente y la ventana de tiempo;
- la fila o el grano del evento;
- campos analizados y sus tipos;
- dimensiones de agrupación;
- numerador y denominador;
- reglas de nulo, duplicado, reintento y llegada tardía;
- columnas esperadas y orden de clasificación.
Ejecute las consultas antiguas y nuevas en el mismo intervalo limitado. Compare primero los totales, luego los resultados a nivel de grupo y luego las filas sin procesar representativas. Un resultado que parece visualmente similar aún puede usar un denominador diferente.
Un evento de ejemplo compartido
Las traducciones siguientes suponen una fila escrita por solicitud API completada:
{
"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"
}
Si el sistema anterior almacena solo un mensaje como "GET /v1/orders/123 returned 503 in 842ms", primero agregue un analizador o cambie la instrumentación. SQL no puede recuperar una plantilla de ruta estable o un tipo numérico confiable que nunca se registró.
mapa conceptual
| Intención | LogQL | KQL | SPL | SQL |
|---|---|---|---|---|
| Elige fuente | selector de flujo | expresión de tabla | búsqueda de índices y fuentes | FROM table |
| Filtrar filas | filtro de línea o etiqueta | where |
search o where |
WHERE |
| Analizar campos | expresión del analizador | parse, extend |
rex, spath, eval |
preferiblemente columnas escritas antes de la consulta |
| Seleccionar columnas | formato de línea | project |
fields o table |
SELECT |
| agregado | consulta métrica | summarize |
stats o timechart |
agregados más GROUP BY |
| Tubería | ` | ` etapas | ` | `operadores |
| cubo de tiempo | vector de rango | bin() |
timechart span= |
date_trunc() |
Esta tabla mapea la intención, no la equivalencia exacta. Por ejemplo, una etiqueta Loki participa en la indexación de flujos y en las restricciones de cardinalidad; una columna SQL no tiene automáticamente el mismo comportamiento de almacenamiento.
Ejemplo 1: filtrar errores recientes
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;
El límite explícito protege una consulta exploratoria de devolver una ventana de incidente ilimitada. No forma parte de un informe agregado.
Ejemplo 2: calcular la tasa de error por ruta
Los lenguajes de canalización a menudo hacen que el numerador sea fácil de ver, mientras que el denominador está implícito en una etapa anterior. Mantenga ambos en el resultado 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;
No traduzca un LogQL count_over_time a COUNT(*) hasta que confirme que una entrada de registro analizada corresponde a una fila SQL y que los reintentos o los mensajes de varias líneas no cambian el grano.
Ejemplo 3: crear un gráfico de tiempo
Las agregaciones de rango KQL summarize ... by bin(Timestamp, 5m), SPL timechart span=5m y LogQL expresan una serie de tiempo. En DataFusion SQL, un primer paso portátil es un cubo de horas:
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;
Elija un depósito compatible con el motor y apropiado para el volumen del evento. Excluya o anote el depósito más nuevo cuando esté incompleto.
Ejemplo 4: reemplazar una canalización con expresiones de tabla comunes
Las canalizaciones son legibles porque cada etapa transforma la tabla anterior. Las expresiones de tabla comunes SQL pueden conservar esa forma:
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;
Nombra las etapas por su significado en lugar de step1 o filtered. La consulta resultante sigue siendo fácil de revisar y probar.
El análisis es el riesgo de migración
Las consultas existentes pueden depender de expresiones regulares, extracción JSON, descubrimiento automático de campos o análisis del tiempo de búsqueda específico del proveedor. Inventario de cada campo derivado:
| campo derivado | Nuevo campo de evento | Tipo | Retroceso durante la transición |
|---|---|---|---|
| método de solicitud | method |
categoría de cadena | analizar mensaje antiguo |
| plantilla de ruta | route |
categoría de cadena | asignar ruta sin formato a la plantilla |
| código de respuesta | status_code |
entero | valor analizado emitido |
| duración | latency_ms |
entero | normalizar segundos o microsegundos |
| liberar | release |
categoría de cadena | enriquecer a partir de metadatos de implementación |
Ejecute la recopilación dual hasta que el campo escrito esté presente y sea correcto en todos los productores. No elimine el analizador antiguo porque coincida un único servicio de ruta feliz.
Funciones específicas del proveedor que necesitan rediseñarse
Algunas construcciones no deben forzarse en SQL genérico:
- Las etiquetas de flujo LogQL y las operaciones de desencapsulado combinan la selección de almacenamiento con el análisis.
- KQL tiene funciones ricas de valores dinámicos, series temporales y anomalías.
- SPL tiene objetos de conocimiento en tiempo de búsqueda, transacciones y comportamiento específico de comandos.
- Cada sistema aplica diferentes zonas horarias predeterminadas, semántica nula, límites y algoritmos de agregación aproximados.
Conservar una consulta de proveedor cuando sea la mejor herramienta para un incidente o tipo de datos. El objetivo es un modelo de evento SQL confiable para preguntas compartidas, no la pureza del lenguaje.
Consulte las referencias propias actuales para Ejemplos de consulta LogQL, Operadores de consulta de Kusto y Referencia de búsqueda de Splunk.
Validación y transición
Para cada consulta migrada:
- congelar un intervalo representativo;
- comparar los recuentos de filas de origen;
- comparar distintos identificadores de operaciones;
- comparar recuentos de nulos y fallos de análisis;
- comparar cada grupo de productos, no sólo el total general;
- explicar las diferencias aceptadas;
- ejecutar ambos paneles durante al menos un ciclo de tráfico normal;
- mantenga un enlace de reversión a la consulta anterior hasta que los usuarios acepten el nuevo resultado.
Utilice Solución de problemas de consultas SQL para problemas de motor y tipo, Migrar registros a eventos estructurados para implementación de instrumentación y Libro de cocina SQL para contratos completos y resultados visuales.