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:

  1. Core beépülő modulok
  2. Átalakítók
  3. Kulcsszolgáltatók
  4. Keresések
  5. Í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:

  1. 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
  2. Hasonló Log4j2Plugins.dat fájl az OSGi csomagokból
  3. Vesszővel elválasztott csomaglista a log4j.plugin.packages rendszer tulajdonság
  4. Programos Log4j 2 konfigurációban hívhatunk PluginManager.addPackages () módszer a lista csomagnevekből
  5. 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.