Logger

Corrections et conseils très bienvenus

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J'ai créé mon propre système de log, pour m'aider à débugger, et j'aimerais avoir vos commentaires et corrections.

Logger.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#ifndef LOGGER_H
#define LOGGER_H

#include <string>
#include <fstream>

#include "Log.h"


class Logger
{
    public:
        Logger(std::string filename);
        void LogSmth(Log log);
        virtual ~Logger();
    private:
        std::ofstream os;
};

Logger.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include "Logger.h"

Logger::Logger(std::string filename)
{
    os.open(filename.c_str());
}

void Logger::LogSmth(Log log)
{
    os << log.getMessage() << std::endl;
}

Logger::~Logger()
{
    os.close();
}

Log.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#ifndef LOG_H
#define LOG_H

#include <string>
#include <ctime>

enum LLevel { ERROR, WARNING, INFO, DEBUG, DEBUG1, UNKNOWN};

class Log
{
    public:
        Log(std::string message, LLevel level);
        std::string getMessage();
    private:
        std::string m_message;

};

#endif // LOG_H

Log.cpp

 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
#include "Log.h"

Log::Log(std::string message, LLevel level)
{
    time_t now = time(0);
    tm *localTime = localtime(&now);

    m_message += std::to_string(localTime->tm_year + 1900);
    m_message += "-";
    m_message += std::to_string(localTime->tm_mon + 1);
    m_message += "-";
    m_message += std::to_string(localTime->tm_mday);
    m_message += " | ";
    m_message += std::to_string(localTime->tm_hour);
    m_message += ":";
    m_message += std::to_string(localTime->tm_min + 1);
    m_message += ":";
    m_message += std::to_string(localTime->tm_sec + 1);

    switch(level)
    {
        case ERROR:
            m_message += " - ERROR    ";
            break;

        case WARNING:
            m_message += " - WARNING    ";
            break;

        case INFO:
            m_message += " - INFO   ";
            break;

        case DEBUG:
            m_message += " - DEBUG   ";
            break;

        case DEBUG1:
            m_message += " - DEBUG1   ";
            break;

        case UNKNOWN:
            m_message += " - UNKNOWN    ";
            break;
    }

    m_message += message;
}

std::string Log::getMessage()
{
    return m_message;
}

main.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <iostream>
#include <string>

#include "Log.h"
#include "Logger.h"

int main()
{
    const std::string filename { "test.txt" };
    Logger l(filename);
    Log m("Abricot", ERROR);
    Log n("Fraise", DEBUG);
    l.LogSmth(m);
    l.LogSmth(n);
    return 0;
}

Et j'obtiens ce fichier :

1
2
2015-9-14 | 16:2:27 - ERROR    Abricot
2015-9-14 | 16:2:27 - DEBUG   Fraise

Par contre, pour le temps notamment, je ne sais pas si les fonctionnalités que j'ai utilisé sont "périmées" ou pas.

Merci d'avance:)

+0 -0

Lu'!

Si le but c'est d'avoir un système de logs parce que tu n'en as pas : boost.log. Maintenant, si c'est pour t'exercer pourquoi pas.

Concernant ton code :

  • le mot clé "const" est ton ami, utilise le,
  • je pense que rentre le type de sortie paramétrique serait une bonne chose (ou au moins recevoir un ostream en paramètre),
  • pourquoi un destructeur virtuel ? Tu comptes rendre ton logger dérivable ? Si c'est le cas, il devrait être non-copiable/non-affectable (sémantique d'entité),
  • les niveaux pourraient également être paramétrique mais ça ce n'est pas obligatoire. En revanche, on aurait bien envie d'ajouter une surcharge de to_string plutôt qu'un switch en milieu de code,
  • pas encore d'autre standard que le C pour la date, par contre celui-ci fournit une fonction de sérialisation. Boost doit proposer des choses aussi.

Ciao.

Édité par Ksass`Peuk

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+0 -0
Auteur du sujet

Salut,

J'ai modifié les problèmes du destructeur virtuel et de const, mais je ne vois pas comment faire les sorties paramétriques(templates?), et la surcharge de to_string.

Pourquoi les nivaux devraient être paramétriques?

Et pour boost.log, pour l'instant je n'ai pas besoin d'autre fonctionnalités que celles là, je trouve que le désavantage de boost c'est :

1
boost::sous_namespace1::sous_namespace2::la_fonction_que_je_cherche

Et je préfère ne pas utiliser de using namespace, et je trouve ma syntaxe plus lisible.

Après si j'ai besoin d'autres fonctionnalités, je regarderais boost.log de plus près.

Édité par 91

+0 -0

je trouve que le désavantage de boost c'est :

1
boost::sous_namespace1::sous_namespace2::la_fonction_que_je_cherche

Et je préfère ne pas utiliser de using namespace, et je trouve ma syntaxe plus lisible.Source:91

Qui a dit qu'on devait nécessairement utiliser tout un namespace ?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
namespace truc{
namespace chose{
namespace muche{
  void foo(){} 
}}}

using truc::chose::muche::foo;

int main()
{
  truc::chose::muche::foo();
  foo();

  return 0;
}

J'ai modifié les problèmes du destructeur virtuel et de const, mais je ne vois pas comment faire (1) les sorties paramétriques(templates?), et (2) la surcharge de to_string.

91

  1. C'est une possibilité, mais on peut simplement se dire qu'on reçoit un ostream et basta :
1
2
3
4
5
6
7
8
9
#include <iosfwd>

class Logger{
public:
  Logger(std::ostream& os) : os(os){}

private:
  ostream& os;
};

(2) Suffit d'ajouter une fonction to_string prenant ton type en entrée :

1
2
3
4
5
6
7
std::string to_string(Type t){
  std::string s = std::to_string(t.carac_1());
  s += t.carac_2();
  ...
  s += t.carac_n();
  return s;
}

Pourquoi les nivaux devraient être paramétriques?

91

Pour pouvoir définir nos propres niveaux de logs.

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte