W poprzednim rozdziale omówiliśmy monitorowanie aplikacji Spring Boot 1.x.
Teraz omówimy jak wygląda to zagadnienie w przypadku Spring Boota 2 i 3.
Zmiany wprowadzone w Actuatorze w Spring Boot 2 są nadal aktualne w wersji 3.
Wprowadzenie Actuatora do projektu w Spring Boot 2 odbywa się poprzez dodanie odpowiedniej zależności:
Wstępna konfiguracja w pliku
application.properties powinna wyglądać podobnie jak w przypadku wersji pierwszej, jednak
trzeba mieć na uwadze, że zmieniły się nieco nazwy własności. Dodane zostało słowo
server. Od teraz mamy:
Przypomnijmy, że w ten sposób określamy
port, na którym będzie działała usługa. Ze względów bezpieczeństwa dobrze jest wybrać port inny niż ten, na którym pracuje nasza aplikacja.
Dodatkowo możemy określić
adres ip, z którego będzie można korzystać z usługi. To również jest zalecane.
W trakcie przeprowadzania testów warto jest włączyć wszystkie endpointy, gdyż domyślnie większość z nich jest wyłączona:
Oczywiście musimy uważać, żeby takiego ustawienia nie wdrożyć niezabezpieczonego hasłem na produkcji, gdyż będzie to miało katastrofalne skutki
w kontekście bezpieczeństwa.
Endpointy
Do Actuatora w wersji drugiej dostejmy się z poziomu przeglądarki używając url-a (na przykładzie znanego nam już endpointa
health):
W obecnej wersji mamy dostępnych kilka nowych endpointów, jednakże najpierw chcielibyśmy pokazać endpoint, którego nie opisaliśmy w wersji pierwszej, a jednak
wydaje się być ważny. Jeśli w pliku
application.properties zdefiniujemy własność
logging.file lub
logging.path
wówczas możemy zajrzeć do naszych plików z logami bezpośrednio z poziomu konsoli webowej. Jest to szczególnie przydatne wtedy, gdy nie mamy dostępu do
logów na produkcji z poziomu serwera.
-
logfile
Wyświetla logi w przeglądarce jeśli została zdefiniowana własność logging.file lub logging.path:
Nowe Endpointy
Tak jak wspomnieliśmy nowy Actuator to również nowe endpointy. Nam wpadły w oko - endpoint pokazujący konfigurację zadań automatycznych (schedulerów) zdefiniowanych
w aplikacji oraz odświeżony mechanizm śledzenia w postaci
httptrace (w Spring Boot 3 —
httpexchanges):
-
scheduledtasks
Wyświetla schedulery z podziałem na typy wraz z podaniem ścieżki do klasy i metody, dla której dany scheduler jest zdefiniowany:
-
httptrace (w Spring Boot 3 — httpexchanges)
Wyświetla informacje o ruchu w aplikacji, podobny do trace znanego z poprzedniej wersji Actuatora. Teraz jednak jest bardziej
skondensowany (zawiera tylko kluczowe dane http), przez co jest bardziej przejrzysty:
Endpoint metrics
Nazwa tego endpointa występowała już co prawda w poprzedniej wersji, ale teraz mamy do czynienia z całkowicie nowym silnikiem ukrytym pod jego "maską".
Actuator 2.x bazuje na rozwiązaniu
Micrometer i dostarcza nam beana o nazwie
MeterRegistry.
-
metrics
Tak jak poprzednio wyświetla zbiór informacji o stanie zasobów oraz szereg innych danych diagnostycznych. W porównaniu do poprzedniej wersji informacje te zawierają więcej metadanych.
Ze względu na ilość informacji zostały one podzielone na osobne sekcje, a więc odpalając sam endpoint metrics dostajemy teraz jedynie
listę dostępnych metryk:
I teraz jeśli interesuje nas na przykład bieżące zużycie procesora w trakcie wykonywania pracy przez aplikację wystarczy, że podamy odpowiednią nazwę własności w url-u (system.cpu.usage).
Własny endpoint
Przygotowanie customowego endpointa w nowej wersji Actuatora wygląda zupełnie inaczej niż miało to miejsce wcześniej. Spowodowane jest
to tym, że mechanizm całego Actuatora przestał współpracować tylko i wyłącznie z Spring MVC. Stał się niezależny od technologii.
Wprowadzone zostały rozwiązania generyczne do tworzenia endpointów.
Klasa, to zwykły komponent Springa, ale już pozostałe adnotacje pochodzą z biblioteki
spring-boot-actuator i są niezależne od frameworka.
Można ich użyć zarówno ze
Spring MVC jak i
Spring Webflux-em, czy nawet z Jerseyem.
Nasz endpoint został stworzony do przechowywania parametrów definiowanych przez nas w celu gromadzenia dodatkowych informacji o pracy systemu.
Dla przykładu wprowadziliśmy mapę z domyślnie ustawionymi wartościami
lastDeploymentAuthor oraz
lastDeploymentIssue.
Następnie przygotowaliśmy metody wykorzystujące tą mapę, opisując je adnotacjami mapującymi konkretne metody HTTP:
-
@ReadOperation - GET
-
@WriteOperation - POST
-
@DeleteOperation - DELETE
Dodatkowo użyliśmy adnotacji
@Selector, której zadaniem jest dopasowanie parametru metody do parametru w
URL. Zobaczmy teraz jak będzie
wyglądało pobranie wszystkich parametrów (metodą GET):
Tak będzie wyglądało pobranie wartości parametru po jego nazwie (metodą GET):
A tak wykonamy zmianę wartości parametru (metodą POST):
To co powinno zwrócić naszą uwagę to fakt, że nadal używamy nazwy parametru, który chcemy ustawić oraz to, że dane przesyłamy w postaci JSON-a, gdzie
value
to
nazwa parametru w metodzie. W rezultacie wywołując ponownie metodę GET pobierającą wszystkie parametry powinniśmy uzyskać widok podobny do tego:
Oczywiście jako parametr możemy przesłać również cały obiekt. Wówczas kolejne pola w JSON-ie będą mapowane na
odpowiednie pola w obiekcie.
Na koniec zostaje nam metoda DELETE, ale jej nie będziemy już analizować. Wywołanie wygląda analogicznie do metody
GET z parametrem.
Appa Notka. Dokumentacja Spring Boota wspomina, że aby powyższe "zabawy" z parametrami w ogóle zadziałały, należy skompilować kod
(implementujący endpointa) z opcją -parameters. W przypadku, gdy używamy Mavena wraz z parentem ustawionym na spring-boot-starter-parent, nie powinno być wymagane
dodawanie tej opcji, powinno to działać automatycznie. Niemniej mogą nadal wystąpić problemy podczas testów w IDE. W przypadku Eclipse pomaga włączenie opcji
kompilatora (w preferencjach wyszukujemy Java Compiler) o nazwie "Store information about method parameters (usable via reflection)". W Intellij w miejscu konfirguracji kompilatora
należy wpisać -parameters, w sekcji "Additional command line parameters".
Bezpieczeństwo ponad wszystko
Tak jak w życiu, tak samo w przypadku systemów informatycznych szczególnie ważne jest odpowiednie zabezpieczenie cennych zasobów przed niepowołanym dostępem.
W przypadku Actuatora ze Spring Boot-a 2 załatwiamy sprawę w standardowy sposób, to znaczy zgodny z szablonowym modelem bezpieczeństwa aplikacji.
Tak więc wystarczy nam stworzenie prostej konfiguracji security, na przykład:
Oczywiście powyższy przykład jest trywialny, choćby z tego powodu, że zawiera tylko zabezpieczenia dotyczące Actuatora.
W rzeczywistości będziemy tutaj mieli wspólny model bezpieczeństwa zarówno dla aplikacji jak i dla Actuatora.
Załóżmy jednak dla ułatwienia, że nasze zabezpieczenia wyglądają tak jak w przykładzie. W tym momencie nie dostaniemy się do żadnych endpointów (poza
health
i
info) jeśli nie posiadamy wymaganej roli. Testując taką konfigurację na naszym własnym endpoincie otrzymamy
AccessDenied:
W ten sposób określamy, które endpointy powinny być widoczne i dla kogo, a które nie. Tym samym nie używamy już konfiguracji znanej z Actuatora 1.x opartej o
własność
sensitive. Przy próbie użycia własności
endpoints.sensitive zostaniemy poinformowani przez nasze IDE
(w tym przypadku Eclipse), że własność została zdeprecjonowana:
W bieżącym rozdziale przyjrzeliśmy się temu jak działa Actuator w Spring Boot 2. Jeśli dla kogoś z Was zgromadzony tutaj materiał nie jest wystarczający, polecamy zapoznać się z linkami poniżej.
Wstawiliśmy tutaj odwołania zarówno do dokumentacji Spring Boota 2 jak również do dokumentacji API Actuatora.
Spring Boot Actuator 3
W poprzednich wersjach Spring Framework automatycznie maskował wartości wrażliwych kluczy w endpointach
/env i
/configprops, które wyświetlają wrażliwe informacje,
takie jak właściwości konfiguracji i zmienne środowiskowe. W
tym wydaniu Spring zmienia podejście, aby domyślnie było bezpieczniejsze.
Zamiast maskować tylko niektóre klucze, teraz domyślnie maskuje wartości dla wszystkich kluczy.
Możemy zmienić tę konfigurację, ustawiając właściwości
management.endpoint.env.show-values (dla punktu końcowego /env ) lub
management.endpoint.configprops.show-values (dla punktu końcowego /configprops ) z jedną z tych wartości:
- NIGDY — nie pokazano żadnych wartości
-
ZAWSZE — wszystkie wyświetlane wartości
-
WHEN_AUTHORIZED — wszystkie wartości są wyświetlane, jeśli użytkownik jest autoryzowany. W przypadku JMX wszyscy użytkownicy są autoryzowani. W przypadku HTTP tylko określona rola może uzyskać dostęp do danych
W Spring Boot 3 pojawiły się też inne aktualizacje w Actuatorze.
JMX obsługuje tylko
/health endpoint.
Możemy je dostosować, konfigurując właściwości
management.endpoints.jmx.exposure.include
i
management.endpoints.jmx.exposure.exclude.
Nastąpiła też zmiana nazwy endpointa
/httptrace na
/httpexchanges.
Kolejne zmiany dotyczą izolacji
ObjectMapper.
W nowej wersji instancja mappera odpowiedzialna za serializację odpowiedzi z Actuatora, jest domyślnie izolowana.
Oznacza to, że ta instancja
ObjectMapper jest oddzielona od innych części aplikacji,
co zwiększa bezpieczeństwo i niezawodność przez unikanie potencjalnych konfliktów z innymi elementami aplikacji używającymi mappera.
Możemy zmienić tę funkcję, ustawiając właściwość
management.endpoints.jackson.isolated-object-mapper na
false.
Autor: Jarek Klimas
Data: 03 stycznia 2024
Labele: Backend, Podstawowy, Java
Czy informacje, które otrzymałeś, były pomocne?
Jeśli tak, zapraszam Cię do podarowania mi kawy.
Topowe Materiały
Spring IO: Spring Boot Actuator Web API Documentation
Baeldung: Spring Boot Actuator
Baeldung: Migrate Application From Spring Boot 2 to Spring Boot 3
Udemy: [NEW] Spring Boot 3, Spring 6 & Hibernate for Beginners — polskie napisy