Aplikační logování – nějaké best practices?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
maarlin
Člen | 207
+
0
-

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:

  1. Vypiš všechny akce, které provedlo UID číslo 123456
  2. Vypiš všechny články, které schválilo UID číslo 3455
  3. Vypiš všechny uživatele, kteří něco prováděli s článkem ID 12
  4. 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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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…