﷽
→ Neueste Version
→ Änderungsprotokoll
→ Beispiele
Überblick Warum noch eine weitere Bibliothek? Funktionen auf einen Blick Erste Schritte Herunterladen Schnellstart Installieren (optional) Anwendungsargumente festlegen Konfiguration Ebene Konfigurieren Verwenden der Konfigurationsdatei Verwendung der el::Configurations-Klasse Verwenden von Inline-Konfigurationen Standardkonfigurationen Globale Konfigurationen Protokollierungsformatspezifizierer Datums-/Uhrzeitformatspezifizierer Benutzerdefinierte Formatspezifizierer Protokollierungsflags Anwendungsargumente Konfigurationsmakros Konfigurationen lesen Protokollierung Basic Bedingte Protokollierung Gelegentliche Protokollierung printf Wie Protokollierung Netzwerkprotokollierung Ausführliche Protokollierung Basic Bedingt und gelegentlich Ausführlicher Level Überprüfen Sie, ob die ausführliche Protokollierung aktiviert ist VModul Registrieren neuer Logger Logger abmelden Vorhandene Logger-IDs füllen Gemeinsames Protokollierungs-Repository Zusätzliche Funktionen Leistungsverfolgung Bedingte Leistungsverfolgung Nutzen Sie Performance-Tracking-Daten Rotierende Protokolldatei Crash-Handling Installieren benutzerdefinierter Crash-Handler Stacktrace Multithreading PRÜFEN Sie Makros Protokollierung perror() Verwenden von Syslog STL-Protokollierung Unterstützte Vorlagen Qt-Protokollierung Boost-Protokollierung wxWidgets-Protokollierung Erweiterung der Bibliothek Protokollieren Sie Ihre eigene Klasse Protokollierung einer Drittanbieterklasse Manuelles Leeren und Rollen von Protokolldateien Protokollversandrückruf Rückruf zur Logger-Registrierung Asynchrone Protokollierung Hilfsklassen Beitrag Einreichen von Patches Einen Fehler melden Kompatibilität Matrix erstellen Lizenz Haftungsausschluss
Easylogging++ ist eine Single-Header-effiziente Protokollierungsbibliothek für C++-Anwendungen. Es ist äußerst leistungsstark, hoch erweiterbar und an die Anforderungen des Benutzers anpassbar. Es bietet die Möglichkeit, eigene Senken zu schreiben (über die als LogDispatchCallback
bezeichnete Funktion). Diese Bibliothek wird derzeit von Hunderten von Open-Source-Projekten auf Github und anderen Open-Source-Sites zur Verwaltung der Quellcodeverwaltung verwendet.
Dieses Handbuch gilt für Easylogging++ v9.97.1. Weitere Versionen finden Sie in der entsprechenden Veröffentlichung auf Github.
Sie könnten auch an einem Residue-Logging-Server interessiert sein.
Nach oben gehen
Wenn Sie an einem kleinen Dienstprogramm oder einem großen Projekt in C++ arbeiten, kann diese Bibliothek nützlich sein. Es basiert auf einem einzelnen Header und erfordert nur eine Verknüpfung mit einer einzelnen Quelldatei. (Ursprünglich war es nur Header und wurde in Problem Nr. 445 auf die Verwendung der Quelldatei geändert. Sie können in Version 9.89 immer noch nur Header verwenden.)
Diese Bibliothek wurde unter Berücksichtigung verschiedener Gesichtspunkte entwickelt (z. B. Portabilität, Leistung, Benutzerfreundlichkeit, Funktionen und einfache Einrichtung).
Warum noch eine weitere Bibliothek? Nun, die Antwort ist ziemlich einfach. Verwenden Sie sie so, wie Sie sie geschrieben haben, damit Sie Probleme (falls vorhanden) im Laufe der Zeit beheben oder sie auf Github ansprechen können. Darüber hinaus habe ich persönlich noch keine auf Single-Header basierende Protokollierungsbibliothek mit einem solchen Design gesehen, die Sie unterwegs konfigurieren, an Ihre Bedürfnisse anpassen und eine schnelle Leistung erzielen können. Ich habe andere Single-Header-Protokollierungsbibliotheken für C++ gesehen, aber entweder verwenden sie externe Bibliotheken, z. B. Boost oder Qt, um bestimmte Funktionen wie Threading, reguläre Ausdrücke oder Datum usw. zu unterstützen. In dieser Bibliothek ist alles integriert, um die Verwendung externer Bibliotheken zu verhindern. Nicht, dass ich diese Bibliotheken nicht mag, ich liebe sie sogar, aber da nicht alle Projekte diese Bibliotheken verwenden, konnte ich nicht das Risiko eingehen, mich auf sie zu verlassen.
Nach oben gehen
Easylogging++ ist funktionsreich und enthält viele Funktionen, die sowohl typische als auch fortgeschrittene Entwickler beim Schreiben einer Software benötigen;
Nach oben gehen
Laden Sie die neueste Version von Latest Release herunter
Weitere Veröffentlichungen finden Sie auf der Veröffentlichungsseite. Wenn Ihre Anwendung C++11 nicht unterstützt, ziehen Sie bitte die Verwendung von v8.91 in Betracht. Dies ist eine stabile Version für C++98 und C++03, es fehlen lediglich einige Funktionen.
Nach oben gehen
Um mit Easylogging++ zu beginnen, können Sie drei einfache Schritte befolgen:
easylogging++.h
und easylogging++.cc
)# include " easylogging++.h "
INITIALIZE_EASYLOGGINGPP
int main ( int argc, char * argv[]) {
LOG (INFO) << " My first info log using default logger " ;
return 0 ;
}
Jetzt kompilieren mit
g++ main.cc easylogging++.cc -o prog -std=c++11
So einfach! Bitte beachten Sie, dass INITIALIZE_EASYLOGGINGPP
nur einmal verwendet werden sollte, da sonst Kompilierungsfehler auftreten. Dies ist die Definition mehrerer extern
Variablen. Dies bedeutet, dass es nur einmal pro Anwendung definiert werden kann. Der beste Ort, um diese Initialisierungsanweisung einzufügen, ist die Datei, in der die Funktion int main(int, char**)
definiert ist, direkt nach der letzten Include-Anweisung.
Wenn Sie diesen Header systemweit installieren möchten, können Sie dies tun über:
mkdir build
cd build
cmake -Dtest=ON ../
make
make test
make install
Die folgenden Optionen werden von Easylogging++ cmake unterstützt und Sie können diese Optionen mit -D<option>=ON
aktivieren
lib_utc_datetime
– Definiert ELPP_UTC_DATETIME
build_static_lib
– Erstellt eine statische Bibliothek für Easylogging++ Dennoch benötigen Sie zum Kompilieren weiterhin die Datei easylogging++.cc
. Bitte überprüfen Sie nur für den Header Version 9.89 und niedriger.
Alternativ können Sie easyloggingpp mit dem vcpkg-Abhängigkeitsmanager herunterladen und installieren:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install easyloggingpp
Der easyloggingpp-Port in vcpkg wird von Microsoft-Teammitgliedern und Community-Mitwirkenden auf dem neuesten Stand gehalten. Wenn die Version veraltet ist, erstellen Sie bitte einen Issue oder Pull Request im vcpkg-Repository.
Nach oben gehen
Es wird immer empfohlen, Anwendungsargumente an Easylogging++ zu übergeben. Für einige Funktionen von Easylogging++ müssen Sie Anwendungsargumente festlegen, z. B. die ausführliche Protokollierung, um die ausführliche Ebene oder vmodules festzulegen (wird später erklärt). Dazu können Sie ein Hilfsmakro oder eine Hilfsklasse verwenden.
int main ( int argc, char * argv[]) {
START_EASYLOGGINGPP (argc, argv);
...
}
Nach oben gehen
Um mit der Konfiguration Ihrer Protokollierungsbibliothek zu beginnen, müssen Sie die Schweregrade verstehen. Easylogging++ verzichtet bewusst auf hierarchische Protokollierung, um vollständig kontrollieren zu können, was aktiviert ist und was nicht. Allerdings gibt es immer noch die Möglichkeit, die hierarchische Protokollierung mit LoggingFlag::HierarchicalLogging
zu verwenden. Easylogging++ verfügt über folgende Ebenen (geordnet nach hierarchischen Ebenen):
Ebene | Beschreibung |
---|---|
Global | Generische Ebene, die alle Ebenen repräsentiert. Nützlich beim Festlegen der globalen Konfiguration für alle Ebenen. |
Verfolgen | Informationen, die nützlich sein können, um bestimmte Ereignisse zurückzuverfolgen – meist nützlich als Debug-Protokolle. |
Debuggen | Informationsereignisse, die für Entwickler zum Debuggen von Anwendungen am nützlichsten sind. Nur anwendbar, wenn NDEBUG nicht definiert ist (für Nicht-VC++) oder _DEBUG definiert ist (für VC++). |
Tödlich | Sehr schwerwiegendes Fehlerereignis, das voraussichtlich zum Abbruch der Anwendung führen wird. |
Fehler | Fehlerinformationen, aber die Anwendung wird weiterhin ausgeführt. |
Warnung | Informationen zu Fehlern in der Anwendung, die Anwendung wird jedoch weiterhin ausgeführt. |
Info | Hauptsächlich nützlich, um den aktuellen Fortschritt der Anwendung darzustellen. |
Ausführlich | Informationen, die sehr nützlich sein können und je nach ausführlicher Protokollierungsstufe variieren. Die ausführliche Protokollierung ist nicht auf die hierarchische Protokollierung anwendbar. |
Unbekannt | Gilt nur für die hierarchische Protokollierung und wird verwendet, um die Protokollierung vollständig zu deaktivieren. |
Nach oben gehen
Easylogging++ ist einfach zu konfigurieren. Dafür gibt es drei Möglichkeiten:
Die Konfiguration kann durch eine Datei erfolgen, die zur Laufzeit von Configurations
geladen wird. Diese Datei hat das folgende Format;
* LEVEL:
CONFIGURATION NAME = "VALUE" ## Comment
ANOTHER CONFIG NAME = "VALUE"
Der Ebenenname beginnt mit einem Stern (*) und endet mit einem Doppelpunkt (:). Es wird dringend empfohlen, Ihre Konfigurationsdatei mit Global
Ebene zu beginnen, damit jede Konfiguration, die nicht in der Datei angegeben ist, automatisch die Konfiguration von Global
verwendet. Wenn Sie beispielsweise Filename
in Global
festlegen und möchten, dass alle Ebenen denselben Dateinamen verwenden, legen Sie ihn nicht explizit für jede Ebene fest. Die Bibliothek verwendet automatisch den Konfigurationswert von Global
. Die folgende Tabelle enthält Konfigurationen, die von der Konfigurationsdatei unterstützt werden.
Konfigurationsname | Typ | Beschreibung |
---|---|---|
Enabled | bool | Legt fest, ob die entsprechende Ebene für den Logger aktiviert ist oder nicht. Sie können alle Protokolle deaktivieren, indem Sie el::Level::Global verwenden |
To_File | bool | Ob das entsprechende Protokoll in die Protokolldatei geschrieben werden soll oder nicht |
To_Standard_Output | bool | Ob Protokolle in die Standardausgabe geschrieben werden sollen, z. B. Terminal oder Eingabeaufforderung |
Format | verkohlen* | Bestimmt Format/Muster der Protokollierung für die entsprechende Ebene und den entsprechenden Logger. |
Filename | verkohlen* | Bestimmt die Protokolldatei (vollständiger Pfad), in die Protokolle für die entsprechende Ebene und den entsprechenden Logger geschrieben werden sollen |
Subsecond_Precision | uint | Gibt die Genauigkeit in Sekundenbruchteilen an (früher „Millisekundenbreite“ genannt). Die Breite kann im Bereich (1–6) liegen. |
Performance_Tracking | bool | Bestimmt, ob die Leistungsverfolgung aktiviert ist oder nicht. Dies ist unabhängig vom Logger oder Level. Die Leistungsverfolgung verwendet immer den „Performance“-Logger, sofern nicht anders angegeben |
Max_Log_File_Size | size_t | Wenn die Protokolldateigröße der entsprechenden Ebene >= angegebene Größe ist, wird die Protokolldatei abgeschnitten. |
Log_Flush_Threshold | size_t | Gibt die Anzahl der Protokolleinträge an, die aufbewahrt werden sollen, bis wir ausstehende Protokolldaten löschen |
Bitte verwenden Sie in Kommentaren keine doppelten Anführungszeichen, da dies zu unerwartetem Verhalten führen könnte.
Beispielkonfigurationsdatei
* 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"
Der Inhalt der Konfigurationsdatei im obigen Beispiel ist unkompliziert. Wir beginnen mit GLOBAL
Ebene, um alle Ebenen zu überschreiben. Jede explizit definierte nachfolgende Ebene überschreibt die Konfiguration von GLOBAL
. Beispielsweise haben alle Ebenen außer DEBUG
das gleiche Format, also Datum/Uhrzeit und Protokollmeldung. Für DEBUG
Ebene haben wir nur Datum (mit Tag und Monat), Quellfunktion und Protokollmeldung. Die restlichen Konfigurationen für DEBUG
werden von GLOBAL
verwendet. Beachten Sie außerdem {%d/%M}
im DEBUG
-Format oben. Wenn Sie kein Datumsformat angeben, wird das Standardformat verwendet. Die Standardwerte für Datum/Uhrzeit sind %d/%M/%Y %h:%m:%s,%g
Weitere Informationen zu diesen Formatbezeichnern finden Sie im Abschnitt „Datum/Uhrzeit-Formatbezeichner“ weiter unten
# 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
}
Ihre Konfigurationsdatei kann in
el::Configurations
Objekt konvertiert werden (mithilfe des Konstruktors), das überall dort verwendet werden kann, wo es benötigt wird (wie im obigen Beispiel).
Nach oben gehen
Sie können Konfigurationen festlegen oder zurücksetzen.
# 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 ;
}
Die Konfiguration muss nur einmal vorgenommen werden. Wenn Sie mit der Standardkonfiguration zufrieden sind, können Sie diese auch verwenden.
Nach oben gehen
Inline-Konfiguration bedeutet, dass Sie Konfigurationen in std::string
festlegen können, aber stellen Sie sicher, dass Sie alle neuen Zeilenzeichen usw. hinzufügen. Dies wird nicht empfohlen, da es immer chaotisch ist.
el::Configurations c;
c.setToDefault();
c.parseFromText( " *GLOBAL: n FORMAT = %level %msg " );
Der obige Code legt nur das Konfigurationsobjekt fest. Sie müssen den/die Logger dennoch mithilfe dieser Konfigurationen neu konfigurieren.
Nach oben gehen
Wenn Sie eine Konfiguration für bestehende und zukünftige Logger wünschen, können Sie el::Loggers::setDefaultConfigurations(el::Configurations& configurations, bool configureExistingLoggers = false)
verwenden. Dies ist nützlich, wenn Sie in größerem Umfang arbeiten oder eine Bibliothek eines Drittanbieters verwenden, die Easylogging++ bereits verwendet. Jeder neu erstellte Logger verwendet Standardkonfigurationen. Wenn Sie auch vorhandene Logger konfigurieren möchten, können Sie das zweite Argument auf true
setzen (der Standardwert ist false
).
Nach oben gehen
Level::Global
hat nichts mit globalen Konfigurationen zu tun, es ist ein Konzept, bei dem Sie Konfigurationen für alle/oder einige Logger registrieren und sogar neue Logger mithilfe einer Konfigurationsdatei registrieren können. Die Syntax der Konfigurationsdatei lautet:
-- LOGGER ID ## Case sensitive
## Everything else is same as configuration file
-- ANOTHER LOGGER ID
## Configuration for this logger
Die Logger-ID beginnt mit zwei Bindestrichen. Sobald Sie Ihre globale Konfigurationsdatei geschrieben haben, können Sie alle Logger mit einer einzigen Funktion konfigurieren (und neue registrieren).
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 ;
}
Bitte beachten Sie, dass es nicht möglich ist, einen neuen Logger mithilfe der globalen Konfiguration zu registrieren, ohne seine Konfiguration zu definieren. Sie müssen mindestens eine einzelne Konfiguration definieren. Weitere Möglichkeiten zur Registrierung von Loggern werden im Abschnitt „Protokollierung“ weiter unten erläutert.
Nach oben gehen
Sie können das Protokollierungsformat mithilfe der folgenden Spezifizierer anpassen:
Spezifizierer | Ersetzt durch |
---|---|
%logger | Logger-ID |
%thread | Thread-ID – Verwendet std::thread, falls verfügbar, andernfalls GetCurrentThreadId() unter Windows |
%thread_name | Verwenden Sie Helpers::setThreadName , um den Namen des aktuellen Threads festzulegen (von dem aus Sie setThreadName ausführen). Siehe Beispiel für Thread-Namen |
%level | Schweregrad (Info, Debug, Fehler, Warnung, Schwerwiegend, Ausführlich, Ablaufverfolgung) |
%levshort | Schweregrad (Kurzversion, z. B. I für Info bzw. D, E, W, F, V, T) |
%vlevel | Ausführlichkeitsgrad (gilt für die ausführliche Protokollierung) |
%datetime | Datum und/oder Uhrzeit – Das Muster ist anpassbar – siehe Datums-/Uhrzeitformatspezifizierer unten |
%user | Der Benutzer führt derzeit die Anwendung aus |
%host | Die Anwendung „Computername“ wird ausgeführt |
%file * | Dateiname der Quelldatei (vollständiger Pfad) – Diese Funktion unterliegt der Verfügbarkeit des __FILE__ Makros des Compilers |
%fbase * | Dateiname der Quelldatei (nur Basisname) |
%line * | Quellzeilennummer – Diese Funktion unterliegt der Verfügbarkeit des __LINE__ Makros der Kompilierung |
%func * | Protokollierungsfunktion |
%loc * | Quelldateiname und Zeilennummer der Protokollierung (durch Doppelpunkt getrennt) |
%msg | Tatsächliche Protokollnachricht |
% | Escape-Zeichen (z. B. %%level schreibt %level) |
__LINE__
, __FILE__
usw Nach oben gehen
Sie können das Datums-/Uhrzeitformat mithilfe der folgenden Spezifizierer anpassen
Spezifizierer | Ersetzt durch |
---|---|
%d | Tag des Monats (mit Nullen aufgefüllt) |
%a | Wochentag – kurz (Mo, Di, Mi, Do, Fr, Sa, So) |
%A | Wochentag – lang (Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag, Sonntag) |
%M | Monat (mit Nullen aufgefüllt) |
%b | Monat – kurz (Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez) |
%B | Monat – Lang (Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember) |
%y | Jahr – zweistellig (13, 14 usw.) |
%Y | Jahr – vierstellig (2013, 2014 usw.) |
%h | Stunde (12-Stunden-Format) |
%H | Stunde (24-Stunden-Format) |
%m | Minute (mit Nullen aufgefüllt) |
%s | Zweiter (mit Nullen aufgefüllter) |
%g | Sekundenteil (Genauigkeit wird durch ConfigurationType::SubsecondPrecision konfiguriert) |
%F | AM/PM-Bezeichnung |
% | Escape-Charakter |
Bitte beachten Sie, dass Datum und Uhrzeit auf maximal 30
Zeichen begrenzt sind.
Nach oben gehen
Sie können auch Ihre eigenen Formatbezeichner angeben. Dazu können Sie el::Helpers::installCustomFormatSpecifier
verwenden. Ein perfektes Beispiel ist %ip_addr
für eine TCP-Serveranwendung;
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 ;
}
Nach oben gehen
Für einige Teile der Protokollierung können Sie Protokollierungs-Flags setzen; Hier werden Flags unterstützt:
Flagge | Beschreibung |
---|---|
NewLineForContainer (1) | Stellt sicher, dass wir für jeden Containerprotokolleintrag eine neue Zeile haben |
AllowVerboseIfModuleNotSpecified (2) | Stellt sicher, dass, wenn -vmodule verwendet wird und kein Modul angibt, eine ausführliche Protokollierung über dieses Modul zulässig ist. Angenommen, der Parameter war -vmodule=main*=3 und es wird ein ausführliches Protokoll aus einer Datei mit dem Namen „something.cpp“ geschrieben. Wenn dieses Flag aktiviert ist, wird das Protokoll geschrieben, andernfalls wird es nicht zugelassen. Hinweis: Dadurch wird der Zweck von -vmodule zunichte gemacht |
LogDetailedCrashReason (4) | Bei der standardmäßigen Behandlung von Abstürzen wird auch die detaillierte Absturzursache protokolliert (standardmäßig deaktiviert) (Problem Nr. 90) |
DisableApplicationAbortOnFatalLog (8) | Ermöglicht das Deaktivieren des Anwendungsabbruchs, wenn die Protokollierung mit der Stufe FATAL erfolgt. Beachten Sie, dass dies nicht für Standard-Crash-Handler gilt, da die Anwendung nach der Verarbeitung des Absturzsignals abgebrochen werden sollte. (Nicht standardmäßig hinzugefügt) (Problem Nr. 119) |
ImmediateFlush (16) | Löscht das Protokoll bei jedem Protokolleintrag (leistungsabhängig) – Standardmäßig deaktiviert |
StrictLogFileSizeCheck (32) | Stellt sicher, dass die Größe der Protokolldatei bei jedem Protokoll überprüft wird |
ColoredTerminalOutput (64) | Die Terminalausgabe ist farbig, wenn sie vom Terminal unterstützt wird. |
MultiLoggerSupport (128) | Aktiviert die Unterstützung für die Verwendung mehrerer Logger zum Protokollieren einer einzelnen Nachricht. (z. B. CLOG(INFO, "default", "network") << This will be logged using default and network loggers; ) |
DisablePerformanceTrackingCheckpointComparison (256) | Deaktiviert den Checkpoint-Vergleich |
DisableVModules (512) | Deaktiviert die Verwendung von VModulen |
DisableVModulesExtensions (1024) | Deaktiviert die vmodules-Erweiterung. Das heißt, wenn Sie ein vmodule -vmodule=main*=4 haben, deckt es alles ab, was mit „main“ beginnt. Wenn Sie dies nicht definiert haben, werden Sie für jede Datei abgedeckt, die mit „main“ beginnt und mit einer der folgenden Erweiterungen endet; .h .c .cpp .cc .cxx .-inl-.h .hxx .hpp. Bitte beachten Sie, dass das folgende vmodule nicht korrekt ist: -vmodule=main.=4, wenn dieses Makro nicht definiert ist, da dadurch nach main..c gesucht wird. Beachten Sie die doppelten Punkte. Wenn Sie möchten, dass dies gültig ist, sehen Sie sich das Protokollierungsflag oben an: AllowVerboseIfModuleNotSpecified '?' und '' Platzhalter werden unterstützt |
HierarchicalLogging (2048) | Aktiviert die hierarchische Protokollierung. Dies gilt nicht für die ausführliche Protokollierung. |
CreateLoggerAutomatically (4096) | Erstellt automatisch einen Logger, wenn dieser nicht verfügbar ist. |
AutoSpacing (8192) | Fügt automatisch Leerzeichen hinzu. Beispiel: LOG(INFO) << "DODGE" << "THIS!"; gibt „DODGE THIS!“ aus. |
FixedTimeFormat (16384) | Gilt nur für die Leistungsverfolgung – dadurch wird Formatierungsaufwand vermieden. Beispielsweise werden 1001 ms unverändert protokolliert, anstatt sie als 1.01 sec zu formatieren |
IgnoreSigInt (32768) | Wenn die Anwendung abstürzt, ignorieren Sie das Unterbrechungssignal |
Sie können diese Flags mithilfe der statischen el::Loggers::addFlag
und el::Loggers::removeFlag
festlegen/deaktivieren. Sie können überprüfen, ob ein bestimmtes Flag verfügbar ist, indem Sie el::Loggers::hasFlag
verwenden. Alle diese Funktionen verwenden die stark typisierte Enumeration el::LoggingFlag
Sie können diese Flags festlegen, indem Sie das Befehlszeilenargument
--logging-flags
verwenden. Sie müssen diese Funktionalität aktivieren, indem Sie das MakroELPP_LOGGING_FLAGS_FROM_ARG
definieren (Sie müssen sicherstellen, dass SieSTART_EASYLOGGINGPP(argc, argv)
verwenden, um Argumente zu konfigurieren).
Sie können mit
ELPP_DEFAULT_LOGGING_FLAGS
auch Standardflags (Anfangsflags) festlegen und einen numerischen Wert für die Anfangsflags festlegen
Nach oben gehen
In der folgenden Tabelle werden alle Befehlszeilenargumente erläutert, die Sie zum Definieren bestimmter Verhaltensweisen verwenden können. Sie müssen Anwendungsargumente initialisieren, indem Sie START_EASYLOGGINGPP(argc, argv)
in Ihrer Funktion main(int, char**)
verwenden.
Argument | Beschreibung |
---|---|
-v | Aktiviert maximale Ausführlichkeit |
--v=2 | Aktiviert die Ausführlichkeit bis zur Ausführlichkeitsstufe 2 (gültiger Bereich: 0–9). |
--verbose | Aktiviert maximale Ausführlichkeit |
-vmodule=MODULE_NAME | Aktiviert die Ausführlichkeit für Dateien beginnend mit „main“ bis Ebene 1, die restlichen Dateien hängen vom Protokollierungs-Flag AllowVerboseIfModuleNotSpecified ab. Weitere Informationen finden Sie im Abschnitt „Protokollierungs-Flags“ oben. Zwei Module können durch Komma getrennt werden. Bitte beachten Sie, dass Vmodules in der Rangfolge der Prüfargumente für die ausführliche Protokollierung an letzter Stelle stehen. Wenn wir beispielsweise -v in den Anwendungsargumenten vor Vmodules haben, werden Vmodules ignoriert. |
--logging-flags=3 | Setzt das Protokollierungsflag. Im Beispiel ie, 3 wird das Protokollierungsflag auf NewLineForContainer und AllowVerboseIfModuleNotSpecified gesetzt. Weitere Details und Werte finden Sie im Abschnitt „Protokollierungsflags“ oben. Informationen zum Deaktivieren dieser Funktion finden Sie im Abschnitt „Makros“. |
--default-log-file=FILE | Legt die Standardprotokolldatei für vorhandene und zukünftige Logger fest. Möglicherweise möchten Sie ELPP_NO_DEFAULT_LOG_FILE definieren, um die Erstellung einer standardmäßig leeren Protokolldatei während der Vorverarbeitung zu verhindern. Informationen zum Deaktivieren dieser Funktion finden Sie im Abschnitt „Makros“. |
Nach oben gehen
Einige Protokollierungsoptionen können durch Makros festgelegt werden. Dies ist eine wohlüberlegte Entscheidung. Wenn wir beispielsweise ELPP_THREAD_SAFE
definiert haben, sind alle Thread-sicheren Funktionen aktiviert, andernfalls deaktiviert (um sicherzustellen, dass damit ein Mehraufwand an Thread-Sicherheit verbunden ist). Um das Merken zu erleichtern und möglichen Konflikten vorzubeugen, beginnen alle Makros mit ELPP_
HINWEIS: Alle Makros können auf eine der folgenden Arten definiert werden:
Definieren Sie Makros mit der Option -D
des Compilers. Im Fall von g++
führen Sie beispielsweise g++ source.cpp ... -DELPP_SYSLOG -DELPP_THREAD_SAFE ...
aus ( empfohlener Weg )
Definieren Sie Makros in "easylogging++.h"
(das Definieren von Makros in anderen Dateien funktioniert nicht)
Makroname | Beschreibung |
---|---|
ELPP_DEBUG_ASSERT_FAILURE | Bricht die Anwendung ab, wenn die erste Behauptung fehlschlägt. Diese Behauptung ist auf eine ungültige Eingabe zurückzuführen, z. B. eine ungültige Konfigurationsdatei usw. |
ELPP_UNICODE | Aktiviert die Unicode-Unterstützung bei der Protokollierung. Erfordert START_EASYLOGGINGPP |
ELPP_THREAD_SAFE | Aktiviert Thread-Sicherheit – stellen Sie sicher, dass die -lpthread-Verknüpfung für Linux erfolgt. |
ELPP_FORCE_USE_STD_THREAD | Erzwingt die Verwendung der C++-Standardbibliothek für Threading (Nur nützlich bei Verwendung von ELPP_THREAD_SAFE |
ELPP_FEATURE_CRASH_LOG | Gilt nur für GCC. Aktiviert Stacktrace bei Anwendungsabsturz |
ELPP_DISABLE_DEFAULT_CRASH_HANDLING | Deaktiviert die standardmäßige Absturzbehandlung. Sie können el::Helpers::setCrashHandler verwenden, um Ihren eigenen Handler zu verwenden. |
ELPP_DISABLE_LOGS | Deaktiviert alle Protokolle – (Vorverarbeitung) |
ELPP_DISABLE_DEBUG_LOGS | Deaktiviert Debug-Protokolle – (Vorverarbeitung) |
ELPP_DISABLE_INFO_LOGS | Deaktiviert Infoprotokolle – (Vorverarbeitung) |
ELPP_DISABLE_WARNING_LOGS | Deaktiviert Warnprotokolle – (Vorverarbeitung) |
ELPP_DISABLE_ERROR_LOGS | Deaktiviert Fehlerprotokolle – (Vorverarbeitung) |
ELPP_DISABLE_FATAL_LOGS | Deaktiviert schwerwiegende Protokolle – (Vorverarbeitung) |
ELPP_DISABLE_VERBOSE_LOGS | Deaktiviert ausführliche Protokolle – (Vorverarbeitung) |
ELPP_DISABLE_TRACE_LOGS | Deaktiviert Trace-Protokolle – (Vorverarbeitung) |
ELPP_FORCE_ENV_VAR_FROM_BASH | Wenn die Umgebungsvariable nicht gefunden werden konnte, erzwingen Sie die Verwendung eines alternativen Bash-Befehls, um den Wert zu finden, z. B. whoami für Benutzernamen. (VERWENDEN SIE DIESES MAKRO NICHT MIT LD_PRELOAD FÜR BIBLIOTHEKEN, DIE BEREITS Easylogging++ VERWENDEN, SONST ENDET ES IM STACK-ÜBERLAUF FÜR PROZESSE ( popen ) (siehe Problem Nr. 87 für Details)) |
ELPP_DEFAULT_LOG_FILE | Vollständiger Dateiname, unter dem die ersten Dateien erstellt werden sollen. Sie müssen den Wert dieses Makros in Anführungszeichen einbetten, z. B. -DELPP_DEFAULT_LOG_FILE='"logs/el.gtest.log"' Beachten Sie die doppelten Anführungszeichen in einfachen Anführungszeichen. Doppelte Anführungszeichen sind die Werte für const char* und einfache Anführungszeichen geben den Wert von an Makro |
ELPP_NO_LOG_TO_FILE | Deaktivieren Sie zunächst die Protokollierung in einer Datei |
ELPP_NO_DEFAULT_LOG_FILE | Wenn Sie die Bibliothek nicht mit der Standardprotokolldatei initialisieren möchten, definieren Sie dieses Makro. Dadurch wird für Unix und Windows auf dem Nullgerät protokolliert. Auf anderen Plattformen erhalten Sie möglicherweise eine Fehlermeldung und müssen ELPP_DEFAULT_LOG_FILE verwenden. (PR für Nullgeräte anderer Plattformen sind sehr willkommen) |
ELPP_FRESH_LOG_FILE | Hängt die Protokolldatei niemals an, wenn eine Protokolldatei erstellt wird (mit Vorsicht verwenden, da dies für einige Benutzer zu unerwarteten Ergebnissen führen kann) |
ELPP_DEBUG_ERRORS | Wenn Sie interne Fehler herausfinden möchten, die von Easylogging++ ausgelöst werden und möglicherweise auf die Konfiguration oder etwas anderes zurückzuführen sind, können Sie diese durch die Definition dieses Makros aktivieren. Sie erhalten Ihre Fehler in der Standardausgabe, z. B. im Terminal oder in der Eingabeaufforderung. |
ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS | Deaktiviert benutzerdefinierte Formatspezifizierer zwangsweise |
ELPP_DISABLE_LOGGING_FLAGS_FROM_ARG | Deaktiviert zwangsweise die Möglichkeit, Protokollierungsflags mithilfe von Befehlszeilenargumenten festzulegen |
ELPP_DISABLE_LOG_FILE_FROM_ARG | Deaktiviert zwangsweise die Möglichkeit, die Standardprotokolldatei über Befehlszeilenargumente festzulegen |
ELPP_WINSOCK2 | Auf Windows-Systemen wird die Verwendung von winsock2.h anstelle von winsock.h erzwungen, wenn WIN32_LEAN_AND_MEAN definiert ist |
ELPP_CUSTOM_COUT (erweitert) | Wird zu einem Wert aufgelöst, z. B. #define ELPP_CUSTOM_COUT qDebug() oder #define ELPP_CUSTOM_COUT std::cerr . Dadurch wird der Wert für die Standardausgabe verwendet (anstelle von std::cout |
ELPP_CUSTOM_COUT_LINE (erweitert) | Wird mit ELPP_CUSTOM_COUT verwendet, um zu definieren, wie eine Protokollzeile mit benutzerdefiniertem Cout geschrieben wird. z. B. #define ELPP_CUSTOM_COUT_LINE(msg) QString::fromStdString(msg).trimmed() |
ELPP_NO_CHECK_MACROS | Definieren Sie nicht die CHECK- Makros |
ELPP_NO_DEBUG_MACROS | Definieren Sie nicht die DEBUG- Makros |
ELPP_UTC_DATETIME | Verwendet UTC-Zeit anstelle von Ortszeit (verwendet im Wesentlichen gmtime anstelle von localtime und Familienfunktionen) |
ELPP_NO_GLOBAL_LOCK | Verschließen Sie beim Versand nicht den gesamten Lagerraum. Dies sollte mit Vorsicht verwendet werden. Siehe Ausgabe Nr. 580 |
Nach oben gehen
Wenn Sie Konfigurationen bestimmter Logger lesen möchten, können Sie dies tun, indem Sie die Funktion typedConfigurations()
in der Logger-Klasse verwenden.
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();
Nach oben gehen
Die Anmeldung in easylogging++ erfolgt über eine Sammlung von Makros. Dies soll es dem Benutzer einfacher machen und verhindern, dass er über unnötige Einzelheiten der Arbeitsabläufe Bescheid weiß.
Ihnen stehen zwei grundlegende Makros zur Verfügung, die Sie zum Schreiben von Protokollen verwenden können:
LOG(LEVEL)
CLOG(LEVEL, logger ID)
LOG
verwendet den „Standard“-Logger, während Sie in CLOG (Custom LOG) die Logger-ID angeben. Informationen zu den Ebenen finden Sie oben im Abschnitt „Konfigurationen – Ebenen“. Verschiedene Logger können je nach Bedarf unterschiedliche Konfigurationen haben. Sie können auch ein benutzerdefiniertes Makro schreiben, um auf den benutzerdefinierten Logger zuzugreifen. Sie haben auch verschiedene Makros für die ausführliche Protokollierung, die im folgenden Abschnitt erläutert werden. Hier ist ein sehr einfaches Beispiel für die Verwendung dieser Makros, nachdem Sie easylogging++ initialisiert haben.
LOG (INFO) << "This is info log";
CLOG (ERROR, " performance " ) << "This is info log using performance logger";
Es gibt eine andere Möglichkeit, dasselbe Makro zu verwenden, nämlich LOG
(und zugehörige Makros). Dies bedeutet, dass Sie die Makros ELPP_DEFAULT_LOGGER
und ELPP_DEFAULT_PERFORMANCE_LOGGER
mit der bereits registrierten Logger-ID definieren. Wenn Sie nun LOG
Makro verwenden, wird automatisch der angegebene Logger anstelle des default
-Loggers verwendet. Bitte beachten Sie, dass dies in der Quelldatei und nicht in der Headerdatei definiert werden sollte. Dies dient dazu, dass wir beim Einfügen von Headern nicht versehentlich einen ungültigen Logger verwenden.
Ein kurzes Beispiel finden Sie hier
# 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
}
Sie können Protokolle auch direkt mit
Logger
-Klasse schreiben. Diese Funktion ist auf Compilern verfügbar, die variadische Vorlagen unterstützen. Weitere Informationen finden Sie untersamples/STL/logger-log-functions.cpp
.
Nach oben gehen
Easylogging++ bietet bestimmte Aspekte der Protokollierung. Einer dieser Aspekte ist die bedingte Protokollierung, dh das Protokoll wird nur geschrieben, wenn eine bestimmte Bedingung erfüllt ist. Das ist in manchen Situationen sehr praktisch. Hilfsmakros enden mit _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)"
Für die ausführliche Protokollierung mit V
am Anfang stehen die gleichen Makros zur Verfügung, nämlich VLOG_IF
und CVLOG_IF
. Weitere Informationen finden Sie im Abschnitt zur ausführlichen Protokollierung weiter unten. Abhängig von Ihrem Bedarf können die Bedingungen so kompliziert sein, wie Sie möchten.
Nach oben gehen
Gelegentliche Protokollierung ist ein weiterer nützlicher Aspekt der Protokollierung mit Easylogging++. Dies bedeutet, dass ein Protokoll geschrieben wird, wenn es zu bestimmten Zeiten oder in Teilen bestimmter Zeiten getroffen wird, z. B. bei jedem 10. Treffer oder 100. Treffer oder 2. Treffer. Hilfsmakros enden mit _EVERY_N
;
LOG_EVERY_N(n, LEVEL)
CLOG_EVERY_N(n, LEVEL, logger ID)
Es gibt auch einige andere Möglichkeiten der Protokollierung, die auf der Trefferzahl basieren. Diese nützlichen Makros sind
LOG_AFTER_N(n, LEVEL)
; Protokolliert nur, wenn wir eine Trefferzahl von n
erreicht habenLOG_N_TIMES(n, LEVEL)
; Protokolliert n-mal 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
Dieselben Versionen von Makros sind nur für
DEBUG
-Modus verfügbar. Diese Makros beginnen mitD
(für Debug) gefolgt von demselben Namen. z. B.DLOG
, um nur im Debug-Modus zu protokollieren (d. h. wenn_DEBUG
definiert oderNDEBUG
undefiniert ist)
Nach oben gehen
printf
Wie Protokollierung Für Compiler, die die Variadic-Vorlagen von C++11 unterstützen, ist die Möglichkeit zur Protokollierung wie „printf“ verfügbar. Dies erfolgt mithilfe der Logger
-Klasse. Diese Funktion ist thread- und typsicher (da wir keine Makros wie LOG(INFO)
usw. verwenden)
Dies geschieht in zwei Schritten:
el::Loggers::getLogger(<logger_id>);
Der einzige Unterschied zu printf
besteht darin, dass für die Protokollierung mit diesen Funktionen %v
für jedes Argument erforderlich ist (dies dient der Typsicherheit); anstelle von benutzerdefinierten Formatbezeichnern. Sie können dies mit %%v
umgehen
Im Folgenden sind verschiedene Funktionssignaturen aufgeführt:
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 );
Die Formatbezeichner
%file
,%func
%line
und%loc
funktionieren nicht mitprintf
ähnlichen Protokollierung.
Nach oben gehen
Sie können Ihre Nachrichten an das Netzwerk senden. Sie müssen die Protokoll-Dispatcher-API jedoch auf Ihre eigene Weise implementieren. Zu diesem Zweck haben wir ein voll funktionsfähiges Beispiel geschrieben. Bitte sehen Sie sich das Beispiel „An Netzwerk senden“ an
Nach oben gehen
Die ausführliche Protokollierung ist in jeder Software nützlich, um mehr Informationen als üblich aufzuzeichnen. Sehr nützlich zur Fehlerbehebung. Im Folgenden finden Sie ausführliche, protokollierungsspezifische Makros.
VLOG(verbose-level)
CVLOG(verbose-level, logger ID)
Nach oben gehen
Die ausführliche Protokollierung umfasst auch bedingte und gelegentliche Protokollierungsaspekte, d. h.
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)
Nach oben gehen
Die Ausführlichkeitsstufe ist die Ausführlichkeitsstufe, die zwischen 1 und 9 liegen kann. Die ausführliche Ebene ist nur dann aktiv, wenn Sie Anwendungsargumente dafür festlegen. Bitte lesen Sie den Abschnitt „Anwendungsargumente“, um mehr über die ausführliche Protokollierung zu erfahren.
Um die Ausführlichkeitsstufe im Handumdrehen zu ändern, verwenden Sie bitte die Funktion Loggers::setVerboseLevel(base::type::VerboseLevel)
auch bekannt als Loggers::setVerboseLevel(int)
. (Sie können die aktuelle Ausführlichkeitsstufe mit Loggers::verboseLevel()
überprüfen.
Nach oben gehen
Mit dem Makro VLOG_IS_ON(verbose-level)
können Sie prüfen, ob eine bestimmte Protokollierung für die Quelldatei für die angegebene ausführliche Ebene aktiviert ist. Dies gibt einen booleschen Wert zurück, den Sie in die if-Bedingung einbetten können.
if (VLOG_IS_ON( 2 )) {
// Verbosity level 2 is on for this file
}
Nach oben gehen
VModule ist eine Funktionalität für die ausführliche Protokollierung (wie in der obigen Tabelle erwähnt), bei der Sie die Ausführlichkeit nach Modulen/Quelldatei angeben können. Im Folgenden finden Sie einige Beispiele mit Erläuterungen. Jedes der folgenden vmodule beginnt mit -vmodule=
und LoggingFlag::DisableVModulesExtensions
-Flag ist nicht gesetzt. Vmodule kann durch Hinzufügen des Flags LoggingFlag::DisableVModules
vollständig deaktiviert werden
Beispiel mit LoggingFlag::AllowVerboseIfModuleNotSpecified
-Flag;
main=3,parser*=4
:
main{.h, .c, .cpp, .cc, .cxx, -inl.h, .hxx, .hpp}
parser{.h, .c, .cpp, .cc, .cxx, -inl.h, .hxx, .hpp}