Files
ampmInsights/docs/09-operacao-observabilidade.html
Antonio Sergio Rodrigues Figueiredo 24a1c8bb6a Baseline v2.0.0-dev: fork de ampmInsights_V1
- Copia integral de ampmInsights_V1/ (docs/ + sql/), que o usuário confirma
  ser exatamente o que foi usado para construir e implementar
  ampmInsights_V1_Cliente no cliente.
- Traz docs/10-carga-cmdb-vulnerabilidades.html de V1_Cliente (existia lá,
  faltava em V1 — gap de conteúdo, não só de tom).
- Rebrand mecânico 'Documentação V1' -> 'Documentação V2' nas 10 páginas de
  docs + link de navegação para o capítulo 10 adicionado onde faltava.
- ampmInsights_V1/ e ampmInsights_V1_Cliente/ ficam congelados a partir de
  agora (réplica validada, já implementada no cliente) — todo o trabalho de
  v2.0.0 (schema aditivo: ALTER/MERGE, sem DROP) acontece nesta pasta.
- Adiciona TASKS.md e CHANGELOG.md próprios desta geração.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:21:14 -03:00

187 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ampmInsights &middot; Operação & observabilidade</title>
<meta name="description" content="Como monitorar consumo e depurar erros de IA/Generative AI no ambiente ampmInsights.">
<link rel="stylesheet" href="assets/main.css">
</head>
<body>
<div class="layout">
<aside class="sidebar">
<div class="brand">
<span class="oracle">ORACLE</span>
<span class="name">ampmInsights</span>
</div>
<button class="menu-toggle" type="button">Menu &#9776;</button>
<div class="kicker">Documentação V2 &middot; AM/PM</div>
<ul class="nav-list">
<li><a class="" href="index.html"><span class="step-no">1</span>Visão geral</a></li>
<li><a class="" href="02-arquitetura.html"><span class="step-no">2</span>Arquitetura</a></li>
<li><a class="" href="03-pre-requisitos-credenciais.html"><span class="step-no">3</span>Pré-requisitos & credenciais</a></li>
<li><a class="" href="04-passo-a-passo-banco.html"><span class="step-no">4</span>Passo a passo: banco de dados</a></li>
<li><a class="" href="05-passo-a-passo-apex.html"><span class="step-no">5</span>Passo a passo: aplicação APEX</a></li>
<li><a class="" href="06-validacao-testes.html"><span class="step-no">6</span>Validação & testes</a></li>
<li><a class="" href="07-seguranca-boas-praticas.html"><span class="step-no">7</span>Segurança & boas práticas</a></li>
<li><a class="" href="08-glossario-roadmap.html"><span class="step-no">8</span>Glossário & roadmap</a></li>
<li><a class="active" href="09-operacao-observabilidade.html"><span class="step-no">9</span>Operação & observabilidade</a></li>
<li><a class="" href="10-carga-cmdb-vulnerabilidades.html"><span class="step-no">10</span>Carga: CMDB & Vulnerabilidades</a></li>
</ul>
<div class="sidebar-footer">
Vulnerability &amp; Audit AI Insights<br>
Oracle AI Database 26ai &middot; AI Vector Search<br>
Versão V1 &middot; ambiente reprodutível do cliente
</div>
</aside>
<main class="content">
<p class="page-kicker">Operação</p>
<h1>Operação & observabilidade</h1>
<p class="lede">Checklist de erros comuns, consultas prontas de troubleshooting/consumo de IA, e onde olhar ferramentas nativas que já vêm sem custo de desenvolvimento.</p>
<p>Esta seção nasceu de um incidente real: o recurso "AI Insight" ficava sempre retornando o texto
genérico de fallback, e não havia nenhum log que revelasse o motivo. Investigando, encontramos duas
causas encadeadas — a Seção 3 (credencial <code>OCI_CRED</code>) tinha sido rodada conectado como
<code>ADMIN</code> em vez de <code>AMPMINSIGHTS</code> (por isso a credencial nunca existiu), e a
função que chama o LLM engolia qualquer erro silenciosamente, sem logar nada. As duas coisas foram
corrigidas: a função agora loga cada chamada (sucesso ou erro) em <code>TB_26AI_TECH_LOG</code>, e
esta página documenta como usar esse log — junto com um checklist dos erros mais comuns — para
nunca mais operar "às cegas".</p>
<h2>Checklist de erros comuns</h2>
<div class="table-wrap">
<table>
<tr><th>Sintoma</th><th>Causa provável</th><th>Como confirmar/corrigir</th></tr>
<tr><td><code>ORA-00942</code> em qualquer objeto <code>TB_26AI_TECH_*</code></td><td>Conectado como <code>ADMIN</code> em vez de <code>AMPMINSIGHTS</code> (aconteceu neste ambiente em 2026-07-24).</td><td>Rode <code>SELECT USER FROM DUAL;</code> — tem que voltar <code>AMPMINSIGHTS</code>. Reconecte e repita a seção que falhou.</td></tr>
<tr><td>"AI Insight"/chat sempre retorna o texto genérico de fallback</td><td>Credencial <code>OCI_CRED</code> ausente ou quebrada (é o sintoma exato do incidente que originou esta página).</td><td><code>SELECT credential_name FROM user_credentials WHERE credential_name = 'OCI_CRED';</code> — se não retornar linha, refaça a Seção 3 conectado como <code>AMPMINSIGHTS</code>. Depois, confira o motivo exato na consulta de "Erros recentes" abaixo.</td></tr>
<tr><td>Erro de rede/timeout ao chamar o Generative AI</td><td>ACL de rede (Seção 1.6) não cobre o host correto.</td><td><code>SELECT host, privilege FROM dba_host_aces WHERE principal = 'AMPMINSIGHTS';</code> — deve listar <code>inference.generativeai.us-chicago-1.oci.oraclecloud.com</code> com <code>RESOLVE</code> e <code>CONNECT</code>.</td></tr>
<tr><td><code>ORA-20404</code> ("Object not found", domínio <code>oci.my$cloud_domain</code>)</td><td>Perfil de SELECT AI usando a região "de casa" do tenancy (<code>OCI_REGION</code>) em vez da região do Generative AI.</td><td>Use o valor de <code>GENAI_REGION</code> (Seção 2), não <code>OCI_REGION</code> — ver Seção 5.3 do <a href="04-passo-a-passo-banco.html">Passo a passo: banco de dados</a>.</td></tr>
<tr><td><code>ORA-20404</code> com URL bem formada (região correta no domínio, ex. <code>inference.generativeai.us-chicago-1.oci.oraclecloud.com</code>)</td><td>A tenancy não alcança essa região do Generative AI (comum em tenancies com escopo regional restrito, ex. América Latina), ou o modelo configurado não está mais ativo para uso on-demand nessa região — descoberto em 2026-07-24 com <code>meta.llama-4-maverick-17b-128e-instruct-fp8</code>, que estava aposentado on-demand em <code>sa-saopaulo-1</code> desde maio/2025 apesar de ainda aparecer no catálogo.</td><td>Rode <code>oci generative-ai model-collection list-models --compartment-id &lt;seu-compartimento&gt; --region &lt;regiao-candidata&gt; --capability CHAT --all</code> (ou o Console OCI) e confirme que o modelo usado em <code>GENAI_REGION</code> está <code>ACTIVE</code> e sem <code>time-on-demand-retired</code> preenchido; ajuste <code>GENAI_REGION</code> (e a ACL da Seção 1.6 para o novo host) para uma região que sua tenancy alcance e que ainda sirva o modelo on-demand.</td></tr>
<tr><td><code>ORA-20404</code> mesmo com credencial/ACL/região corretos</td><td><code>EMBEDDING_COMPARTMENT</code> preenchido com o OCID errado (ex.: do Autonomous Database em vez do compartimento — os dois "parecem" um OCID válido).</td><td>Confira o prefixo: tem que ser <code>ocid1.compartment....</code>, nunca <code>ocid1.autonomousdatabase....</code>. Se corrigir, recrie a credencial (<code>OCI_CRED</code>) — ela grava o compartimento internamente na criação.</td></tr>
<tr><td>Lupa do "AI Insight" falha mesmo com tudo certo em <code>TB_26AI_TECH_PARAMS</code></td><td><code>COMPARTMENT_ID</code>/<code>OCI_CREDENTIAL</code>/<code>REGION</code> nas Application Settings do APEX (config separada, ver seção abaixo) desatualizados em relação à tabela.</td><td>App Builder → Shared Components → Application Settings — compare com <code>TB_26AI_TECH_PARAMS</code>.</td></tr>
</table>
</div>
<h2>O que <code>TB_26AI_TECH_LOG</code> guarda</h2>
<p>Toda chamada a Generative AI/embeddings feita pelas funções <code>FNC_26ai_rag</code>,
<code>fnc_26ai_tech_rag</code>, <code>fnc_26ai_embed</code> e <code>PRC_26AI_TECH</code> grava uma
linha nesta tabela — sucesso ou erro, sem exceção. Guarda metadados de uso (objeto/função de
origem, provider, modelo, duração, tamanho do prompt/resposta em caracteres, usuário, e o
<code>SQLCODE</code>/<code>SQLERRM</code> completo quando há erro) — <strong>deliberadamente não
guarda o prompt ou a resposta completos</strong>, só o tamanho, por privacidade e para não inchar a
tabela.</p>
<h2>Consultas prontas</h2>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Erros recentes (últimas 24h)</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">SELECT log_ts, calling_object, operation, provider, model_name,
error_code, error_message
FROM TB_26AI_TECH_LOG
WHERE status = 'ERROR'
AND log_ts >= SYSTIMESTAMP - INTERVAL '24' HOUR
ORDER BY log_ts DESC;</code></pre>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Taxa de erro por dia e por função/modelo</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">SELECT TRUNC(log_ts) AS dia, calling_object, model_name,
COUNT(*) AS total,
SUM(CASE WHEN status = 'ERROR' THEN 1 ELSE 0 END) AS erros,
ROUND(100 * SUM(CASE WHEN status = 'ERROR' THEN 1 ELSE 0 END) / COUNT(*), 1) AS pct_erro
FROM TB_26AI_TECH_LOG
GROUP BY TRUNC(log_ts), calling_object, model_name
ORDER BY dia DESC, pct_erro DESC;</code></pre>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Chamadas mais lentas</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">SELECT log_ts, calling_object, operation, model_name, duration_ms, status
FROM TB_26AI_TECH_LOG
WHERE duration_ms IS NOT NULL
ORDER BY duration_ms DESC
FETCH FIRST 20 ROWS ONLY;</code></pre>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Qual registro de negócio está falhando</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">SELECT l.log_ts, l.source_type, l.source_id, l.error_message,
v.asset_name, v.definition_name
FROM TB_26AI_TECH_LOG l
LEFT JOIN TB_26AI_TECH_v2 v ON v.rowid = CHARTOROWID(l.source_id)
WHERE l.status = 'ERROR'
AND l.source_id IS NOT NULL
ORDER BY l.log_ts DESC;</code></pre>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Purga do log (usa AI_LOG_RETENTION_DAYS)</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">DECLARE
v_days TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE;
BEGIN
SELECT param_value INTO v_days FROM TB_26AI_TECH_PARAMS WHERE param_name = 'AI_LOG_RETENTION_DAYS';
DELETE FROM TB_26AI_TECH_LOG WHERE log_ts < SYSTIMESTAMP - NUMTODSINTERVAL(v_days, 'DAY');
COMMIT;
END;
/</code></pre>
</div>
<h2>Application Settings do APEX — uma segunda fonte de configuração</h2>
<p>A funcionalidade "AI Insight" (lupa na lista de vulnerabilidades) <strong>não</strong> lê
<code>EMBEDDING_COMPARTMENT</code> direto de <code>TB_26AI_TECH_PARAMS</code> — o processo da página
81 chama <code>apex_app_setting.get_value('OCI_CREDENTIAL')</code> e
<code>apex_app_setting.get_value('COMPARTMENT_ID')</code>, valores configurados
<strong>dentro do próprio APEX</strong> (App Builder → Shared Components → Application Settings),
totalmente separados da tabela de configuração do banco. Descobrimos isso em 2026-07-24 depois de
corrigir tudo no banco e a lupa continuar falhando — os dois lugares tinham valores diferentes.</p>
<div class="table-wrap">
<table>
<tr><th>Application Setting (APEX)</th><th>Deve bater com</th></tr>
<tr><td><code>OCI_CREDENTIAL</code></td><td><code>OCI_CRED</code> (nome da credencial da Seção 3)</td></tr>
<tr><td><code>COMPARTMENT_ID</code></td><td>o mesmo valor de <code>EMBEDDING_COMPARTMENT</code> em <code>TB_26AI_TECH_PARAMS</code></td></tr>
<tr><td><code>REGION</code></td><td>o mesmo valor de <code>GENAI_REGION</code> em <code>TB_26AI_TECH_PARAMS</code></td></tr>
</table>
</div>
<p>Não há uma view SQL simples e confiável pra conferir isso via Database Actions (evite adivinhar o
nome — já tentamos <code>apex_application_settings</code> com colunas erradas e perdemos tempo);
confira direto no App Builder: abra a aplicação → <strong>Shared Components</strong> →
<strong>Application Settings</strong>, e compare os três valores acima com a
<code>TB_26AI_TECH_PARAMS</code> atual. Sempre que corrigir <code>EMBEDDING_COMPARTMENT</code> ou
<code>GENAI_REGION</code> no banco, atualize também aqui — são dois lugares de armazenamento
independentes, corrigir um não corrige o outro.</p>
<h2>Ferramentas nativas — sem código novo</h2>
<div class="grid">
<div class="card"><h4>ADB Performance Hub</h4><p>Saúde do banco (CPU, I/O, sessões, SQL Monitor) direto no Console OCI, sem instrumentação extra.</p></div>
<div class="card"><h4>OCI Cost Analysis</h4><p>Custo real do Generative AI, filtrado por serviço/compartimento — complementa o <code>TB_26AI_TECH_LOG</code> (que dá contagem/latência, não valor faturado).</p></div>
<div class="card"><h4>Activity Reports (páginas 10020-10026)</h4><p>Atividade de usuário/sessão e erros não tratados do APEX, já vêm prontas na aplicação (<code>apex_activity_log</code>).</p></div>
</div>
<div class="callout warning">
<div class="callout-title">Job de geração em lote (JOB_26AI_TECH_VULNERABILIDADE)</div>
<p>O botão "Gerar Insights em Lote" cria um job que roda a cada 20 segundos. Antes desta versão,
ele nunca se auto-encerrava — ficava rodando indefinidamente até alguém clicar em "parar",
consumindo chamadas de IA mesmo sem linhas pendentes. Agora ele mesmo verifica, a cada execução,
se ainda há registros com <code>insight_report</code> nulo e se auto-remove
(<code>DBMS_SCHEDULER.stop_job</code>/<code>drop_job</code>) quando não sobra nada para processar.
Confirme isso rodando <code>SELECT job_name, state FROM dba_scheduler_jobs WHERE job_name = 'JOB_26AI_TECH_VULNERABILIDADE';</code>
depois de um lote — não deve mais retornar linha quando o processamento terminar.</p>
</div>
<div class="pillnav"><a class="prev" href="08-glossario-roadmap.html">&larr; Glossário & roadmap</a></div>
</main>
</div>
<script src="assets/main.js"></script>
</body>
</html>