Pular para o conteúdo principal

Telemetria com o Application Insights

Telemetria opcional do Azure Application Insights sobre o pipeline de assinatura — como habilitá-la, o que é coletado, o que é intencionalmente excluído e as consultas KQL para encontrar gargalos.

observação

A telemetria vem desligada por padrão. Com ela desabilitada, o serviço não tem dependência do Application Insights e não faz conexões de saída em nome dele. Tudo nesta página descreve uma funcionalidade opcional.

Em resumo​

PerguntaResposta
Como habilitar?Defina Telemetry:Enabled = true e forneça uma connection string (Telemetry:ConnectionString ou a variável de ambiente APPLICATIONINSIGHTS_CONNECTION_STRING).
Estado padrão?Desligado.
Qual é o SDK?A distro do Azure Monitor OpenTelemetry — activities e meters padrão do OpenTelemetry, não o SDK clássico do Application Insights.
O que é coletado?Um trace correlacionado por job, os passos do ciclo de vida como span events, chamadas do PKI SDK como dependências, métricas de duração de assinatura e de processamento total, e exceções de processamento.
O que é excluído?Logs (logs estruturados não são encaminhados), segredos (mascarados), conteúdo de arquivos, material de certificado e o caminho remoto do Lacuna Signer.
Quais tabelas do Application Insights?Spans → dependencies; métricas → customMetrics; exceções → exceptions; requisições web coletadas automaticamente → requests. Não há customEvents — veja abaixo.

Escopo: esta página cobre a assinatura local. O fluxo remoto do Lacuna Signer é apenas parcialmente rastreado — veja O que é intencionalmente excluído.

Habilitando o Application Insights​

1. Crie o recurso e copie a connection string​

Crie um recurso do Application Insights no portal do Azure e copie sua connection string (painel Overview → Connection String). Ela tem este formato:

InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://<region>.in.applicationinsights.azure.com/;LiveEndpoint=https://<region>.livediagnostics.monitor.azure.com/

2. Configure o Bulk Signer​

A connection string carrega a instrumentation key e é tratada como um segredo — nunca faça commit dela. Prefira a variável de ambiente.

Opção A — variável de ambiente (recomendada):

# Linux / Docker
export Telemetry__Enabled=true
export APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=...;IngestionEndpoint=https://.../"
# Windows
[Environment]::SetEnvironmentVariable("Telemetry__Enabled", "true", "Machine")
[Environment]::SetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING", "InstrumentationKey=...;IngestionEndpoint=https://.../", "Machine")

Opção B — arquivo de configuração do operador (por exemplo, appsettings.Production.json):

{
"Telemetry": {
"Enabled": true,
"ConnectionString": "InstrumentationKey=...;IngestionEndpoint=https://.../",
"RoleName": "Lacuna.BulkSigner"
}
}
ChaveTipoPadrãoOverride por envObservações
Telemetry:EnabledboolfalseTelemetry__EnabledChave mestra. Quando true, uma connection string é obrigatória — o serviço se recusa a iniciar sem ela.
Telemetry:ConnectionStringstring""Telemetry__ConnectionStringSECRET. Deixe vazia para usar a variável de ambiente padrão abaixo.
(variável de ambiente padrão)string(não definida)APPLICATIONINSIGHTS_CONNECTION_STRINGLida diretamente pela distro e respeitada pelo validador de inicialização. Use-a para manter o segredo fora dos arquivos de configuração.
Telemetry:RoleNamestringLacuna.BulkSignerTelemetry__RoleNameInformado como cloud_RoleName, para que vários serviços no mesmo recurso continuem distinguíveis.

3. Reinicie e verifique​

Reinicie o serviço. Um ou dois minutos depois de processar um job, você deve ver entradas no recurso do Application Insights: uma linha em dependencies chamada signing.job por job, dependências filhas Lacuna.Pki … e linhas em customMetrics para bulksigner.signing.duration e bulksigner.job.duration.

O que é coletado​

Traces — span por job mais eventos de ciclo de vida​

Cada job abre um span raiz (signing.job, tipo Internal, que aparece no Application Insights como dependencies) no momento da captura, com as tags job.id, signing.profile, signing.method e signing.format. Cada passo abaixo é registrado como um span event nesse span, de modo que todos compartilham o mesmo operation_Id para correlação:

EventoQuando
JobCreatedNo enfileiramento (um trace signing.job.created independente — o span do worker ainda não existe)
JobPickedForProcessingO worker reivindica o job
SigningStarted / SigningCompletedEm torno da chamada de assinatura local
VerificationStarted / VerificationCompletedEm torno da chamada de verificação (somente quando o perfil tem Verify = true)
OutputFileCreatedArtefato assinado promovido para output/
JobCompletedSucesso terminal (status do span Ok)
JobFailedFalha terminal (status do span Error)
JobCanceledCancelamento pelo operador (um trace signing.job.canceled independente)
DispatchedToSignerJob entregue ao Lacuna Signer (caminho remoto — cobertura parcial)
Cnab240PaymentDateCheckSkippedUma remessa CNAB240 cuja data de pagamento mais antiga já havia passado foi liberada em vez de recusada, porque a verificação da data de pagamento do perfil (ou a verificação de CNAB240) está desligada — uma decisão, não uma assinatura

Dependências — chamadas do PKI SDK​

As chamadas de assinatura e verificação do Lacuna PKI SDK são encapsuladas em spans filhos do tipo Client, chamados Lacuna.Pki SignAsync e Lacuna.Pki VerifyAsync, que aparecem como dependencies. Cada um tem sua própria duração e uma flag de sucesso; uma chamada que falhou é marcada como Error, com uma mensagem mascarada, para que chamadas externas com problema fiquem visíveis com contexto de diagnóstico.

Métricas — customMetrics​

MétricaUnidadeDimensões
bulksigner.signing.durationmssigning.method, signing.profile, signing.format, job.status (Success / Failed)
bulksigner.job.durationmsjob.status (Success / Failed), signing.profile, signing.method

O bulksigner.signing.duration é o tempo decorrido da própria operação de assinatura; o bulksigner.job.duration é o total, da criação do job até o estado terminal.

Exceções — exceptions​

Exceções de processamento tratadas e não tratadas são registradas no span do job com o id do job, o perfil, o método de assinatura e o passo de processamento em que o erro ocorreu. Mensagens e stack traces são mascarados antes de deixarem o processo.

O que é intencionalmente excluído​

  • Segredos. A licença do PKI, senhas de certificado e de PFX, o PIN do PKCS#11, o client secret do Azure Key Vault, chaves de API, a senha de criptografia e connection strings são mascarados em todo valor anexado à telemetria — inclusive mensagens de exceção e stack traces. Veja Segurança.
  • Conteúdo de arquivos e material de certificado. Nunca são anexados a nenhum span, evento ou métrica.
  • Logs da aplicação. Logs estruturados não são encaminhados ao Application Insights. Somente spans, métricas e exceções explicitamente registradas são enviados; os logs permanecem nos destinos de arquivo e de console.
  • O id do job como dimensão de métrica. Mantido fora dos histogramas para limitar a cardinalidade; a medição de tempo por job fica nos spans correlacionados.
  • O caminho remoto do Lacuna Signer. A cobertura prioriza a assinatura local. Um job remoto emite apenas um span da captura até o despacho; a espera pelo assinante e a conclusão remota não são rastreadas.

Consultas de exemplo (KQL)​

Execute estas consultas no recurso do Application Insights (painel Logs). Ajuste o intervalo de tempo conforme necessário.

Tempo médio de assinatura (local), últimas 24 h:

customMetrics
| where name == "bulksigner.signing.duration"
| where timestamp > ago(24h)
| summarize avg(value), percentiles(value, 50, 95) by tostring(customDimensions["signing.profile"])

Jobs de assinatura mais lentos:

dependencies
| where name == "signing.job"
| where timestamp > ago(24h)
| project timestamp, jobId = tostring(customDimensions["job.id"]),
profile = tostring(customDimensions["signing.profile"]), duration, success
| top 20 by duration desc

Falhas de assinatura por método de assinatura:

customMetrics
| where name == "bulksigner.signing.duration"
| where tostring(customDimensions["job.status"]) == "Failed"
| summarize failures = count() by method = tostring(customDimensions["signing.method"])

Tempo médio total de processamento:

customMetrics
| where name == "bulksigner.job.duration"
| where tostring(customDimensions["job.status"]) == "Success"
| summarize avg(value), percentiles(value, 50, 95)

Chamadas do PKI SDK que falharam (diagnóstico de chamadas externas):

dependencies
| where name startswith "Lacuna.Pki"
| where success == false
| project timestamp, name, jobId = tostring(customDimensions["job.id"]),
operation = tostring(customDimensions["pki.operation"]), resultCode
| order by timestamp desc

Exceções de processamento por passo:

exceptions
| where timestamp > ago(24h)
| summarize count() by step = tostring(customDimensions["processing.step"]), type
| order by count_ desc

Por que não há customEvents​

O Bulk Signer usa a distro do Azure Monitor OpenTelemetry, que não tem equivalente ao TrackEvent — o OpenTelemetry não tem uma primitiva de "evento personalizado". Por isso, os passos do ciclo de vida são modelados como span events no span por job e consultados pela tabela dependencies e seu customDimensions, e não por customEvents. Consultas escritas para uma aplicação com o SDK clássico precisarão ser adaptadas.

Relacionados​

  • Estatísticas de jobs — os tempos por etapa do dashboard, mantidos no banco de dados operacional e lidos no escopo de toda a implantação.
  • API REST — o endpoint Prometheus /api/metrics, o registro durável, baseado em coleta (scrape).
  • Configuração — cada chave de configuração.
  • Segurança — tratamento de segredos e o mascaramento de logs em duas camadas.

A seguir: API REST — endpoints, autenticação e o envelope de erro. Anterior: Estatísticas de jobs.