Wprowadzenie
Administracja serwerem to nie tylko wstępna konfiguracja usług. Obejmuje to również nadzorowanie tych usług i zapewnienie, że działają one tak płynnie, jak to możliwe. Jednym z najważniejszych źródeł wiedzy dla administratorów są pliki dziennika, które zawierają informacje o zdarzeniach systemowych.
W przypadku serwera WWW, takiego jak Nginx, dzienniki zawierają cenne informacje o każdej próbie uzyskania dostępu do zasobów za pośrednictwem serwera WWW. Każdy odwiedzający witrynę i obraz, widoczny lub pobrany plik jest skrupulatnie rejestrowany w dziennikach. Gdy wystąpią błędy, zostaną one również zapisane w dziennikach. Znacznie łatwiej jest pracować z plikami dziennika, które są dobrze skonstruowane.
W tym przewodniku przyjrzymy się, jak wykorzystać moduł logowania Nginx. Skonfigurujemy osobne pliki dziennika dla różnych bloków serwera, a następnie dostosujemy wyniki rejestrowania. Dodamy również dodatkowe informacje o żądaniach (w tym przykładzie samouczka, czas potrzebny na dostarczenie żądania) do dziennika dostępu, poza tym, co zawiera Nginx domyślnie.
Wymagania wstępne
Aby wykonać ten samouczek, będziesz potrzebować:
- Jeden serwer Debian 8 skonfigurowany za pomocą tego wstępnego samouczka konfiguracji serwera
- Nginx zainstalowany na twoim serwerze, postępując zgodnie z instrukcją Jak zainstalować Nginx na Debianie 9 .
Krok 1 – Tworzenie plików testowych
W tym kroku utworzymy kilka plików testowych w domyślnym katalogu witryny Nginx. Użyjemy ich do przetestowania naszej konfiguracji logowania.
Kiedy Nginx (lub jakikolwiek inny serwer WWW) otrzymuje żądanie HTTP dla pliku, otwiera ten plik i udostępnia go użytkownikowi, przesyłając jego zawartość przez sieć. Im mniejszy plik, tym szybciej można go przenieść. Gdy plik zostanie przesłany w całości, żądanie uznaje się za zakończone, a dopiero potem następuje rejestracja transferu.
W dalszej części tego samouczka będziemy modyfikować konfigurację rejestrowania, aby zawierała przydatne informacje o tym, ile czasu zajęło każde żądanie. Najprostszym sposobem przetestowania zmodyfikowanej konfiguracji i zauważenia różnicy między różnymi żądaniami jest utworzenie kilku plików testowych o różnych rozmiarach, które będą przesyłane w różnym czasie.
Stwórzmy plik o 1mb.testwielkości 1 megabajta q domyślnym katalogu Nginx za pomocą truncate.
1
|
truncate-s1M/var/www/html/1mb.test
|
Podobnie, stwórzmy dwa kolejne pliki o różnych rozmiarach, najpierw 10, a potem 100 megabajtów, nadając im odpowiednie nazwy.
1
2
|
truncate-s10M/var/www/html/10mb.test
truncate-s100M/var/www/html/100mb.test
|
Wreszcie, stwórzmy też pusty plik:
1
|
touch/var/www/html/empty.test
|
Użyjemy tych plików w następnym kroku, aby wypełnić plik dziennika domyślną konfiguracją, a następnie w samouczku, aby zademonstrować dostosowaną konfigurację.
Krok 2 – Zrozumienie konfiguracji domyślnej
Moduł logu jest podstawowym modułem Nginx, co oznacza, że nie trzeba go instalować osobno. Domyślna konfiguracja jest jednak absolutnym minimum. W tym kroku zobaczymy, jak działa domyślna konfiguracja.
W nowej instalacji Nginx rejestruje wszystkie żądania w dwóch osobnych plikach: dzienniku dostępu i dzienniku błędów. Rejestr błędów, znajdujący się w /var/log/nginx/error.log, przechowuje informacje o nietypowych błędach serwera lub błędach w przetwarzaniu żądania.
Dziennik dostępu, umieszczony w /var/log/nginx/access.log, jest wykorzystywany częściej. Tutaj przechowywane są informacje o wszystkich reqestach do Nginx. W tym dzienniku można zobaczyć między innymi, które pliki użytkownicy pobierają(otwierają), które przeglądarki używają, jakie mają adresy IP, i jakim kodem odpowiedzi HTTP Nginx odpowiedział na każde żądanie.
Zobaczmy, jak wygląda przykładowa linia pliku logu dostępu. Najpierw poproś o pusty plik, który utworzyliśmy w Kroku 1 z Nginx, aby plik dziennika nie był pusty.
1
|
curl-ihttp://localhost/empty.test
|
W odpowiedzi powinieneś zobaczyć kilka nagłówków odpowiedzi HTTP:
1
2
3
4
5
6
7
8
9
|
HTTP/1.1200OK
Server:nginx/1.6.2
Date:Fri,09Dec201623:05:18GMT
Content-Type:application/octet-stream
Content-Length:0
Last-Modified:Fri,09Dec201623:05:13GMT
Connection:keep-alive
ETag:"584b38a9-0"
Accept-Ranges:bytes
|
Z tej odpowiedzi dowiesz się kilku rzeczy:
- HTTP/1.1 200 OK mówi nam, że Nginx odpowiedział kodem statusu “200 OK”, informując nas, że nie wystąpił błąd.
- Content-Length: 0 oznacza, że zwracany dokument ma zerową długość.
- Żądanie zostało przetworzone Fri, 09 Dec 2016 23:05:18 GMT.
Zobaczmy, czy to pasuje do tego, co Nginx zapisał w swoim dzienniku dostępu:
1
|
tail/var/log/nginx/access.log
|
Dziennik będzie zawierał linię podobną do tej, odpowiadającą żądaniu testowemu, które wydaliśmy wcześniej.
1
|
127.0.0.1--[09/Dec/2016:23:07:02+0000]"GET /empty.test HTTP/1.1"2000"-""curl/7.38.0"
|
Nginx używa Combined Log Format , który jest standaryzowanym formatem logów dostępowych, powszechnie używanych przez serwery WWW do interoperacyjności. W tym formacie każda informacja jest ograniczona pojedynczą przestrzenią; łączniki reprezentują brakujące fragmenty informacji.
Od lewej do prawej kategorie to:
- Adres IP użytkownika, który zażądał zasobu. Ponieważ stosowaliśmy curl lokalnie, adres ip to localhost, czyli 127.0.0.1.
- Zdalne informacje rejestracyjne . Zawsze będzie to łącznik, ponieważ Nginx nie obsługuje tych informacji.
- Nazwa zalogowanego użytkownika zgodnie z podstawowym uwierzytelnianiem HTTP. To będzie puste dla wszystkich anonimowych żądań.
- Data żądania . Możesz zobaczyć, że pasuje do daty z naszych nagłówków odpowiedzi.
- Ścieżka żądania , która zawiera metodę request ( GET), ścieżkę do żądanego pliku ( /empty.text) oraz użyty protokół ( HTTP/1.1).
- Kod statusu odpowiedzi , co było 200 OK, co oznacza że odpowiedź na żądanie była poprawna.
- Długość przeniesionego pliku , która jest tutaj 0, ponieważ plik był pusty.
- Nagłówek Referer HTTP , który zawiera adres dokumentu, z którego pochodzi żądanie. W tym przykładzie jest on pusty, ale jeśli był to plik obrazu, referer wskazywałby stronę, na której obraz był używany.
Nagłówek HTTP Referer to błędna pisownia słowa “referrer”, które pochodzi z początków HTTP i jest częścią standardu HTTP. - klient , którym w tym przypadku jest curl.
Nawet pojedyncza pozycja dziennika w dzienniku dostępu zawiera wiele cennych informacji o żądaniu. Jednak brakuje jednej ważnej informacji. Chociaż zażądaliśmy dokładnej lokalizacji http://localhost/empty.test, tylko ścieżka do /empty.testpliku znajduje się we wpisie dziennika; informacje o nazwie hosta (tutaj localhost) zostaną utracone.
Krok 3 – Konfigurowanie oddzielnego dziennika dostępu
Następnie zastąpimy domyślną konfigurację rejestrowania (gdzie Nginx przechowuje jeden plik dziennika dostępu dla wszystkich żądań) i zmusimy Nginx do przechowywania oddzielnego pliku dziennika dla domyślnego vhosta serwera, który jest dostarczany z czystą instalacją Nginx.
Dobrą praktyką jest przechowywanie oddzielnych plików dziennika dla każdego vhosta serwera, skutecznie oddzielając logi dla różnych stron internetowych. Nie tylko powoduje to, że pliki dzienników są mniejsze, ale znacząco ułatwia analizę dzienników w celu wykrycia błędów i podejrzanej aktywności.
Aby zmienić domyślną konfigurację vhosta serwera Nginx, otwórz plik konfiguracyjny serwera Nginx nano lub ulubionym edytorem tekstu.
1
|
nano/etc/nginx/sites-available/default
|
Znajdź blok konfiguracji, który wygląda następująco:
1
2
3
4
5
6
|
# Default server configuration
#
server{
listen80default_server;
listen[::]:80default_server;
|
i dodaj dwie linie zaznaczone na czerwono do konfiguracji:
1
2
3
4
5
6
7
8
9
10
|
# Default server configuration
#
server{
listen80default_server;
listen[::]:80default_server;
<span style="color: #993300;">access_log/var/log/nginx/default-access.log;
error_log/var/log/nginx/default-error.log;
</span>
|
Dyrektywa access_log określa ścieżkę do pliku, w którym będą zapisywane logi dostępu, a error_log robi to samo dla dziennika błędów. Używamy tego samego katalogu co domyślne logi Nginx ( /var/log/nginx), ale z różnymi nazwami plików. Jeśli masz wiele vhostów serwera, dobrym pomysłem jest nazwanie plików dziennika w spójny i znaczący sposób, na przykład użycie nazwy domeny w nazwie pliku.
Zapisz i zamknij plik, aby zakończyć.
Uwaga: Należy pamiętać, że w celu utrzymania oddzielnych plików dziennika dla każdego vhosta serwera, należy zastosować powyższą zmianę konfiguracji przy każdym tworzeniu nowego bloku serwera w konfiguracji Nginx.
Aby włączyć nową konfigurację, uruchom ponownie Nginx.
1
|
systemctl restart nginx.service
|
Aby przetestować nową konfigurację, wykonaj to samo żądanie dla naszego pustego pliku testowego, jak wcześniej.
1
|
curl-ihttp://localhost/empty.test
|
Sprawdź, czy linia dziennika identyczna z tą, którą widzieliśmy wcześniej, jest zapisana w osobnym pliku, który właśnie skonfigurowaliśmy.
1
|
tail/var/log/nginx/default-access.log
|
W następnym kroku dostosujemy format dzienników do nowego pliku i uwzględnimy dodatkowe informacje.
Krok 4 – Konfigurowanie niestandardowego formatu dziennika
Tutaj skonfigurujemy niestandardowy format rejestrowania, aby zapełnić dziennik Nginx dodatkowymi informacjami (czas przetworzenia żądania) i skonfigurować domyślny blok serwera do korzystania z tego nowego formatu.
Musimy zdefiniować nowy format dziennika, zanim będzie można go użyć. W Nginx każdy format dziennika ma unikalną nazwę, która jest globalna dla całego serwera. Poszczególne bloki serwerów można skonfigurować, aby później używać tych formatów, po prostu odwołując się do ich nazw.
Aby zdefiniować nowy format rejestrowania, utwórz nowy plik konfiguracyjny timed-log-format.conf w dodatkowym katalogu konfiguracyjnym Nginx.
1
|
nano/etc/nginx/conf.d/timed-log-format.conf
|
Dodaj w nim następującą zawartość:
1
2
3
|
log_format timed'$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" $request_time';
|
Zapisz i zamknij plik, aby zakończyć.
Dyrektywa log_format ustawienie definiuje nowy format dziennika. Następny element to unikalny identyfikator tego formatu; tutaj używamy czasu , ale możesz wybrać dowolną nazwę.
Dalej jest sam format dziennika, podzielony na trzy wiersze w celu lepszej czytelności. Nginx udostępnia informacje o wszystkich żądaniach w nazwanych zmiennych systemowych poprzedzonych znakiem dolara. Zostaną one zastąpione faktycznymi informacjami o żądaniu podczas zapisywania szczegółów żądania w dzienniku dostępu (np. $request_addr zostaną zastąpione adresem IP odwiedzającego).
Powyższy format jest identyczny z Common Log Format omówionym wcześniej z jedną różnicą: dodanie zmiennej systemowej $request_time na samym końcu. Nginx używa tej zmiennej do przechowywania długości żądania w milisekundach, a używając tej zmiennej w naszym formacie dziennika, powiadamiamy Nginx, aby zapisał te informacje do pliku logu.
Teraz mamy niestandardowy format dziennika o nazwie czasowej zdefiniowany w konfiguracji Nginx, ale domyślny blok serwera nie używa jeszcze tego formatu. Następnie otwórz plik konfiguracyjny Nginx vhosta serwera.
1
|
nano/etc/nginx/sites-available/default
|
Znajdź blok konfiguracji, który wcześniej zmieniliśmy i dodaj timed – nazwę formatu dziennika do ustawienia access_log, jak zaznaczono poniżej na czerwono:
1
2
3
4
5
6
7
8
9
|
# Default server configuration
#
server{
listen80default_server;
listen[::]:80default_server;
access_log/var/log/nginx/default-access.log<span style="color: #993300;">timed</span>;
error_log/var/log/nginx/default-error.log;
|
Zapisz i zamknij plik, aby zakończyć.
Aby włączyć nową konfigurację, uruchom ponownie Nginx.
1
|
systemctl restart nginx.service
|
Teraz, gdy wszystko jest gotowe, sprawdźmy, czy to działa.
Krok 5 – Weryfikacja nowej konfiguracji
Możemy przetestować nową konfigurację, wywołując niektóre żądania do Nginx za pomocą curl, tak jak zrobiliśmy to w kroku 2. Tym razem użyjemy przykładowych plików utworzonych w kroku 1:
1
2
3
4
|
curl-ihttp://localhost/empty.test
curl-ihttp://localhost/1mb.test
curl-ihttp://localhost/10mb.test
curl-ihttp://localhost/100mb.test
|
Zauważysz, że każde następne polecenie będzie trwało dłużej, ponieważ pliki będą większe i przeniesienie ich zajmie więcej czasu.
Wyświetlmy dziennik dostępu po wykonaniu tych żądań.
1
|
tail/var/log/nginx/default-access.log
|
Dziennik będzie zawierał więcej linii, ale ostatnie cztery będą odpowiadały żądaniom testowym, które właśnie wykonałeś.
1
2
3
4
5
|
127.0.0.1--[09/Dec/2016:23:07:02+0000]"GET /empty.test HTTP/1.1"2000"-""curl/7.38.0"
127.0.0.1--[09/Dec/2016:23:08:28+0000]"GET /empty.test HTTP/1.1"2000"-""curl/7.38.0"0.000
127.0.0.1--[09/Dec/2016:23:08:28+0000]"GET /1mb.test HTTP/1.1"2001048576"-""curl/7.38.0"0.000
127.0.0.1--[09/Dec/2016:23:08:28+0000]"GET /10mb.test HTTP/1.1"20010485760"-""curl/7.38.0"0.302
127.0.0.1--[09/Dec/2016:23:08:39+0000]"GET /100mb.test HTTP/1.1"20068516844"-""curl/7.38.0"7.938
|
Zobaczysz, że ścieżki różnią się za każdym razem, pokazując poprawną nazwę pliku, a rozmiar żądania wzrasta za każdym razem. Ważną częścią jest ostatnio podświetlona liczba, czyli czas przetwarzania żądań w milisekundach, które właśnie skonfigurowaliśmy w naszym niestandardowym formacie dziennika. Jak można się spodziewać, im większy plik, tym dłużej trwa przesyłanie.
W takim przypadku pomyślnie skonfigurowałeś niestandardowy format dziennika w Nginx – gratulacje!
Wniosek
Chociaż nie jest szczególnie przydatne, aby zobaczyć, że większe pliki wymagają więcej czasu, czas przetwarzania żądania może być bardzo przydatny, gdy Nginx jest używany do obsługi dynamicznych stron internetowych. Może być używany do śledzenia wąskich gardeł na stronie internetowej i łatwo znajdować żądania, które trwały dłużej niż powinny.
$request_time to tylko jedna z wielu zmiennych systemowych, które można wykorzystać w Nginx w niestandardowych konfiguracjach rejestrowania. Inne obejmują na przykład wartość nagłówków odpowiedzi wysłanych z odpowiedzią na klienta. Dodawanie innych zmiennych do formatu dziennika jest tak proste, jak umieszczanie ich w łańcuchu formatu dziennika, tak jak robiliśmy to $request_time. Jest to potężne narzędzie, które możesz wykorzystać na swoją korzyść podczas konfigurowania rejestrowania dla twoich stron internetowych.
Lista zmiennych, które mogą być używane z formatami dziennika Nginx, została opisana w dokumentacji modułu rejestru Nginx .