Pendant le fonctionnement du projet, il est souvent nécessaire d'effectuer un débogage fonctionnel et de suivre et d'enregistrer le comportement des utilisateurs. Certaines personnes sont habituées à utiliser System.out, mais cela n'est pas recommandé. Il est facile à utiliser mais pas facile à entretenir et n'a aucune évolutivité. Par rapport à Log4J, Log4J peut contrôler la destination, le format de sortie et le niveau d'informations sur le journal, etc., afin que nous puissions contrôler avec soin le processus de génération de journaux.
Log4j2 est une mise à niveau vers Log4J1, avec des améliorations significatives des performances et des fonctionnalités, y compris un débit amélioré dans les multithreads, la prise en charge des espaces réservés, le rechargement de fichiers de configuration automatique, etc.
1. Introduction
1. Téléchargez le package JAR
pox.xml
<Dependances> <Dependency> <GroupId> org.apache.logging.log4j </prôdId> <ArtifActid> Log4j-API </ Artifactid> <DERVIÈRE> 2.10.0 </ Version> </ Dependency> <Dedency> <ProupId> org.apache.logging.log4j </proupId> <ArtifActid> log4j-core </ artifact> <version> 2.10.0 </ version> </dependency> </Dependances>
2. Fichier de configuration
Log4j contient quatre implémentations d'usine de configuration: JSON, YAML, Properties et XML. Cet article présente la méthode couramment utilisée XML.
Log4j a la capacité de se configurer automatiquement lors de l'initialisation. Lorsque Log4j démarre, il localisera tous les fichiers de conformes de noms sous le ClassPath, avec l'ordre prioritaire: log4j2-test.properties> log4j2-test.xml> log4j2.properties> log4j2.xml
3. Un exemple simple
Configuration XML:
<? xml version = "1.0" Encoding = "utf-8"?> <configuration status = "warn"> <annexes> <console name = "console" target = "system_out"> <patternlayout Pattern = "% d {hh: mm: ss.sss} [% t]% -5level% logger <pogers> <root niveau = "info"> <appenderRef ref = "console" /> </ root> </gogers> </figionfing> Code Java:
Logger final statique privé = logManager.getLogger (myApp.class); @Test public void testLog4j () {logger.info ("Hello World!"); }}Informations sur la console
22: 17: 47.146 [Main] Info MyApp - Hello World!
2. Introduction du module
<Iconguration>
| propriété | décrire |
| MonitorInterval | Si le fichier est modifié, la configuration sera rechargée après l'heure spécifiée. Unités de secondes, la valeur minimale est de 5 |
| packages | Une liste de noms de packages séparés par des virgules utilisés pour rechercher des plug-ins, tels que des filtres personnalisés, des annexes, etc. Le plugin ne se chargera qu'une seule fois, vous devez donc redémarrer le projet s'il veut prendre effet après modification. |
| statut | Le niveau de journal interne, la définition de la valeur de débogage peut clairement voir l'intégralité du flux d'événements de journal sur la console. L'enregistreur utilisé est org.apache.logging.log4j.core.logger |
| strict | Le format XML strict est autorisé. La configuration JSON n'est pas prise en charge |
| verbeux | Activer les informations de diagnostic lors du chargement du plugin |
<Annexes>
LOG4J permet d'imprimer les demandes de journal sur plusieurs destinations. Dans le langage log4j, la destination de sortie est appelée appender. Actuellement, les annexes existent dans les consoles, les fichiers, les serveurs à socket distants, le Flume Apache, le JMS, les démons à distance Unix Syslog et diverses API de base de données. Ce qui suit introduit plusieurs annexes plus couramment utilisées. Si vous avez besoin d'en savoir plus, vous pouvez le vérifier sur le site officiel.
1. ConsoleAppender
Sortie à la console, <console>
Nom du paramètre | taper | décrire |
filtre | Filtre | Filtre |
mise en page | Mise en page | Format de sortie du journal |
Suivre | booléen | |
direct | booléen | |
nom | Chaîne | Le nom de l'appender |
IgnoreExceptions | booléen | Par défaut vrai, ignorez les exceptions d'écriture |
cible | Chaîne | System_out ou System_err, par défaut est System_out |
2. FileAppender
Sortie en fichier, <fichier>
paramètre | taper | décrire |
|---|---|---|
ajouter | booléen | La valeur par défaut est vraie et les nouveaux enregistrements seront annexés à la fin du fichier |
tampon | booléen | La valeur par défaut est vraie, l'utilisation de tampons peut considérablement améliorer les performances |
tamponner | int | Lorsque Bufferidio est vrai, la taille du tampon de cette propriété est par défaut de 8192. |
Créerondemand | booléen | L'appender crée des fichiers à la demande. L'appenner ne créera ce fichier que lorsqu'un événement de journal passe par tous les filtres et est acheminé vers l'appender. La valeur par défaut est fausse |
filtre | Filtre | Un filtre pour déterminer si l'événement doit être géré par cet appender. Plusieurs filtres peuvent être utilisés avec des filtres composites |
nom de fichier | Chaîne | Le nom du fichier à écrire. Si le fichier ou l'un de ses répertoires parents n'existe pas, ils seront créés |
immédiatement | booléen | Par défaut, il y aura un rafraîchissement après chaque écriture. Cela garantira que les données du tampon sont écrites sur le disque, mais peuvent affecter les performances. |
mise en page | Mise en page | Format de journal |
verrouillage | booléen | Verrouillage de fichier, par défaut faux |
nom | Chaîne | Le nom de l'appender |
IgnoreExceptions | booléen | Par défaut vrai, ignorez les exceptions d'écriture |
filetermmissions | Chaîne | Définir les autorisations de fichier Exemple: RW ------ ou RW-RW-RW- etc ... |
propriétaire | Chaîne | Définir le propriétaire du fichier |
groupe de fichiers | Chaîne | Définir les groupes de fichiers |
3. JDBCAAPPENDRE
JDBCAPPENDER utilise JDBC standard pour écrire des événements de journal dans les tables de base de données relationnelles. Il peut être configuré pour obtenir une connexion JDBC à l'aide d'une source de données JNDI ou d'une méthode d'usine personnalisée. Quelle que soit la méthode, il doit être pris en charge par le pool de connexions.
Sinon, les performances de l'exploitation forestière seront grandement affectées.
Si le pilote JDBC configuré prend en charge les instructions de lots et configure la taille du tampon en un nombre positif, l'événement de journal sera lancé.
(1) <jdbc>
paramètre | taper | décrire |
|---|---|---|
nom | Chaîne | MUST, nom de l'appender |
IgnoreExceptions | booléen | Par défaut True, ignorez les exceptions des événements de journal |
filtre | Filtre | Filtre |
tamponner | int | Si un entier supérieur à 0, cela fera enfiler l'appender l'événement de journal et actualiser les données d'écriture lorsque le tampon atteint cette taille |
connexion | Connexion | Doit être récupéré la connexion de la base de données |
nom de table | Chaîne | Requis, insérez le nom de la table de données de l'événement de journal |
ColumnConfigs | ColumnConfig [] | MUST, les champs qui doivent être insérés dans la base de données sont composés de plusieurs éléments <oumning> |
colonnes | ColumnMapping [] | Requis, configuration de mappage de champ |
(2) Utilisez <DataSource> pour obtenir la connexion JDBC, seul JNDI est répertorié ici:
| paramètre | taper | décrire |
|---|---|---|
| jndiname | Chaîne | Obligatoire, si le JNDI configuré est JDBC / LoggingDatabase, la valeur ici est Java: comp / env / jdbc / loggingDatabase. La source de données doit être prise en charge par le pool de connexions; Sinon, l'exploitation forestière sera très lente. |
(3) Utilisez <polonne> pour spécifier quelles colonnes à écrire dans la table et comment les écrire. Il n'a pas de vulnérabilité d'injection SQL.
| paramètre | taper | décrire |
|---|---|---|
| nom | Chaîne | Requis, nom de champ de table |
| modèle | Chaîne | Insérer des valeurs à l'aide du mode Patternlayout. Remarque: Dans le même élément de colonne, un seul des trois attributs de motif, littéral et iseventTimestamp peut exister dans le même élément de colonne. |
| littéral | Chaîne | Cette valeur sera directement incluse dans l'instruction SQL et exécutée, par exemple: la fonction rand () générera des nombres aléatoires, similaires à $ {} dans Myibats |
| iseventtimestamp | booléen | Si le format de temps java.sql.types.timestamp |
| ISUNICODE | booléen | Cette propriété est ignorée à moins qu'un modèle ne soit spécifié. Si c'est vrai, la valeur sera insérée dans Unicode. Sinon, la valeur sera insérée dans un non-Unicode. |
| isclob | booléen | Cette propriété est ignorée à moins qu'un modèle ne soit spécifié. Si c'est vrai, la valeur sera insérée dans le CLOB, sinon le varchar, nvarchar sera inséré dans le |
Exemple:
<? xml version = "1.0" Encoding = "UTF-8"?> <Configuration Status = "Error"> <Penders> <jdbc name = "databaseAppender" tableName = "dbo.application_log"> <datasource jndiname = "java: / compg / jdbc / loggingdata iSeventtimestamp = "true" /> <colonnel name = "niveau" pattern = "% niveau" /> <colonnelle name = "logger" pattern = "% logger" /> <colonnel name = "message" pattern = "% message" /> <column name = "exception" Pattern = "% ex {full}" /> </ jdbc> </Pendenters> <loggers> ref = "databaseAppender" /> </ root> </gogers> </ configuration><Patternlayout>
(1) Date,% D /% Date
Modèle | Exemple |
|---|---|
% d {par défaut} | 2012-11-02 14: 34: 02 781 |
% d {ISO8601} | 2012-11-02T14: 34: 02,781 |
% d {iso8601_basic} | 20121102T143402,781 |
% d {absolu} | 14: 34: 02 781 |
% d {date} | 02 novembre 2012 14: 34: 02 781 |
% d {compact} | 20121102143402781 |
% D {HH: MM: SS, SS} | 14: 34: 02 781 |
% d {dd mmm yyy hh: mm: ss, ss} | 02 novembre 2012 14: 34: 02 781 |
% d {hh: mm: ss} {gmt + 0} | 18:34:02 |
% d {Unix} | 1351866842 |
% d {Unix_millis} | 1351866842781 |
Bien sûr, vous pouvez également personnaliser le format, tel que% d {yyyy-mm-dd hh: mm: ss}
(2) Enregistreur,% C /% Logueur
Modèle de conversion | Nom de l'enregistreur | résultat |
|---|---|---|
% c {1} | org.apache.commons.foo | Foo |
% c {2} | org.apache.commons.foo | commons.foo |
% c {10} | org.apache.commons.foo | org.apache.commons.foo |
% c {-1} | org.apache.commons.foo | apache.commons.foo |
% c {-2} | org.apache.commons.foo | commons.foo |
% c {-10} | org.apache.commons.foo | org.apache.commons.foo |
% c {1.} | org.apache.commons.foo | oacfoo |
% c {1.1. ~. ~} | org.apache.commons.test.foo | OA ~. ~ .foo |
% c {.} | org.apache.commons.test.foo | .... foo |
{?} - Quand ? est un entier positif, cela signifie que N parties sont prises de la droite, et un entier négatif signifie que les pièces N sont retirées de la gauche. Alors pourquoi% c {-10} est le nom complet, je ne sais pas. Bienvenue pour laisser un message
(3) Informations sur le journal,% M /% MSG /%
(4) Niveau de journal, niveau%
<filtre>
LOG4J2 est livré avec une variété de filtres à usage direct, et nous pouvons également définir nous-mêmes des filtres:
MyFilter.java
import org.apache.logging.log4j.level; import org.apache.logging.log4j.marker; import org.apache.logging.log4j.threadcontext; import org.apache.logging.log4j.core.logger; import org.apache.logging.log4j.core.config.plugins.import org.apache.logging.log4j.core.config.plugins.pluginfactory; import org.apache.logging.log4j.core.filter.abstractfilter; import; org.apache.logging.log4j.message.message; @plugin (name = "myFilter", catégorie = "core", elementType = "filter", printObject = true) public class final myFilter étend abstractFilter {private final niveau final; MyFilter privé (niveau de niveau, résultat onMatch, résultats OnMismatch) {super (onMatch, OnMismatch); this.level = niveau; } Filtre de résultat public (logger logger, niveau de niveau, marqueur de marqueur, chaîne msg, objet [] params) {return filter (niveau); } Filtre de résultat public (journaliste logique, niveau de niveau, marqueur de marqueur, MSG objet, t) {return filtre (niveau); } Filtre de résultat public (journaliste logique, niveau de niveau, marqueur de marqueur, message MSG, t) {return filtre (niveau); } @Override Public Result Filter (LOGEvent Event) {return Filter (event.getLevel ()); } Filtre de résultat privé (niveau de niveau) {/ * * Logique métier * * / return NIVEAL.ISMORESPECICIFICTHAN (this.level)? OnMatch: OnMismatch; } @Override public String toString () {return Level.ToString (); } @Pluginfactory public static myFilter CreateFilter (@pluginAttribute (value = "niveau", defaultString = "error") Niveau de niveau, @PlugInAttribute (valeur = "OnMatch", defaultString = "Neutr") Résultat Onmatch, @pluginAttribute (Value = "OnMismatch", defaultstring = "Deny") MyFilter (niveau, OnMatch, OnMismatch); }}log4j2.xml
<? xml version = "1.0" encoding = "utf-8"?> <configuration status = "warn" monitorterval = "5" packages = "vos packages" verbose = "false" strict = "true"> <appenders> <console name = "console" cible = "System_out" IgnoreExceptions = "true"> <atmAyout Pattern = "% d {yyy-mm-mm-mm-mm-mm HH: mm: ss}% de niveau% logger {10} -% msg "/> <myfilter newled =" info "onMatch =" accept "/> </console> </neckers> <gogers> <root niveau =" info "> <appenDef Ref =" Console "/> </root> </oggrers> </figuration>Remplir:
Dans les applications pratiques, il est parfois nécessaire d'enregistrer des informations d'accès aux utilisateurs, telles que les paramètres de demande, l'ID utilisateur, etc. Dans LOG4J1, nous utiliserons MDC et NDC pour stocker les informations de contexte de l'application, tandis que Log4j2 utilise ThreadContext pour implémenter les fonctions de MDC et NDC.
(1) NDC utilise un mécanisme de type pile pour stocker les informations de contexte et les threads sont indépendants.
Utilisez% x pour sortir dans Patternlayout, notez que x est en minuscules.
Exemple:
Test.java
ThreadContext.push ("Hello World!");log4j2.xml
<Colonne name = "TIP" Pattern = "% x" />
(2) MDC utilise un mécanisme de type carte pour stocker les informations et les threads sont indépendants.
Utilisez% x {userId} dans Patternlayout pour sortir, notez que x est capitalisé.
Exemple:
Test.java
ThreadContext.put ("userId", "1");log4j2.xml
<Colonnen name = "userId" pattern = "% x {userId}" />Notez qu'après l'avoir utilisé, appelez Clearall () pour effacer la carte de contexte et la pile.
API: http://logging.apache.org/log4j/2.x/javadoc.html
Adresse officielle du site Web: https://logging.apache.org/log4j/2.x/index.html
L'exemple de code ci-dessus du composant LOG4J2 Project Log est tout le contenu que je partage avec vous. J'espère que vous pourrez vous faire référence et j'espère que vous pourrez soutenir Wulin.com plus.