Partage
  • Partager sur Facebook
  • Partager sur Twitter

Log et source_location

    10 janvier 2022 à 22:13:53

    Bonjour a toutes et tous

    Je suis entrain de coder un logger qui me permettrai d'afficher, le nom du fichier, le nom de la fonction, le numero de ligne où je log.

    Je pensais que std::source_location::current(); qui est dans la surcharge de << me donnerait les infos de l'endroit où je log.

    #ifndef Log_H
    #define Log_H
    
    #include <fstream>
    #include <string>
    #include <ostream>
    #include <source_location>
    #include "Export.h"
    
    
    class Log
    {
    public:
    	Log(std::string path);
    	~Log();
    	inline std::string& getPath() { return path; };
    	void operator<<( std::string const &b);
    private:
    	std::string path;
    	std::ofstream file;
    	std::source_location sl;
    };
    
    
    #endif // !Log_H
    
    #include "..\include\Log.h"
    #include <iostream>
    
    
    Log::Log(std::string path)
    {
    	sl = std::source_location::current();
    	file.open(path);
    	if (!file.is_open())
    	{
    		std::cout << "pas ouvert";
    	}
    }
    
    Log::~Log()
    {
    	file.close();
    }
    
    
    void Log::operator<<(std::string const& b)
    {
    	sl = std::source_location::current();
    	this->file
    	<< this->sl.file_name() << " "
    	<< this->sl.function_name() << " "
    	<< this->sl.line() << " "
    	<< b << '\n';
    }
    #include "../Log/include/Log.h"
    
    void test(Log &l)
    {
    	l << "dans test";//function test line 5
    }
    
    
    int main()
    {
    	Log log("test.txt");
    	log << "dans le main";// function main line 12
    	test(log);
    
    	return 0;
    }

    le fichier de sorti

    Log.cpp operator << 23 dans le main
    Log.cpp operator << 23 dans test
    


    ce que j'aimerai avoir

    main.cpp main 12 dans le main
    main.cpp test 5 dans test
    



    -
    Edité par JEANBAPTISTECOMTE1 10 janvier 2022 à 22:23:28

    • Partager sur Facebook
    • Partager sur Twitter
      10 janvier 2022 à 22:48:37

      Salut pourquoi n'est pas utilisé les variables du préprocesseur au lieu de te casser la tête ?

      voici quelques variables qui pourrons t'être utile:

      • _ _FILE_ _ chaîne littérale contenant le nom du fichier
      • _ _LINE_ _ littéral entier contenant le numéro de la ligne courante
      •  _ _func_ _ pour imprimer le nom de la fonction; Il s'agit d'un tableau local statique de const char qui contient le nom de la fonction.
      • _ _TIME_ _ chaîne de caractères contenant l'heure de compilation du fichier
      • _ _DATE_ _ chaîne de caractères contenant la date de compilation du fichier
      • Partager sur Facebook
      • Partager sur Twitter

      Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .

        10 janvier 2022 à 22:54:04

        Bin, ça marche comme tu l'as expliqué, ça donne l'endroit où l'appel à "std::source_location::current()" est effectué.

        L'erreur, c'est d'avoir factoriser cette partie dans l'opérateur << et pas l'avoir appeler avant.

        Pour les framework de Log que j'ai l'habitude d'utiliser, ça passe par des MACRO qui appellent l'équivalent de "std::source_location::current()" avant l'appel à la routine de Log proprement dite. Généralement, lors de l'évaluation de ses paramètres.

        Si vous voulez garder cette factorisation tardive, il ne vous faut pas la "source_location" lors de l'appel avoir accès à la "frame" de pile appelante. C'est souvent possible avec des framework de log capable de logger les piles d'appels.

        • Partager sur Facebook
        • Partager sur Twitter
        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
          10 janvier 2022 à 23:45:29

          La subtilité de std::source_location est de demander au compilateur de le faire à travers std::source_location::current() comme paramètre par défaut d'une fonction. Les valeurs de position seront celles de l'appelant. Par contre, avec <<, il faudra passer par un intermédiaire.

          • Partager sur Facebook
          • Partager sur Twitter
            12 janvier 2022 à 23:06:25

            Merci pour vos réponses je fais un update

            J'ai fait une class Singleton.

            La class Log hérite de Singleton ce qui me permet de ne pas avoir 50 instances, et me permet de faire une macro sans avoir a passer un objet Log.

            Par contre est ce que quelqu'un aurai une idée pour set le path ?

            #ifndef Singleton_H
            #define Singleton_H
            
            namespace orion
            {
                template<typename T>
                class Singleton
                {
                public:
                    static T* GetInstance();
            
                    Singleton(const Singleton&) = delete;
                    Singleton& operator= (const Singleton) = delete;
            
                protected:
                    Singleton() {}
                private:
                };
            
            
                template<typename T>
                T* Singleton<T>::GetInstance()
                {
                    static T instanceUnique;
                    return &instanceUnique;
                }
            }
            
            
            #endif // !1
            #ifndef Log_H
            #define Log_H
            
            #include <fstream>
            #include <string>
            #include <ostream>
            #include <iostream>
            #include <sstream>
            #include <source_location>
            #include "Singleton.h"
            
            #define LOG(str){ orion::Log *inst = orion::Log::GetInstance(); inst->sl = std::source_location::current(); *inst << str;}
            namespace orion
            {
            	class Log : public orion::Singleton<Log>
            	{
            	public:
            		Log();
            		~Log();
            		inline std::string& getPath() { return path; };
            		void operator<<(std::string const b);
            		std::source_location sl;
            	private:
            		std::string path;
            		std::ofstream file;
            	};
            }
            #endif // !Log_H
            
            #include "Log.h"
            
            namespace orion
            {
            	Log::Log()
            	{
            		file.open("C:/test/test.txt");
            		if (!file.is_open())
            		{
            			std::cout << "pas ouvert";
            		}
            	}
            
            	Log::~Log()
            	{
            		file.close();
            	}
            
            
            	void Log::operator<<(std::string const b)
            	{
            		this->file
            			<< this->sl.file_name() << " "
            			<< this->sl.function_name() << " "
            			<< this->sl.line() << " "
            			<< b << '\n';
            	}
            }
            #include "Log.h"
            
            void test()
            {
            	LOG("dans test");
            }
            
            
            int main()
            {
            	test();
            	std::stringstream olg;
            	olg << "###";
            
            	olg << "dans le main";
            
            	LOG(olg.str());
            
            	return 0;
            }
            main.cpp test 5 dans test
            main.cpp main 17 ###dans le main
            




            -
            Edité par JEANBAPTISTECOMTE1 12 janvier 2022 à 23:12:27

            • Partager sur Facebook
            • Partager sur Twitter
              13 janvier 2022 à 16:29:47

              Quitte à utiliser des Singleton, autant la boire jusqu'à la lie et utiliser un Singleton Config pour récupérer les informations de configurations dont le chemin vers les Logs. (Je vous laisse vous démerder pour avoir le Singleton Config "up" avant le Singleton Log.)
              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                13 janvier 2022 à 21:49:47

                Un Singleton Config "up" ?

                C'est a dire ?

                • Partager sur Facebook
                • Partager sur Twitter
                  14 janvier 2022 à 20:47:03

                  Un Singleton qui contient la configuration du programme, qui est généralement dans un fichier de configuration ou donnée en paramètre de la ligne de commande, etc...

                  Tu ne pense pas à avoir le chemin en dur et à recompiler quand il change, quand même ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                    17 janvier 2022 à 12:49:46

                    J'ai modifié mes classes justement pour ne pas avoir de chemin en dur

                    #ifndef Log_H
                    #define Log_H
                    
                    #include <fstream>
                    #include <string>
                    #include <source_location>
                    #include "Singleton.h"
                    
                    #define LOG(str){ orion::Log *inst = orion::Log::GetInstance(); inst->sl = std::source_location::current(); *inst << str;}
                    namespace orion
                    {
                    
                    	class NetworkEngine Log : public orion::Singleton<Log>
                    	{
                    	public:
                    		Log();
                    		~Log();
                    		inline std::string& getPath() { return path; };
                    		bool Init(std::string path, std::ios_base::openmode mode = std::ios_base::app);
                    		void operator<<(std::string const b);
                    		std::source_location sl;
                    	private:
                    		std::string path;
                    		std::ofstream file;
                    		bool isOpened = false;
                    	};
                    }
                    #endif // !Log_H
                    #include "Log.h"
                    #include <iostream>
                    
                    namespace orion
                    {
                    	Log::Log()
                    	{
                    
                    	}
                    
                    	Log::~Log()
                    	{
                    		file.close();
                    	}
                    
                    
                    
                    	bool Log::Init(std::string path, std::ios_base::openmode mode )
                    	{
                    		if (file.is_open())
                    		{
                    			return false;
                    		}
                    		file.open(path, mode);
                    		if (!file.is_open())
                    		{
                    			this->path = path;
                    			std::cout << path << " pas ouvert";
                    			return false;
                    		}
                    		isOpened = true;
                    		return true;
                    	}
                    
                    	void Log::operator<<(std::string const b)
                    	{
                    		if (isOpened)
                    		{
                    			this->file
                    				<< this->sl.file_name() << " "
                    				<< this->sl.function_name() << " "
                    				<< this->sl.line() << " "
                    				<< b << '\n';
                    		}
                    	}
                    }





                    -
                    Edité par JEANBAPTISTECOMTE1 17 janvier 2022 à 12:50:33

                    • Partager sur Facebook
                    • Partager sur Twitter
                      17 janvier 2022 à 18:52:10

                      >J'ai modifié mes classes justement pour ne pas avoir de chemin en dur

                      Et ?

                      Pourquoi la "solution" que vous avez trouvé pour les Log ne fonctionnerait pas pour la gestion des fichiers de configuration ?

                      J'essaye de vous faire toucher du doigt toutes les limitations et emmerdements que votre solution implique. (mais les constructeurs publics de vos Singleton, c'est de votre faute, pas de la leur)

                      Pourquoi ne pas utiliser une librairie de logs déjà implémentée, qui a déjà résolue ou passée outre ces problèmes ?

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                      Log et source_location

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      • Editeur
                      • Markdown