Saltearse al contenido

Observabilidad: métricas y el guard de paridad de Calcite

Mondrian emite un pequeño conjunto de métricas de OpenTelemetry para que pueda observar el rendimiento de consultas, la carga SQL, la localidad de caché y — importante para el backend de Calcite — cuándo el motor cae a SQL heredado o, con el guard de paridad activo, cuándo los dos backends no coinciden.

Conectar un exporter

Los instrumentos se resuelven contra el SDK global de OpenTelemetry. Si su despliegue ya configura el agente Java de OpenTelemetry o autoconfigure (por ejemplo, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_METRICS_EXPORTER), las métricas de Mondrian fluyen a través de él sin configuración adicional. Si no hay SDK registrado, los instrumentos son no-ops — registrar es siempre seguro y nunca lanza.

Métricas

MétricaTipoSignificadoAtributos clave
mondrian.queries.executedcontadorConsultas MDX completadasmondrian.query.outcome = success | failure
mondrian.query.durationhistograma (ms)latencia por consulta MDXmismo outcome
mondrian.sql.statementscontadorSentencias JDBC emitidasmondrian.sql.kind (segment-load / member-read / drillthrough / other)
mondrian.sql.durationhistograma (ms)latencia por sentencia JDBCmismo kind
mondrian.cache.segment.hitscontadorpeticiones de celda servidas desde la caché de segmentos
mondrian.cache.segment.missescontadorpeticiones de celda que cayeron a una carga SQL
mondrian.calcite.fallbackcontadorLa traducción de Calcite lanzó → cayó a SQL heredado…fallback.site, …fallback.exception
mondrian.calcite.divergencecontadorel guard de paridad encontró que Calcite y heredado no coincidieron…divergence.site, …divergence.detail

Una alta razón cache.segment.hits / misses significa buena localidad de caché. Un calcite.fallback distinto de cero es esperable y benigno — cuenta casos donde Calcite declinó correctamente una forma y el generador heredado tomó el relevo. El contador sobre el que alertar es calcite.divergence.

El guard de paridad de Calcite

El fallback basado en excepciones solo captura “Calcite lanzó.” No puede capturar la clase peligrosa: SQL válido pero incorrecto — una traducción de Calcite que se ejecuta sin error pero devuelve un resultado diferente al de la ruta heredada. Esa divergencia es invisible para la red de seguridad del fallback y solo aparece como un “sin datos” reportado por el usuario o un total incorrecto.

El guard de paridad cierra ese hueco. Cuando está habilitado, cada carga de segmento elegible de Calcite también ejecuta el SQL heredado para la misma carga y compara los dos conjuntos de filas JDBC. Una discrepancia incrementa mondrian.calcite.divergence (con una categoría detail de baja cardinalidad — row-count / cell-value, nunca valores crudos) y registra un WARN.

Habilitarlo

Ventana de terminal
# record divergences to telemetry + logs; still returns the Calcite result
-Dmondrian.calcite.parityCheck=true
# additionally hard-fail (throw) on any divergence — for CI / pre-prod gates
-Dmondrian.calcite.parityCheck.strict=true

Ambos por defecto están desactivados. Cuando están desactivados, el único coste es una lectura de un booleano — no hay sobrecarga en la ruta caliente.

Lo que nunca hace (seguridad)

El guard se omite deliberadamente para dos clases de carga, para que una divergencia registrada siempre signifique un bug real de corrección de Calcite — nunca una falsa alarma y nunca un riesgo de seguridad:

  • Cargas aseguradas por predicado. Un grupo de medidas protegido por un <PredicateGrant> nunca se compara contra SQL heredado — el generador heredado descarta el filtro de seguridad de fila, así que ejecutarlo filtraría filas. La seguridad de fila gana sobre los diagnósticos, siempre.
  • Agregaciones solo correctas en Calcite. La granularidad distinct a nivel de medida, la mediana / percentil y el fan-out de puente / simétrico son correctos por diseño en Calcite y diferentes de lo que computaría el generador heredado (por ejemplo, una medida de granularidad distinct devuelve los 450 deduplicados donde un SUM heredado ingenuo devolvería los 950 expandidos). Compararlos registraría una falsa divergencia, así que se omiten.

En otras palabras: mondrian.calcite.divergence > 0 es una alerta de alta señal de que una forma de consulta que debería ser idéntica en todos los backends no lo es. Capture el contexto de carga del log WARN y archívelo como un bug de corrección de Calcite.

Alertas recomendadas

  • Tasa de mondrian.calcite.divergence > 0 (cuando el guard está habilitado en staging/CI) → bloquee la release; existe una forma silenciosa con resultado incorrecto.
  • Tasa de mondrian.calcite.fallback con tendencia al alza → un dialecto o forma de schema que Calcite dejó de gestionar; vale la pena investigar la pérdida de pushdown, aunque los resultados siguen siendo correctos.
  • Picos de cache.segment.misses → caché batida o un cubo frío; considere el calentamiento de caché.