Aplikační logování – nějaké best practices?
- maarlin
- Člen | 207
Chystám se implementovat do aplikace běžící na Nette dodělat logování akcí v aplikaci (tj. ne logování programových chyb atd.).
Tyhle logy potřebuji pak zpětně využívat a zobrazovat nějak v administraci aplikace.
Prakticky řeším hodně podobný problém, jako zde:
https://forum.nette.org/…stnich-zprav
Nicméně všechno to jsou řešení primárně využívající filesystem a tudíž použitelná z hlediska zpětného čtení spíše pro programátora a moc dobře nevyužitelné zpětně pro ostatní z mnoha důvodů.
Typické problémy, které budu řešit:
- Vypiš všechny akce, které provedlo UID číslo 123456
- Vypiš všechny články, které schválilo UID číslo 3455
- Vypiš všechny uživatele, kteří něco prováděli s článkem ID 12
- A to všechno prosím s prolinky na konkrétní články a uživatele a ideálně zpětnou kompatibilitou, pokud bych někdy v budoucnu změnil strukturu URL
Logicky proto nebudu projíždět hotový textový log a marně hledat
IDčka… :)
Navíc standardní textové logy drží zbytečně moc duplicitních dat.
Příklad?
Uživatel XYZ vytvořil článek ABC
Uživatel XXX vytvořil článek BCC
Peci1 se trochu posunul k tomu, co potřebuji: https://forum.nette.org/cs/2612-logging#…
Moje představa je taková, že v databázi budu mít 2 tabulky:
log_events
==========
id (integer) | message_mask (varchar) | variables_mask (varchar[])
------------------------------------------------------------------
1 | User %i deleted post %i | {user, post}
// Dat. typ pole jde dobře využít v PostgreSQL, ostatní DB jsem nezkoumal
log_messages
============
event_id integer | variables any[], příp. integer[]
---------------------------------------------------
1 | {1212, 3}
Což by mělo srazit potřebu místa na nutné minimum a zároveň usnadnit pak zpětné hledání. Navíc mám představu, že navenek by se to používalo takto:
MyLog::log('User %i deleted post %i', 1231, 23);
Což by se při zavolání chovalo takto:
Existuje taková maska v log_events? Vrať její ID a zaloguj do log_messages. Neexistuje? vytvoř ji a vrať nové ID a zaloguj do log_messages.
Napadají vás nějaké problémy, které by tam mohly vznikat, případě napadá vás nějaké lepší/jiné řešení?
Editoval maarlin (14. 6. 2011 19:17)
- Nox
- Člen | 378
Použití mi přijde moc závislé na konkrétním řetězci… nechtělo by se mi neustále vzpomínat, jak to má znít a psát to, nebo vždycky hledat, odkud to zkopírovat
<?php
$logger->deletedPost( $user->id, $post->id );
?>
případně pokud chceš staticky
<?php
YourLog::deletePost( $user->id, $post->id );
?>
a bude ti to napovídat a doplňovat IDE a navíc ti ještě řekne jaké všechny parametry to potřebuje
ty serializovaný data by asi šly nahradit za spešl tabulku 1:N aby byly variabilní, ale přes SQl dostupný, data – nevim ale jestli je to dobré u logu, kde se furt hlavně zapisuje
Editoval Nox (15. 6. 2011 8:54)
- Filip Procházka
- Moderator | 4668
Proč to dělat staticky… Logování můžeš zabudovat do modelu ne? Pak nebudeš muset řešit texty, protože logovat se bude automaticky.
Jinak mi to přijde v pohodě. Jenom bych asi „povýšil“ prioritu informace „kdo akci provedl“ a taky tam nevidím čas (ale předpokládám, že jsi to vynechal kvůli jednoduchosti)
Shodou okolností řeším teď podobnou věc, ale nehodlám to komplikovat :) udělal jsem si tabulku a budu ukládat akci (tvoje zpráva), uživatele, čas a případné rozdíly změn.
Editoval HosipLan (15. 6. 2011 10:03)
- maarlin
- Člen | 207
Nox napsal(a):
Použití mi přijde moc závislé na konkrétním řetězci… nechtělo by se mi neustále vzpomínat, jak to má znít a psát to, nebo vždycky hledat, odkud to zkopírovat
<?php $logger->deletedPost( $user->id, $post->id ); ?>
případně pokud chceš staticky
<?php YourLog::deletePost( $user->id, $post->id ); ?>
a bude ti to napovídat a doplňovat IDE a navíc ti ještě řekne jaké všechny parametry to potřebuje
ty serializovaný data by asi šly nahradit za spešl tabulku 1:N aby byly variabilní, ale přes SQl dostupný, data – nevim ale jestli je to dobré u logu, kde se furt hlavně zapisuje
Pravda, taková vrstva nad tím by mohly být přímo logovací metody… Asi to bude lepší… Sice pak kvůli logování nového elementu budu muset přidat novou metodu, ale to nějak přežiju.
Proč to dělat staticky… Logování můžeš zabudovat do modelu ne? Pak nebudeš muset řešit texty, protože logovat se bude automaticky.
Rád bych měl logování nějak centralizované – když si třeba vzpomenu, že nějaké konkrétní hlášky budu chtít logovat najednou do souboru, abych nemusel sahat do x modelů, ale do jedné třídy.
Díky za tipy!
- Filip Procházka
- Moderator | 4668
To jsem samozřejmě myslel, předat DatabaseLogger pomocí DI a pak ho použít na logování. Můžeš ho pak vyměňovat za FileLogger, nebo DevNullLogger…