JustPaste.it

Centralny serwer logów MS Windows na PostgreSQL

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/

 

Źródło: http://blog.siebab.net/2006/12/centralny-serwer-logw-ms-windows-na.html