Beta wersja loggera do obaczenia

0

(Modów działu proszę o przyklejenie tematu)

Czołem Bracia

Prezentuję wam tutaj beta wersję loggera dla biblioteki Qt nad którym od pewnego czasu pracuję:
http://4programmers.net/Forum/C_i_C++/183646-logger-lista_wymogow
Moją przewodnią ideą było stworzyć loggera dającego duże możliwości,ale zarazem prostego,a wręcz banalnego w instalacji oraz używaniu.Czy mi się to udało,sami oceńcie,a takoż czy jakiegoś ficzera mu nie brakło.

Instrukcja w załączniku;ponieważ prace nad loggerem nie zakończyły się jeszcze,to się nie spinałem żeby zrobić ją po angielsku.

**A,i istotna sprawa-**w tej beta wersji logger nie jest przystosowany do używania go z wątków pobocznych aplikacji,więc nawet tego nie próbujcie.

Chciałem podziękować za rady i wskazówki Braciom Kumashiro,byku_guzio oraz vpiotr

EDIT:Poprawiłem dokumentację,traktujcie tą w .zipie jako nieaktualną i bierzcie tą z oddzielnego linka

0

Patrząc w nagłówek bez używania:

  1. setMaximumLogFileSizexB - wywaliłbym bo niepotrzebnie rozbudowuje interfejs (każdy PROGRAMISTA potrafi sobie to przeliczyć)

  2. bool allowLogTypes(unsigned int type); - nazwy funkcji powinny pochodzić od czynności, a atrybutów od rzeczowników lub przymiotników
    tutaj masz taką trochę pseudo-czynność w odniesieniu do atrybutu, lepsze byłoby "allowedLogTypes"

  3. dla atrybutów używasz schematu setXxx(value) - setter, xxx() - getter, ale allowLogTypes się tego nie trzyma, LogWindowAlwaysOnTop też
    Lepszy jest schemat setXxx(value), getXxx() - czytelniejsze

  4. QString identifier(void);

  • jeśli identyfikator się nie zmienia to lepiej:
    const QString &identifier() const; // w C++ pisze się bez void w argumentach + const correctness + szybsze

  • jeśli identyfikator się zmienia - bo to jest generator identyfikatorów
    QString nextIdentifier();

  1. bool setLogMode(LogMode mode);
  • zwracanie bool w tym wypadku jest trochę nadmiarowe, naprawdę może się nie udać?
  1. bazowanie na QStringu od razu zawęża grupę odbiorców (właśnie ostatnio wywaliłem wxString z projektu, bo bazowanie na stringach z GUI ma później niepotrzebny wpływ na projekt - np. niekompatybilną obsługę Unicode - w Wx). Ale jeśli to i tak przede wszystkim okienko to chyba jest OK.

  2. do dokumentacji kodu polecam doxygen - dokumentacja praktycznie sama wychodzi - przy okazji

Licencja
Gdybyś dał BSD lub MIT to nie byłoby potrzeby zastanawiania się czy czasami gdzieś nie ma zwodniczego przecinka.

Gdybyś chciał się odgryźć lub sprawdzić recenzenta to wystarczy zaguglać "vpiotr c++" - wszelkie uwagi chętnie przeczytam.

0
vpiotr napisał(a)

setMaximumLogFileSizeKB - wywaliłbym bo niepotrzebnie rozbudowuje interfejs (każdy PROGRAMISTA potrafi sobie to przeliczyć)

Pewnie,ale nie tędy droga prowadzi żeby kalkulatorem/w mysli wyliczać wielkość pliku logu,jeśli celem jest wygoda użytkowania biblioteki.

vpiotr napisał(a)

bool allowLogTypes(unsigned int type); - nazwy funkcji powinny pochodzić od czynności, a atrybutów od rzeczowników lub przymiotników
tutaj masz taką trochę pseudo-czynność w odniesieniu do atrybutu, lepsze byłoby "allowedLogTypes"

allowedLogTypes() są getterem.Ale fakt,jak oglądałem te funkcje leżące obok siebie w klasie to mnie nachodziły myśli,czy czasem nie lepiej przemianować na setAllowedLogTypes()

vpiotr napisał(a)

dla atrybutów używasz schematu setXxx(value) - setter, xxx() - getter, ale allowLogTypes się tego nie trzyma, LogWindowAlwaysOnTop też
Lepszy jest schemat setXxx(value), getXxx() - czytelniejsze

Czytaj wyżej ;) A ja stosuję konwencję z biblioteki Qt,gdzie gettery mają postać xxx() właśnie.

vpiotr napisał(a)

QString identifier(void);

  • jeśli identyfikator się nie zmienia to lepiej:
    const QString &identifier() const; // w C++ pisze się bez void w argumentach + const correctness + szybsze

  • jeśli identyfikator się zmienia - bo to jest generator identyfikatorów
    QString nextIdentifier();

Cóż,tutaj jest trochę względów historycznych.Nie chciałem dać żadnej możliwości zmiany tego identyfikatora przez złośliwego użytkownika,bo przewidywałem na przyszłość,iż będzie mi on potrzebny-stąd zwracanie wskaźnika/referencji odpada,bo consta da się obejść jak się ktoś uprze.
Jak jednak czas pokazał,akurat stąd nie używam go,niewykluczone więc iż ta funkcja wyleci-chociaż z 2 mańki,ktoś może sobie getLoggerem() natworzyć dużo logerów i wpakować do listy.I żeby rozróżnić który jest który to tego identyfikatora będzie potrzebował.
A voida pisać akurat lubię,wstukanie tych paru literek więcej mi nie przeszkadza.

vpiotr napisał(a)

bool setLogMode(LogMode mode);

  • zwracanie bool w tym wypadku jest trochę nadmiarowe, naprawdę może się nie udać?

Może się nie udać.Nie czytałeś instrukcji,co Piotr? :P No więc false da próba nastawienia któregoś trybu LogToWindow w aplikacji konsolowej.

vpiotr napisał(a)

bazowanie na QStringu od razu zawęża grupę odbiorców (właśnie ostatnio wywaliłem wxString z projektu, bo bazowanie na stringach z GUI ma później niepotrzebny wpływ na projekt - np. niekompatybilną obsługę Unicode - w Wx). Ale jeśli to i tak przede wszystkim okienko to chyba jest OK.

Grupa odbiorców na wstępie jest zawężona do tych,co to biblioteki Qt używają,a im tam QString nie wadzi.Ponadto używam wewnętrznie duużo elementów kuteka,od QCoreApplication po model/view programming,a dojdzie do tego jeszcze kutowska obsługa wielowątkowości.

vpiotr napisał(a)

do dokumentacji kodu polecam doxygen - dokumentacja praktycznie sama wychodzi - przy okazji

Znam,używałem w pracy-imo nędza,a to potemu,że straszliwy burdel robi się w pliku .h z klasą i niełatwo jest w tym gąszczu wychwytywać definicje pól i metod,nawet przy kolorowaniu składni.Fakt,dokumentacja potem z tych komentarzy doxygenowych powstaje sama.

vpiotr napisał(a)

Licencja
Gdybyś dał BSD lub MIT to nie byłoby potrzeby zastanawiania się czy czasami gdzieś nie ma zwodniczego przecinka.

Nie jest to projekt opensourcowy,więc MIT i BSD nie przejdą.

vpiotr napisał(a)

Gdybyś chciał się odgryźć lub sprawdzić recenzenta to wystarczy zaguglać "vpiotr c++" - wszelkie uwagi chętnie przeczytam.

Za co mam się odgryzać to nie wiem,a co do moich uwag apropos Twojego wrappera:
1)Mam awersję to zapisów w stylu typedef list<coś>.Lubię jednak wiedzieć patrząc na definicję,że to na co patrzę to lista,czy mapa.Mam jednak świadomość,że dzięki typedefowi w niezwykle łatwy sposób zmienisz sobie używanie np z listy na wektor w całym projekcie zmieniając tylko tego typedefa
2)

static void calcMD5(const std::string &text, std::string &output);

przy tej metodzie zaliczyłem lekkie WTF?MD5 nic mi nie mówi,imo lepiej byłoby skrót rozwinąć,zwłaszcza że inne metody nie są zapisywane w tak kryptograficznej postaci

0
MasterBLB napisał(a)
vpiotr napisał(a)

setMaximumLogFileSizeKB - wywaliłbym bo niepotrzebnie rozbudowuje interfejs (każdy PROGRAMISTA potrafi sobie to przeliczyć)

Pewnie,ale nie tędy droga prowadzi żeby kalkulatorem/w mysli wyliczać wielkość pliku logu,jeśli celem jest wygoda użytkowania biblioteki.

tu nie ma co liczyć, jeśli ktoś chce być super-dokładny to pisze:

log.setMaximumLogFileSize(14*1024);

Mnożenie metod przez liczbę dostępnych jednostek dla danej wartości jest IMHO słabe.

MasterBLB napisał(a)
vpiotr napisał(a)

QString identifier(void);

  • jeśli identyfikator się nie zmienia to lepiej:
    const QString &identifier() const; // w C++ pisze się bez void w argumentach + const correctness + szybsze

  • jeśli identyfikator się zmienia - bo to jest generator identyfikatorów
    QString nextIdentifier();

Cóż,tutaj jest trochę względów historycznych.Nie chciałem dać żadnej możliwości zmiany tego identyfikatora przez złośliwego użytkownika,bo przewidywałem na przyszłość,iż będzie mi on potrzebny-stąd zwracanie wskaźnika/referencji odpada,bo consta da się obejść jak się ktoś uprze.
Jak jednak czas pokazał,akurat stąd nie używam go,niewykluczone więc iż ta funkcja wyleci-chociaż z 2 mańki,ktoś może sobie getLoggerem() natworzyć dużo logerów i wpakować do listy.I żeby rozróżnić który jest który to tego identyfikatora będzie potrzebował.
A voida pisać akurat lubię,wstukanie tych paru literek więcej mi nie przeszkadza.

To trochę pesymistyczne założenie, ale przynajmniej bezpieczne - więc jeśli funkcja nie jest zbyt często wywoływana to OK.

MasterBLB napisał(a)
vpiotr napisał(a)

Gdybyś chciał się odgryźć lub sprawdzić recenzenta to wystarczy zaguglać "vpiotr c++" - wszelkie uwagi chętnie przeczytam.

Za co mam się odgryzać to nie wiem,a co do moich uwag apropos Twojego wrappera:
1)Mam awersję to zapisów w stylu typedef list<coś>.Lubię jednak wiedzieć patrząc na definicję,że to na co patrzę to lista,czy mapa.Mam jednak świadomość,że dzięki typedefowi w niezwykle łatwy sposób zmienisz sobie używanie np z listy na wektor w całym projekcie zmieniając tylko tego typedefa
2)

static void calcMD5(const std::string &text, std::string &output);

przy tej metodzie zaliczyłem lekkie WTF?MD5 nic mi nie mówi,imo lepiej byłoby skrót rozwinąć,zwłaszcza że inne metody nie są zapisywane w tak kryptograficznej postaci

</quote>

Skrótów używam wtedy, gdy są one oczywiste. Przykłady oczywistych to HTTP, CRC, SQL, Ascii, Os. Tutaj powinno być właściwie calcMd5 (case), poza tym jest OK.
Akurat trafiłeś, bo MD5 to kryptografia :) Więcej znajdziesz tutaj: http://en.wikipedia.org/wiki/MD5

0

Ja akurat tych metod mam na tyle mało,że 1 więcej nie robi.Za to sam powiedz vpiotr,częściej nastawiałbyś wielkość logu w megabajtach czy kilobajtach?Wiadomo że w MB,ale tutaj powstaje pytanie a co jak będzie trzeba akurat w kilobajtach nastawić?I już lipa,bo jako parametr jest liczba całkowita.Z kolei ciągle wymnażać żeby uzyskać MB to też tak nie do końca teges-i stąd zapodałem 2 wersje.

Właśnie sprawdziłem swój kod i wyszło mi,że ten identifier() zwraca identyfikator wewnętrznego obiektu loggera używanego ostro przez wszelakie mechanizmy mojej biblioteki.O to nie ma bata,w takiej postaci nie dam żadnej,nawet teoretycznej możliwości jego zepsucia przez użytkownika zwracając doń referencję.

Co do MD5 tak myślałem,że to jakiś skrót od nazwy algorytmu,no ale na chwilę czytania kodu nie kojarzyłem co to,a góglować mi się nie chciało :P

0
MasterBLB napisał(a)

Ja akurat tych metod mam na tyle mało,że 1 więcej nie robi.Za to sam powiedz vpiotr,częściej nastawiałbyś wielkość logu w megabajtach czy kilobajtach?Wiadomo że w MB,ale tutaj powstaje pytanie a co jak będzie trzeba akurat w kilobajtach nastawić?I już lipa,bo jako parametr jest liczba całkowita.Z kolei ciągle wymnażać żeby uzyskać MB to też tak nie do końca teges-i stąd zapodałem 2 wersje.

Staram się ograniczać permutacje funkcji, jeśli prowadzą w gruncie rzeczy do tego samego.
Co innego, gdybyś jakieś kalkulacje tego typu miał robić przed każdym (wielokrotnym) wywołaniem.
Ja w sumie u siebie w loggerze też się nad tym zastanawiałem, ale uznałem że dwa mnożenia są lepsze. Kwestia gustu.

0

Hmmm 14 ludków zassalo 3 dni temu i żadnego odzewu?Dziwne

0

Wrzucę sobie maksymalny rozmiar do configu to mam walnąć drabinkę ifów bo jest "przyjazny interfejs"?

0

Chciałbym zadać głupie pytanie.
Czy nie ma na rynku takich rozwiązań? Bo projekt "do nauki języka" to chyba nie jest.

0

Być to są,np Log4Cpp,inna sprawa jak wygodne w użyciu.A dla mnie to jest bardziej projekt do wpisania w CV i pokazania pracodawcy oraz żeby utrzymać się w formie podczas okresu bezrobocia.Drugą jego funkcją jest poćwiczenie aplikacji wielowątkowych 'tak na serio',bo owszem teorię znam,jakieś tam programy wykorzystujące wielowątkowość napisałem ale nie były to programy,w których owa wielowątkowość faktycznie była potrzebna do celów innych niż ćwiczebne.

0

No Bracia co pobraliście bibliotekę,jakiś odzew może?Jeden Demonical Monk miał jakąś myśl skrzydlatą,ale nie chce się widzę nią podzielić.

0
MasterBLB napisał(a)

No Bracia co pobraliście bibliotekę,jakiś odzew może?Jeden Demonical Monk miał jakąś myśl skrzydlatą,ale nie chce się widzę nią podzielić.

		void setMaximumLogFileSizekB(unsigned int kB);
		void setMaximumLogFileSizeMB(unsigned int MB);

Po co tworzyć do tego dwie osobne funkcje, z czego jedna zajmuje się tylko mnożeniem i przekazywaniem danych do drugiej? Powinna do tego służyć jedna funkcja przyjmująca rozmiar w jak najmniejszej jednostce, nikomu korona z głowy nie spadnie jak sobie walnie dwa razy mnożenie. Co jeśli ktoś będzie chciał w configu aplikacji zrobić pole "maxLogSize" i w nim umożliwić użytkownikowi ręczne skonfigurowanie rozmiaru? Trzeba będzie robić cuda typu:

if (...) {
   setMaximumFileSizekB(userInput);
} else if (...) {
   setMaximumFileSizeMB(userinput);
} else {
   ...
}

Trzeba oszacować ile razy ta funkcja będzie w ogóle używana w programie? Raz? Dwa razy? Wtedy takie "ułatwienia" stają się niestety utrudnieniami.

0

Monk,dlaczego nie mogę edytować 1 posta w temacie??Bo chciałbym dodać poprawioną dokumentację,a nie mogę :/

0

Jeszcze nie testowałem, ale jeśli chciałbym tego używać to chciałbym mieć też możliwość wyrzucania logów do konsoli (qDebug()). Logger którego używam przy projekcie w firmie pluje logami do bazy sqlite. Na początku wydało mi się to mało potrzebne, ale jak uświadomiłem sobie rzecz oczywistą że w bazie mogę zrobić osobne relacje to zdałem sobie sprawę że to nawet nie głupie.

0

Hej wszyscy

No i co,nikt kto używał loggera nic nie napisze?Bo tu czeka aktualizacja wprowadzająca wsparcie wielowątkowości,ale nie widzę sensu publikowania skoro nie ma żadnego odzewu.

0

To i ja dodam kilka uwag:

  • dlaczego konfiguracja w .ini a nie xml?
  • oczekiwałbym innych appenderów, zamiast tylko plucia do pliku, przykładowo może to być pchanie po udp, do bazy, do sysloga na linuksie (event loga na Windows), na stdout/stderr, na emaila. Zobacz sobie jak to działa w log4net - dodajesz nowy appender jako sekcję w xml z całą konfiguracją i tam mogą byc pchane logi - appendery możesz dodatkowo włączać i wyłączać poprzez ustawienie jednego przełącznika w xml. Możesz tez tworzyć własne appendery jako wtyczki - czy przewidziałeś taką możliwość u siebie?
  • jakieś łatwe automatyczne logowanie wyjątków?
  • kompresja logów archiwalnych?

Na koniec: ogólnie praktycznie cała konfiguracja loggera powinna siedzieć w pliku konfiguracyjnym (łącznie m.in. z rzeczami o których wspomniałem wyżej) - dlatego powinieneś zrezygnować z pliku ini na rzecz xml, a w przyszłości (wiadomo, po ukończeniu samej biblioteki) miłym dodatkiem by było graficzny konfigurator generujący takowy .xml konfiguracyjny + wtyczki do popularnych ide tak aby konfigurację loggera można było sobie wyklikać z poziomu ide - podobnie jak to jest w EnterpriseLibrary od Microsoftu. Faktycznie dla qt i C++ nie widziałem niczego analogicznego, więc jakaś luka do wypełnienia jest.

0

ad "czemu w ini"-bo prościej,ponadto w moim odczuciu czytanie takiego pliku jest przyjaźniejsze dla człowieka zamiast przebijać się przez gąszcze tagów-chociaż z 2 strony,edytory html/xml istnieją.
ad "appendery"-w obecnej chwili nie tylko do pliku,ale także do okna desktopa oraz poprzez qDebug() na stdout/stderr.Po udp ani do bazy do wrzuca,co zaś do maila to w sumie nieco poza zakres stricte logera wychodzi-no ale skoro mówisz że by się przydało to obaczę co tam Qt ma do wysyłania poprzez email.A,no i do owego event loga Windows też widzę trzeba będzie dodać.
Tworzenia własnych appenderów nie ma.
ad "kompresja logów"-też w sumie trochę poza "głównym nurtem" loggera,niemniej mogłoby być użyteczne.
ad "automatyczne logowanie wyjątków" opisz Bracie proszę dokładniej co masz na myśli?Żeby łapał wszystkie wyjątki z aplikacji?

0
MasterBLB napisał(a)

co zaś do maila to w sumie nieco poza zakres stricte logera wychodzi

A jak szybciej powiadomić administratora o jakimś super fatal exception w aplikacji produkcyjnej?

1 użytkowników online, w tym zalogowanych: 0, gości: 1