Pesquisa de site

Como configurar formatos personalizados de acesso e log de erros no Nginx


O servidor Nginx HTTP possui um recurso de registro fenomenal que é altamente personalizável. Neste artigo, explicaremos como configurar seus próprios formatos de acesso e logs de erros para Nginx no Linux.

O objetivo deste guia é ajudá-lo a entender como os logs são gerados, de modo a configurar formatos de log personalizados para fins de depuração, solução de problemas ou análise do que acontece em seu servidor web, bem como em aplicativos web (como solicitações de rastreamento).

Leia também: 4 boas ferramentas de gerenciamento e monitoramento de log de código aberto para Linux

Este artigo é composto de três seções que irão esclarecê-lo sobre como configurar logs de acesso/erro e como habilitar o log condicional no Nginx.

Configurando logs de acesso no Nginx

No Nginx, todas as solicitações do cliente ao servidor são registradas no log de acesso em um formato especificado usando o módulo ngx_http_log_module.

O arquivo de log padrão é log/access.log (geralmente /var/log/nginx/access_log em sistemas Linux) e o formato padrão para registro é normalmente o combinado ou principal formato (isso pode variar de uma distribuição para outra).

A diretiva access_log (aplicável em http, servidor, local, se estiver em local e limite exceto contexto) é usada para definir o arquivo de log e a diretiva log_format (aplicável sob o somente contexto http) é usado para definir o formato do log. O formato do log é descrito por variáveis comuns e variáveis geradas apenas no momento em que um log é gravado.

A sintaxe para configurar um formato de log é:

log_format format_name 'set_of_variables_to_define_format';

e a sintaxe para configurar o log de acesso é:

access_log /path/to/log_file format_name;		#simplest form 
OR
access_log /path/to/log_file [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

A seguir está um trecho do arquivo de configuração padrão do Nginx /etc/nginx/nginx.conf no CentOS 7.

http {
	#main log format 
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                               '$status $body_bytes_sent "$http_referer" '
                               '"$http_user_agent" "$http_x_forwarded_for"';

	access_log /var/log/nginx/access.log;
}

Este formato de log produz a seguinte entrada de log.

127.0.0.1 - dbmanager [20/Nov/2017:18:52:17 +0000] "GET / HTTP/1.1" 401 188 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"

A seguir está outro formato de registro útil que usamos para rastrear solicitações para nossos aplicativos da web usando algumas das variáveis padrão. O mais importante é que ele possui o ID da solicitação e registra os detalhes da localização do cliente (país, código do país, região e cidade).

log_format  custom '$remote_addr - $remote_user [$time_local] '
                         	     '"$request" $status $body_bytes_sent '
                      		     '"$http_referer" "$http_user_agent" '
                     		     '"$http_x_forwarded_for" $request_id '
                   		     '$geoip_country_name $geoip_country_code '
                  		     '$geoip_region_name $geoip_city ';

Você pode usá-lo assim:

access_log  /var/log/nginx/access.log custom;

Isso produzirá uma entrada de log semelhante a esta.

153.78.107.192 - - [21/Nov/2017:08:45:45 +0000] "POST /ngx_pagespeed_beacon?url=https%3A%2F%2Fwww.example.com%2Fads%2Ffresh-oranges-1509260795 HTTP/2.0" 204 0 "https://www.suasell.com/ads/fresh-oranges-1509260795" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" a02b2dea9cf06344a25611c1d7ad72db Uganda UG Kampala Kampala 

Você pode especificar vários logs usando as diretivas access_log no mesmo nível, aqui estamos usando mais de um arquivo de log no contexto http.

http{
	##default log format
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                	      '$status $body_bytes_sent "$http_referer" '
                                         '"$http_user_agent" "$http_x_forwarded_for"';
      
	##request tracing using custom format
	log_format custom '$remote_addr - $remote_user [$time_local] '
                                           '"$request" $status $body_bytes_sent '
                                           '"$http_referer" "$http_user_agent" '
                                           '"$http_x_forwarded_for" $request_id '
                                           '$geoip_country_name $geoip_country_code '
                                          '$geoip_region_name $geoip_city ';

	##this uses the default log format
	access_log /var/log/nginx/access.log;

	##this uses the our custom log format
	access_log /var/log/nginx/custom_log custom;
}

A seguir estão exemplos de configurações de log mais avançadas, que são úteis para formatos de log que contêm variáveis relacionadas à compactação e para criar arquivos de log compactados:

access_log /var/log/nginx/custom_log custom buffer 32k;
access_log /path/to/log.gz compression  gzip  flush=5m;

Configurando logs de erros no Nginx

Caso o Nginx apresente alguma falha, ele registra informações relacionadas a ela no log de erros. Esses problemas se enquadram em diferentes níveis de gravidade: depuração, informações, aviso, aviso, erro (este é o nível padrão e funciona globalmente), crit, alert ou emerg.

O arquivo de log padrão é log/error.log, mas normalmente está localizado em /var/log/nginx/ nas distribuições Linux. A diretiva error_log é usada para especificar o arquivo de log e pode ser usada no contexto principal, http, mail, stream, server, location (nessa ordem).

Você também deve observar que:

  • As configurações no contexto principal são sempre herdadas pelos níveis inferiores na ordem acima.
  • e as configurações nos níveis inferiores substituem as configurações herdadas dos níveis superiores.

Você pode configurar o log de erros usando a seguinte sintaxe:

error_log /path/to/log_file log_level;

Por exemplo:

error_log /var/log/nginx/error_log warn; 

Isso instruirá o Nginx a registrar todas as mensagens do tipo warn e níveis de log mais graves crit, alert e emerg mensagens.

No próximo exemplo, mensagens de níveis crit, alert e emerg serão registradas.

error_log /var/www/example1.com/log/error_log crit;

Considere a configuração abaixo, aqui definimos o log de erros em diferentes níveis (no contexto http e servidor). Em caso de erro, a mensagem é gravada em apenas um log de erros, aquele mais próximo do nível onde o erro apareceu.

http {
	log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';
	
	error_log  /var/log/nginx/error_log  crit;

    	server {
		listen 80;
		server_name example1.com;

		#this logs errors messages for example1.com only
      		error_log  /var/log/nginx/example1.error_log  warn;
            	…...
	}

     	server {
		listen 80;
		server_name  example2.com;

		#this logs errors messages for example2.com only
        		error_log  /var/log/nginx/example1.error_log;
        		…….
    	}
}

Se você usar mais de uma diretiva error_log como na configuração abaixo (mesmo nível), as mensagens serão gravadas em todos os logs especificados.

server {
		listen 80;
		server_name example1.com;

      		error_log  /var/www/example1.com/log/error_log  warn;
		error_log  /var/log/nginx/example1.error_log  crit;
            	…...
	}

Configurando o log condicional no Nginx

Em alguns casos, podemos querer que o Nginx execute o registro condicional de mensagens. Nem todas as mensagens precisam ser registradas pelo Nginx, portanto, podemos ignorar entradas de log insignificantes ou menos importantes de nossos logs de acesso para instâncias específicas.

Podemos usar o módulo ngx_http_map_module que cria variáveis cujos valores dependem dos valores de outras variáveis. Os parâmetros dentro de um bloco de mapa (que deve existir apenas no conteúdo http) especificam um mapeamento entre os valores de origem e resultantes.

Para este tipo de configuração, uma solicitação não será registrada se a condição for avaliada como “0 ” ou como uma string vazia. Este exemplo exclui solicitações com códigos de status HTTP 2xx e 3xx.

http{
	map $status $condition {
		~^[23] 0;
    		default 1;
	}
	server{
		access_log  /path/to/access.log  custom if=$condition;
	}
}

Aqui está outro exemplo útil para depurar um aplicativo da web em fase de desenvolvimento. Isso ignorará todas as mensagens e registrará apenas as informações de depuração.

 
http{
	map $info  $debuggable { 
    		default     0; 
    		debug       1; 
	} 
	server{
		……..
		access_log /var/log/nginx/testapp_debug_access_log  debug if=$debuggable; 
		#logs other requests 
		access_log  /var/log/nginx/testapp_access.log  main; 
		…….
	}
}

Você pode encontrar mais informações, incluindo registro no syslog aqui.

É tudo por agora! Neste guia, explicamos como configurar o formato de log personalizado para logs de acesso e erros no Nginx. Use o formulário de feedback abaixo para fazer perguntas ou compartilhar suas idéias sobre este artigo.