Comment utiliser java.util.logging

Utilisation de base

Tout d'abord, l'utilisation de base. Les apparences principales sont les trois suivantes.

  1. Logger-Un objet qui génère des journaux.
  2. Handler - Objet qui contrôle la destination de sortie du journal.
  3. Formatter-Un objet qui contrôle le format du journal.

Commencez par créer une instance Logger.

Logger logger = Logger.getLogger("nom de l'enregistreur")

Ensuite, créez une instance Handler et enregistrez-la avec le logger. Vous pouvez enregistrer plusieurs gestionnaires. Cette fois, créez un gestionnaire avec C: \ sample \ sample.log comme destination de sortie. Si vous voulez sortir dans un fichier, utilisez la classe d'implémentation d'interface Handler`` FileHandler.

Handler handler = new FileHandler("C:\\sample\\sample.log");
logger.addHandler(handler);

Enfin, créez une instance du formateur et enregistrez-la dans le gestionnaire. Cette fois, nous utiliserons SimpleFormatter pour le formater sous une forme facile à lire pour les humains. SimpleFormatter est une classe d'implémentation de l'interface Formatter.

Formatter formatter =  new SimpleFormatter();
handler.setFormatter(formatter);

Maintenant, vous êtes prêt à partir. Transmettez le message à l'enregistreur et sortez le journal.

logger.log(Level.INFO, "message");

Comme mentionné ci-dessus, lors de la sortie du journal, spécifiez le niveau de journalisation du message. Les 7 types de niveaux de journal suivants sont préparés par java.util.logging. Plus vous descendez, plus le journal devient sérieux.

--FINE ST - Message de trace très détaillé --FINER --Un message de trace assez détaillé --FINE --Message de trace détaillé --CONFIG --Message de configuration statique --INFO --Message d'information --AVERTISSEMENT --Message d'avertissement --SEVERE --Message critique

Vous pouvez configurer l'enregistreur pour qu'il n'émette que les messages au-dessus d'un certain niveau de journal. Par exemple, si vous souhaitez afficher uniquement les messages de niveau INFO ou supérieur, procédez comme suit.

logger.setLevel(Level.INFO);

L'exemple de programme d'utilisation de base est décrit ci-dessous.

BasicLoggingSample


package sample;

import java.io.IOException;
import java.util.function.Supplier;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class BasicLoggingSample {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Obtenez un enregistreur et définissez le niveau de journalisation sur INFO
		Logger logger = Logger.getLogger(BasicLoggingSample.class.getName());
		logger.setLevel(Level.INFO);

		//Créez un gestionnaire et enregistrez-le comme enregistreur
		Handler handler = new FileHandler("C:\\sample\\sample.log");
		logger.addHandler(handler);
		
		//Créez un formateur et enregistrez-le en tant que gestionnaire
		Formatter formatter =  new SimpleFormatter();
		handler.setFormatter(formatter);
		
		//Message INFO de sortie
		logger.log(Level.INFO, "Message INFO");

		//Il existe une méthode simple pour afficher chaque message de niveau journal.
		logger.finest("MEILLEUR message");
		logger.finer("Message FINER");
		logger.fine("Message FINE");
		logger.config("Message CONFIG");
		logger.info("Message INFO");
		logger.warning("Message d'alerte");
		logger.severe("Message GRAVE");
		
		//En plus de la méthode de transmission du message sous forme de chaîne de caractères, Supplier<String>Il y a aussi un moyen de passer.
		Supplier<String> supplier = new Supplier<String>() {
			@Override
			public String get() {
				return "Message d'approvisionnement";
			}
		};
		logger.info(supplier);
		
		//La méthode de sortie du journal lorsqu'une exception se produit est la suivante. La trace de pile Throwable passée en argument est sortie.
		logger.log(Level.WARNING, "Une erreur est survenue.", new RuntimeException("Erreur d'exécution"));
	}
}

Hiérarchie des enregistreurs

Les enregistreurs ont une structure hiérarchique basée sur les espaces de noms. Par exemple, si vous créez le logger suivant,

Logger logger = Logger.getLogger("com.sample.App");

La structure hiérarchique est la suivante. L'enregistreur parent de «com.sample.App» est «com.sample» et l'enregistreur parent de «com.sample» est «com». De plus, le journal parent de com sera le journal racine.

Root
└─com
    └─sample
        └─App

Si l'enregistreur imprime un message, la sortie est également propagée vers l'enregistreur parent. En d'autres termes, dans l'exemple ci-dessus, si vous envoyez un message à l'enregistreur de com.sample.App, le message sera émis respectivement à partir de com.sample, com et de l'enregistreur racine.

Je ne pense pas que ce soit facile à expliquer avec des mots, alors jetons un coup d'œil à l'exemple de programme.

NameSpaceSample


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class NameSpaceSample {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Obtenez chaque enregistreur. Pour obtenir le journal racine, spécifiez un caractère vide dans le nom du journal.
		Logger root = Logger.getLogger("");
		Logger com = Logger.getLogger("com");
		Logger sample = Logger.getLogger("com.sample");
		Logger app = Logger.getLogger("com.sample.App");
		
		// com.sample.Les parents d'applications sont com.sample、com.Le parent de sample est com et le parent de com est root logger.
		System.out.println(app.getParent() == sample);
		System.out.println(app.getParent().getParent() == com);
		System.out.println(app.getParent().getParent().getParent() == root);
		
		//L'enregistreur racine a un parent nul.
		System.out.println(root.getParent());
		
		//Définissez un gestionnaire pour chaque enregistreur.
		Formatter formatter = new SimpleFormatter();
		Handler rootHandler = new FileHandler("C:\\sample\\root.log");
		root.addHandler(rootHandler);
		rootHandler.setFormatter(formatter);
		
		Handler comHandler = new FileHandler("C:\\sample\\com.log");
		com.addHandler(comHandler);
		comHandler.setFormatter(formatter);
		
		Handler sampleHandler = new FileHandler("C:\\sample\\sample.log");
		sample.addHandler(sampleHandler);
		sampleHandler.setFormatter(formatter);
		
		Handler appHandler = new FileHandler("C:\\sample\\App.log");
		app.addHandler(appHandler);
		appHandler.setFormatter(formatter);
		
		//Lorsque vous sortez un message avec l'application, un message est également émis par chaque enregistreur parent.
		app.info("Message INFO");
	}
}

Lorsque l'exemple de programme est exécuté, les journaux sont envoyés dans root.log, com.log, sample.log et ʻApp.log sous le répertoire C: \ sample`.

Comment utiliser le filtre

J'ai présenté comment définir le niveau de journalisation dans l'enregistreur et le contrôler afin que seuls les messages au-dessus d'un certain niveau de journal soient sortis, mais si vous voulez un contrôle plus détaillé, utilisez la classe Filter.

Filter filter = new Filter() {
	@Override
	public boolean isLoggable(LogRecord record) {
		return record.getMessage().contains("Nombre de dossiers traités=");
	}
};
logger.setFilter(filter);

Si le filtre est défini comme ci-dessus, seuls les journaux contenant «nombre de processus =» »dans le message seront affichés.

Définir le niveau de journal et le filtre dans le gestionnaire

L'explication ci-dessus a montré comment définir un filtre de niveau de journal sur un enregistreur. En fait, les niveaux de journalisation et les filtres peuvent également être définis dans Handler.

L'exemple de programme est décrit ci-dessous.

FiltringSample


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class FiltringSample {
	
	public static void main(String[] arg) throws SecurityException, IOException {
		//Créer un enregistreur et définir des gestionnaires et des formateurs
		Logger logger = Logger.getLogger("sample1");
		Handler handler = new FileHandler("C:\\sample\\sample.log");
		logger.addHandler(handler);
		handler.setFormatter(new SimpleFormatter());
		
		//Réglez le niveau de journal de l'enregistreur sur INFO
		logger.setLevel(Level.INFO);
		logger.info("Exemple de message");                          //Production
		
		//Définir un filtre sur l'enregistreur
		Filter filter1 = new Filter() {
			@Override
			public boolean isLoggable(LogRecord record) {
				return record.getMessage().contains("Nombre de dossiers traités=");
			}
		};
		logger.setFilter(filter1);
		logger.info("Exemple de message");                          //Pas de sortie
		logger.info("Exemple de message,Nombre de dossiers traités=1");               //Production
		
		//Définir un filtre sur le gestionnaire
		Filter filter2 = (record) -> record.getMessage().contains("Nombre de mises à jour=");
		handler.setFilter(filter2);
		logger.info("Exemple de message");                          //Pas de sortie
		logger.info("Exemple de message,Nombre de dossiers traités=1");               //Pas de sortie
		logger.info("Exemple de message,Nombre de dossiers traités=1,Nombre de mises à jour=1");    //Production
		
		//Définir le niveau de journalisation dans le gestionnaire
		handler.setLevel(Level.WARNING);
		logger.info("Exemple de message");                          //Pas de sortie
		logger.info("Exemple de message,Nombre de dossiers traités=1");               //Pas de sortie
		logger.info("Exemple de message,Nombre de dossiers traités=1,Nombre de mises à jour=1");    //Pas de sortie
		logger.warning("Message d'alerte,Nombre de dossiers traités=1,Nombre de mises à jour=1");   //Production
	}
}

Si vous exécutez ce qui précède, vous pouvez voir que la sortie du journal est limitée par le niveau de journal et le jeu de filtres pour l'enregistreur et le gestionnaire.

Contrôle de sortie de journal dans la hiérarchie des enregistreurs

Nous avons présenté ci-dessus que les enregistreurs ont une structure hiérarchique et que lorsqu'un message est émis vers l'enregistreur, il se propage vers l'enregistreur parent. En fait, il y a un piège dans ce mécanisme de propagation, et si vous ne comprenez pas correctement le mécanisme, vous risquez de rester coincé dans le pot. (Je m'intègre ...) Cela peut être difficile à comprendre même si vous l'expliquez avec des mots, mais une fois que vous l'expliquez avec des mots, les spécifications pour la propagation à l'enregistreur parent sont les suivantes.

Oui, je pense que c'est difficile à comprendre. Je pense que vous pouvez comprendre cela plus rapidement en regardant directement la logique. En gros, la logique de sortie du journal est celle illustrée dans la figure ci-dessous.

フローチャート.png

Avez-vous compris? Le filtre de niveau de journal défini sur l'enregistreur est vérifié uniquement sur le premier enregistreur qui reçoit l'appel, alors qu'il est vérifié. Tous les gestionnaires vérifient le filtre de niveau de journal défini dans le gestionnaire.

Deux exemples pour confirmer cela sont décrits ci-dessous.

NameSpaceSample2


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class NameSpaceSample2 {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Obtenez 3 enregistreurs. Définissez le gestionnaire et le formateur.
		Logger root = Logger.getLogger("");
		Logger sample = Logger.getLogger("sample");
		Logger loggerTreeSample = Logger.getLogger("sample.NameSpaceSample2");
		Handler rootHandler = new FileHandler("C:\\sample\\root.log");
		Handler sampleHandler = new FileHandler("C:\\sample\\sample.log");
		Handler NameSpaceSample2Handler = new FileHandler("C:\\sample\\NameSpaceSample2.log");
		Formatter formatter = new SimpleFormatter();
		rootHandler.setFormatter(formatter);
		sampleHandler.setFormatter(formatter);
		NameSpaceSample2Handler.setFormatter(formatter);
		root.addHandler(rootHandler);
		sample.addHandler(sampleHandler);
		loggerTreeSample.addHandler(NameSpaceSample2Handler);
		
		//Définissez le niveau de journalisation de l'enregistreur.
		root.setLevel(Level.WARNING);
		sample.setLevel(Level.INFO);
		loggerTreeSample.setLevel(Level.FINE);

		//Le gestionnaire est configuré pour autoriser tous les niveaux de journalisation. (Niveau.Le réglage ALL permet la sortie de tous les messages de niveau journal. )
		rootHandler.setLevel(Level.ALL);
		sampleHandler.setLevel(Level.ALL);
		NameSpaceSample2Handler.setLevel(Level.ALL);
		
		//Journal de sortie
		root.fine("Sortant de la racine.Message FINE");
		root.info("Sortant de la racine.Message INFO");
		root.warning("Sortant de la racine.Message d'alerte");
		sample.fine("Envoyer à partir de l'échantillon.Message FINE");
		sample.info("Envoyer à partir de l'échantillon.Message INFO");
		sample.warning("Envoyer à partir de l'échantillon.Message d'alerte");
		loggerTreeSample.fine("Appelé depuis NameSpaceSample2Handler.Message FINE");
		loggerTreeSample.info("Appelé depuis NameSpaceSample2Handler.Message INFO");
		loggerTreeSample.warning("Appelé depuis NameSpaceSample2Handler.Message d'alerte");
	}
}

Lorsque ce qui précède est exécuté, le message émis par loggerTreeSample.fine (...) est C: \\ sample \\ root même s'il est défini comme root.setLevel (Level.WARNING);. Vous pouvez voir qu'il est sorti vers .log

Voici un autre exemple. La seule différence par rapport à l'exemple ci-dessus est le paramètre de niveau de journal.

NameSpaceSample3


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class NameSpaceSample3 {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Obtenez 3 enregistreurs. Définissez le gestionnaire et le formateur.
		Logger root = Logger.getLogger("");
		Logger sample = Logger.getLogger("sample");
		Logger loggerTreeSample = Logger.getLogger("sample.NameSpaceSample2");
		Handler rootHandler = new FileHandler("C:\\sample\\root.log");
		Handler sampleHandler = new FileHandler("C:\\sample\\sample.log");
		Handler NameSpaceSample3Handler = new FileHandler("C:\\sample\\NameSpaceSample3.log");
		Formatter formatter = new SimpleFormatter();
		rootHandler.setFormatter(formatter);
		sampleHandler.setFormatter(formatter);
		NameSpaceSample3Handler.setFormatter(formatter);
		root.addHandler(rootHandler);
		sample.addHandler(sampleHandler);
		loggerTreeSample.addHandler(NameSpaceSample3Handler);
		
		//L'enregistreur est configuré pour autoriser tous les niveaux de journalisation. (Niveau.Le réglage ALL permet la sortie de tous les messages de niveau journal. )
		root.setLevel(Level.ALL);
		sample.setLevel(Level.ALL);
		loggerTreeSample.setLevel(Level.ALL);

		//Définissez le niveau de journalisation dans le gestionnaire.
		rootHandler.setLevel(Level.WARNING);
		sampleHandler.setLevel(Level.INFO);
		NameSpaceSample3Handler.setLevel(Level.FINE);
		
		//Journal de sortie
		root.fine("Sortant de la racine.Message FINE");
		root.info("Sortant de la racine.Message INFO");
		root.warning("Sortant de la racine.Message d'alerte");
		sample.fine("Envoyer à partir de l'échantillon.Message FINE");
		sample.info("Envoyer à partir de l'échantillon.Message INFO");
		sample.warning("Envoyer à partir de l'échantillon.Message d'alerte");
		loggerTreeSample.fine("Appelé depuis NameSpaceSample3Handler.Message FINE");
		loggerTreeSample.info("Appelé depuis NameSpaceSample3Handler.Message INFO");
		loggerTreeSample.warning("Appelé depuis NameSpaceSample3Handler.Message d'alerte");
	}
}

Si vous exécutez ce qui précède, vous pouvez voir que seuls les journaux de niveau AVERTISSEMENT sont générés dans C: \\ sample \\ root.log.

Lire le fichier de paramètres

Comme vous l'avez peut-être vu dans les exemples de programmes jusqu'à présent, écrire beaucoup de code pour configurer les enregistreurs et les gestionnaires peut être fastidieux. Après tout, je veux pousser la partie de réglage hors du programme et l'écrire dans le fichier de réglage. Par conséquent, la méthode suivante consiste à lire le fichier de paramètres de l'extérieur.

La méthode pour lire le fichier de paramètres à partir du programme est la suivante. Cette fois, j'ai essayé de lire logging.properties situé dans le même chemin de classe de l'exemple de programme. Le fichier de configuration doit être lu au format java.util.Properties.

LogManager.getLogManager().readConfiguration(SettingFileSample.class.getResourceAsStream("logging.properties"));

Le fichier de configuration d'exemple est le suivant. Veuillez vous référer à {java.home} \ lib \ logging.properties pour une explication détaillée.

logging.properties


#Le paramètre de niveau de journal du gestionnaire de journalisation racine ConsoleHandler a une erreur standard(System.err)Exportez le journal vers.
handlers=java.util.logging.ConsoleHandler
.level=INFO

#Enregistreur utilisé dans l'exemple de programme"sample.SettingFileSample"paramètres de
sample.SettingFileSample.level=FINE
sample.SettingFileSample.handlers=java.util.logging.FileHandler

#Paramètres de ConsoleHandler
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

#Paramètres FileHandler
java.util.logging.FileHandler.pattern=C:/sample/sample.log
java.util.logging.FileHandler.limit=1000
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

L'exemple de programme utilisant le fichier de configuration ci-dessus est décrit ci-dessous.

SettingFileSample


package sample;

import java.io.IOException;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class SettingFileSample {

	public static void main(String[] arg) throws SecurityException, IOException {
		LogManager.getLogManager().readConfiguration(SettingFileSample.class.getResourceAsStream("logging.properties"));

		Logger logger = Logger.getLogger("sample.SettingFileSample");
		logger.finer("Message FINER");
		logger.fine("Message FINE");
		logger.info("Message INFO");
	}
}

C'est bien car il n'y a pas de paramètres de journalisation ou de gestionnaire.

Comment utiliser ResourceBundle avec logger

java.util.logging peut également prendre en charge l'internationalisation à l'aide de ResourceBundle. L'exemple de programme est décrit ci-dessous. L'exemple utilise «resource_ja.properties» et «resource_en.properties» dans le même chemin de classe que la classe Java.

ResourceBundleSample


package sample;

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Logger;

public class ResourceBundleSample {

	public static void main(String[] arg) {
		Logger lggr = Logger.getLogger(ResourceBundleSample.class.getName());
		lggr.setResourceBundle(ResourceBundle.getBundle("sample.resource", Locale.JAPANESE));
		lggr.info("ID1");
		
		lggr.setResourceBundle(ResourceBundle.getBundle("sample.resource", Locale.ENGLISH));
		lggr.info("ID1");
	}
}

resource_ja.properties


ID1=Message japonais

resource_en.properties


ID1=english message

Lorsque vous exécutez l'exemple de programme, le premier journal affichera «message japonais» et le second journal affichera «message anglais».

Comment utiliser Security Manager avec Logger

Lorsque Security Manager est activé, les paramètres du journal ne peuvent pas être modifiés par programme. Lorsque l'exemple de programme suivant est exécuté avec Security Manager activé, ʻAccessControlException` est exécuté.

LoggingPermissionSample


package sample;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingPermissionSample {
	
	public static void main(String[] arg) {
		Logger lg = Logger.getLogger("");
		lg.setLevel(Level.FINE);
		lg.fine("fine message");
		lg.info("info message");
	}
}

Pour autoriser les modifications du journal lorsque Security Manager est activé, écrivez ce qui suit dans votre fichier de stratégie: Pour plus de détails, reportez-vous au Javadoc de LoggerPermission.

java.policy


grant {
        permission java.util.logging.LoggingPermission "control", "";
}

Pour activer le gestionnaire de sécurité, spécifiez java.security.manager dans l'argument VM comme indiqué ci-dessous. Pour spécifier explicitement le fichier de stratégie, spécifiez java.security.policy dans l'argument VM comme indiqué ci-dessous.

java -Djava.security.manager -Djava.security.policy=exemple de chemin de fichier de stratégie.LoggingPermissionSample

Recommended Posts

Comment utiliser java.util.logging
Comment utiliser Map
Comment utiliser rbenv
Comment utiliser with_option
Comment utiliser fields_for
Comment utiliser la carte
Comment utiliser collection_select
Comment utiliser Twitter4J
Comment utiliser active_hash! !!
Comment utiliser MapStruct
Comment utiliser TreeSet
[Comment utiliser l'étiquette]
Comment utiliser l'identité
Comment utiliser le hachage
Comment utiliser Dozer.mapper
Comment utiliser Gradle
Comment utiliser org.immutables
Comment utiliser java.util.stream.Collector
Comment utiliser VisualVM
Comment utiliser Map
Comment utiliser l'API Chain
[Java] Comment utiliser Map
Comment utiliser Queue avec priorité
[Rails] Comment utiliser enum
Comment utiliser java Facultatif
Comment utiliser JUnit (débutant)
Comment utiliser le retour Ruby
[Rails] Comment utiliser enum
Comment utiliser @Builder (Lombok)
Comment utiliser la classe Java
Comment utiliser Big Decimal
[Java] Comment utiliser removeAll ()
Comment utiliser String [] args
Comment utiliser la jonction de rails
Comment utiliser Java Map
Ruby: Comment utiliser les cookies
Comment utiliser Dependant :: Destroy
Comment utiliser Eclipse Debug_Shell
Comment utiliser Apache POI
[Rails] Comment utiliser la validation
Comment utiliser les variables Java
[Rails] Comment utiliser authenticate_user!
Comment utiliser GC Viewer
Comment utiliser Lombok maintenant
[Création] Comment utiliser JUnit
[Rails] Comment utiliser Scope
Comment utiliser la méthode link_to
[Rails] Comment utiliser la "devise" des gemmes
Comment utiliser Lombok au printemps
Comment utiliser StringBurrer et Arrays.toString.
Comment utiliser le tableau (mémorandum personnel)