Saturday 30 December 2006

Centralny serwer logów MS Windows na PostgreSQL

© 2006-04-18 Bartłomiej Siębab ver. 2.1 Spis treści:

Wstęp Działanie aplikacji Skrypt SQL Uwagi do kodu Do pobrania

Wstęp

Głównym założeniem projektu była centralizacja logów zbieranych z różnych systemów MS Windows z dzienników evenlog oraz innych (za pośrednictwem protokołu syslog) w jednej darmowej bazie SQL. Z powodu wymagań co do wydajności bazy, objętości gromadzonych dzienników oraz faktu iż baza ma być darmowa, sql'owa i ma być bazą (a nie programem do wyświetlania tabelek takim jak "mójsql" ;-) a ponadto koniecznym "połączeniem" do bazy w postaci komponentu .NET 2.0 na placu boju pozostał PostgreSQL...

Początkowo założyłem, iż aplikacja zbierająca logi z maszyn MS Windows będzie rezydować na jednej z maszyn i zasysać dzienniki z pozostałych - wstawiając rekordy do bazy SQL. Tak też zostało to zrealizowane. W trakcie testowania okazało się że wąskim gardłem jest sam protokół zasysający dane z dzienników. Wydajność tegoż protokołu - jak sądzę bazującego na RPC - była żenująca - zaledwie 30-40 rekordów na sekundę dlatego też dorobiłem możliwość działania aplikacji na każdej maszynie z której pobierane są rekordy dzienników i wstawiania ich zdalnie do bazy PostgreSQL. Tutaj wydajność po zasosowaniu paczkowania rekordów w większej transakcji (po kilkaset insertów) oraz zastosowaniu "prepared statement" wzrosła do 300-400 rekordów/sek (baza stojąca na zwyczajnym, średniej wydajności pececie).

W dalszym etapie rozwoju aplikacji planowane jest dołożenie interfejsu wyszukiwawczo-raportującego pozwalającego na zautomatyzowanie wyszukiwania pewnych podejrzanych zdarzeń w logach, tworzenie syntetycznych i analitycznych raportów, backupowanie i kasowanie starych rekord ów z bazy, daemon/usługa syslogd (jako odrębny projekt pgsyslogd).

Całość napisałem zgodnie z obowiązującą "modą" w środowisku .NET 2005 (NetFramework 2.0). Jako że nie przepadam za pisaniem aplikacji w C# czy C++ na NET2005 postanowiłem z wrodzonego twórczego lenistwa i ku wygodzie własnej i ewentualnych użytkowników napisać całość w darmowym VisualBasic 2005 Express Edition przy użyciu komponentu Npgsql dla dostępu do bazy PostgreSQL.

Działanie aplikacji:

Aplikacja pgeventcollector może być uruchomiona na dwa sposoby. Pierwszy - zwykły tryb interakcyjny - dostępne menu, konfiguracja, podgląd postepu wczytywania logów itp. wodotryski. Drugi - tryb wsadowy z linii poleceń lub harmonogramu zadań - przydatny do kolejnych cyklicznych automatycznych importów logów do bazy.

Aplikacja pgsyslogd może byc uruchomiona jako usługa (nt service) systemowa nasłuchująca na porcie zgodnym z protokołem syslog i odbierająca dane przesyłane protokołem UDP w tym formacie (w planach także TCP).

Aplikacja rejestruje w rejestrze systemu ostatnia pozycje rekordu dziennika na którym zakończone zostało importowanie w poprzednim przebiegu. Wpisy pojawiają się po pierwszym wczytywaniu rekordów w gałęzi [HKLM]/Software/pgeventlogger/[nazwa maszyny]/...

Wymagania

W pierwszym etapie wdrożenia należało utworzyć odpowiednią bazę danych, tabelę na gromadzone logi, ewentualne indeksy przyśpieszające wyszukiwanie itp. Poniższy skrypt SQL utworzy nam bazę w kodowaniu UNICODE (utf-8), tabelę log i sekwencję autonumerowania. Ewentualne indeksy i użytkownika na którym będzie realizowane połączenie z bazą należy założyć sobie samemu. Instalacji i konfiguracji bazy PostgreSQL (na MS Windows lub na BSD/UNIX/Linux) nie będę tu opisywać - to przedstawia dokumentacja PostgreSQL. Ja zainstalowałem PostgreSQL w wersji 8.1.3 (taka wersja była najnowsza na moment wdrożenia). Do wykonania skryptu można zastosować interfejs zarządzania bazą PostgreSQL instalowany wraz z bazą (lub odrębnie) PgAdminIII. W celu zwiększenia bezpieczeństwa należało by utworzyć dedykowaną rolę (grupę), nadać prawa wstawiania rekordów w tabeli log dla tej roli + użycia sekwencji seqlogid; utworzyć dedykowanego użytkownika którym było by realizowane połączenie aplikacji z bazą a dziedziczącego uprawnienia po tej dedykowanej roli grupowej. Aplikacja wymaga aby dzienniki miały skonfigurowaną odpowiednią wielkość tak by mogły pomieścić wszystkie rekordy pomiędzy kolejnymi przebiegami importowania. Należy koniecznie zablokować resetowanie dzienników i nigdy ich nie resetować - nawet ręcznie, dzienniki powinny być ustawione w tryb automatycznego zastępowania najstarszych rekordów w razie potrzeby - stąd konieczne zaplanowanie ich odpowiedniego rozmiaru. Przy zresetowaniu dziennika następuje wyzerowanie wewnętrznej numeracji rekordów dzienników - ten właśnie numer rekordu jest wykorzystywany do zapamiętywania w rejestrze pozycji na której w poprzednim przebiegu aplikacja zakończyła import zatem wyzerowanie tej numeracji zablokuje importowanie logów - koniecznym będzie ręczne wyzerowanie liczników aplikacji w rejestrze.

Skrypt SQL

-- SET default_with_oids = false; -- Database: slog CREATE DATABASE slog WITH OWNER = postgres ENCODING = 'UTF8' TABLESPACE = pg_default; -- Sequence: seqlogid CREATE SEQUENCE seqlogid; ALTER TABLE seqlogid OWNER TO postgres; -- Table: log CREATE TABLE log ( id int8 NOT NULL DEFAULT nextval('seqlogid'), -- id rekordu kto varchar(15) NOT NULL DEFAULT "current_user"(), -- kto zmodyfikowal rekord kiedy timestamptz NOT NULL DEFAULT now(), -- kiedy zmodyfikowano rekord eventlog varchar DEFAULT '', -- z jakiego dziennika pochodzi wpis entrytype varchar DEFAULT '', -- typ wpisu category varchar DEFAULT '', -- kategoria wpisu source varchar DEFAULT '', -- zrodlo wpisu eventid int4 DEFAULT 0, -- kod eventu machine varchar DEFAULT '', -- z jakiej maszyny username varchar DEFAULT '', -- jaki uzytkownik timegenerated timestamp DEFAULT now(), -- kiedy zaistnialo zdarzenie timewritten timestamp DEFAULT now(), -- kiedy zarejestrowano zdarzenie w dzienniku message text DEFAULT '', -- komunikat CONSTRAINT idlog_pk PRIMARY KEY (id) ) WITHOUT OIDS; ALTER TABLE log OWNER TO postgres; COMMENT ON TABLE log IS 'event log table'; COMMENT ON COLUMN log.id IS 'id rekordu'; COMMENT ON COLUMN log.kto IS 'kto zmodyfikowal rekord'; COMMENT ON COLUMN log.kiedy IS 'kiedy zmodyfikowano rekord'; COMMENT ON COLUMN log.eventlog IS 'z jakiego dziennika pochodzi wpis'; COMMENT ON COLUMN log.entrytype IS 'typ wpisu'; COMMENT ON COLUMN log.category IS 'kategoria wpisu'; COMMENT ON COLUMN log.source IS 'zrodlo wpisu'; COMMENT ON COLUMN log.eventid IS 'kod eventu'; COMMENT ON COLUMN log.machine IS 'z jakiej maszyny'; COMMENT ON COLUMN log.username IS 'jaki uzytkownik'; COMMENT ON COLUMN log.timegenerated IS 'kiedy zaistnialo zdarzenie'; COMMENT ON COLUMN log.timewritten IS 'kiedy zarejestrowano zdarzenie w dzienniku'; COMMENT ON COLUMN log.message IS 'komunikat'; -- Indexes: CREATE INDEX idxcategory ON log USING btree (category varchar_pattern_ops); CREATE INDEX idxentrytype ON log USING btree (entrytype varchar_pattern_ops); CREATE INDEX idxeventid ON log USING btree (eventid); CREATE INDEX idxeventlog ON log USING btree (eventlog varchar_pattern_ops); CREATE INDEX idxmachine ON log USING btree (machine varchar_pattern_ops); CREATE INDEX idxsource ON log USING btree (source varchar_pattern_ops); CREATE INDEX idxusername ON log USING btree (username varchar_pattern_ops); --

Instalacja

NetFramework 2.0

Standartowo aplikacje napisane w MS Visual Studio 2005 wymagają zainstalowania NetFramework 2.0. Do pobrania ze stron producenta lub z pakietu instalacyjnego MS Visual Studio 2005 Express.

Baza danych PostgreSQL

Standartowa instalacja PostgreSQL (u mnie wersja 8.1.3 tak na MS Windows jak i na *nix).

Instalacja aplikacji

Instalacja aplikacji jest prosta. Pierwsze ręczne uruchomienie powoduje zainstalowanie aplikacji i utworzenie odpowiednich pozycji w "Menu Start" systemu oraz automatyczne pierwsze uruchomienie aplikacji. W tym momencie należy wejść w menu "Tools->Options" i wprowadzić swoje odpowiednie parametry konfiguracyjne połaczenia z bazą. Po zatwierdzeniu konfiguracji możliwe jest uruchomienie interakcyjne lub tez w trybie wsadowym z liniii poleceń lub harmonogramu zadań. Aktualnie obsługiwany jest jedynie przełącznik "/start" wyzwalający natychmiastowy "produkcyjny" przebieg zaimportowania logów do bazy przy użyciu wcześniej ustawionej konfiguracji. Okienko konfiguracyjne domyślnie zawiera domyślny wpis postaci "." - odpowiednik "localhost" symbolizujący iż domyślnie importowane sa logi jedynie z bieżącej maszyny na której została uruchomiona aplikacja. Ewentualne kolejne maszyny należy podawać w kolejnych liniach w tradycyjnej postaci FQDN lub notacji adresu IP. Podczas wczytywania logów w trybie interakcyjnym aplikacja sygnalizuje paskiem postępu aktualny etap importowania, ponadto w lini statusu aplikacji mogą pojawiać się statusy typu "Idle" - bezczynna, "Running..." - importowanie rekordów, "Skipping..." - pomijanie rekordów wcześniej wczytanych i przeskoczenie do miejsca ostatniego zakończenia wczytywania.

Kod źródłowy i wersja binarna

Aplikacja dostępna jest jako spakowana paczka projektu Visual Basic 2005 a także jako skompilowana wykonywalna działająca wersja binarna z niezbędnymi bibliotekami Npgsql. Kod źródłowy szeroko komentowałem tak aby był łatwy do zrozumienia i ewentualnej rozbudowy lub dopasowania do własnych potrzeb. Od czasu do czasu będę publikował nowsze wersje źródeł i binariów - w miarę jak będa postępowac ewentualne dalsze prace rozwojowe. Licencja kodu aplikacji - standartowa nowa licencja BSD - inne komponenty moga mieć inną - proszę sobie sprawdzić własnoręcznie jaką (np. Npgsql czy MS Visual Studio 2005 Express).

Uwagi do kodu źródłowego

Aplikacja jest napisana "as is" - nie najgorzej ale i mogło być lepiej - jak będe miał chęci i czas to może popoprawiam conieco w wyglądzie tak kodu jak i samej aplikacji - narazie jak to mówią "feel free to do it yourself" ;-) Ręczna rekompilacja projektu wymaga "podpięcia" a właściwie wskazania lokalizacji komponentu Npgsql i biblioteki npgsql.dll oraz ewentualnego wygenerowania klucza tymczasowego do podpisania projektu. Spakowane binaria skompilowanej aplikacji już zawierają bibliotekę npgsql.dll.

Features

- tryb interakcyjny oraz wsadowy - pasek postępu wczytywania logów - zakładka z błedami i ostrzeżeniami - statystyki przetwarzania logów - rejestrowanie w dzienniku aplikacji statystyk z przetwarzania - predefiniowana modyfikowalna konfiguracja - statystyki ilości wpisów w dziennikach - możliwość zasysania logów z wielu maszyn - ...

ToDo

- dorobienie rejestrowania w eventlogu statystyki po każdym przetworzonym logu - dalsze modyfikacje okna konfuguracyjnego - wielojęzykowość aplikacji - wielowątkowość aplikacji - oblokowanie menu aplikacji przy pracy interakcyjnej - automatyczne rozpoznanie zresetowania logów - automatyczne cykliczne uruchamianie aplikacji wg wewnętrznego timera - dołożenie automatycznego utworzenia bazy i tabeli przy instalacji (na żądanie) - dołożenie współpracy z innymi bazami SQL - dołożenie modułu raportowania, wyszukiwania, analiz i statystyk - dokończenie i opublikowanie modułu pgsyslogd współpracującego z protokołem syslog - ...

Screenshoots

- okno główne aplikacji - okno konfiguracji aplikacji - postęp wczytywania w trybie interakcyjnym - wpisy liczników w rejestrze

Do pobrania

Spakowane kody źródłowe aplikacji w postaci projektu MS Visual Studio 2005 Express: - aktualna wersja źródeł z dnia 2006-04-18 to 1.0.1.2 Spakowana działająca wersja binarna palikacji: - aktualna wersja binarna z dnia 2006-04-18 to 1.0.1.2

Przydatne linki

- baza danych PostgreSQL http://www.postgresql.org - aktualna dokumentacja PostgreSQL http://www.postgresql.org/docs/manuals/ - MS Visual Studio 2005 Express http://msdn.microsoft.com/vstudio/express/default.aspx - MS NET Framework 2.0 http://msdn.microsoft.com/netframework/downloads/updates/default.aspx - komponent Npgsql http://npgsql.projects.postgresql.org/docs/manual/UserManual.htm - dokumentacja API komponentu Npgsql http://npgsql.projects.postgresql.org/docs/api/

No comments: