JeuWeb - Crée ton jeu par navigateur
Logging - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Logging (/showthread.php?tid=2356)

Pages : 1 2


RE: Logging - Ziliev - 06-02-2008

Personellement j'suis pas grand fan de Big Brother, je trace les connexions (IP, étude du nom d'hote pour chasser les proxy pas discrets, du nombre de forwarded dans la même optique) avec un coefficient de suspectabilité, je log les erreurs pi basta (avec dedans les tentatives échouées d'accès à des trucs sensibles qu'un joueur normal est pas censé toucher). Les logs dans des fichiers textes, les accès directement dans la bdd de joueurs.

Après je pense pas qu'il faille tomber dans la sur-surveillance, parce que bon au final 'faudra bien qu'un bonhomme se coltine les 150 écrans de logs pour y chercher les transactions pas nettes (bin oui, si tu savais reconnaitre une transaction pas nette par le code, t'aurais implanté la condition directement dans ton code plutot que dans un script secondaire de vérification non ? A moins que tu ne chasses les actions sur-représentées parce qu'un ou plusieurs joueurs en abusent, mais bon si t'es pas radin avec les joueurs qui avouent les failles qu'ils trouvent t'ne aura bien un pour venir te voir ...).

Pour la vérification par l'admin, des sauvegardes récentes (ca aussi c'est plutot efficace comme système de logs ... Et en plus c'est utile en cas de crash ou d'abus de faille) dans lesquelles aller farfouiller ca suffit selon moi (parce que bon là dedans aussi tu peux repérer les suspects à la main ...). Et une communauté soudée et honnète :p


RE: Logging - barst - 07-02-2008

Pour ma part, je considère les logs, les traces et le suivi des utilisateurs comme importants mais je distingue les 3.

Pour moi une trace sert au débuggage de l'application.
Les traces indiquent ce par quoi passe le code et permet de suivre toutes les actions.
Les traces sont stockés dans des fichiers textes horodatés et j'ai un fichier par Objet.

Voici un exemple de trace généré
Code PHP :
<?php 
27
/12/2007 11:21:45 | INFO | BuildingModel | 10 | [BuildingModel::__construct] ==> Begin
27
/12/2007 11:21:45 | INFO | BuildingModel | 11 | [BuildingModel::__construct] ==> End
27
/12/2007 11:21:47 | INFO | BuildingModel | 34 | [BuildingModel::loadBuildingByPlanet] ==> Begin
27
/12/2007 11:21:47 | DEBUG | BuildingModel | 35 | [BuildingModel::loadBuildingByPlanet] ==> Paramater universe_id=[1]
27/12/2007 11:21:47 | DEBUG | BuildingModel | 36 | [BuildingModel::loadBuildingByPlanet] ==> Parameter planet_id=[1]
27/12/2007 11:21:47 | DEBUG | BuildingModel | 41 | [BuildingModel::loadBuildingByPlanet] ==> Query=[select b.id,a.building_id,a.building_level,b.category,b.img,b.effect_value,b.effect_formule,b.energy_value,b.energy_formule,b.time_value,b.time_formule from exodus_building_planet_1 a,admin_building b where b.universe_id=1 and a.building_id=b.building_id and a.planet_id=1 order by b.building_id]
27/12/2007 11:21:48 | INFO | BuildingModel | 44 | [BuildingModel::loadBuildingByPlanet] ==> End
27
/12/2007 11:21:48 | INFO | BuildingModel | 51 | [BuildingModel::loadCostByBuilding] ==> Begin
27
/12/2007 11:21:48 | DEBUG | BuildingModel | 52 | [BuildingModel::loadCostByBuilding] ==> Paramater universe_id=[1]
27/12/2007 11:21:48 | DEBUG | BuildingModel | 53 | [BuildingModel::loadCostByBuilding] ==> Parameter building_row_id=[1]
27/12/2007 11:21:48 | DEBUG | BuildingModel | 58 | [BuildingModel::loadCostByBuilding] ==> Query=[select ore_id,cost_value,cost_formule from admin_building_cost where ext_id=1 order by ore_id]
27/12/2007 11:21:48 | INFO | BuildingModel | 61 | [BuildingModel::loadCostByBuilding] ==> End


Et voici la classe "Tracer"
Code PHP :
<?php 
class Tracer
{
private
$path;
private
$filename;
private
$type;

function
__construct($path,$filename,$type='D')
{
if( !
is_string($path) ) throw new Exception('Invalid Parameter [path] : '.$path,2001);
if( !
is_string($filename) ) throw new Exception('Invalid Parameter [filename] : '.$filename,2002);
if( !
is_string($type) ) throw new Exception('Invalid Parameter [type] : '.$type,2003);
if( (
'H' != $type ) && ( 'D' != $type ) ) throw new Exception('Unexpected Value [type] : '.$type,2004);
$this->path = $path;
$this->filename = $filename;
$this->type = $type;
}

public function
trace($level,$file,$line,$mess)
{
if(
$_GLOBALS['config']['debug'] )
{
if( !
is_string($level) ) throw new Exception('Invalid Parameter [level] : '.$level,2008);
if( !
is_string($mess) ) throw new Exception('Invalid Parameter [mess] : '.$mess,2009);
$name = $this->path.'/'.$this->filename.'-'.(('D'==$this->type)?date('Ymd'):date('YmdH')).'.txt';
$h = @fopen($name,'a');
if(
false === $h ) throw new Exception('Impossible to open trace file : '.$name,2005);
$mess = sprintf("%s | %-7s | %s | %-5u | %s\n",date("d/m/Y H:i:s"),$level,$file,$line,$mess);
if(
false === @fwrite($h, $mess)) throw new Exception('Impossible to write trace in '.$name.' ['.$mess.']',2006);
fclose($h);
}
}
}

Et voici dans le code comment les traces sont appellées
Code PHP :
<?php 
public function loadBuildingByPlanet($universe_id,$planet_id)
{
$this->trace('INFO',basename(__CLASS__),__LINE__,'['.__METHOD__.'] ==> Begin');
$this->trace('DEBUG',basename(__CLASS__),__LINE__,'['.__METHOD__.'] ==> Paramater universe_id=['.$universe_id.']');
$this->trace('DEBUG',basename(__CLASS__),__LINE__,'['.__METHOD__.'] ==> Parameter planet_id=['.$planet_id.']');
if(!
is_numeric($universe_id)) throw new Exception('Invalid Parameter ==> universe_id=['.$universe_id.']',14003);
if(!
is_numeric($planet_id)) throw new Exception('Invalid Parameter ==> planet_id=['.$planet_id.']',14004);

$qry = "select b.id,a.building_id,a.building_level,b.category,b.img,b.effect_value,b.effect_formule,b.energy_value,b.energy_formule,b.time_value,b.time_formule from exodus_building_planet_".$universe_id." a,admin_building b where b.universe_id=".$universe_id." and a.building_id=b.building_id and a.planet_id=".$planet_id." order by b.building_id";
$this->trace('DEBUG',basename(__CLASS__),__LINE__,'['.__METHOD__.'] ==> Query=['.$qry.']');
$rows = $GLOBALS['db']->fetchArray($qry);

$this->trace('INFO',basename(__CLASS__),__LINE__,'['.__METHOD__.'] ==> End');
return
$rows;
}

Et dans un fichier de configuration, il y a une variable qui permet d'activer ou non les traces ($_GLOBALS['config']['debug'] = true; ).
Quand le débuggage est fini et que l'application part en environnement de PROD, il vaut mieux commenter les appels aux traces pour améliorer les performances mais il vaut mieux pas les supprimer car en cas de bug, il suffit de décommenter pour suivre ce qui se passe.


D'un autre côté, j'ai les logs qui remontent des problèmes sur l'application en environnement de PROD.
Chaque comportement non prévu déclenche un processus d'alerte avec un niveau de criticité.
En fonction du niveau de la criticité, une réaction a lieu :
- envoi d'une exception
- log dans un fichier
- envoi d'un mail à l'administrateur
avec la possibilité de faire toutes les réactions à la fois.

Pour cela, j'utilise un design pattern : "Chain of Responsability" [http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern]
Le principe est en gros le suivant : si un alerte de niveau 1 est déclenché alors une exception est levée, si l'alerte est de nievau 2 alors on écrit dans un log et on lève une exception et si elle est de nievau 3 alors on effectue les 3 actions.


Pour finir, il y a le suivi des actions d'un utilisateur.
Là, pas de mystère, j'historise toutes les actions effectuées par les utilisateurs.
Chaque action représente un ordre envoyé au système, cette ordre est stockée et il contient une liste de paramètre dont la signification change selon la nature de l'ordre.
J'ai ensuite une interface de visualisation de ces historiques, en filtrant sur les joueurs et/ou le type d'ordre (construction, achat, attaque, déplacement,...)


Et au fianl, il vaut mieux prévoir un petit script à part déclenché par crontab qui va archiver/purger les traces et les historiques.


RE: Logging - joshua - 07-02-2008

tu remplace tes | par des "," et tu as un csv :d