CONTEÚDO

01. VISÃO GERAL
O RM TRACKLOG é o motor de logs do RM responsável por disponibilizar informações sobre o sistema através de arquivos de texto contendo data e hora do evento e mensagens criadas de forma automática.
Portanto, com o TRACKLOG, os logs são capazes de mostrar o que, quando e onde aconteceu um evento, além de indicar quem deu início a ele.
1.1 O TRACKLOG REGISTRA VÁRIOS NÍVEIS (LEVEL) DE LOG
Ordem | Nível (Level) | Identificado no arquivo | Uso |
---|
0 | Verbose | [VRB] | Verbose é o nível mais ruidoso, raramente (ou nunca) habilitado para um aplicativo de produção. |
1 | Debug | [DBG] | Debug é usado para eventos internos do sistema que não são necessariamente observáveis de fora, mas são úteis para determinar como algo aconteceu. |
2 | Information | [INF] | Os eventos de informação descrevem coisas que acontecem no sistema que correspondem às suas responsabilidades e funções. Geralmente estas são as ações observáveis que o sistema pode realizar. |
3 | Warning | [WRN] | Quando o serviço está degradado, em perigo ou pode estar se comportando fora de seus parâmetros esperados, os eventos de nível de aviso são usados. |
4 | Error | [ERR] | Quando a funcionalidade não está disponível ou as expectativas são quebradas, um evento de Erro é usado. |
5 | Fatal | [FTL] | O nível mais crítico, os eventos fatais exigem atenção imediata. |
1.2 INFORMAÇÕES CONTIDAS NO ARQUIVO DE LOG
O arquivo de log é escrito conforme um template padrão (outputTemplate):
"{SourceContext}{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} ({EnvironmentName}|{EnvironmentUserName}) <{ThreadId}:{ThreadName}>[{ProcessId}:{ProcessName}] [{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] [{Module}, {Category}, {Funcionality}] {NewLine}{Exception}" |
Propriedades do templete | Exemplo de dados logado | Descrição |
---|
{SourceContext} | RM.Lib.Monitoring.Tracklog.Test.LogUnitTest | Contexto onde o log se encontra. Geralmente o namespace da classe que está usando o TrackLog. |
{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} | 2022-08-30 17:44:44.870 -03:00 | Data e hora do evento. |
{Legacy} | [LGC] | Registros do sistema antigo de log são identificado com a tag [LGC] |
[{Level:u3}] | [INF] | Nível (level) do evento. |
{Tenant} | shared-environment | Identifica o Tenant do evento. Esse item é acoplado à mensagem. |
{Message:lj} | Information log test | Mensagem do evento. |
({EnvironmentName}|{EnvironmentUserName}) | (Production|BH01\carlos.almeida) | Nome do ambiente e do usuário. |
<{ThreadId}:{ThreadName}> | <13:Host> | ThreadId e ThreadName do evento. |
[{ProcessId}:{ProcessName}] | [36956:Host.exe] | ProcessId e ProcessName do evento. |
[{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] | [Lib\RM.Lib.Monitoring.Tracklog.TesteUnitario\LogUnitTest.cs - (114) - Should_Write_Info_Log] | Arquivo de onde foi registrado o evento de log com o número da linha e o método que o chamou. |
[{Module}, {Category}, {Funcionality}] | [RMLib, SmartClient, Configuracao] | Módulo, categoria e funcionalidade do sistema onde o evento ocorreu. |
{NewLine}{Exception} | NullReferenceException: Write Error Log Exception ---> System.Exception: Should_Write_Error_Log | Warning, Error e Fatal é registrado e uma nova linha com a exceção |
02. COMO CONFIGURAR
O TRACKLOG é configurado através do arquivo JSON appsettings.log.json, o qual deve ficar no diretório raiz do sistema RM. Caso o arquivo não seja encontrado, o sistema assume as configurações padrões.
O conteúdo do arquivo de configuração é divido em algumas sessões, conforme detalhado a seguir.
2.1 SESSÕES DO ARQUIVO DE CONFIGURAÇÃO
A a sessão principal do arquivo de configuração é a "Serilog", onde é informado como o sistema deve escrever o arquivo de log e os recursos que serão utilizados:
Sessão Principal | Subsesões | Pode ser alterado? |
|
---|
Serilog |
|
| Using | Não | Recursos usados pelo Serilog |
Enrich | Não | Informações usadas para enriquecer os dados do log. |
MinimumLevel | Sim | Nível mínimo que deve ser registrado. 0-Verbose, 1-Debug, 2 - Information, 3-Warning, 4-Error, 5-Fatal |
Filter | Sim | Usa expressão para filtrar eventos que passam pelo pipeline Serilog - Opções de Name: ByExcluding ou ByIncludingOnly |
WriteTo | Somente os argumentos na subseção Args da MapToFile | Define como e onde o log deve ser escrito e salvo. |
Sessão que configura a escrita no arquivo de log
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MapToFile",
"Args": {
Propriedade | Descrição |
---|
enable | A propriedade "enable" tem como objetivo desabilitar o recurso de escrita de log em arquivo. Por padrão, o valor dessa propriedade é definido como "false", indicando que o recurso está desativado. |
path | Caminho onde o arquivo de log vai ser salvo Formato: Os diretórios devem ser separados por duas barras invertidas \\ ou uma barra normal / Exemplo: "path": "C:\\TOTVS\\RM\\Logs\\" ✔️ "path": "C:/TOTVS/RM/Logs/" ✔️ "path": "C:\TOTVS\RM\Logs\" ❌ |
restrictedToMinimumLevel | Somente mensagens de log deste nível ou acima deste nível serão enviadas para este coletor.
|
formatProvider | Fornece informações de formatação específicas da cultura ou null.
Padrão: Null |
outputTemplate | Um modelo de mensagem descrevendo o formato usado para gravar no coletor.
- O padrão é "{SourceContext}{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} ({EnvironmentName}|{EnvironmentUserName}) <{ThreadId}:{ThreadName}>[{ProcessId}:{ProcessName}] [{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] [{Module}, {Category}, {Funcionality}] {NewLine}{Exception}".
|
fileSizeLimitBytes | O tamanho máximo aproximado, em bytes, para o qual um arquivo de log poderá crescer. Para crescimento irrestrito, passe null.
- O padrão é 1073741824 (1 GB). Para evitar escrever eventos parciais, o último evento dentro do limite
será escrito na íntegra mesmo que exceda o limite. |
buffered | Indica se a liberação para o arquivo de saída pode ser armazenada em buffer ou não.
|
shared | Permitir que o arquivo de log seja compartilhado por vários processos.
|
flushToDiskInterval | Se fornecido, uma limpeza completa do disco será executada periodicamente no intervalo especificado. Deve ser maior ou igual a 0. Formato: d.hh:mm:ss d : numero de dias. hh: numero de horas. mm: numero de minuto. ss: numero de segundos. Exemplo: flushToDiskInterval: "2.00:00:00" A limpeza completa do disco será executada a cada dois dias.
|
rollingInterval | O intervalo no qual o registro será transferido para um novo arquivo. RollingInterval |
|
---|
Infinite | O arquivo de log nunca rolará; nenhuma informação de período de tempo será anexada ao nome do arquivo de log. | Year | Role todos os anos. Os nomes dos arquivos terão um ano de quatro dígitos anexado no padrão yyyy. | Month | Role a cada mês do calendário. Os nomes dos arquivos terão yyyyMM anexado. | Day | Role todos os dias. Os nomes dos arquivos terão yyyyMMdd anexado. | Hour | Role a cada hora. Os nomes dos arquivos terão yyyyMMddHH anexado. | Minute | Role a cada minuto. Os nomes dos arquivos terão yyyyMMddHHmm anexado. |
|
rollOnFileSizeLimit | Se True, um novo arquivo será criado quando o limite de tamanho do arquivo for atingido. Nomes de arquivo terá um número anexado no formato _NNN, com o primeiro nome de arquivo sem número. |
retainedFileCountLimit | O número máximo de arquivos de log que serão retidos, incluindo o arquivo de log atual. Para retenção ilimitada, passe null.
|
encoding | Codificação de caracteres usada para escrever o arquivo de texto. Opções: UTF8, UTF7, UTF32, Unicode, BigEndianUnicode, ASCII, Default
|
retainedFileTimeLimit | O tempo máximo após o término de um intervalo em que um arquivo de log contínuo será retido. Deve ser maior ou igual a 0. Ignorado se rollingInterval for Infinite. Formato: d.hh:mm:ss d : numero de dias. hh: numero de horas. mm: numero de minuto. ss: numero de segundos. Exemplo: retainedFileTimeLimit: "6.14:32:15" O arquivo será retido depois de 6 dias 14 horas e 32 minutos e 15 segundos. Caso o valor informado esteja em um formato invalido esse parâmetro será ignorado pelo sistema. |
Sessão que configura a escrita do log no console
"WriteTo": [
{
"Name": "Console",
"Args": {
Propriedade | Descrição |
---|
theme | Define um tema para ser usado ao escrever o log no console |
outputTemplate | Um modelo de mensagem descrevendo o formato usado para gravar no console. Padrão: {Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} {EnvironmentUserName} {EnvironmentName}- <{ThreadId}>{NewLine}{ExceptionDetails} |
Sessão que configura o envio do log para o sistema de monitoramento Seq
"WriteTo": [
{
"Name": "Seq",
"Args": {
Propriedade | Descrição |
---|
serverUrl | Define a url do servidor Seq. |
*O Seq é um servidor de pesquisa e análise em tempo real para dados de log de aplicativos estruturados.
2.2 ARQUIVO DE CONFIGURAÇÃO PADRÃO
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} {EnvironmentUserName} {EnvironmentName}- <{ThreadId}>{NewLine}{ExceptionDetails}"
}
},
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MapToFile",
"Args": {
"enable": false, //para habilitar a escrita em arquivo altere esse valor para 'true'
"rollOnFileSizeLimit": true,
"rollingInterval": "Day",
"fileSizeLimitBytes": 1073741824,
"retainedFileCountLimit": 31,
"outputTemplate": "{SourceContext}{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} ({EnvironmentName}|{EnvironmentUserName}) <{ThreadId}:{ThreadName}>[{ProcessId}:{ProcessName}] [{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] [{Module}, {Category}, {Funcionality}] {NewLine}{Exception}"
}
}
]
}
}
]
}
} |
|
2.3 ARQUIVO DE CONFIGURAÇÃO EXPURGO DE ARQUIVOS
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MapToFile",
"Args": {
"enable": false, //para habilitar a escrita em arquivo altere esse valor para 'true'
"rollOnFileSizeLimit": true, //Habilita um tamanho limite para o arquivo de log
"fileSizeLimitBytes": "52428800", // Especifica o tamanho de cada arquivo de log
"rollingInterval": "Day", //Criar um novo arquivo a cada dia
"retainedFileCountLimit": "100", //Limite máximo de arquivos se ultrapassar esse valor o sistema exclui os mais antigos
"retainedFileTimeLimit": "7.00:00:00", //Exclui arquivos com mais de 7 dias
}
}
]
}
}
]
}
} |
|
2.4 EXEMPLOS DE CONFIGURAÇÕES
2.4.1 Registrar log somente no console
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"WriteTo": [
{
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} {EnvironmentUserName} {EnvironmentName}- <{ThreadId}>{NewLine}{ExceptionDetails}"
}
}
]
}
} |
|
2.4.2 Registrar log somente no Seq
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"WriteTo": [
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341"
}
}
]
}
} |
|
2.4.3 Registrar log somente no Arquivo, excluindo arquivos antigos a cada 7 após serem criados
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MapToFile",
"Args": {
"enable": false, //para habilitar a escrita em arquivo altere esse valor para 'true'
"rollingInterval": "Day",
"fileSizeLimitBytes": "52428800",
"rollOnFileSizeLimit": "true",
"retainedFileCountLimit": "100",
"retainedFileTimeLimit": "7.00:00:00", //Deletes files older than 7 days
"outputTemplate":"{SourceContext}{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} ({EnvironmentName}|{EnvironmentUserName}) <{ThreadId}:{ThreadName}>[{ProcessId}:{ProcessName}] [{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] [{Module}, {Category}, {Funcionality}] {NewLine}{Exception}"
}
}
]
}
}
]
}
} |
|
2.4.4 Registrar logs somente de erro ou superior no Arquivo, excluindo arquivos antigos a cada 7 dias após serem criados.
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"MinimumLevel": "Error",
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MapToFile",
"Args": {
"enable": false, //para habilitar a escrita em arquivo altere esse valor para 'true'
"rollingInterval": "Day",
"fileSizeLimitBytes": "52428800",
"rollOnFileSizeLimit": "true",
"retainedFileCountLimit": "100",
"retainedFileTimeLimit": "7.00:00:00", //Deletes files older than 7 days
"outputTemplate": "{SourceContext}{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} ({EnvironmentName}|{EnvironmentUserName}) <{ThreadId}:{ThreadName}>[{ProcessId}:{ProcessName}] [{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] [{Module}, {Category}, {Funcionality}] {NewLine}{Exception}"
}
}
]
}
}
]
}
} |
|
2.4.5 Definindo o path para especificar onde os arquivos de logs devem ser salvos.
{
"Serilog": {
"Using": [
"Serilog",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Process",
"Serilog.Settings.Configuration",
"Serilog.Sinks.Seq",
"Serilog.Expressions",
"RM.Lib.Monitoring.Tracklog"
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithEnvironmentUserName",
"WithEnvironmentName"
],
"MinimumLevel": "Error",
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MapToFile",
"Args": {
"enable": false, //para habilitar a escrita em arquivo altere esse valor para 'true'
"path": "C:\\TOTVS\\RM\\Logs\\",
"rollingInterval": "Day",
"fileSizeLimitBytes": "52428800",
"rollOnFileSizeLimit": "true",
"retainedFileCountLimit": "100",
"retainedFileTimeLimit": "7.00:00:00", //Deletes files older than 7 days
"outputTemplate":"{SourceContext}{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Legacy} [{Level:u3}] {Message:lj} ({EnvironmentName}|{EnvironmentUserName}) <{ThreadId}:{ThreadName}>[{ProcessId}:{ProcessName}] [{CallerFilePath} - ({CallerLineNumber}) - {CallerMemberName}] [{Module}, {Category}, {Funcionality}] {NewLine}{Exception}"
}
}
]
}
}
]
}
} |
|

Para usar o arquivo após o download, renomeie-o para appsettings.log.json e o coloque dentro do diretório raiz do sistema RM. |