Bonjour, je suis entrain de faire un logger en c++, et je voulais afficher la fonction d'appel dans le message de log.
Par exemple :
int test() {
Logger::debug("Ceci est un test");
}
Output :
[DEBUG] [test] Ceci est un test
J'ai pensé à la pile d'exécution, en Java ou en Python il y a des trucs tout simple à utiliser mais en c++ ...
J'ai déjà un peu cherché sur internet. J'ai trouvé backtrace et backtrace_symbols mais ça ne fonctionne pas, de même pour stacktrace de la librairie boost qui a des erreurs de fonctions non-définies lors de la compilation.
Pour boost, il faut ajouter stacktrace dans les libs à link. Perso pour gcc et clang je compile soit avec -DBOOST_STACKTRACE_DYN_LINK et link avec -lboost_stacktrace_backtrace -rdynamic soit avec -DBOOST_STACKTRACE_USE_BACKTRACE -DBOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE=dossier_de_includes_backtrace.h et link avec -lbacktrace.
Mais c'est un process extrêmement lourd, faire cela va plomber les perfs. Pour afficher le nom des fonctions, on passe par une macro qui ajoute le nom de la fonction en paramètre et éventuellement le numéro de ligne (__PRETTY_FUNCTION__ / __FUNC__ / etc en fonction du compilo (boost à une macro qui le fait pour nous) et __LINE__). Sinon en C++20 il y a std::source_location.
Ce type d'info n'est utile que, selon moi, sur incident, et l'utilisation des fichiers des symboles (sous Windows, tout du moins) permettent de reconstruire cette information. C'est utilisé/utilisable dans les watchdog type ADP ou les analyseurs de dump.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Pourquoi ne pas utiliser les directives __LINE__ et __FILE__ (et __FUNC__ depuis C99)? dispo sur tout les compilateurs C/C++ standard depuis (houlà) ...
Le problème avec source_location, c'est qu'il n'est disponible qu'à partir de la libstd 11, or les dépots s'arrêtent à 10.
@jo_link_noir @jeancharlesg Ces macros on l'air très bien, mais elles renvoient la valeur pour l'endroit ou elles sont appelées, et je peux pas demander à l'utilisateur du logger de renseigner lui-même ou il est dans son code.
@bacelar
Je suis sous linux donc les solutions windows n'iront pas, et puis c'est mieux si ça fonctionne sur toutes les plateformes
Si patientes jusqu'au C++23, tu auras en plus std::stack_trace. En attendant, à toi de choisir l'artillerie de boost à réserver au debug (cf toi et jo_link_noir), l'analyse de la stack (cf bacelar) moins évidente mais accessible même en release avec plein d'infos, où la solution avec un rapport qualité/prix imbattable (de jo_link_noir et jeancharlesg)
Pour ton exemple cette dernière solution devrait suffire, il suffit d'utiliser une macro entre ton code et ta fonction de log:
void DoLog( unsigned long long line, const char* file, const char* func, std::string_view message ) {
endl( std::cerr << "Dans " << file << " ligne " << line << " fonction " << func << " : " << message );
}
#define LOG(msg) DoLog(__LINE__,__FILE__,__FUNC__,msg) // ou mieux: Log(__LINE__,__FILE__,__PRETTY_FUNCTION__,msg)
int main() {
LOG("hello");
}
while (true) { be happy }
JC Gibier
while (true) { be happy }
En recherche d'emploi.
while (true) { be happy }