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.
No comments:
Post a Comment