IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

wxWidgets Discussion :

Comment utiliser les wxLog ?


Sujet :

wxWidgets

  1. #1
    dug
    dug est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 151
    Points : 84
    Points
    84
    Par défaut Comment utiliser les wxLog ?
    Bonjour,

    je cherche à utiliser les log de wxwidgets, en utilisant plusieurs niveaux, pour pouvoir afficher ou non tel ou tel niveau de log. Par exemple, un niveau pour les fonctions de base, un niveau pour les fonctions de l'interface, etc...
    j'aurai voulu savoir si on pouvait rediriger tel niveau dans un ctrl text, et un autre dans un fichier.

    j'ai cherché des tutos ou exemple sur le net sans succès
    quelqu'un aurai des pistes pour faire cela, ou un exemple de code ?
    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    wxWidgets propose des classes de log :

    Tu peux définir ta propre classe de log en dérivant de wxLog ou de wxLogPassThrough

    Les classes qui dérivent de wxLogPassThrough permettent d'enchaîner automatiquement les log : les messages iront de logger en logger sur toute la chaîne montée.
    Les classes qui dérivent de wxLog sont soit la seule destination des logs, soit doivent utiliser wxLogChain pour enchaîner les logs.

    La fonction statique wxLog::SetActiveTarget permet d'installer un log. Elle est prise en charge implicitement par wxLogPassThrough et wxLogChain.

    Par exemple, pour installer un log GUI :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wxLog::SetActiveTarget(new wxLogGui());
    Ici, les messages ne sont plus envoyés vers les logger précédent.

    Pour enchaîner les logger, il faut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new wxLogChain(new wxLogGui());
    Pour installer un log wxLogWindow (qui dérive de wxLogPassThrough) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new wxLogWindow(frame,wxT("log 1"));
    Ainsi, si tu veux logger vers un fichier et vers une fenêtre dédiée, ce serait ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    bool wxMonApp::OnInit(void)
    {
    // [.. initialisations ... ]
     
    // installations des logs :
       new wxLogChain(new wxLogStream(new std::ofstream(wxT("fichier.log"),std::ios_base::out|std::ios_base::trunc)));
       new wxLogWindow(frame,wxT("log 1"));
    }
    Pour filtrer tes logs par niveau, l'idéal aurait été de passer par le pattern décorateur. Mais, la classe wxLog a été mal faite pour ça. Donc le mieux est de créer ta classe wxLogFilter, de spécialiser DoLog et de filtrer en fonction du niveau que tu souhaites. Pour bénéficier des classes existantes, tu peux utiliser les template :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<class TBase>
    class wxLogFilter : public TBase
    {[...]};
    //....
    new wxLogFilter<wxLogWindow>(frame,wxT("log 1"));

  3. #3
    dug
    dug est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 151
    Points : 84
    Points
    84
    Par défaut
    merci beaucoup 3DArchi pour toutes ces précisions !

    nickel, je vais testé tout ça

  4. #4
    dug
    dug est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 151
    Points : 84
    Points
    84
    Par défaut
    voilà le bout de code que j'ai pondu grâce à ton aide entre autre.

    le but, rajouter des tags au début de la chaine de log, et activer ou non la log suivant les tags.
    ci dessous, on logue toutes les lignes dans un fichier, et dans un TextCtrl, on affiche que les logs qui ont les tags désirés.

    la dernière fonction ce trouve dans la frame qui contient le TextCtrl.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
     
     
    #include <string>
    #include <sstream>
     
    //	gestion des logs
     
    #define LOG_FCT_HIGH_LEVEL	0x0001
    #define LOG_FCT_LOW_LEVEL	0x0002
    #define LOG_FCT_SYNCHRO		0x0004
    #define LOG_PATH			0x0008
    #define LOG_DETAIL			0x0010
    #define LOG_SQL				0x0020
     
    #define LOG_LBL_FCT_HIGH_LEVEL	_T("FCT_HIGH_LEVEL")
    #define LOG_LBL_FCT_LOW_LEVEL	_T("FCT_LOW_LEVEL")
    #define LOG_LBL_FCT_SYNCHRO		_T("FCT_SYNCHRO")
    #define LOG_LBL_PATH			_T("PATH")
    #define LOG_LBL_DETAIL			_T("DETAIL")
    #define LOG_LBL_SQL				_T("SQL")
     
     
    #define LOG_DELIMITER	'@'
     
    typedef unsigned short	type_tag;
     
     
    unsigned short	ConvHexDec( wxString hex )
    {
    	std::string sHex = wx2std(hex);
    	unsigned short x;
     
    	std::istringstream iss( sHex );
    	iss >> std::hex >> x;
     
    	return x;
    }
     
    //! converts wxString to std::string
    std::string wx2std(const wxString& input, wxMBConv* conv)
    {
        if (input.empty())
            return "";
        if (!conv)
            conv = wxConvCurrent;
        return std::string(input.mb_str(*conv));
    }
     
    wxString	LogTagString( type_tag tag )
    {
    	wxString	s;
    	s.Empty();
     
    	if( (tag & LOG_FCT_HIGH_LEVEL) != 0 )
    		s << LOG_LBL_FCT_HIGH_LEVEL << _T(", ");
     
    	if( (tag & LOG_FCT_LOW_LEVEL) != 0 )
    		s << LOG_LBL_FCT_LOW_LEVEL << _T(", ");
     
    	if( (tag & LOG_FCT_SYNCHRO) != 0 )
    		s << LOG_LBL_FCT_SYNCHRO << _T(", ");
     
    	if( (tag & LOG_PATH) != 0 )
    		s << LOG_LBL_PATH << _T(", ");
     
    	if( (tag & LOG_DETAIL) != 0 )
    		s << LOG_LBL_DETAIL << _T(", ");
     
    	if( (tag & LOG_SQL) != 0 )
    		s << LOG_LBL_SQL << _T(", ");
     
    	if( !s.IsEmpty() )
    		s = s.Left( s.Len() -2 );	// désallocation de s avant sa réaffectation ?
     
    	return( s );
    }
     
    class LogTextCtrlLevel : public wxLogTextCtrl
    {
     public:
    	type_tag	tag;
    	bool		bShowTag;
     
    	LogTextCtrlLevel(wxTextCtrl *textctrl, type_tag _tag, bool _bShowTag)
    			: tag(_tag) , bShowTag(_bShowTag) , wxLogTextCtrl(textctrl) { }
    	void	DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp);
    };
     
    void	LogTextCtrlLevel::DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp)
    {
    	//	recherche du filtre en début du message
    	wxString	log = wxString(msg).AfterFirst( wxChar(LOG_DELIMITER) );
     
    	if( log.IsEmpty() || wxString(msg).Find(log) != 5 ) {
    		//	log du message sans tag
    		wxLogTextCtrl::DoLog( level, msg, timestamp );
    	} else {
    		//	conversion des tags en valeur
    		wxString	s = msg[0];
    		s << msg[1] << msg[2] << msg[3];
    		type_tag	i = ConvHexDec( s );
     
    		//	affichage des tags
    		if( bShowTag )
    			log = LogTagString(i) + _T(" -> ") + log;	// désallocation de log avant sa réaffectation ?
     
    		//	comparaison des tags
    		if( (tag & i) != 0 ) {
    			//	affichage de la log
    			wxLogTextCtrl::DoLog( level, log.GetData(), timestamp );
    		} /*else { // à commenter
    			wxLogTextCtrl::DoLog( level, log.GetData(), timestamp );
    			wxLogTextCtrl::DoLog( level, log.GetData(), timestamp );
    		}*/
    	}
    }
    ///     ***********************************************************************
     
    void	MainFrame::InitLog()
    {
    	//	création du TextCtrl qui contient l'affichage des logs
        m_Log = new wxTextCtrl(this,wxID_ANY, wxEmptyString,
                              wxPoint(0,0), wxSize(600,150),
                              wxTE_MULTILINE | wxTE_READONLY );
     
    	//	redirection de toutes les logs vers le fichier de log
    	wxLogStream*	logger = new wxLogStream(new std::ofstream("app.log", std::ios_base::out|std::ios_base::app));
     
    	//	activation de la log cible
        m_logOld = wxLog::SetActiveTarget( logger );	// ?
     
    	//	ajout d'un chainage des log vers le TextCtrl
    	wxLogChain	*logger2 = new wxLogChain( new LogTextCtrlLevel( m_Log, LOG_DETAIL | LOG_SQL, true ) );
     
    	wxLog::SetTimestamp( wxT("%Y-%M-%d %X") );
     
    	///     Exemple de log
        wxLogMessage( wxT("%.4x%c Essai Log affiche"), (type_tag) LOG_PATH | LOG_SQL, LOG_DELIMITER );
        wxLogMessage( wxT("%.4x%c Essai Log non affiche"), (type_tag) LOG_FCT_LOW_LEVEL | LOG_PATH, LOG_DELIMITER );
    }
    n'hésitez pas si vous avez des commentaires ou questions sur ce code.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Quelques remarques en vrac :
    #define j'aime pas du tout. C'est du C. En C++, tu peux utiliser des static const int au même coût.
    typedef unsigned short type_tag; j'aime pas trop non plus.
    Pour les flags, il y a mieux côté C++ mais là il est tard et il faut que je réfléchisse à ton truc
    La fonction std::string wx2std(const wxString& input, wxMBConv* conv) ne sert à rien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    typedef std::basic_string<wxChar, std::char_traits<wxChar>, std::allocator<wxChar> > std_string;// choisira automatiquement std::string ou std::wstring en fonction de wxChar
    typedef std::basic_istringstream<wxChar, std::char_traits<wxChar>, std::allocator<wxChar> > std_istringstream; // idem
     
    unsigned short	ConvHexDec( wxString hex )
    {
    	std_string sHex = hex.c_str();
    	unsigned short x;
     
    	std_istringstream iss( sHex );
    	iss >> std::hex >> x;
     
    	return x;
    }
    LogTagString : là c'est pareil. Ca me dérange, c'est du code à la C et c'est pas très souple. A chaque ajout d'un nouveau niveau de filtrage, faut venir ici.

    Je n'aurais pas fait hériter LogTextCtrlLevel de wxLogTextCtrl, mais j'aurais plutôt opté pour une composition avec un design pattern décorateur. En gros, tu veux ajouter une fonctionnalité à un log. Ca correspond à ce pattern. Et autant le mettre en place pour tout type de wxLog.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class LogTextCtrlLevel : public wxLog
    {
     public:
    	type_tag	tag;
    	bool		bShowTag;
     
    	LogTextCtrlLevel(wxLog *base_, type_tag _tag, bool _bShowTag)
    			: tag(_tag) , bShowTag(_bShowTag) , wxLogTextCtrl(textctrl) { }
     
    private:
    	virtual void DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp);
     
    private:
    	wxLog *m_base;
    private:
       LogTextCtrlLevel (LogTextCtrlLevel const&);// ne pas définir (cf F.A.Q. classe non copiable)
       LogTextCtrlLevel &operator=(LogTextCtrlLevel const&); // (cf F.A.Q. classe non copiable)
    };
     
    void	LogTextCtrlLevel::DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp)
    {
    	//	recherche du filtre en début du message
    	wxString	log = wxString(msg).AfterFirst( wxChar(LOG_DELIMITER) );
     
    	if( log.IsEmpty() || wxString(msg).Find(log) != 5 ) {
    		//	log du message sans tag
    		m_base->DoLog( level, msg, timestamp );
    	} else {
    //etc...
    Enfin, wxWidget offre déjà plus ou moins ce que tu essais de faire : wxLogTrace et les masques wxLog::AddTraceMask

    Enfin, bon boulot

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [HTTP] Comment utiliser les POST par programation
    Par Popof dans le forum Général Conception Web
    Réponses: 9
    Dernier message: 31/01/2005, 10h14
  2. Réponses: 4
    Dernier message: 13/12/2004, 21h37
  3. [COM] Comment utiliser les événements Word ?
    Par Laurent Dardenne dans le forum API, COM et SDKs
    Réponses: 7
    Dernier message: 30/05/2004, 13h38
  4. Réponses: 11
    Dernier message: 22/12/2003, 22h06
  5. Comment utiliser les styles XP avec Dev-C++?
    Par abraxas dans le forum Dev-C++
    Réponses: 3
    Dernier message: 05/10/2003, 20h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo