Wyszukiwanie w witrynie

Jak skonfigurować niestandardowe formaty dostępu i dziennika błędów w Nginx


Serwer Nginx HTTP ma fenomenalną funkcję rejestrowania, którą można w dużym stopniu dostosować. W tym artykule wyjaśnimy, jak skonfigurować własne formaty dzienników dostępu i błędów dla Nginx w systemie Linux.

Celem tego przewodnika jest pomoc w zrozumieniu sposobu generowania dzienników, tak aby można było skonfigurować niestandardowe formaty dzienników na potrzeby debugowania, rozwiązywania problemów lub analizy tego, co dzieje się na serwerze internetowym oraz w aplikacjach internetowych (takich jak żądania śledzenia).

Przeczytaj także: 4 dobre narzędzia do monitorowania logów Open Source i zarządzania nimi dla systemu Linux

Ten artykuł składa się z trzech sekcji, które wyjaśnią Ci konfigurowanie dzienników dostępu/błędów oraz włączanie rejestrowania warunkowego w Nginx.

Konfigurowanie dzienników dostępu w Nginx

W Nginx wszystkie żądania klientów kierowane do serwera są zapisywane w dzienniku dostępu w określonym formacie przy użyciu modułu ngx_http_log_module.

Domyślny plik dziennika to log/access.log (zwykle /var/log/nginx/access_log w systemach Linux), a domyślny format rejestrowania to zwykle łączony lub główny format (może się różnić w zależności od dystrybucji).

Dyrektywa access_log (obowiązująca w przypadku http, serwera, lokalizacji, jeśli znajduje się w lokalizacji i limitach z wyjątkiem kontekstu) służy do ustawiania pliku dziennika, a dyrektywa log_format (obowiązuje w ramach tylko w kontekście http) służy do ustawiania formatu dziennika. Format dziennika jest opisywany przez zmienne wspólne oraz zmienne, które są generowane tylko w momencie zapisywania dziennika.

Składnia konfigurowania formatu dziennika jest następująca:

log_format format_name 'set_of_variables_to_define_format';

a składnia konfigurowania dziennika dostępu to:

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]];

Poniżej znajduje się fragment domyślnego pliku konfiguracyjnego Nginx /etc/nginx/nginx.conf w 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;
}

Ten format dziennika daje następujący wpis dziennika.

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"

Poniżej znajduje się kolejny przydatny format rejestrowania, którego używamy do śledzenia żądań do naszych aplikacji internetowych przy użyciu niektórych domyślnych zmiennych. Co najważniejsze, zawiera on identyfikator żądania i rejestruje szczegóły lokalizacji klienta (kraj, kod kraju, region i miasto).

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 ';

Możesz go użyć w ten sposób:

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

Spowoduje to utworzenie wpisu dziennika, który będzie wyglądał następująco.

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 

Możesz określić kilka dzienników za pomocą dyrektyw access_log na tym samym poziomie, tutaj używamy więcej niż jednego pliku dziennika w kontekście 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;
}

Poniżej znajdują się bardziej zaawansowane przykłady konfiguracji rejestrowania, które są przydatne w przypadku formatów dziennika zawierających zmienne związane z kompresją oraz do tworzenia skompresowanych plików dziennika:

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

Konfigurowanie dzienników błędów w Nginx

W przypadku, gdy Nginx doświadczy jakichkolwiek usterek, zapisuje informacje na ich temat w dzienniku błędów. Problemy te mają różne poziomy ważności: debugowanie, informacje, powiadomienie, ostrzeżenie, błąd (jest to poziom domyślny i działa globalnie), krytyczny, alarm lub emerg.

Domyślny plik dziennika to log/error.log, ale zwykle w dystrybucjach Linuksa znajduje się on w katalogu /var/log/nginx/. Dyrektywa error_log służy do określenia pliku dziennika i może być używana w kontekście głównym, http, poczty, strumienia, serwera, lokalizacji (w tej kolejności).

Należy również pamiętać, że:

  • Konfiguracje w kontekście głównym są zawsze dziedziczone przez niższe poziomy w powyższej kolejności.
  • a konfiguracje na niższych poziomach zastępują konfiguracje odziedziczone z wyższych poziomów.

Rejestrowanie błędów można skonfigurować przy użyciu następującej składni:

error_log /path/to/log_file log_level;

Na przykład:

error_log /var/log/nginx/error_log warn; 

Spowoduje to, że Nginx będzie rejestrował wszystkie wiadomości typu warn i poważniejszy poziom rejestrowania crit, alert i emerg wiadomości.

W następnym przykładzie rejestrowane będą wiadomości na poziomie krytycznym, alarmowym i emergicznym.

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

Rozważ poniższą konfigurację, tutaj zdefiniowaliśmy rejestrowanie błędów na różnych poziomach (w kontekście http i serwera). W przypadku wystąpienia błędu komunikat zapisywany jest tylko w jednym dzienniku błędów, najbliższym poziomowi, na którym wystąpił błąd.

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;
        		…….
    	}
}

Jeśli użyjesz więcej niż jednej dyrektywy error_log, jak w poniższej konfiguracji (ten sam poziom), komunikaty będą zapisywane we wszystkich określonych logach.

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;
            	…...
	}

Konfigurowanie rejestrowania warunkowego w Nginx

W niektórych przypadkach możemy chcieć, aby Nginx wykonywał warunkowe rejestrowanie wiadomości. Nie każda wiadomość musi być logowana przez Nginx, dlatego dla poszczególnych instancji możemy zignorować nieistotne lub mniej ważne wpisy z naszych logów dostępowych.

Możemy skorzystać z modułu ngx_http_map_module, który tworzy zmienne, których wartości zależą od wartości innych zmiennych. Parametry wewnątrz bloku mapy (które powinny istnieć tylko w treści http) określają mapowanie pomiędzy wartościami źródłowymi i wynikowymi.

W przypadku tego rodzaju ustawień żądanie nie zostanie zarejestrowane, jeśli warunek ma wartość „0 ” lub jest pustym ciągiem znaków. Ten przykład nie obejmuje żądań z kodami stanu HTTP 2xx i 3xx.

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

Oto kolejny przydatny przykład debugowania aplikacji internetowej w fazie programowania. Spowoduje to zignorowanie wszystkich komunikatów i zarejestrowanie jedynie informacji debugowania.

 
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; 
		…….
	}
}

Więcej informacji, w tym logowanie do syslog, znajdziesz tutaj.

To wszystko na teraz! W tym przewodniku wyjaśniliśmy, jak skonfigurować niestandardowy format rejestrowania dzienników dostępu i błędów w Nginx. Skorzystaj z poniższego formularza opinii, aby zadać pytania lub podzielić się przemyśleniami na temat tego artykułu.