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 eu ligo isso?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 eventos de span, 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.

Nota de escopo: isto 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 de Visão geral → Connection String). Ela se parece com:

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 a versione. 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 honrada pelo validador de inicialização. Use esta para manter o segredo fora dos arquivos de configuração.
Telemetry:RoleNamestringLacuna.BulkSignerTelemetry__RoleNameReportado como cloud_RoleName, de modo que vários serviços em um mesmo recurso continuem distinguíveis.

3. Reinicie e verifique

Reinicie o serviço. Dentro de um ou dois minutos após 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, aparecendo no Application Insights como dependencies) na captura, marcado com job.id, signing.profile, signing.method e signing.format. Cada passo abaixo é registrado como um evento de span naquele span, de modo que todos compartilham seu operation_Id para correlação:

EventoQuando
JobCreatedNo enfileiramento (um trace signing.job.created autônomo — 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 autônomo)
DispatchedToSignerJob entregue ao Lacuna Signer (caminho remoto — cobertura parcial)

Dependências — chamadas do PKI SDK

As chamadas de assinatura e verificação do Lacuna PKI SDK são envolvidas em spans filhos do tipo Client, chamados Lacuna.Pki SignAsync e Lacuna.Pki VerifyAsync, aparecendo como dependencies. Cada um carrega sua própria duração e uma flag de sucesso; uma chamada falha é marcada como Error com uma mensagem mascarada, de modo que chamadas externas quebradas 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 de todo valor anexado à telemetria — inclusive mensagens de exceção e stack traces. Veja Segurança.
  • Conteúdo de arquivos e material de certificado. Nunca anexados a span, evento ou métrica alguma.
  • 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 cronometragem por job vive 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 assinador e a conclusão remota não são rastreadas.

Consultas de exemplo (KQL)

Rode estas 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 customizado". Os passos do ciclo de vida são, portanto, modelados como eventos de span no span por job e consultados pela tabela dependencies e seu customDimensions, e não por customEvents. Consultas escritas contra uma aplicação com o SDK clássico precisarão de adaptação.

Relacionados

  • Estatísticas de jobs — os tempos por etapa do dashboard, mantidos na base operacional e lidos no escopo da implantação.
  • API REST — o endpoint Prometheus /api/metrics, o registro durável baseado em coleta.
  • 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.