﷽
→ Dernière version
→ Journal des modifications
→ Échantillons
Aperçu Pourquoi encore une autre bibliothèque Caractéristiques en un coup d'oeil Commencer Télécharger Démarrage rapide Installer (facultatif) Définition des arguments d'application Configuration Niveau Configurer Utilisation du fichier de configuration Utilisation de la classe el::Configurations Utilisation des configurations en ligne Configurations par défaut Configurations globales Spécificateurs de format de journalisation Spécificateurs de format de date/heure Spécificateurs de format personnalisés Indicateurs de journalisation Arguments de candidature Macros de configuration Lecture des configurations Enregistrement Basique Journalisation conditionnelle Journalisation occasionnelle printf J'aime la journalisation Journalisation réseau Journalisation détaillée Basique Conditionnel et occasionnel Niveau verbeux Vérifiez si la journalisation détaillée est activée Module V Enregistrement de nouveaux enregistreurs Désenregistrer les enregistreurs Remplir les ID d'enregistreur existants Partage du référentiel de journalisation Fonctionnalités supplémentaires Suivi des performances Suivi des performances conditionnelles Utiliser les données de suivi des performances Rotation du fichier journal Gestion des crashs Installation de gestionnaires de crash personnalisés Trace de pile Multi-thread VÉRIFIER les macros Erreur de journalisation() Utiliser Syslog Journalisation STL Modèles pris en charge Journalisation Qt Boostez la journalisation Journalisation wxWidgets Extension de la bibliothèque Enregistrer votre propre classe Classe de journalisation tierce Vidage et roulement manuels des fichiers journaux Rappel d'envoi de journaux Rappel d'enregistrement de l'enregistreur Journalisation asynchrone Classes d'assistance Contribution Soumission de correctifs Signaler un bug Compatibilité Construire une matrice Licence Clause de non-responsabilité
Easylogging++ est une bibliothèque de journalisation efficace à en-tête unique pour les applications C++. Il est extrêmement puissant, hautement extensible et configurable selon les besoins de l'utilisateur. Il offre la possibilité d'écrire vos propres récepteurs (via une fonctionnalité appelée LogDispatchCallback
). Cette bibliothèque est actuellement utilisée par des centaines de projets open source sur github et d'autres sites de gestion de contrôle open source.
Ce manuel concerne Easylogging++ v9.97.1. Pour les autres versions, veuillez vous référer à la version correspondante sur github.
Vous pourriez également être intéressé par le serveur de journalisation des résidus.
Aller en haut
Si vous travaillez sur un petit utilitaire ou un grand projet en C++, cette bibliothèque peut s'avérer utile. Il est basé sur un seul en-tête et ne nécessite qu'un lien vers un fichier source unique. (À l'origine, il s'agissait uniquement d'en-tête et a été modifié pour utiliser le fichier source dans le numéro 445. Vous pouvez toujours utiliser l'en-tête uniquement dans la version 9.89).
Cette bibliothèque a été conçue avec diverses idées à l'esprit (c'est-à-dire portabilité, performances, convivialité, fonctionnalités et facilité de configuration).
Pourquoi encore une autre bibliothèque ? Eh bien, la réponse est assez simple, utilisez-la telle que vous l'avez écrite afin de pouvoir résoudre les problèmes (le cas échéant) au fur et à mesure ou les soulever sur github. En plus de cela, je n'ai personnellement vu aucune bibliothèque de journalisation basée sur un en-tête unique avec une telle conception où vous pouvez la configurer en déplacement, l'étendre à vos besoins et obtenir des performances rapides. J'ai vu d'autres bibliothèques de journalisation à en-tête unique pour C++, mais soit elles utilisent des bibliothèques externes, par exemple boost ou Qt pour prendre en charge certaines fonctionnalités telles que le threading, l'expression régulière ou la date, etc. Cette bibliothèque a tout intégré pour empêcher l'utilisation de bibliothèques externes, non pas que je n'aime pas ces bibliothèques, en fait je les aime, mais comme tous les projets n'utilisent pas ces bibliothèques, je ne pouvais pas prendre le risque d'en dépendre.
Aller en haut
Easylogging++ est riche en fonctionnalités et contient de nombreuses fonctionnalités dont les développeurs classiques et avancés auront besoin lors de l'écriture d'un logiciel ;
Aller en haut
Téléchargez la dernière version à partir de la dernière version
Pour les autres versions, veuillez visiter la page des versions. Si votre application ne prend pas en charge C++11, envisagez d'utiliser la version 8.91. Il s'agit d'une version stable pour C++98 et C++03, il manque juste quelques fonctionnalités.
Aller en haut
Pour démarrer avec Easylogging++, vous pouvez suivre trois étapes simples :
easylogging++.h
et easylogging++.cc
)# include " easylogging++.h "
INITIALIZE_EASYLOGGINGPP
int main ( int argc, char * argv[]) {
LOG (INFO) << " My first info log using default logger " ;
return 0 ;
}
Compilez maintenant en utilisant
g++ main.cc easylogging++.cc -o prog -std=c++11
C'est aussi simple que ça ! Veuillez noter que INITIALIZE_EASYLOGGINGPP
doit être utilisé une seule fois, sinon vous finirez par obtenir des erreurs de compilation. C'est la définition de plusieurs variables extern
. Cela signifie qu'il ne peut être défini qu'une seule fois par application. Le meilleur endroit pour placer cette instruction d'initialisation est dans le fichier où la fonction int main(int, char**)
est définie, juste après la dernière instruction include.
Si vous souhaitez installer cet en-tête à l'échelle du système, vous pouvez le faire via :
mkdir build
cd build
cmake -Dtest=ON ../
make
make test
make install
Les options suivantes sont prises en charge par Easylogging++ cmake et vous pouvez activer ces options en utilisant -D<option>=ON
lib_utc_datetime
- Définit ELPP_UTC_DATETIME
build_static_lib
- Construit une bibliothèque statique pour Easylogging++ Cela dit, vous aurez toujours besoin du fichier easylogging++.cc
pour compiler. Pour l'en-tête uniquement, veuillez vérifier la version 9.89 et inférieure.
Alternativement, vous pouvez télécharger et installer easyloggingpp à l'aide du gestionnaire de dépendances vcpkg :
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install easyloggingpp
Le port easyloggingpp dans vcpkg est tenu à jour par les membres de l'équipe Microsoft et les contributeurs de la communauté. Si la version est obsolète, veuillez créer un problème ou une pull request sur le référentiel vcpkg.
Aller en haut
Il est toujours recommandé de transmettre les arguments de l'application à Easylogging++. Certaines fonctionnalités d'Easylogging++ nécessitent que vous définissiez des arguments d'application, par exemple, la journalisation détaillée pour définir le niveau détaillé ou les vmodules (expliqué plus tard). Pour ce faire, vous pouvez utiliser une macro d'assistance ou une classe d'assistance ;
int main ( int argc, char * argv[]) {
START_EASYLOGGINGPP (argc, argv);
...
}
Aller en haut
Afin de commencer à configurer votre bibliothèque de journalisation, vous devez comprendre les niveaux de gravité. Easylogging++ n'utilise délibérément pas de journalisation hiérarchique afin de contrôler entièrement ce qui est activé et ce qui ne l'est pas. Cela étant dit, il existe toujours la possibilité d'utiliser la journalisation hiérarchique à l'aide de LoggingFlag::HierarchicalLogging
. Easylogging++ a les niveaux suivants (classés pour les niveaux hiérarchiques)
Niveau | Description |
---|---|
Mondial | Niveau générique qui représente tous les niveaux. Utile lors de la définition d'une configuration globale pour tous les niveaux. |
Tracer | Informations qui peuvent être utiles pour retracer certains événements - surtout utiles que les journaux de débogage. |
Déboguer | Événements d'information les plus utiles aux développeurs pour déboguer l'application. Applicable uniquement si NDEBUG n'est pas défini (pour non-VC++) ou si _DEBUG est défini (pour VC++). |
Fatal | Événement d’erreur très grave qui entraînera probablement l’abandon de l’application. |
Erreur | Informations d'erreur, mais l'application continuera à fonctionner. |
Avertissement | Informations représentant les erreurs dans l'application, mais l'application continuera à fonctionner. |
Informations | Principalement utile pour représenter la progression actuelle de l’application. |
Verbeux | Informations qui peuvent être très utiles et varient en fonction du niveau de journalisation détaillée. La journalisation détaillée ne s'applique pas à la journalisation hiérarchique. |
Inconnu | Applicable uniquement à la journalisation hiérarchique et utilisé pour désactiver complètement la journalisation. |
Aller en haut
Easylogging++ est facile à configurer. Il existe trois manières possibles de le faire,
La configuration peut être effectuée par un fichier chargé au moment de l'exécution par la classe Configurations
. Ce fichier a le format suivant :
* LEVEL:
CONFIGURATION NAME = "VALUE" ## Comment
ANOTHER CONFIG NAME = "VALUE"
Le nom du niveau commence par une étoile (*) et se termine par deux points (:). Il est fortement recommandé de démarrer votre fichier de configuration avec le niveau Global
afin que toute configuration non spécifiée dans le fichier utilise automatiquement la configuration de Global
. Par exemple, si vous définissez Filename
dans Global
et que vous souhaitez que tous les niveaux utilisent le même nom de fichier, ne le définissez pas explicitement pour chaque niveau, la bibliothèque utilisera automatiquement la valeur de configuration de Global
. Le tableau suivant contient les configurations prises en charge par le fichier de configuration.
Nom de la configuration | Taper | Description |
---|---|---|
Enabled | bouffon | Détermine si le niveau correspondant pour l'enregistreur est activé ou non. Vous pouvez désactiver tous les journaux en utilisant el::Level::Global |
To_File | bouffon | S'il faut ou non écrire le journal correspondant dans le fichier journal |
To_Standard_Output | bouffon | S'il faut ou non écrire des journaux sur une sortie standard, par exemple un terminal ou une invite de commande |
Format | carboniser* | Détermine le format/modèle de journalisation pour le niveau et l'enregistreur correspondants. |
Filename | carboniser* | Détermine le fichier journal (chemin complet) dans lequel écrire les journaux pour le niveau et l'enregistreur correspondants |
Subsecond_Precision | uint | Spécifie une précision inférieure à la seconde (anciennement appelée « largeur en millisecondes »). La largeur peut être comprise dans la plage (1-6) |
Performance_Tracking | bouffon | Détermine si le suivi des performances est activé ou non. Cela ne dépend pas de l'enregistreur ou du niveau. Le suivi des performances utilise toujours un enregistreur de « performances », sauf indication contraire |
Max_Log_File_Size | taille_t | Si la taille du fichier journal du niveau correspondant est >= taille spécifiée, le fichier journal sera tronqué. |
Log_Flush_Threshold | taille_t | Spécifie le nombre d'entrées de journal à conserver jusqu'à ce que nous vidions les données de journal en attente |
Veuillez ne pas utiliser de guillemets doubles dans les commentaires, vous pourriez vous retrouver avec un comportement inattendu.
Exemple de fichier de configuration
* GLOBAL:
FORMAT = "%datetime %msg"
FILENAME = "/tmp/logs/my.log"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
SUBSECOND_PRECISION = 6
PERFORMANCE_TRACKING = true
MAX_LOG_FILE_SIZE = 2097152 ## 2MB - Comment starts with two hashes (##)
LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs
* DEBUG:
FORMAT = "%datetime{%d/%M} %func %msg"
Le contenu du fichier de configuration dans l’exemple ci-dessus est simple. Nous commençons par le niveau GLOBAL
afin de remplacer tous les niveaux. Tout niveau ultérieur explicitement défini remplacera la configuration de GLOBAL
. Par exemple, tous les niveaux, à l'exception de DEBUG
ont le même format, c'est-à-dire dateheure et message de journal. Pour le niveau DEBUG
, nous n'avons que la date (avec jour et mois), la fonction source et le message de journal. Le reste des configurations pour DEBUG
est utilisé à partir de GLOBAL
. Notez également {%d/%M}
au format DEBUG
ci-dessus, si vous ne spécifiez pas le format de date, le format par défaut est utilisé. Les valeurs par défaut de la date/heure sont %d/%M/%Y %h:%m:%s,%g
Pour plus d'informations sur ces spécificateurs de format, veuillez vous référer à la section Spécificateur de format date/heure ci-dessous.
# include " easylogging++.h "
INITIALIZE_EASYLOGGINGPP
int main ( int argc, const char ** argv) {
// Load configuration from file
el::Configurations conf ( " /path/to/my-conf.conf " );
// Reconfigure single logger
el::Loggers::reconfigureLogger ( " default " , conf);
// Actually reconfigure all loggers instead
el::Loggers::reconfigureAllLoggers (conf);
// Now all the loggers will use configuration from file
}
Votre fichier de configuration peut être converti en objet
el::Configurations
(à l'aide du constructeur) qui peut être utilisé partout où cela est nécessaire (comme dans l'exemple ci-dessus).
Aller en haut
Vous pouvez définir des configurations ou réinitialiser des configurations ;
# include " easylogging++.h "
INITIALIZE_EASYLOGGINGPP
int main ( int argc, const char ** argv) {
el::Configurations defaultConf;
defaultConf. setToDefault ();
// Values are always std::string
defaultConf. set (el::Level::Info,
el::ConfigurationType::Format, " %datetime %level %msg " );
// default logger uses default configurations
el::Loggers::reconfigureLogger ( " default " , defaultConf);
LOG (INFO) << " Log using default file " ;
// To set GLOBAL configurations you may use
defaultConf. setGlobally (
el::ConfigurationType::Format, " %date %msg " );
el::Loggers::reconfigureLogger ( " default " , defaultConf);
return 0 ;
}
La configuration ne doit être définie qu'une seule fois. Si vous êtes satisfait de la configuration par défaut, vous pouvez également l'utiliser.
Aller en haut
La configuration en ligne signifie que vous pouvez définir des configurations dans std::string
mais assurez-vous d'ajouter tous les nouveaux caractères de ligne, etc. Ceci n'est pas recommandé car c'est toujours compliqué.
el::Configurations c;
c.setToDefault();
c.parseFromText( " *GLOBAL: n FORMAT = %level %msg " );
Le code ci-dessus définit uniquement l'objet Configurations, vous devez toujours reconfigurer les enregistreurs à l'aide de ces configurations.
Aller en haut
Si vous souhaitez avoir une configuration pour les enregistreurs existants et futurs, vous pouvez utiliser el::Loggers::setDefaultConfigurations(el::Configurations& configurations, bool configureExistingLoggers = false)
. Ceci est utile lorsque vous travaillez à une assez grande échelle ou que vous utilisez une bibliothèque tierce qui utilise déjà Easylogging++. Tout enregistreur nouvellement créé utilisera les configurations par défaut. Si vous souhaitez également configurer les enregistreurs existants, vous pouvez définir le deuxième argument sur true
(la valeur par défaut est false
).
Aller en haut
Level::Global
n'a rien à voir avec les configurations globales, c'est un concept dans lequel vous pouvez enregistrer des configurations pour tous/ou certains enregistreurs et même enregistrer de nouveaux enregistreurs à l'aide d'un fichier de configuration. La syntaxe du fichier de configuration est :
-- LOGGER ID ## Case sensitive
## Everything else is same as configuration file
-- ANOTHER LOGGER ID
## Configuration for this logger
L'ID de l'enregistreur commence par deux tirets. Une fois que vous avez écrit votre fichier de configuration globale, vous pouvez configurer tous vos enregistreurs (et en enregistrer de nouveaux) à l'aide d'une seule fonction ;
int main ( void ) {
// Registers new and configures it or
// configures existing logger - everything in global.conf
el::Loggers::configureFromGlobal ( " global.conf " );
// .. Your prog
return 0 ;
}
Attention, il n'est pas possible d'enregistrer un nouvel enregistreur en utilisant la configuration globale sans définir sa configuration. Vous devez définir au moins une seule configuration. D'autres façons d'enregistrer les enregistreurs sont abordées dans la section Journalisation ci-dessous.
Aller en haut
Vous pouvez personnaliser le format de journalisation à l'aide des spécificateurs suivants :
Spécificateur | Remplacé par |
---|---|
%logger | ID de l'enregistreur |
%thread | ID de fil - Utilise std::thread si disponible, sinon GetCurrentThreadId() sous Windows |
%thread_name | Utilisez Helpers::setThreadName pour définir le nom du thread actuel (à partir duquel vous exécutez setThreadName ). Voir l'exemple de noms de sujets |
%level | Niveau de gravité (Info, Débogage, Erreur, Avertissement, Fatal, Verbeux, Trace) |
%levshort | Niveau de gravité (version courte, c'est-à-dire I pour Info et respectivement D, E, W, F, V, T) |
%vlevel | Niveau de verbosité (applicable à la journalisation détaillée) |
%datetime | Date et/ou heure – Le motif est personnalisable – voir les spécificateurs de format de date/heure ci-dessous |
%user | Utilisateur exécutant actuellement l'application |
%host | L'application de nom d'ordinateur est en cours d'exécution sur |
%file * | Nom du fichier source (chemin complet) - Cette fonctionnalité est soumise à la disponibilité de la macro __FILE__ du compilateur |
%fbase * | Nom de fichier du fichier source (uniquement le nom de base) |
%line * | Numéro de ligne source - Cette fonctionnalité est soumise à la disponibilité de la macro __LINE__ de compilation |
%func * | Fonction de journalisation |
%loc * | Nom du fichier source et numéro de ligne de journalisation (séparés par deux points) |
%msg | Message de journal réel |
% | Caractère d'échappement (par exemple, %%level écrira %level) |
__LINE__
, __FILE__
etc. Aller en haut
Vous pouvez personnaliser le format date/heure à l'aide des spécificateurs suivants
Spécificateur | Remplacé par |
---|---|
%d | Jour du mois (avec zéro) |
%a | Jour de la semaine - court (lun, mardi, mercredi, jeudi, vendredi, samedi, dimanche) |
%A | Jour de la semaine - long (lundi, mardi, mercredi, jeudi, vendredi, samedi, dimanche) |
%M | Mois (avec zéro) |
%b | Mois - court (janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre) |
%B | Mois - Long (janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre) |
%y | Année - Deux chiffres (13, 14, etc.) |
%Y | Année - Quatre chiffres (2013, 2014, etc.) |
%h | Heure (format 12 heures) |
%H | Heure (format 24 heures) |
%m | Minute (avec zéro) |
%s | Deuxième (avec zéro) |
%g | Partie sous-seconde (la précision est configurée par ConfigurationType :: SubsecondPrecision) |
%F | Désignation AM/PM |
% | Caractère d'évasion |
Attention, la date/heure est limitée à 30
caractères maximum.
Aller en haut
Vous pouvez également spécifier vos propres spécificateurs de format. Pour ce faire, vous pouvez utiliser el::Helpers::installCustomFormatSpecifier
. Un exemple parfait est %ip_addr
pour l'application serveur TCP ;
const char * getIp ( const el::LogMessage*) {
return " 192.168.1.1 " ;
}
int main ( void ) {
el::Helpers::installCustomFormatSpecifier ( el::CustomFormatSpecifier ( " %ip_addr " , getIp));
el::Loggers::reconfigureAllLoggers (el::ConfigurationType::Format, " %datetime %level %ip_addr : %msg " );
LOG (INFO) << " This is request from client " ;
return 0 ;
}
Aller en haut
Dans certaines parties de la journalisation, vous pouvez définir des indicateurs de journalisation ; voici les drapeaux pris en charge :
Drapeau | Description |
---|---|
NewLineForContainer (1) | S'assure que nous avons une nouvelle ligne pour chaque entrée du journal du conteneur |
AllowVerboseIfModuleNotSpecified (2) | S'assure que si -vmodule est utilisé et ne spécifie pas de module, alors la journalisation détaillée est autorisée via ce module. Supposons que le paramètre soit -vmodule=main*=3 et qu'un journal détaillé soit écrit à partir d'un fichier appelé quelque chose.cpp, alors si cet indicateur est activé, le journal sera écrit sinon il sera interdit. Remarque : cela va à l'encontre du but de -vmodule |
LogDetailedCrashReason (4) | Lors de la gestion des crashs par défaut, la raison détaillée du crash sera également enregistrée (désactivée par défaut) (problème n°90) |
DisableApplicationAbortOnFatalLog (8) | Permet de désactiver l'interruption d'application lors d'une connexion en utilisant le niveau FATAL. Notez que cela ne s'applique pas aux gestionnaires de crash par défaut, car l'application doit être abandonnée une fois le signal de crash traité. (Non ajouté par défaut) (numéro 119) |
ImmediateFlush (16) | Vide le journal avec chaque entrée de journal (sensible aux performances) - Désactivé par défaut |
StrictLogFileSizeCheck (32) | S'assure que la taille du fichier journal est vérifiée avec chaque journal |
ColoredTerminalOutput (64) | La sortie du terminal sera colorée si elle est prise en charge par le terminal. |
MultiLoggerSupport (128) | Permet la prise en charge de l'utilisation de plusieurs enregistreurs pour enregistrer un seul message. (Par exemple, CLOG(INFO, "default", "network") << This will be logged using default and network loggers; ) |
DisablePerformanceTrackingCheckpointComparison (256) | Désactive la comparaison des points de contrôle |
DisableVModules (512) | Désactive l'utilisation des vmodules |
DisableVModulesExtensions (1024) | Désactive l’extension vmodules. Cela signifie que si vous avez un vmodule -vmodule=main*=4, il couvrira tout commençant par main, alors que si vous ne l'aviez pas défini, vous serez couvert pour tout fichier commençant par main et se terminant par l'une des extensions suivantes ; .h .c .cpp .cc .cxx .-inl-.h .hxx .hpp. Veuillez noter que le vmodule suivant n'est pas correct -vmodule=main.=4 avec cette macro non définie car cela vérifiera main..c, remarquez les doubles points. Si vous voulez que cela soit valide, jetez un œil à l'indicateur de journalisation ci-dessus : AllowVerboseIfModuleNotSpecified '?' et « les caractères génériques sont pris en charge |
HierarchicalLogging (2048) | Active la journalisation hiérarchique. Ceci ne s'applique pas à la journalisation détaillée. |
CreateLoggerAutomatically (4096) | Crée automatiquement un enregistreur lorsqu'il n'est pas disponible. |
AutoSpacing (8192) | Ajoute automatiquement des espaces. Par exemple, LOG(INFO) << "DODGE" << "THIS!"; affichera "DODGE THIS!" |
FixedTimeFormat (16384) | Applicable uniquement au suivi des performances : cela évite le temps de formatage. Par exemple, 1001 ms seront enregistrés tels quels, au lieu de les formater en 1.01 sec |
IgnoreSigInt (32768) | Lorsque l'application plante, ignorez le signal d'interruption |
Vous pouvez définir/désactiver ces indicateurs en utilisant static el::Loggers::addFlag
et el::Loggers::removeFlag
. Vous pouvez vérifier si certains indicateurs sont disponibles en utilisant el::Loggers::hasFlag
, toutes ces fonctions prennent une énumération fortement typée el::LoggingFlag
Vous pouvez définir ces indicateurs en utilisant l'argument de ligne de commande
--logging-flags
. Vous devez activer cette fonctionnalité en définissant la macroELPP_LOGGING_FLAGS_FROM_ARG
(vous devrez vous assurer d'utiliserSTART_EASYLOGGINGPP(argc, argv)
pour configurer les arguments).
Vous pouvez également définir des indicateurs par défaut (initiaux) à l'aide de
ELPP_DEFAULT_LOGGING_FLAGS
et définir une valeur numérique pour les indicateurs initiaux.
Aller en haut
Le tableau suivant expliquera tous les arguments de ligne de commande que vous pouvez utiliser pour définir certains comportements ; Vous devrez initialiser les arguments de l'application en utilisant START_EASYLOGGINGPP(argc, argv)
dans votre fonction main(int, char**)
.
Argument | Description |
---|---|
-v | Active une verbosité maximale |
--v=2 | Active la verbosité jusqu'au niveau verbeux 2 (plage valide : 0-9) |
--verbose | Active une verbosité maximale |
-vmodule=MODULE_NAME | Active la verbosité pour les fichiers commençant par main jusqu'au niveau 1, le reste des fichiers dépend de l'indicateur de journalisation AllowVerboseIfModuleNotSpecified Veuillez consulter la section Indicateurs de journalisation ci-dessus. Deux modules peuvent être séparés par une virgule. Veuillez noter que les vmodules sont les derniers dans l'ordre de priorité des arguments de vérification pour la journalisation détaillée, par exemple, si nous avons -v dans les arguments d'application avant les vmodules, les vmodules seront ignorés. |
--logging-flags=3 | Définit l'indicateur de journalisation. Dans l'exemple ie, 3 , il définit l'indicateur de journalisation sur NewLineForContainer et AllowVerboseIfModuleNotSpecified . Voir la section des indicateurs de journalisation ci-dessus pour plus de détails et de valeurs. Voir la section macros pour désactiver cette fonction. |
--default-log-file=FILE | Définit le fichier journal par défaut pour les enregistreurs existants et futurs. Vous souhaiterez peut-être envisager de définir ELPP_NO_DEFAULT_LOG_FILE pour empêcher la création d'un fichier journal vide par défaut pendant le prétraitement. Voir la section macros pour désactiver cette fonction. |
Aller en haut
Certaines options de journalisation peuvent être définies par des macros, c'est une décision réfléchie, par exemple si nous avons défini ELPP_THREAD_SAFE
, toutes les fonctionnalités thread-safe sont activées, sinon désactivées (en s'assurant que la surcharge de sécurité des threads va avec). Pour faciliter la mémorisation et éviter d'éventuels conflits, toutes les macros commencent par ELPP_
REMARQUE : Toutes les macros peuvent être définies de l'une des manières suivantes :
Définissez les macros en utilisant l'option -D
du compilateur, par exemple dans le cas de g++
vous ferez g++ source.cpp ... -DELPP_SYSLOG -DELPP_THREAD_SAFE ...
( méthode recommandée )
Définissez des macros dans "easylogging++.h"
(définir des macros dans d'autres fichiers ne fonctionnera pas)
Nom de la macro | Description |
---|---|
ELPP_DEBUG_ASSERT_FAILURE | Abandonne l’application en cas d’échec de la première assertion. Cette assertion est due à une entrée non valide, par exemple un fichier de configuration non valide, etc. |
ELPP_UNICODE | Active la prise en charge d'Unicode lors de la journalisation. Nécessite START_EASYLOGGINGPP |
ELPP_THREAD_SAFE | Active la sécurité des threads - assurez-vous de la liaison -lpthread pour Linux. |
ELPP_FORCE_USE_STD_THREAD | Force à utiliser la bibliothèque standard C++ pour le threading (utile uniquement lors de l'utilisation de ELPP_THREAD_SAFE |
ELPP_FEATURE_CRASH_LOG | Applicable uniquement à GCC. Active le stacktrace en cas de crash de l'application |
ELPP_DISABLE_DEFAULT_CRASH_HANDLING | Désactive la gestion des crashs par défaut. Vous pouvez utiliser el::Helpers::setCrashHandler pour utiliser votre propre gestionnaire. |
ELPP_DISABLE_LOGS | Désactive tous les journaux - (prétraitement) |
ELPP_DISABLE_DEBUG_LOGS | Désactive les journaux de débogage - (prétraitement) |
ELPP_DISABLE_INFO_LOGS | Désactive les journaux d'informations - (prétraitement) |
ELPP_DISABLE_WARNING_LOGS | Désactive les journaux d'avertissement - (prétraitement) |
ELPP_DISABLE_ERROR_LOGS | Désactive les journaux d'erreurs - (prétraitement) |
ELPP_DISABLE_FATAL_LOGS | Désactive les journaux fatals - (prétraitement) |
ELPP_DISABLE_VERBOSE_LOGS | Désactive les journaux détaillés - (prétraitement) |
ELPP_DISABLE_TRACE_LOGS | Désactive les journaux de trace - (prétraitement) |
ELPP_FORCE_ENV_VAR_FROM_BASH | Si la variable d'environnement n'a pas pu être trouvée, forcez l'utilisation d'une commande bash alternative pour trouver la valeur, par exemple whoami pour le nom d'utilisateur. (N'UTILISEZ PAS CETTE MACRO AVEC LD_PRELOAD POUR LES BIBLIOTHÈQUES QUI UTILISENT DÉJÀ Easylogging++ OU VOUS FINIREZ EN DÉBORDEMENT DE PILE POUR LES PROCESSUS ( popen ) (voir le numéro 87 pour plus de détails)) |
ELPP_DEFAULT_LOG_FILE | Nom de fichier complet dans lequel vous souhaitez que les fichiers initiaux soient créés. Vous devez intégrer la valeur de cette macro avec des guillemets, par exemple, -DELPP_DEFAULT_LOG_FILE='"logs/el.gtest.log"' Notez les guillemets doubles entre guillemets simples, les guillemets doubles sont les valeurs de const char* et les guillemets simples spécifient la valeur de macro |
ELPP_NO_LOG_TO_FILE | Désactiver initialement la journalisation dans le fichier |
ELPP_NO_DEFAULT_LOG_FILE | Si vous ne souhaitez pas initialiser la bibliothèque avec le fichier journal par défaut, définissez cette macro. Cela se connectera au périphérique nul pour Unix et Windows. Sur d'autres plates-formes, vous pouvez obtenir une erreur et vous devrez utiliser ELPP_DEFAULT_LOG_FILE . (Les relations publiques pour les appareils nuls d'autres plates-formes sont les bienvenues) |
ELPP_FRESH_LOG_FILE | N'ajoute jamais de fichier journal chaque fois que le fichier journal est créé (à utiliser avec précaution car cela peut entraîner des résultats inattendus pour certains utilisateurs) |
ELPP_DEBUG_ERRORS | Si vous souhaitez découvrir les erreurs internes générées par Easylogging++ qui peuvent être dues à la configuration ou à autre chose, vous pouvez les activer en définissant cette macro. Vous obtiendrez vos erreurs sur la sortie standard, c’est-à-dire sur un terminal ou une invite de commande. |
ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS | Désactive de force les spécificateurs de format personnalisés |
ELPP_DISABLE_LOGGING_FLAGS_FROM_ARG | Désactive de force la possibilité de définir des indicateurs de journalisation à l'aide d'arguments de ligne de commande |
ELPP_DISABLE_LOG_FILE_FROM_ARG | Désactive de force la possibilité de définir le fichier journal par défaut à partir des arguments de ligne de commande |
ELPP_WINSOCK2 | Sur le système Windows, forcez à utiliser winsock2.h au lieu de winsock.h lorsque WIN32_LEAN_AND_MEAN est défini |
ELPP_CUSTOM_COUT (avancé) | Se résout en une valeur, par exemple #define ELPP_CUSTOM_COUT qDebug() ou #define ELPP_CUSTOM_COUT std::cerr . Cela utilisera la valeur pour la sortie standard (au lieu d'utiliser std::cout |
ELPP_CUSTOM_COUT_LINE (avancé) | Utilisé avec ELPP_CUSTOM_COUT pour définir comment écrire une ligne de journal avec un cout personnalisé. par exemple, #define ELPP_CUSTOM_COUT_LINE(msg) QString::fromStdString(msg).trimmed() |
ELPP_NO_CHECK_MACROS | Ne pas définir les macros CHECK |
ELPP_NO_DEBUG_MACROS | Ne pas définir les macros DEBUG |
ELPP_UTC_DATETIME | Utilise l'heure UTC au lieu de l'heure locale (utilise essentiellement gmtime au lieu de localtime et des fonctions familiales) |
ELPP_NO_GLOBAL_LOCK | Ne verrouillez pas tout le stockage lors de l'expédition. Cela doit être utilisé avec précaution. Voir le numéro 580 |
Aller en haut
Si vous souhaitez lire les configurations de certains enregistreurs, vous pouvez le faire en utilisant la fonction typedConfigurations()
dans la classe Logger.
el::Logger* l = el::Loggers::getLogger( " default " );
bool enabled = l-> typedConfigurations ()->enabled(el::Level::Info);
// Or to read log format/pattern
std::string format =
l-> typedConfigurations ()->logFormat(el::Level::Info).format();
Aller en haut
La connexion à easylogging++ se fait à l’aide d’une collection de macros. Il s'agit de faciliter la tâche de l'utilisateur et de l'empêcher de connaître des détails inutiles sur la façon dont les choses sont faites.
Vous disposez de deux macros de base que vous pouvez utiliser pour écrire des journaux :
LOG(LEVEL)
CLOG(LEVEL, logger ID)
LOG
utilise l'enregistreur « par défaut » tandis que dans CLOG (Custom LOG), vous spécifiez l'ID de l'enregistreur. Pour les NIVEAUX, veuillez vous référer à la section Configurations - Niveaux ci-dessus. Différents enregistreurs peuvent avoir des configurations différentes en fonction de vos besoins, vous pouvez également écrire une macro personnalisée pour accéder à un enregistreur personnalisé. Vous disposez également de différentes macros pour la journalisation détaillée qui sont expliquées dans la section ci-dessous. Voici un exemple très simple d’utilisation de ces macros après avoir initialisé easylogging++.
LOG (INFO) << "This is info log";
CLOG (ERROR, " performance " ) << "This is info log using performance logger";
Il existe une autre façon d'utiliser la même macro, c'est-à-dire LOG
(et les macros associées). En d'autres termes, vous définissez les macros ELPP_DEFAULT_LOGGER
et ELPP_DEFAULT_PERFORMANCE_LOGGER
avec un identifiant d'enregistreur déjà enregistré. Désormais, lorsque vous utilisez la macro LOG
, elle utilisera automatiquement l'enregistreur spécifié au lieu de l'enregistreur default
. Veuillez noter que cela doit être défini dans le fichier source plutôt que dans le fichier d'en-tête. Ceci afin que lorsque nous incluons l'en-tête, nous n'utilisons pas accidentellement un enregistreur invalide.
Un exemple rapide est ici
# ifndef ELPP_DEFAULT_LOGGER
# define ELPP_DEFAULT_LOGGER " update_manager "
# endif
# ifndef ELPP_DEFAULT_PERFORMANCE_LOGGER
# define ELPP_DEFAULT_PERFORMANCE_LOGGER ELPP_DEFAULT_LOGGER
# endif
# include " easylogging++.h "
UpdateManager::UpdateManager {
_TRACE; // Logs using LOG(TRACE) provided logger is already registered - i.e, update_manager
LOG (INFO) << " This will log using update_manager logger as well " ;
}
# include " easylogging++.h "
UpdateManager::UpdateManager {
_TRACE; // Logs using LOG(TRACE) using default logger because no `ELPP_DEFAULT_LOGGER` is defined unless you have it in makefile
}
Vous pouvez également écrire des journaux en utilisant directement la classe
Logger
. Cette fonctionnalité est disponible sur les compilateurs prenant en charge les modèles variadiques. Vous pouvez en savoir plus en consultantsamples/STL/logger-log-functions.cpp
.
Aller en haut
Easylogging++ fournit certains aspects de la journalisation, l'un de ces aspects est la journalisation conditionnelle, c'est-à-dire que le journal ne sera écrit que si certaines conditions sont remplies. Cela s’avère très pratique dans certaines situations. Les macros d'assistance se terminent par _IF ;
LOG_IF(condition, LEVEL)
CLOG_IF(condition, LEVEL, logger ID)
LOG_IF (condition, INFO) << "Logged if condition is true";
LOG_IF ( false , WARNING) << "Never logged";
CLOG_IF ( true , INFO, " performance " ) << "Always logged (performance logger)"
Les mêmes macros sont disponibles pour la journalisation détaillée avec V
au début, c'est-à-dire VLOG_IF
et CVLOG_IF
. voir la section de journalisation détaillée ci-dessous pour plus d'informations. Vous pouvez avoir des conditions aussi compliquées que vous le souhaitez en fonction de vos besoins.
Aller en haut
La journalisation occasionnelle est un autre aspect utile de la journalisation avec Easylogging++. Cela signifie qu'un journal sera écrit s'il est touché à certaines heures ou une partie de certaines heures, par exemple tous les 10èmes coups, 100èmes coups ou 2èmes coups. Les macros d'assistance se terminent par _EVERY_N
;
LOG_EVERY_N(n, LEVEL)
CLOG_EVERY_N(n, LEVEL, logger ID)
Il existe également d'autres moyens de journalisation en fonction du nombre d'accès. Ces macros utiles sont
LOG_AFTER_N(n, LEVEL)
; Enregistre uniquement lorsque nous avons atteint le nombre d'accès de n
LOG_N_TIMES(n, LEVEL)
; Se connecte n fois for ( int i = 1 ; i <= 10 ; ++i) {
LOG_EVERY_N ( 2 , INFO) << " Logged every second iter " ;
}
// 5 logs written; 2, 4, 6, 7, 10
for ( int i = 1 ; i <= 10 ; ++i) {
LOG_AFTER_N ( 2 , INFO) << " Log after 2 hits; " << i;
}
// 8 logs written; 3, 4, 5, 6, 7, 8, 9, 10
for ( int i = 1 ; i <= 100 ; ++i) {
LOG_N_TIMES ( 3 , INFO) << " Log only 3 times; " << i;
}
// 3 logs writter; 1, 2, 3
Les mêmes versions de macros sont disponibles pour le mode
DEBUG
uniquement, ces macros commencent parD
(pour débogage) suivi du même nom. par exemple,DLOG
pour se connecter uniquement en mode débogage (c'est-à-dire lorsque_DEBUG
est défini ouNDEBUG
n'est pas défini)
Aller en haut
printf
J'aime la journalisation Pour les compilateurs prenant en charge les modèles variadiques de C++11, la possibilité de se connecter comme "printf" est disponible. Cela se fait en utilisant la classe Logger
. Cette fonctionnalité est sécurisée pour les threads et les types (car nous n'utilisons aucune macro comme LOG(INFO)
etc.)
Cela se fait en deux étapes :
el::Loggers::getLogger(<logger_id>);
La seule différence avec printf
est que la journalisation à l'aide de ces fonctions nécessite %v
pour chaque argument (c'est pour la sécurité du type) ; au lieu de spécificateurs de format personnalisés. Vous pouvez y échapper en %%v
Voici différentes signatures de fonctions :
info(const char*, const T&, const Args&...)
warn(const char*, const T&, const Args&...)
error(const char*, const T&, const Args&...)
debug(const char*, const T&, const Args&...)
fatal(const char*, const T&, const Args&...)
trace(const char*, const T&, const Args&...)
verbose(int vlevel, const char*, const T&, const Args&...)
// Use default logger
el::Logger* defaultLogger = el::Loggers::getLogger( " default " );
// STL logging (`ELPP_STL_LOGGING` should be defined)
std::vector< int > i;
i.push_back( 1 );
defaultLogger-> warn ( " My first ultimate log message %v %v %v " , 123 , 222 , i);
// Escaping
defaultLogger-> info ( " My first ultimate log message %% %%v %v %v " , 123 , 222 );
Les spécificateurs de format
%file
,%func
%line
et%loc
ne fonctionneront pas avecprintf
comme la journalisation.
Aller en haut
Vous pouvez envoyer vos messages au réseau. Mais vous devrez implémenter votre propre méthode en utilisant l'API du répartiteur de journaux. Nous avons rédigé un exemple entièrement fonctionnel à cet effet. Veuillez consulter l'exemple d'envoi au réseau.
Aller en haut
La journalisation détaillée est utile dans tous les logiciels pour enregistrer plus d'informations que d'habitude. Très utile pour le dépannage. Voici les macros détaillées spécifiques à la journalisation ;
VLOG(verbose-level)
CVLOG(verbose-level, logger ID)
Aller en haut
La journalisation détaillée présente également des aspects de journalisation conditionnelle et occasionnelle, c'est-à-dire
VLOG_IF(condition, verbose-level)
CVLOG_IF(condition, verbose-level, loggerID)
VLOG_EVERY_N(n, verbose-level)
CVLOG_EVERY_N(n, verbose-level, loggerID)
VLOG_AFTER_N(n, verbose-level)
CVLOG_AFTER_N(n, verbose-level, loggerID)
VLOG_N_TIMES(n, verbose-level)
CVLOG_N_TIMES(n, verbose-level, loggerID)
Aller en haut
Le niveau verbeux est un niveau de verbosité qui peut aller de 1 à 9. Le niveau verbeux ne sera actif que si vous définissez des arguments d'application pour celui-ci. Veuillez lire la section Arguments d'application pour en savoir plus sur la journalisation détaillée.
Afin de modifier le niveau détaillé à la volée, veuillez utiliser la fonction Loggers::setVerboseLevel(base::type::VerboseLevel)
alias Loggers::setVerboseLevel(int)
. (Vous pouvez vérifier le niveau détaillé actuel par Loggers::verboseLevel()
Aller en haut
Vous pouvez utiliser une macro VLOG_IS_ON(verbose-level)
pour vérifier si une certaine journalisation est activée pour le fichier source pour le niveau détaillé spécifié. Cela renvoie un booléen dans lequel vous pouvez intégrer une condition if.
if (VLOG_IS_ON( 2 )) {
// Verbosity level 2 is on for this file
}
Aller en haut
VModule est une fonctionnalité de journalisation détaillée (comme mentionné dans le tableau ci-dessus) où vous pouvez spécifier la verbosité par modules/fichier source. Voici quelques exemples avec explication : L'un des vmodules ci-dessous commence par -vmodule=
et l'indicateur LoggingFlag::DisableVModulesExtensions
n'est pas défini. Le Vmodule peut être complètement désactivé en ajoutant l'indicateur LoggingFlag::DisableVModules
Exemple avec l'indicateur LoggingFlag::AllowVerboseIfModuleNotSpecified
;
main=3,parser*=4
:
main{.h, .c, .cpp, .cc, .cxx, -inl.h, .hxx, .hpp}
parser{.h, .c, .cpp, .cc, .cxx, -inl.h, .hxx, .hpp}