# Gerenciamento de logs

### Ativar o registo no Azure Monitor

Desde a versão 3.0, o SCEPman, bem como o Certificate Master, utilizarão a API de Log Ingestion da Microsoft para escrever registos no Azure Monitor. Isto utiliza o conceito de um Log Analytics Workspace para armazenar os dados e permitir a análise, bem como uma Data Collection Rule que faz a interface entre o App Service e o armazenamento de registos. Isto permite uma abordagem mais moderna, incluindo permissões baseadas em RBAC para o SCEPman aceder ao LAW.

A criação do Log Analytics Workspace, bem como a configuração da Data Collection Rule, é feita automaticamente ao executar `Complete-SCEPmanInstallation` do módulo PowerShell do SCEPman.

{% hint style="info" %}
O **retenção predefinida** o período para dados armazenados numa Log Analytics Table é **30 dias**. Caso seja necessário um período de retenção diferente, ajuste a configuração da tabela "SCEPman\_CL" em conformidade.
{% endhint %}

#### Reativar a Data Collector API

Se, por qualquer motivo, quiser reinstaurar a API anterior a ser utilizada, pode fazê-lo removendo as variáveis do App Service relacionadas com a Log Ingestion e adicionando novamente as variáveis a serem utilizadas pela Data Collector API.

Variáveis a **remover**:

* [AppConfig:LoggingConfig:DataCollectionEndpointUri](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-datacollectionendpointuri)
* [AppConfig:LoggingConfig:RuleId](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-ruleid)

Variáveis a adicionar:

* [AppConfig:LoggingConfig:WorkspaceId](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-workspaceid)
* [AppConfig:LoggingConfig:SharedKey](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-sharedkey)

O SCEPman irá detetar automaticamente as definições após um reinício e utilizará novamente a Data Collector API.

## Exemplos de consultas KQL

### Ver problemas na sua instância do SCEPman

```kusto
SCEPman_CL
| where Level == "Warn" or Level == "Error" or Level == "Fatal"
```

### Número de certificados emitidos por endpoint no período de tempo selecionado

{% hint style="success" %}
Esta consulta é garantidamente compatível com o SCEPman 3.0 e versões posteriores quando se utiliza a Log Ingestion API para registo. Alterações no SCEPman que tornem esta consulta inutilizável serão consideradas Breaking Changes.
{% endhint %}

{% tabs %}
{% tab title="Log Ingestion API (predefinida)" %}

```kql
SCEPman_CL
| where Level == "Info" and Message startswith_cs "Issued a certificate with serial number"
| project Message, RequestBase = trim_end('/', replace_string(replace_string(replace_regex(RequestUrl, "(/pkiclient\\.exe)?(\\?operation=PKIOperation(&message=.+)?)?", ""),"certsrv/mscep/mscep.dll","intune"),"step/enrollment","activedirectory"))
| summarize IssuanceCount = count() by Endpoint = extract("/([a-zA-Z]+)$", 1, RequestBase)
```

{% endtab %}

{% tab title="Data Collector API (antiga)" %}

```kusto
SCEPman_CL
| where Level == "Info" and Message startswith_cs "Issued a certificate with serial number"
| project Message, RequestBase = trim_end('/', replace_string(replace_string(replace_regex(RequestUrl_s, "(/pkiclient\\.exe)?(\\?operation=PKIOperation(&message=.+)?)?", ""),"certsrv/mscep/mscep.dll","intune"),"step/enrollment","activedirectory"))
| summarize IssuanceCount = count() by Endpoint = extract("/([a-zA-Z]+)$", 1, RequestBase)
```

{% endtab %}
{% endtabs %}

A partir do SCEPman 2.8, existe sempre exatamente uma entrada de registo de nível Info cujo texto de registo começa com "Issued a certificate with serial number " por cada certificado emitido, seguida do respetivo número de série. No entanto, devido ao insolúvel [Problema dos Dois Exércitos](https://en.wikipedia.org/wiki/Two_Generals'_Problem), pode acontecer que o certificado criado nunca chegue ao requerente ou que algum outro tipo de erro impeça o registo efetivo. Da mesma forma, em caso de erros graves, pode acontecer que exista uma entrada de registo sem entrada correspondente na base de dados, ou vice-versa.

### Certificados distintos com verificação OCSP

{% tabs %}
{% tab title="Log Ingestion API (predefinida)" %}

```kusto
let map_certtype = datatable(serial_start:string, readable:string)
[
  "40", "Intune Device",
  "41", "Intune Device",
  "42", "Intune Incompliant Device",
  "50", "Static",
  "51", "Static",
  "60", "Intune User",
  "61", "Intune User",
  "64", "Jamf User",
  "65", "Jamf User",
  "6C", "Jamf User on Device",
  "6D", "Jamf User on Device",
  "70", "Domain Controller",
  "7C", "Jamf User on Computer",
  "7D", "Jamf User on Computer",
  "54", "Jamf Computer",
  "55", "Jamf Computer",
  "44", "Jamf Device",
  "45", "Jamf Device"
];
SCEPman_CL
| where LogCategory == "Scepman.Server.Controllers.OcspController" and Level == "Info"
| where Message startswith_cs "OCSP Response"
| project serial = extract("Serial Number ([A-F0-9]+)", 1, Message)
| distinct serial
| extend serial_start = substring(serial,0,2)
| join kind=leftouter map_certtype on serial_start
| summarize count() by (readable)
```

{% endtab %}

{% tab title="Data Collector API (antiga)" %}

```kql
let map_certtype = datatable(serial_start:string, readable:string)
[
  "40", "Intune Device",
  "41", "Intune Device",
  "42", "Intune Incompliant Device",
  "50", "Static",
  "51", "Static",
  "60", "Intune User",
  "61", "Intune User",
  "64", "Jamf User",
  "65", "Jamf User",
  "6C", "Jamf User on Device",
  "6D", "Jamf User on Device",
  "70", "Domain Controller",
  "7C", "Jamf User on Computer",
  "7D", "Jamf User on Computer",
  "54", "Jamf Computer",
  "55", "Jamf Computer",
  "44", "Jamf Device",
  "45", "Jamf Device"
];
SCEPman_CL
| where LogCategory_s == "Scepman.Server.Controllers.OcspController" and Level == "Info"
| where Message startswith_cs "OCSP Response"
| project serial = extract("Serial Number ([A-F0-9]+)", 1, Message)
| distinct serial
| extend serial_start = substring(serial,0,2)
| join kind=leftouter map_certtype on serial_start
| summarize count() by (readable)
```

{% endtab %}
{% endtabs %}
