Tworzymy nową aplikację i chciałbym włączyć rejestrowanie strukturalne. Moja idealna konfiguracja byłaby podobna Serilog
do naszego kodu C # i Bunyan
naszego JS. Te miały się zasilać, fluentd
a potem mogły przejść do dowolnej liczby rzeczy, początkowo myślałem elasticsearch + kibana
. Mamy już bazę danych MySQL, więc w najbliższym czasie bardziej interesuje mnie konfiguracja Serilog + Bunyan i deweloperów, aby z niej korzystać i możemy logować się do MySQL, podczas gdy poświęcamy nieco więcej czasu na płynną i resztę.
Jednak jeden z naszych bardziej doświadczonych programistów wolałby po prostu zrobić coś takiego: log.debug("Disk quota {0} exceeded by user {1}", quota, user);
używając, log4net
a następnie po prostu uruchomić instrukcje select przeciwko MySQL, takie jak:SELECT text FROM logs WHERE text LIKE "Disk quota";
Biorąc to pod uwagę, które podejście jest lepsze i / lub jakie rzeczy należy wziąć pod uwagę przy wyborze rodzaju systemu rejestrowania?
źródło
Odpowiedzi:
Istnieją dwa podstawowe postępy w podejściu strukturalnym , których nie można emulować za pomocą dzienników tekstowych bez (czasem ekstremalnych) dodatkowego wysiłku.
Rodzaje zdarzeń
Kiedy piszesz dwa zdarzenia z log4net, takie jak:
Spowoduje to wytworzenie podobnego tekstu:
Ale jeśli chodzi o przetwarzanie maszynowe, to tylko dwa wiersze innego tekstu.
Możesz znaleźć wszystkie zdarzenia „Przekroczone miejsce na dysku”, ale uproszczony przypadek wyszukiwania zdarzeń
like 'Disk quota%'
spadnie, gdy tylko pojawi się inne zdarzenie wyglądające jak:Rejestrowanie tekstu odrzuca informacje, które początkowo posiadamy na temat źródła zdarzenia, i należy to zrekonstruować, czytając logi zwykle za pomocą coraz bardziej rozbudowanych wyrażeń dopasowania.
Natomiast podczas pisania następujących dwóch zdarzeń Serilog :
Wywołują one tekst wyjściowy podobny do wersji log4net, ale za kulisami
"Disk quota {Quota} exceeded by user {Username}"
szablon wiadomości jest przenoszony przez oba zdarzenia.Z odpowiednim ujściem możesz później pisać zapytania
where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'
i uzyskiwać dokładnie zdarzenia, w których limit miejsca został przekroczony.Nie zawsze wygodne jest przechowywanie całego szablonu wiadomości przy każdym zdarzeniu dziennika, więc niektóre zatapiają szablon wiadomości w
EventType
wartości liczbowej (np.0x1234abcd
), Lub możesz dodać wzbogacenie do potoku rejestrowania, aby zrobić to sam .Jest bardziej subtelny niż kolejna różnica poniżej, ale jest niezwykle potężny w przypadku dużych objętości kłód.
Dane strukturalne
Ponownie, biorąc pod uwagę dwa zdarzenia dotyczące wykorzystania miejsca na dysku, może być dość łatwe przy użyciu dzienników tekstowych, aby zapytać o konkretnego użytkownika
like 'Disk quota' and like 'DTI-Matt'
.Jednak diagnostyka produkcji nie zawsze jest tak prosta. Wyobraź sobie, że konieczne jest znalezienie zdarzeń, w których przekroczony limit miejsca był mniejszy niż 125 MB?
Z Serilog jest to możliwe w większości zlewów przy użyciu wariantu:
Konstruowanie tego rodzaju zapytań z wyrażenia regularnego jest możliwe, ale szybko się męczy i zwykle jest miarą ostateczności.
Teraz dodaj do tego typ zdarzenia:
Zaczynasz widzieć, jak te możliwości łączą się w prosty sposób, dzięki czemu debugowanie produkcyjne za pomocą dzienników wydaje się być działaniem programistycznym najwyższej klasy.
Kolejną zaletą, być może nie tak łatwą do uniknięcia z góry, ale po usunięciu debugowania produkcyjnego z krainy hakowania wyrażeń regularnych, programiści zaczynają bardziej doceniać dzienniki i bardziej uważnie pisząc je. Lepsze logi -> aplikacje lepszej jakości -> więcej szczęścia dookoła.
źródło
Podczas zbierania dzienników do przetworzenia, czy to parsowania do jakiejś bazy danych i / lub późniejszego przeszukiwania przetworzonych dzienników, korzystanie z rejestrowania strukturalnego sprawia, że niektóre przetwarzanie jest łatwiejsze / bardziej wydajne. Analizator składni może wykorzystać znaną strukturę ( np. JSON, XML, ASN.1, cokolwiek) i używać maszyn stanu do parsowania, w przeciwieństwie do wyrażeń regularnych (których kompilacja i wykonanie może być drogie obliczeniowo (względnie). Analiza tekstu w dowolnej formie, takiego jak sugerowany przez współpracownika, zwykle polega na wyrażeniach regularnych i na niezmiennym tekście . Może to sprawić, że parsowanie tekstu swobodnego będzie raczej kruche ( tzn. Parsowanie jest ściśle powiązane z dokładnym tekstem w kodzie).
Rozważ również przypadek wyszukiwania / wyszukiwania, np . :
LIKE
warunki wymagają porównań z każdątext
wartością wiersza; znowu jest to względnie drogie obliczeniowo, szczególnie gdy używa się symboli wieloznacznych:W przypadku rejestrowania strukturalnego komunikat dziennika związany z błędem dysku może wyglądać tak w JSON:
Pola tego rodzaju struktury można dość łatwo odwzorować np. Na nazwy kolumn tabeli SQL, co oznacza, że wyszukiwanie może być bardziej szczegółowe / szczegółowe:
Możesz umieszczać indeksy w kolumnach, których wartości będą często wyszukiwać / wyszukiwać, o ile nie użyjesz
LIKE
klauzul dla tych wartości kolumn . Im bardziej możesz podzielić swój dziennik na określone kategorie, tym bardziej ukierunkowane możesz dokonać wyszukiwania. Na przykład, opróczerror_type
pola / kolumny w powyższym przykładzie, możesz zrobić parzyste"error_category": "disk", "error_type": "quota"
lub takie.Im bardziej struktura masz w wiadomościach dziennika, systemy bardziej swój parsowanie / wyszukiwanie (takie jak
fluentd
,elasticsearch
,kibana
) mogą skorzystać z tej struktury i wykonywać swoje zadania z większą prędkością i mniejszą CPU / pamięci.Mam nadzieję że to pomoże!
źródło
Rejestrowanie strukturalne nie przyniesie większych korzyści, gdy aplikacja tworzy kilkaset dzienników wiadomości. Z pewnością to zrobisz, gdy będziesz mieć kilkaset komunikatów dziennika na sekundę pochodzących z wielu różnych wdrożonych aplikacji.
Powiązane, konfiguracja, w której komunikaty dziennika kończą się na stosie ELK, jest również odpowiednia dla skali, w której logowanie do SQL staje się wąskim gardłem.
Widziałem konfigurację „podstawowego rejestrowania i wyszukiwania” z SQL
select .. like
i regexps przesunięte do granic możliwości tam, gdzie się rozpada - są fałszywe pozytywy, pominięcia, okropny kod filtru z błędami knwon, które są trudne do utrzymania i nikt nie chce ich dotykać, nowe komunikaty w dzienniku, które nie są zgodne z założeniami filtru, niechęć do dotykania instrukcji rejestrowania w kodzie, aby nie złamać raportów itp.Pojawia się kilka pakietów oprogramowania, które lepiej radzą sobie z tym problemem. Jest Serilog, słyszę, że zespół NLog na to patrzy , i napisaliśmy
StructuredLogging.Json
do Nlog , widzę również, że nowe abstrakcje rejestrowania rdzenia ASP.Net „umożliwiają dostawcom rejestrowania wdrożenie… rejestrowania strukturalnego”.Przykład z StructuredLogging. Logujesz się do rejestratora NLog, takiego jak to:
Te uporządkowane dane trafiają do kibana. Wartość
1234
jest przechowywana wOrderId
polu wpisu dziennika. Następnie możesz wyszukiwać za pomocą składni zapytania kibana np. Wszystkie wpisy w dzienniku gdzie@LogType:nlog AND Level:Error AND OrderId:1234
.Message
iOrderId
są teraz tylko polami, które można wyszukiwać w celu dopasowania dokładnego lub niedokładnego według potrzeb, lub agregować w celu obliczenia. Jest to potężne i elastyczne.Z najlepszych praktyk StructuredLogging :
źródło