Log4j2 Config Guide 🇱🇰 | Logger, Appenders, Levels | සිංහලෙන්

Mastering Log4j2 Configuration: A Developer's SC Guide
කොහොමද යාලුවනේ! ❤️ අද අපි කතා කරන්න යන්නේ ඔයාලා හැමෝටම ගොඩක් වැදගත් වෙන, Software Development වලදී නැතුවම බැරි Logging System එකක් ගැන. ඒ තමයි Log4j2. මේක ඇත්තටම අපේ Coding Life එකේ Super Power එකක් වගේ. මොකද Error එකක් හොයාගන්න, System එක මොකද කරන්නේ කියලා බලන්න, මේවාට Log තමයි අපේ හොඳම යාළුවා.
ඉතින් අපි බලමු Log4j2 කියන්නේ මොකක්ද? ඒක හරියටම configure කරගන්නේ කොහොමද? කියන එක ගැන. අපි ලංකාවේ විදියට, අපිට තේරෙන භාෂාවෙන් කතා කරමු.
1. Log4j2 කියන්නේ මොකක්ද?
සරලවම කිව්වොත්, Log4j2 කියන්නේ Apache Software Foundation එකෙන් හදපු, Java Applications වලට Logging කරන්න පුළුවන් Library එකක්. මේක Log4j 1.x වලට වඩා ගොඩක් දියුණු වෙලා තියෙනවා, විශේෂයෙන්ම Performance අතින්. Log4j2 එකේ තියෙන ලොකුම වාසිය තමයි, මේක Asynchronous logging support කරන එක. ඒ කියන්නේ අපේ Application එකේ Performance එකට අවම බලපෑමක් ඇතිව Logging කරන්න පුළුවන්.
ඇයි අපිට Logging ඕනෙ?
- Debugging: Error එකක් ආපු වෙලාවට ඒක ආවේ කොහෙන්ද, මොකක් නිසාද කියලා හොයාගන්න ලේසියි.
- Monitoring: Application එක Run වෙන විදිය, ඒකේ Flow එක බලන්න පුළුවන්.
- Auditing: සමහර වෙලාවට, Security Reasons වලට කවුද මොනවද කළේ කියලා Record කරගන්න ඕනේ වෙනවා.
- Troubleshooting: Production එකේදී එන Issues fix කරන්න Log තමයි හොඳම Tool එක.
හරි, දැන් ඔයාලට අදහසක් ඇති Log4j2 කියන්නේ මොකක්ද? ඇයි මේක අපිට වැදගත් වෙන්නේ කියලා. අපි ඊළඟට බලමු මේකේ තියෙන ප්රධානම Parts දෙකක් ගැන.
2. Log Levels සහ Appenders ගැන දැනගමු
Log Levels - වැදගත්කම අනුව වර්ග කිරීම
Log4j2 වලදී, අපි ලියන හැම Log Message එකක්ම Level එකකට අයිති වෙනවා. මේ Level එකෙන් කියන්නේ ඒ Message එකේ වැදගත්කම මොකක්ද කියන එක. මේ තියෙන්නේ ප්රධාන Log Levels ටික:
- TRACE: මේක තමයි Low Level එකේ තියෙන, ගොඩක්ම Detailed Logs. Programming Flow එකේ හැම පොඩි දෙයක්ම Log කරන්න මේක පාවිච්චි කරනවා. Production එකේදී මේවා Active කරන්නේ හරිම අඩුවෙන්.
- DEBUG: Debugging වලට ගොඩක්ම පාවිච්චි කරන Level එක. Variables වල Values, Method Calls වගේ දේවල් Log කරන්න පුළුවන්.
- INFO: Application එකේ සාමාන්ය ක්රියාකාරිත්වය පෙන්නන Logs. "Application Started", "User Logged In" වගේ දේවල් මේ Level එකෙන් Log කරනවා.
- WARN: පොඩි අවුලක් තියෙනවා, ඒත් Application එකේ වැඩේට ලොකු බලපෑමක් නෑ කියලා කියන්න මේ Level එක පාවිච්චි කරනවා. උදාහරණයක් විදියට "Deprecated API used", "Configuration file not found, using default" වගේ දේවල්.
- ERROR: Critical Issues, Exceptions වගේ දේවල් මේ Level එකෙන් Log කරනවා. මේවා අනිවාර්යයෙන්ම බලන්න ඕනේ දේවල්.
- FATAL: Application එකට වැඩ කරන්න බැරි තරම් ලොකු වැරදීමක් වුණාම මේ Level එක පාවිච්චි කරනවා. Application එක Crash වෙන්න වගේ තත්ත්වයකදී.
වැදගත් දේ තමයි, අපි Logger එකක් Configure කරනකොට Level එකක් දෙනවා. ඒ Level එකට වඩා වැඩි Level එකේ Logs විතරයි Record වෙන්නේ. උදාහරණයක් විදියට Logger එකක් INFO Level එකේ configure කරලා නම්, TRACE සහ DEBUG Logs Record වෙන්නේ නෑ. INFO, WARN, ERROR, FATAL විතරයි Record වෙන්නේ.
Appenders - Logs කොහෙටද යවන්නේ?
Appender එකකින් කියන්නේ අපි ලියන Log Message එකක් කොහෙටද යවන්නේ කියන එක. අපි Appender වර්ග කිහිපයක් ගැන බලමු:
- ConsoleAppender: මේකෙන් Logs ටික Console එකට (Standard Output/Error Stream) print කරනවා. Development කරනකොට මේක ගොඩක් ප්රයෝජනවත්.
- FileAppender: Logs ටික File එකකට ලියනවා. සාමාන්යයෙන් මේක Production Environments වලදී පාවිච්චි කරනවා.
- RollingFileAppender: මේක FileAppender එකේ දියුණු Version එකක්. මේකෙන් Logs ටික File එකකට ලියනවා, හැබැයි File එකේ Size එකක් නැත්නම් කාලයක් ගියාම අලුත් File එකකට Logs ලියනවා. මේකෙන් වෙන්නේ Log Files ගොඩක් ලොකු වෙන එක වළක්වා ගන්න එකයි. (උදා: දවසකට එක File එකක්, නැත්නම් 10MB ක File එකක්)
- JDBCAppender, SMTPAppender, JMSAppender: Logs Database එකකට, Email එකකට, JMS Queue එකකට යවන්න පුළුවන්. මේවා ගැන වැඩිදුරටත් Log4j2 Documentation එකෙන් බලන්න පුළුවන්.
හරි, දැන් ඔයාලට Log Levels සහ Appenders ගැන හොඳ අවබෝධයක් ඇති. අපි දැන් බලමු මේවා කොහොමද log4j2.xml File එකේ Configure කරන්නේ කියලා.
3. log4j2.xml Confirguration එක හදමු
Log4j2 Configure කරන්න පුළුවන් ගොඩක් ක්රම තියෙනවා (XML, JSON, YAML, Properties File). ඒත් අපි අද බලන්නේ ගොඩක්ම පාවිච්චි කරන XML Configuration එක ගැන. මේ File එක සාමාන්යයෙන් අපේ Project එකේ src/main/resources
ෆෝල්ඩර් එකේ තියෙන්න ඕනේ.
මෙන්න පොඩි Simple log4j2.xml
File එකක්. මේකෙන් අපි Console එකටයි, File එකකටයි Logs යවන්නේ.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- Console Appender -->
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<!-- Rolling File Appender -->
<RollingFile name="FileAppender" fileName="logs/application.log"
filePattern="logs/$${${date:yyyy-MM}}/application-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<!-- Roll over daily -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- Roll over when file size reaches 10 MB -->
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<DefaultRolloverStrategy max="20"/> <!-- Keep a maximum of 20 archived files -->
</RollingFile>
</Appenders>
<Loggers>
<!-- Specific Logger for a package/class -->
<Logger name="com.example.myapp" level="DEBUG" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Logger>
<!-- Root Logger (default for all loggers) -->
<Root level="INFO">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
Configuration File එකේ Structure එක
අපි එකින් එක බලමු මේ File එකේ මොනවද තියෙන්නේ කියලා:
<Configuration>
Tag එක
status="WARN"
: මේකෙන් කියන්නේ Log4j2 Internal Events (configuration issues වගේ) Log කරන Level එක. අපි මේක WARN දාලා තියෙන්නේ, අනවශ්ය Internal Logs එන එක නවත්තන්න.
<Appenders>
Section එක
මේක ඇතුළේ තමයි අපේ Appenders define කරන්නේ.
- ConsoleAppender:
name="ConsoleAppender"
: මේ Appender එකට දෙන නම.target="SYSTEM_OUT"
: Logs Console එකේ Standard Output Stream එකට යවනවා. Standard Error Stream එකට යවන්න ඕන නම්SYSTEM_ERR
කියලා දාන්න පුළුවන්.<PatternLayout pattern="..."/>
: Log Message එක Display වෙන Format එක. මේක ගැන පොඩ්ඩක් විස්තර කරමු:%d{yyyy-MM-dd HH:mm:ss.SSS}
: Date and Time එක. (e.g., 2023-10-27 10:30:45.123)[%t]
: Thread Name එක.%-5level
: Log Level එක (INFO, DEBUG etc.), 5 characters වලට align කරලා.%logger{36}
: Logger Name එක. 36 කියන්නේ Logger Name එකේ පෙන්වන Max Length එක. (e.g., c.e.m.MyClass)%msg%n
: Log Message එක සහ Line Break එක.
- RollingFileAppender:
name="FileAppender"
: මේ Appender එකට දෙන නම.fileName="logs/application.log"
: මේ වෙලාවේ Active වෙලා තියෙන Log File එකේ නම.filePattern="logs/$${${date:yyyy-MM}}/application-%d{yyyy-MM-dd}-%i.log.gz"
: Rolled Over වුණාම Archive කරන Files වල Name Pattern එක.logs/$${${date:yyyy-MM}}/
: මේකෙන් කියන්නේlogs
ෆෝල්ඩර් එක ඇතුළේ, මාසය අනුව ෆෝල්ඩර් එකක් හදලා ඒක ඇතුළේ Files දානවා කියන එක. (e.g., `logs/2023-10/`)application-%d{yyyy-MM-dd}-%i.log.gz
: මේකෙන් කියන්නේ File Name එකට Date එකයි, Index එකයි (%i
- එක දවසට Files කිහිපයක් තිබ්බොත්), compressed format (.gz
) එකයි දානවා කියන එක.
<Policies>
: File Rolling Policies define කරනවා.<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
: දවසකට සැරයක් File එක Roll කරනවා.<SizeBasedTriggeringPolicy size="10MB"/>
: File එක 10MB වුණාම Roll කරනවා. මේ Policies දෙකම තිබ්බොත්, දෙකෙන් මොකක් හරි Condition එකක් fulfill වුණාම File එක Roll වෙනවා.
<DefaultRolloverStrategy max="20"/>
: මේකෙන් කියන්නේ අපි Archive කරලා තියෙන Files වලින් අන්තිම 20 විතරයි තියාගන්නේ, ඊට වඩා පරණ ඒවා Delete කරනවා කියන එක.
<Loggers>
Section එක
මේක ඇතුළේ තමයි අපේ Loggers define කරන්නේ. Logger එකක් කියන්නේ අපි Java Code එකේ පාවිච්චි කරන Logger
Instance එකට. මේවා Class Name එකට හෝ Package Name එකට අනුරූපව හැදෙනවා.
- Specific Logger:
<Logger name="com.example.myapp" level="DEBUG" additivity="false">
: මේකෙන් කියන්නේcom.example.myapp
Package එකේ නැත්නම් ඒකේ Sub-packages වල තියෙන හැම Class එකකම Logger වලට Debug Level එකෙන් පටන්ගෙන Logs ගන්න කියලා.additivity="false"
: මේක ගොඩක් වැදගත්. මේකtrue
වුණොත්, මේ Logger එකෙන් Record වෙන Logs Root Logger එකටත් යනවා. එතකොට එකම Log එක දෙපාරක් වැටෙන්න පුළුවන් (Root Logger එකත් මේ Appender එකම පාවිච්චි කරනවා නම්). ඒ නිසා අපි මේකfalse
කරනවා.<AppenderRef ref="ConsoleAppender"/>
සහ<AppenderRef ref="FileAppender"/>
: මේ Logger එකෙන් එන Logs මේ Appenders දෙකටම යවන්න කියලා මේකෙන් කියනවා.
- Root Logger:
<Root level="INFO">
: මේක තමයි Default Logger එක. අපි වෙන Logger එකක් define නොකරන හැම Class එකකම Logs මේ Root Logger එකට යනවා. අපි මේක INFO Level එකේ තියන්නේ, අනවශ්ය DEBUG/TRACE Logs Production එකේදී File එකට වැටෙන එක නවත්තන්න.- මේකත් අපේ ConsoleAppender සහ FileAppender දෙකටම Logs යවනවා.
දැන් ඔයාලට Configuration File එක ගැන හොඳටම තේරෙන්න ඇති කියලා හිතනවා. අපි ඊළඟට බලමු මේක Java Code එකෙන් පාවිච්චි කරන්නේ කොහොමද කියලා.
4. Java Code එකෙන් පාවිච්චි කරමු
අපි මේ configure කරපු Log4j2 Library එක අපේ Java Application එකට add කරගන්න ඕනේ. ඒකට Maven (Pom.xml) නැත්නම් Gradle එකට Dependencies add කරන්න පුම්ළුවන්. Maven නම් මෙහෙම add කරන්න:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
ඊට පස්සේ, අපේ Java Class එක ඇතුළේ Logger එකක් create කරලා Logs ලියන්න පුළුවන්. මෙන්න පොඩි Example එකක්:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyApplication {
// Logger instance for this class
private static final Logger logger = LogManager.getLogger(MyApplication.class);
// OR if you configured for a specific package, like "com.example.myapp"
// private static final Logger logger = LogManager.getLogger("com.example.myapp.MyApplication");
public static void main(String[] args) {
logger.trace("This is a TRACE message.");
logger.debug("This is a DEBUG message. Value of x: {}", 10);
logger.info("Application started successfully!");
try {
int result = 10 / 0; // This will cause an ArithmeticException
} catch (ArithmeticException e) {
logger.error("An error occurred during division.", e);
}
logger.warn("Configuration file not found, using default settings.");
logger.fatal("Critical error: Application is shutting down due to an unrecoverable error.");
}
}
මේ Code එක Run කරලා බලන්න, ඔයාලා configure කරපු විදියට Console එකටයි, Log File එකටයි Logs වැටෙනවාද කියලා. com.example.myapp
Package එක configure කරපු නිසා, ඒ Logger එකෙන් යන Logs වලට DEBUG Level එකෙන් පටන්ගෙන පේන්න ඕනේ. Root Logger එකෙන් යන ඒවාට INFO Level එකෙන් පටන්ගෙන පේන්න ඕනේ.
5. Practical Tips and Tricks
- Performance: Production Environments වලදී DEBUG සහ TRACE Level Logs Disable කරලා තියන්න. මේවා System Performance එකට ලොකු බලපෑමක් කරනවා.
- Asynchronous Logging: Log4j2 වල Asynchronous logging Use කරන්න. මේකෙන් Logs Write කරන එක Main Thread එකෙන් වෙන් කරනවා, ඒ නිසා Application එකේ Response Time එක වැඩි වෙන එක අඩු වෙනවා. මේක Default activate වෙන්නේ නෑ, Explicitly configure කරන්න ඕනේ. (උදා:
<AsyncRoot level="INFO">
) - Filtering: සමහර වෙලාවට අපිට Log Message එකක Content එක අනුව Filter කරන්න ඕනේ වෙනවා. ඒකට Filters පාවිච්චි කරන්න පුළුවන්. (උදා: BurstFilter, ThresholdFilter)
- External Configuration: Configuration File එක Jar එක ඇතුළේ තියන්නේ නැතුව, External File එකක් විදියට තියන්න පුළුවන්. ඒකෙන් Configuration Changes කරන්න Application එක Deploy කරන්නේ නැතුව පුළුවන් වෙනවා.
- Security: Sensitive Information (Passwords, PII data) Logs වලට වැටෙන එක නවත්තන්න. මේවා Log Masking වගේ Techniques වලින් කරන්න පුළුවන්.
අපි දැන් කොහොමද?
ඉතින් යාලුවනේ, අද අපි Log4j2 කියන්නේ මොකක්ද? ඒකේ Log Levels සහ Appenders ගැන වගේම, log4j2.xml
Configuration File එක හරියටම හදන්නේ කොහොමද කියලත් ඉගෙන ගත්තා. මේක ඔයාලගේ Software Development ගමනට ලොකු ශක්තියක් වෙයි කියලා මම විශ්වාස කරනවා.
මතක තියාගන්න, හොඳ Logging Practices කියන්නේ හොඳ Software Engineering වල ප්රධාන අංගයක්. ඒකෙන් ඔයාලගේ Application එක maintain කරන්න, troubleshoot කරන්න ලොකු පහසුවක් ලැබෙනවා.
මේ ගැන ඔයාලගේ අදහස්, ප්රශ්න පහළින් Comment කරන්න. ඔයාලත් මේ Log4j2 Configuration එක හදලා බලන්න, ඒකෙන් ලැබෙන අත්දැකීම් Share කරන්න. තවත් මෙවැනිම වැදගත් Technical Post එකකින් හමුවෙමු! හැමෝටම ජය!