תצורה פרוגרמטית עם Log4j 2

1. הקדמה

במדריך זה, נבחן דרכים שונות להגדרת תכנות Apache Log4j 2.

2. הגדרה ראשונית

כדי להתחיל להשתמש ב- Log4j 2, עלינו רק לכלול את התלות log4j-core ו- log4j-slf4j-impl pom.xml:

 org.apache.logging.log4j log4j-core 2.11.0 org.apache.logging.log4j log4j-slf4j-impl 2.11.0 

3. ConfigurationBuilder

לאחר שהגדרנו את Maven, עלינו ליצור ConfigurationBuilder, שהוא הכיתה המאפשרת לנו להגדיר appenders, מסננים, פריסות, ו חוטבי עצים.

Log4j 2 מספק מספר דרכים להשיג ConfigurationBuilder.

נתחיל בדרך הישירה ביותר:

ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder ();

וכדי להתחיל להגדיר רכיבים, ConfigurationBuilder מצויד בתואם חָדָשׁ שיטה, כמו newAppender אוֹ newLayout, עבור כל רכיב.

לרכיבים מסוימים יש תת-סוגים שונים, כמו FileAppender אוֹ ConsoleAppender, ואלה מכונים בממשק ה- API תוספים.

3.1. קביעת תצורה של תומכים

בואו נגיד ל בּוֹנֶה לאן לשלוח כל שורת יומן באמצעות הגדרת תצורה של appender:

קונסולת AppenderComponentBuilder = builder.newAppender ("stdout", "Console"); builder.add (קונסולה); AppenderComponentBuilder file = builder.newAppender ("יומן", "קובץ"); file.addAttribute ("fileName", "target / logging.log"); builder.add (קובץ);

בעוד שרוב חָדָשׁ שיטות אינן תומכות בכך, newAppender (שם, תוסף) מאפשר לנו לתת למוסף שם, אשר יתברר כחשוב בהמשך. המועמדים האלה, התקשרנו stdout ו עֵץ, אם כי יכולנו למנות אותם כל דבר.

סיפרנו גם ל- בּוֹנֶה איזה מתלהב חיבור (או, יותר פשוט, איזה סוג של appender) להשתמש. לְנַחֵם ו קוֹבֶץ עיין במוספי Log4j 2 לכתיבה לתקינה ולמערכת הקבצים בהתאמה.

אף על פי ש- Log4j 2 תומך במספר תוספים, קביעת התצורה שלהם באמצעות Java יכולה להיות קצת מסובכת מאז AppenderComponentBuilder הוא מחלקה גנרית לכל סוגי האפליקציות.

זה גורם לזה להיות שיטות כמו addAttribute ו addComponent במקום setFileName ו addTriggeringPolicy:

AppenderComponentBuilder rollingFile = builder.newAppender ("מתגלגל", "RollingFile"); rollingFile.addAttribute ("fileName", "rolling.log"); rollingFile.addAttribute ("filePattern", "rolling-% d {MM-dd-yy} .log.gz"); builder.add (rollingFile); 

ולבסוף, אל תשכח להתקשר builder.add לצרף אותו לתצורה הראשית!

3.2. הגדרת מסננים

אנו יכולים להוסיף פילטרים לכל אחד מהמתאימים שלנו, אשר מחליטים בכל שורת יומן אם יש לצרף אותו או לא.

בואו נשתמש ב- מרקרפילטר תוסף בתוספת בקונסולה שלנו:

FilterComponentBuilder flow = builder.newFilter ("MarkerFilter", Filter.Result.ACCEPT, Filter.Result.DENY); flow.addAttribute ("סמן", "FLOW"); console.add (זרימה);

שים לב לכך חָדָשׁ השיטה לא מאפשרת לנו למנות את המסנן, אך היא מבקשת מאיתנו לציין מה לעשות אם המסנן עובר או נכשל.

במקרה זה שמרנו על פשטנו וקבענו שאם מרקרפילטר עובר, אם כן לְקַבֵּל קו היומן. אחרת, לְהַכּחִישׁ זה.

שים לב במקרה זה שאנחנו לא מצרפים את זה ל- בּוֹנֶה אלא במקום למבקשים שאנו רוצים להשתמש במסנן זה.

3.3. הגדרת תצורה של פריסות

לאחר מכן, בואו נגדיר את הפריסה עבור כל שורת יומן. במקרה זה נשתמש ב- תבנית פריסה חיבור:

LayoutComponentBuilder standard = builder.newLayout ("PatternLayout"); standard.addAttribute ("תבנית", "% d [% t]% -5 רמת:% msg% n% זורק"); console.add (סטנדרטי); file.add (סטנדרטי); rolling.add (סטנדרטי);

שוב, הוספנו אותם ישירות למתאימים המתאימים במקום ל- בּוֹנֶה באופן ישיר.

3.4. קביעת תצורה של לוגר השורשים

כעת, כשאנו יודעים לאן יועברו היומנים, אנו רוצים להגדיר אילו יומנים יעברו לכל יעד.

לוגר לוגר הוא הלוגר הגבוה ביותר, בערך כמו לְהִתְנַגֵד בג'אווה. לוגר זה הוא מה שישמש כברירת מחדל אלא אם כן יעקף אותו.

אז בואו נשתמש ביומן שורשים כדי להגדיר את רמת הרישום המוגדרת כברירת מחדל שְׁגִיאָה ומוגדר ברירת המחדל לשלנו stdout מתלה מלמעלה:

RootLoggerComponentBuilder rootLogger = builder.newRootLogger (Level.ERROR); rootLogger.add (builder.newAppenderRef ("stdout")); builder.add (rootLogger);

כדי להפנות את הלוגר שלנו למוגדר ספציפי, איננו נותנים לו מופע של הבונה. במקום זאת, אנו מתייחסים אליו על ידי שֵׁם שנתנו את זה קודם.

3.5. קביעת תצורה של רישומי עצים נוספים

ניתן להשתמש בילוגררים בכדי למקד לחבילות ספציפיות או שמות לוגים.

בואו להוסיף לוגר עבור ה- com חבילה ביישום שלנו, ומגדירה את רמת הרישום לנפות וכי אלה הולכים אל שלנו עֵץ appender:

LoggerComponentBuilder logger = builder.newLogger ("com", Level.DEBUG); logger.add (builder.newAppenderRef ("יומן")); logger.addAttribute ("תוסף", שקר); builder.add (לוגר);

שים לב שאנחנו יכולים להגדיר תוספות עם הלוגים שלנו, המציין אם לוגר זה צריך לרשת מאפיינים כמו רמת רישום וסוגי appender מאבותיו.

3.6. קביעת תצורה של רכיבים אחרים

לא לכל הרכיבים יש ייעודי חָדָשׁ שיטה ב ConfigurationBuilder.

אז, במקרה כזה, אנו מתקשרים newComponent.

לדוגמא, כי אין TriggeringPolicyComponentBuilder, אנחנו צריכים להשתמש newComponent למשהו כמו ציון מדיניות ההפעלה שלנו למריחת קובצי רולינג:

ComponentBuilder triggeringPolicies = builder.newComponent ("מדיניות") .addComponent (builder.newComponent ("CronTriggeringPolicy") .addAttribute ("לוח זמנים", "0 0 0 * *?")) .AddComponent (builder.newComponent ("SizeBasedTrigger) .addAttribute ("גודל", "100 מיליון"); rolling.addComponent (triggeringPolicies);

3.7. המקבילה ל- XML

ConfigurationBuilder מגיע עם שיטה שימושית להדפסת ה- XML ​​המקביל:

builder.writeXmlConfiguration (System.out);

הפעלת השורה שלעיל מדפיסה:

זה שימושי כשאנחנו רוצים לבדוק פעמיים את התצורה שלנו או אם אנחנו רוצים להמשיך את התצורה שלנו, למשל, למערכת הקבצים.

3.8. לשים את הכל ביחד

עכשיו שאנחנו מוגדרים לחלוטין, בואו נגיד ל- Log4j 2 להשתמש בתצורה שלנו:

Configurator.initialize (builder.build ());

אחרי שהופעל זה, שיחות עתידיות ל- Log4j 2 ישתמשו בתצורה שלנו.

שים לב שזה אומר שאנחנו צריכים להפעיל Configurator.initialize לפני שאנחנו מתקשרים אל LogManager.getLogger.

4. ConfigurationFactory

עכשיו כשראינו דרך אחת להשיג ולהחיל א ConfigurationBuilderבואו נסתכל על עוד אחד:

מחלקה ציבורית CustomConfigFactory מרחיב את ConfigurationFactory {תצורה ציבורית createConfiguration (הקשר LoggerContext, ConfigurationSource src) {בניית ConfigurationBuilder = סופר .newConfigurationBuilder (); // ... הגדר תצורת appenders, פילטרים וכו 'להחזיר builder.build (); } מחרוזת ציבורית [] getSupportedTypes () {להחזיר מחרוזת חדשה [] {"*"}; }}

במקרה זה, במקום להשתמש ConfigurationBuilderFactory, סווגנו משנה ConfigurationFactory, כיתה מופשטת המיועדת ליצירת מקרים של תְצוּרָה.

ואז, במקום להתקשר Configurator.initialize כמו שעשינו בפעם הראשונה, אנחנו פשוט צריכים ליידע את Log4j 2 על מפעל התצורה החדש שלנו.

ישנן שלוש דרכים לעשות זאת:

  • אתחול סטטי
  • נכס זמן ריצה, או
  • ה @חיבור ביאור

4.1. השתמש באתחול סטטי

Log4j 2 תומך בשיחות setConfigurationFactory במהלך אתחול סטטי:

סטטי {ConfigurationFactory custom = חדש CustomConfigFactory (); ConfigurationFactory.setConfigurationFactory (מותאם אישית); }

לגישה זו יש מגבלה זהה לזו של הגישה האחרונה שראינו, והיא שנצטרך להפעיל אותה לפני שיחות כלשהן אל LogManager.getLogger.

4.2. השתמש במאפיין זמן ריצה

אם יש לנו גישה לפקודת ההפעלה של Java, אז Log4j 2 תומך גם בציון ה- ConfigurationFactory לשימוש באמצעות א פָּרָמֶטֶר:

-Dlog4j2.configurationFactory = com.baeldung.log4j2.CustomConfigFactory

היתרון העיקרי בגישה זו הוא שאיננו צריכים לדאוג לסדר האתחול כמו בשתי הגישות הראשונות.

4.3. להשתמש ב @חיבור ביאור

ולבסוף, בנסיבות בהן איננו רוצים להתעסק בפקודת ההפעלה של Java על ידי הוספת a אנחנו יכולים פשוט להוסיף הערות שלנו CustomConfigurationFactory עם Log4j 2 @חיבור ביאור:

@Plugin (name = "CustomConfigurationFactory", קטגוריה = ConfigurationFactory.CATEGORY) @Order (50) מחלקה ציבורית CustomConfigFactory מרחיב את ConfigurationFactory {// ... שאר היישום}

Log4j 2 יסרוק את מסלול הכיתה לאיתור שיעורים עם @חיבור ביאור, ומציאת כיתה זו ב ConfigurationFactory קטגוריה, ישתמש בה.

4.4. שילוב עם תצורה סטטית

יתרון נוסף לשימוש ב- ConfigurationFactory הרחבה היא שנוכל לשלב בקלות את התצורה המותאמת אישית שלנו עם מקורות תצורה אחרים כמו XML:

תצורה ציבורית createConfiguration (הקשר LoggerContext, ConfigurationSource src) {להחזיר WithXmlConfiguration חדש (הקשר, src); } 

ה מָקוֹר הפרמטר מייצג את קובץ התצורה XML או JSON הסטטי שמצא Log4j 2 אם קיים.

אנו יכולים לקחת את קובץ התצורה ולשלוח אותו ליישום המותאם אישית שלנו תצורת Xml היכן שנוכל למקם את התצורה העיקרית הדרושה לנו:

מחלקה ציבורית WithXmlConfiguration מרחיב XmlConfiguration {@Override מוגן ריק doConfigure () {super.doConfigure (); // לנתח מסמך XML // ... להוסיף את התצורה המותאמת אישית שלנו}}

5. מסקנה

במאמר זה בדקנו כיצד להשתמש בחדש ConfigurationBuilder ממשק API זמין ב- Log4j 2.

בדקנו גם התאמה אישית ConfigurationFactory בקומבינציה עם ConfigurationBuilder למקרי שימוש מתקדמים יותר.

אל תשכח לבדוק את הדוגמאות המלאות שלי ב- GitHub.