Log4j 2 beépülő modulok
1. Áttekintés
A Log4j 2 olyan beépülő modulokat használ, mint az Appenders és az Layouts a naplók formázásához és kimenetéhez. Ezeket alap plugineknek nevezik, és a Log4j 2 rengeteg lehetőséget kínál számunkra, amelyek közül választhatunk.
Bizonyos esetekben előfordulhat, hogy a meglévő bővítményt is ki kell terjesztenünk, vagy akár egyénieket is írhatunk.
Ebben az oktatóanyagban a Log4j 2 kiterjesztési mechanizmust használjuk az egyedi beépülő modulok megvalósításához.
2. A Log4j 2 bővítmények kiterjesztése
A Log4j 2 beépülő moduljai nagyjából öt kategóriába sorolhatók:
- Core beépülő modulok
- Átalakítók
- Kulcsszolgáltatók
- Keresések
- Írja be a konvertereket
A Log4j 2 lehetővé teszi számunkra, hogy az összes fenti kategóriában egyedi beépülő modulokat valósítsunk meg egy közös mechanizmus segítségével. Ezenkívül lehetővé teszi számunkra a meglévő bővítmények kiterjesztését ugyanazzal a megközelítéssel.
A Log4j 1.x-ben a meglévő bővítmény kibővítésének egyetlen módja a megvalósítási osztályának felülbírálása. Másrészt a Log4j 2 megkönnyíti a meglévő bővítmények kiterjesztését azáltal, hogy egy osztályt feljegyez @Csatlakoztat.
A következő szakaszokban egy egyéni beépülő modult valósítunk meg néhány ilyen kategóriában.
3. Core beépülő modul
3.1. Egyéni mag beépülő modul megvalósítása
Az olyan kulcselemek, mint a Függelék, az Elrendezések és a Szűrők, a Log4j 2 központi bővítményeként ismertek. Bár az ilyen beépülő modulok listája sokféle van, bizonyos esetekben előfordulhat, hogy egyedi mag-bővítményt kell bevezetnünk. Vegyük például a ListAppender amely csak naplóbejegyzéseket ír be egy memóriába Lista:
@Plugin (név = "ListAppender", kategória = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) nyilvános osztály A ListAppender kiterjeszti az AbstractAppender {private List logList; védett ListAppender (karakterlánc neve, szűrőszűrő) {szuper (név, szűrő, null); logList = Collections.synchronizedList (új ArrayList ()); } @PluginFactory public static ListAppender createAppender (@PluginAttribute ("name") String name, @PluginElement ("Filter") final Filter filter) {return new ListAppender (name, filter); } @Orride public void append (LogEvent event) {if (event.getLevel (). IsLessSpecificThan (Level.WARN)) {hiba ("Nem lehet WARN szintnél kevesebbet bejelentkezni."); Visszatérés; } logList.add (esemény); }}
Megjegyeztük az osztályt @Csatlakoztat amellyel megnevezhetjük a beépülő modulunkat. Ezenkívül a paramétereket is feljegyzik @PluginAttribute. A beágyazott elemeket, például a szűrőt vagy az elrendezést, a rendszer átadja @PluginElement. Most hivatkozhatunk erre a bővítményre a konfigurációban ugyanazzal a névvel:
3.2. Plugin Builders
Az utolsó szakaszban szereplő példa meglehetősen egyszerű, és csak egyetlen paramétert fogad el név. Általánosságban elmondható, hogy az alapvető pluginok, mint például a függelékek, sokkal összetettebbek, és általában több konfigurálható paramétert fogadnak el.
Vegyünk például egy jelentkezőt, amelyikbe bejelentkezik Kafka:
Az ilyen függelékek megvalósításához a Log4j 2 egy plugin készítő megvalósítást biztosít a Építész minta:
@Plugin (name = "Kafka2", category = Core.CATEGORY_NAME) nyilvános osztály A KafkaAppender kiterjeszti az AbstractAppender {public static class Builder megvalósítja az org.apache.logging.log4j.core.util.Builder {@PluginBuilderAttribute ("name") @Required private Karakterlánc neve; @PluginBuilderAttribute ("ip") privát karakterlánc ipAddress; // ... további tulajdonságok // ... getterek és beállítók @Orride public KafkaAppender build () {return new KafkaAppender (getName (), getFilter (), getLayout (), true, new KafkaBroker (ipAddress, port, topic, partíció)); }} KafkaBroker magánügynök; privát KafkaAppender (karakterlánc neve, szűrőszűrő, elrendezés elrendezése, logikai ignoreExceptions, KafkaBroker broker) {szuper (név, szűrő, elrendezés, ignoreExceptions); this.bróker = bróker; } @Orride public void append (LogEvent esemény) {connectAndSendToKafka (bróker, esemény); }}
Röviden, bevezettük a Építész osztályba, és a paraméterekkel jelölte @PluginBuilderAttribute. Emiatt, KafkaAppender elfogadja a Kafka kapcsolati paramétereket a fenti konfigurációból.
3.3. Meglévő bővítmény kiterjesztése
Kiterjeszthetünk egy meglévő központi plugint is a Log4j 2-ben. Ezt úgy érhetjük el, hogy a beépülő modulunknak ugyanolyan nevet adunk, mint egy meglévő bővítmény. Például, ha kiterjesztjük a RollingFileAppender:
@Plugin (name = "RollingFile", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) public class RollingFileAppender kiterjeszti az AbstractAppender {public RollingFileAppender (karakterlánc neve, szűrő szűrő, elrendezés elrendezése) {szuper (név, szűrő, elrendezés); } @Orride public void append (LogEvent esemény) {}}
Nevezetesen, most két azonos nevű függelékünk van. Ilyen esetekben a Log4j 2 az először felfedezett függeléket használja. A bővítmények felfedezéséről egy későbbi részben olvashatunk többet.
Felhívjuk figyelmét, hogy a Log4j 2 nem ösztönzi több azonos nevű bővítményt. Jobb, ha egyéni plugint hajt végre, és ezt használja a naplózási konfigurációban.
4. Converter plugin
Az elrendezés egy erőteljes bővítmény a Log4j 2-ben. Ez lehetővé teszi számunkra, hogy meghatározzuk a naplóink kimeneti struktúráját. Például használhatjuk JsonLayout a naplók JSON formátumban történő megírásához.
Egy másik ilyen plugin a PatternLayout. Bizonyos esetekben egy alkalmazás információkat szeretne közzétenni, például a szálazonosítót, a szál nevét vagy az időbélyegzőt minden napló utasításhoz. PatternLayout A plugin lehetővé teszi számunkra, hogy az ilyen részleteket beágyazzuk egy átalakítási minta karaktersorozatba a konfigurációban:
Itt, % d a konverziós minta. A Log4j 2 átalakítja ezt a% d mintát a segítségével DatePatternConverter amely megérti a konverziós mintát és lecseréli a formázott dátumra vagy időbélyegre.
Tegyük fel, hogy egy Docker-tárolóban futó alkalmazás minden napló utasítással ki akarja nyomtatni a tároló nevét. Ehhez megvalósítjuk a DockerPatterConverter és módosítsa a fenti konfigurációt a konverziós karakterlánccal:
@Plugin (name = "DockerPatternConverter", category = PatternConverter.CATEGORY) @ConverterKeys ({"docker", "container"}) nyilvános osztály A DockerPatternConverter kiterjeszti a LogEventPatternConverter {private DockerPatternConverter (String [] opciók) {super ( dokkmunkás"); } public static DockerPatternConverter newInstance (String [] opciók) {return new DockerPatternConverter (opciók); } @Orride public void format (LogEvent event, StringBuilder toAppendTo) {toAppendTo.append (dockerContainer ()); } private String dockerContainer () {return "container-1"; }}
Tehát megvalósítottunk egy szokást DockerPatternConverter hasonló a dátummintához. A konverziós mintát a Docker-tároló nevével helyettesíti.
Ez a beépülő modul hasonlít a korábban beépített alapvető pluginhoz. Nevezetesen csak egy feljegyzés létezik, amely eltér az utolsó bővítménytől. @ConverterKeys az annotáció elfogadja ennek a bővítménynek a konverziós mintáját.
Ennek eredményeként ez a bővítmény konvertálni fog %dokkmunkás vagy %tartály mintasztring a tároló nevébe, amelyben az alkalmazás fut:
5. Keresési bővítmény
A keresési beépülő modulok dinamikus értékek hozzáadására szolgálnak a Log4j 2 konfigurációs fájlban. Lehetővé teszik az alkalmazások számára, hogy futási értékeket ágyazzanak be a konfigurációs fájl egyes tulajdonságaiba. Az érték hozzáadódik egy kulcsalapú keresés révén különböző forrásokból, például fájlrendszerből, adatbázisból stb.
Az egyik ilyen plugin a DateLookupPlugin amely lehetővé teszi a dátumminta cseréjét az alkalmazás aktuális rendszerdátumával:
% d% p% c {1.} [% t]% m% n
Ebben a minta konfigurációs fájlban RollingFileAppender használja a dátum keresés, ahol a kimenet MM-dd-yyyy formátumban lesz. Ennek eredményeként a Log4j 2 naplókat ír egy dátum utótagú kimeneti fájlba.
A többi pluginhoz hasonlóan a Log4j 2 is sok forrást kínál a keresésekhez. Ezenkívül megkönnyíti az egyéni keresések végrehajtását, ha új forrás szükséges:
@Plugin (name = "kafka", category = StrLookup.CATEGORY) public class KafkaLookup implementálja a StrLookup {@Orride public String lookup (String kulcs) {return getFromKafka (kulcs); } @Orride public String lookup (LogEvent event, String key) {return getFromKafka (kulcs); } privát karakterlánc getFromKafka (karakterlánc témaNév) {return "topic1-p1"; }}
Így KafkaLookup az értéket egy Kafka-téma lekérdezésével oldja meg. Most átadjuk a téma nevét a konfigurációból:
% d% p% c {1.} [% t]% m% n
Cseréltük a dátum keresés a korábbi példánkban a lekérdező Kafka kereséssel 1. téma.
Mivel a Log4j 2 csak egy keresési plugin alapértelmezett konstruktorát hívja meg, ezért nem hajtottuk végre @PluginFactory mint a korábbi pluginokban tettük.
6. Plugin Discovery
Végül értsük meg, hogy a Log4j 2 hogyan fedezi fel a beépülő modulokat egy alkalmazásban. Amint azt a fenti példákban láthattuk, minden bővítménynek egyedi nevet adtunk. Ez a név kulcsként működik, amelyet a Log4j 2 plugin osztályra bont.
Van egy meghatározott sorrend, amelyben a Log4j 2 keresést végez egy plugin osztály megoldására:
- Sorosított plugin-listafájl a log4j2-mag könyvtár. Pontosabban, a Log4j2Plugins.dat az edény belsejébe van csomagolva az alapértelmezett Log4j 2 beépülő modulok felsorolásához
- Hasonló Log4j2Plugins.dat fájl az OSGi csomagokból
- Vesszővel elválasztott csomaglista a log4j.plugin.packages rendszer tulajdonság
- Programos Log4j 2 konfigurációban hívhatunk PluginManager.addPackages () módszer a lista csomagnevekből
- A vesszőkkel elválasztott csomagok listája hozzáadható a Log4j 2 konfigurációs fájlba
Feltételként engedélyezni kell a kommentárok feldolgozását, hogy a Log4j 2 megoldja a plugint a név adott a @Csatlakoztat annotáció.
Mivel a Log4j 2 neveket használ a plugin megkeresésére, a fenti sorrend fontossá válik. Például, ha két azonos nevű bővítményünk van, a Log4j 2 felfedezi az előbb megoldott plugint. Ezért, ha ki kell terjesztenünk egy meglévő bővítményt a Log4j 2-ben, a plugint külön edénybe kell csomagolnunk, és a log4j2-core.jar.
7. Következtetés
Ebben a cikkben a bővítmények széles kategóriáit vizsgáltuk a Log4j 2-ben. Megbeszéltük, hogy annak ellenére, hogy létezik egy teljes listája a meglévő bővítményeknek, előfordulhat, hogy egyes felhasználási esetekben egyedi beépülő modulokat kell bevezetnünk.
Később néhány hasznos bővítmény egyedi megvalósítását néztük meg. Továbbá láttuk, hogy a Log4j 2 lehetővé teszi számunkra, hogy megnevezzük ezeket a bővítményeket, és később ezt a bővítménynevet használjuk a konfigurációs fájlban. Végül megbeszéltük, hogy a Log4j 2 hogyan oldja meg a beépülő modulokat ezen név alapján.
Mint mindig, minden példa elérhető a GitHubon.