Dzienniki zdarzeń i aktywność użytkowników¶
Logi pomagają ustalić, kto i kiedy wykonywał operacje w systemie, jakich dokumentów dotyczyły żądania oraz dlaczego wystąpił błąd. Służą do diagnozowania problemów i analizowania aktywności użytkowników.
Gdzie znaleźć logi¶
| Miejsce | Zawartość |
|---|---|
| System → Dziennik zdarzeń | Poziom, data i czas, komunikat, wyjątek, powiązany dokument, login oraz kontekst operacji. Dostępność pozycji w menu zależy od konfiguracji środowiska. |
Tabela logs w PostgreSQL |
Dane diagnostyczne, użytkownik, parametry żądania HTTP i kontekst operacji w kolumnie operation_context. |
Plik logs/api.csv w katalogu aplikacji API |
Logi NLog, w tym zakończone żądania HTTP i operation_context. Plik ma kodowanie UTF-8 i separator średnikowy. |
| Konsola API / logi kontenera | Bieżące komunikaty i podsumowania żądań HTTP. Domyślny format konsoli nie wyświetla operation_context. |
W menu systemowym dostępny jest jeden „Dziennik zdarzeń”. Dawne osobne listy błędów i informacji zostały zastąpione wspólną listą; rodzaj wpisów wybiera się filtrem kolumny poziomu.
Standardowa lista systemowa korzysta z funkcji fn_get_logs i pokazuje poziomy Info, Warn i Error. Kolumny „Login” (username) i „Kontekst operacji” (operation_context) są dostępne na liście. Funkcja zwraca kontekst jako tekst JSON do wyświetlenia, natomiast w tabeli logs nadal jest on przechowywany jako jsonb.
Akcja workflow Loguj informacje zapisuje komunikat przez ten sam mechanizm NLog co pozostałe logi. Trafia on do bazy, CSV i konsoli zgodnie z ustawionym poziomem logowania. Kontekst zawiera DocumentId, WorkflowHistoryId i WorkflowId. Poziomy Debug i Trace wymagają odpowiedniego ustawienia LoggingSettings.MinLevel.
Zapis NLog do bazy jest asynchroniczny i niezależny od transakcji workflow. Komunikat może być widoczny z opóźnieniem i pozostać po wycofaniu transakcji. Sukces akcji oznacza przekazanie komunikatu do loggera, a nie potwierdzenie zapisu w każdym miejscu docelowym.
Wpis zakończenia żądania HTTP¶
Wpis HttpRequest Completed pochodzi z loggera NLogRequestLogging i podsumowuje obsługę żądania. Przy analizie sprawdź następujące pola:
| Pole | Znaczenie |
|---|---|
timestamp |
Czas zdarzenia; NLog zapisuje czas w UTC. |
username |
Nazwa użytkownika przypisana do żądania. |
original_username |
Pierwotna tożsamość, jeśli żądanie zawiera taki kontekst użytkownika. |
url, request_method |
Ścieżka i metoda HTTP. URL nie zawiera parametrów query string. |
status_code |
Kod odpowiedzi HTTP; pozwala odróżnić udaną obsługę od błędu. |
duration |
Czas obsługi w milisekundach. |
operation_context |
Nazwy operacji i identyfikatory obiektów, których dotyczyło żądanie. |
Żądanie bez wywołań Command/Query ma NULL w kolumnie kontekstu w bazie i puste pole w CSV. Domyślna konfiguracja pomija logi zakończenia żądań do /notificationshub i /groupworkhub.
Kontekst operacji¶
Command oznacza operację wykonującą działanie, a Query — zapytanie o dane. Dla każdego wywołania dispatcher zbiera nazwę operacji i wartości jej bezpośrednich publicznych właściwości, których nazwy kończą się dokładnie na Id lub Guid.
Przykładowy format kontekstu zakończonego żądania HTTP:
[
{
"name": "GetDocumentQuery",
"identifiers": {
"DocumentId": 123,
"FormId": 45
}
}
]
Nazwy w przykładzie ilustrują format. Jeśli jedno żądanie wywoła kilka operacji, tablica zawiera kilka elementów, również dla wywołań zagnieżdżonych. Nie powstaje dodatkowy wpis rozpoczęcia dla każdej operacji.
Zbierane są wartości proste, np. liczby, tekst i GUID, także wartości null. Mechanizm nie zapisuje całego żądania, zagnieżdżonych obiektów ani kolekcji takich jak DocumentIds. Kontekst jest zbierany przed sprawdzeniem uprawnień i walidacją, dlatego obejmuje także operacje zakończone odmową dostępu lub błędem.
Log wewnątrz operacji oraz wpis błędu z filtra wyjątków zawierają kontekst pojedynczej operacji jako obiekt JSON, a nie tablicę całego żądania. Przy zagnieżdżonych wywołaniach filtr zachowuje kontekst operacji, z której pochodzi wyjątek.
W bazie operation_context ma typ jsonb. W CSV ten sam JSON jest zawartością jednego pola; cudzysłowy są kodowane zgodnie z formatem CSV.
Powiązanie z dokumentem i historią workflow¶
Identyfikatory dokumentu i historii workflow są przechowywane w operation_context. Kolumna „Dokument” rozpoznaje DocumentId, a dla odczytu GetDocumentQuery i zapisu istniejącego dokumentu UpdateDocumentCommand także pole Id. W innych operacjach samo Id nie jest uznawane za identyfikator dokumentu. Lista dzienników odczytuje z JSON-a powiązane dokumenty. Identyfikator historii workflow (WorkflowHistoryId) jest dostępny w kontekście operacji, bez osobnej kolumny na liście. Jeśli wpis obejmuje kilka dokumentów, kolumna „Dokument” może zawierać kilka pozycji. Pełny kontekst jest dostępny w kolumnie „Kontekst operacji”, bazie i CSV.
Migracja przenosi identyfikatory ze starszych kolumn document_id i workflow_history_id do JSON-a, zanim usunie te kolumny. Po usunięciu dokumentu jego identyfikator pozostaje w logu, ale lista nie wyświetli powiązania do nieistniejącego dokumentu.
Jak sprawdzić aktywność na dokumentach¶
Zestaw username, czas, nazwę operacji, identyfikatory i wynik HTTP. Dla administratora z dostępem do bazy przykładowe zapytanie o zakończone żądania dotyczące dokumentu 123 wygląda tak:
SELECT timestamp, username, request_method, url, status_code, operation_context
FROM logs
WHERE logger = 'NLogRequestLogging'
AND timestamp >= NOW() - INTERVAL '7 days'
AND operation_context @> '[{"identifiers":{"DocumentId":123}}]'::jsonb
ORDER BY timestamp DESC;
Zapytanie dotyczy pola DocumentId. Operacje przekazujące identyfikator pod inną nazwą, np. Id, wymagają odpowiedniego filtra i sprawdzenia nazwy operacji.
Wywołanie dotyczące dokumentu może wynikać z otwarcia dokumentu, odświeżenia ekranu, pobierania danych pomocniczych albo automatycznej operacji. Jedno otwarcie może powodować kilka żądań. Do raportu „kto otwierał dokumenty” należy wybrać operacje pobierające dokument do wyświetlenia i uwzględnić wynik ich obsługi. Sama obecność identyfikatora nie potwierdza dostępu ani przeczytania treści dokumentu.
Poziom logowania i przechowywanie¶
Minimalny poziom logów aplikacji określa LoggingSettings.MinLevel, domyślnie Info. Sposób włączenia Debug opisuje konfiguracja appsettings.json. Logger zakończonych żądań HTTP ma osobną regułę NLog od poziomu Info.
| Miejsce | Domyślne przechowywanie |
|---|---|
| Baza danych | MaxAgeOfLogsInDays wynosi 30. Czyszczenie uruchamia się przy starcie usługi i następnie co 24 godziny. Wartość 0 wyłącza automatyczne usuwanie. |
| Pliki CSV | Rotacja dzienna do katalogu logs/archive; konfiguracja zachowuje maksymalnie 30 plików archiwalnych. |
MaxAgeOfLogsInDays dotyczy bazy, a nie CSV. Jeżeli logi służą do analizy aktywności za dłuższy okres, odpowiednio skonfiguruj ich retencję i przechowywanie plików kontenera.