Observabilidade: métricas e o guard de paridade Calcite
O Mondrian emite um pequeno conjunto de métricas OpenTelemetry para que você possa observar throughput de consulta, carga SQL, localidade de cache e — importante para o backend Calcite — quando o engine cai para SQL legado ou, com o guard de paridade ligado, quando os dois backends discordam.
Conectar um exporter
Os instrumentos resolvem contra o SDK OpenTelemetry global. Se sua implantação já configura o Java agent ou autoconfigure do OpenTelemetry (ex.: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_METRICS_EXPORTER), as métricas do Mondrian fluem por ele sem setup extra. Se nenhum SDK estiver registrado, os instrumentos são no-ops — gravação é sempre segura e nunca lança.
Métricas
| Métrica | Tipo | Significado | Atributos chave |
|---|---|---|---|
mondrian.queries.executed | counter | Consultas MDX completadas | mondrian.query.outcome = success | failure |
mondrian.query.duration | histogram (ms) | latência por consulta MDX | mesmo outcome |
mondrian.sql.statements | counter | Statements JDBC emitidos | mondrian.sql.kind (segment-load / member-read / drillthrough / other) |
mondrian.sql.duration | histogram (ms) | latência por statement JDBC | mesmo kind |
mondrian.cache.segment.hits | counter | requisições de célula servidas do cache de segmento | — |
mondrian.cache.segment.misses | counter | requisições de célula que caíram em uma carga SQL | — |
mondrian.calcite.fallback | counter | tradução Calcite lançou → caiu para SQL legado | …fallback.site, …fallback.exception |
mondrian.calcite.divergence | counter | guard de paridade achou que Calcite e legado discordaram | …divergence.site, …divergence.detail |
Uma razão alta de cache.segment.hits / misses significa boa localidade de cache. Um calcite.fallback não zero é esperado e benigno — conta casos onde o Calcite corretamente declinou um formato e o gerador legado assumiu. O counter para alertar é calcite.divergence.
O guard de paridade Calcite
O fallback baseado em exceção só pega “Calcite lançou.” Não consegue pegar a classe perigosa: SQL válido mas errado — uma tradução Calcite que roda sem erro mas retorna um resultado diferente do caminho legado. Essa divergência é invisível à rede de segurança de fallback e aparece apenas como um “sem dados” reportado por usuário ou um total errado.
O guard de paridade fecha esse gap. Quando habilitado, cada carga de segmento Calcite elegível também roda o SQL legado para a mesma carga e compara os dois row-sets JDBC. Um mismatch incrementa mondrian.calcite.divergence (com uma categoria detail de baixa cardinalidade — row-count / cell-value, nunca valores brutos) e loga um WARN.
Habilitar
# 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=trueAmbos default para off. Quando off, o único custo é uma única leitura booleana — não há overhead no caminho quente.
O que ele nunca faz (segurança)
O guard é deliberadamente pulado para duas classes de carga, então uma divergência gravada sempre significa um bug real de correção Calcite — nunca um falso alarme e nunca um risco de segurança:
- Cargas predicate-secured. Um measure group protegido por um
<PredicateGrant>nunca é comparado contra SQL legado — o gerador legado descarta o filtro de row-security, então rodá-lo vazaria linhas. Row security vence diagnósticos, sempre. - Agregações corretas apenas no Calcite. Grão distinto no nível da medida, median / percentile e bridge / fan-out simétrico são corretos por design no Calcite e diferentes do que o gerador legado computaria (ex.: uma medida de grão distinto retorna o 450 deduplicado onde um
SUMlegado ingênuo retornaria o 950 fanned-out). Compará-los gravaria uma falsa divergência, então são pulados.
Em outras palavras: mondrian.calcite.divergence > 0 é um alerta de alto sinal que um formato de consulta que deveria ser idêntico entre backends não é. Capture o contexto de carga do log WARN e arquive como bug de correção Calcite.
Alertas recomendados
- Taxa de
mondrian.calcite.divergence> 0 (quando o guard está habilitado em staging/CI) → bloqueie o release; um formato silenciosamente errado existe. - Taxa de
mondrian.calcite.fallbackem tendência de alta → um dialeto ou formato de schema que o Calcite parou de lidar; vale investigar por pushdown perdido, embora resultados permaneçam corretos. cache.segment.missesem pico → churn de cache ou um cubo frio; considere cache warming.