Spring Boot Logging: SLF4J/Logback Sinhala Guide

Spring Boot Logging: SLF4J/Logback Sinhala Guide

කොහොමද යාලුවනේ! Spring Boot Logging ගැන සරලව ඉගෙන ගමු

අද අපි කතා කරන්න යන්නේ Spring Boot applications වලදී නැතුවම බැරි topic එකක් ගැන. ඒ තමයි Logging. අපි application එකක් develop කරද්දි, ඒක වැඩ කරන විදිය, error එනවද, user requests handle කරන විදිය වගේ දේවල් දැනගන්න logging කියන එක ගොඩක් වැදගත්. ගොඩක් අය මුලින්ම පටන් ගනිද්දි `System.out.println()` පාවිච්චි කරනවා data print කරන්න. ඒත් production environment එකකදී ඒක නියම විසඳුමක් නෙවෙයි. එතකොට තමයි අපිට SLF4J/Logback වගේ powerful logging frameworks ඕන වෙන්නේ.

මේ guide එකෙන් අපි බලමු Spring Boot එකේදී SLF4J සහ Logback පාවිච්චි කරලා logging configure කරගන්නෙ කොහොමද, custom log messages add කරන්නෙ කොහොමද, ඒ වගේම පොඩි exercise එකකුත් කරමු.

1. මොකක්ද මේ Logging කියන්නේ?

සරලවම කිව්වොත්, Logging කියන්නේ software application එකක් run වෙද්දි ඒක ඇතුලේ සිද්ධවෙන සිදුවීම් (events) record කරන process එකට. මේවා text files වලට, database වලට, console එකට වගේ විවිධ තැන් වලට export කරන්න පුළුවන්. මේ log records අපිට ගොඩක් ප්‍රයෝජනවත් වෙනවා:

  • Troubleshooting සහ Debugging: Application එකේ bug එකක් ආවොත්, log files බලලා ඒක සිද්ධ වෙච්ච විදිය, මොන line එකේදීද error එක ආවේ වගේ දේවල් හොයාගන්න පුදූම විදියට උදව් වෙනවා.
  • Monitoring: Application එකේ performance එක, user behavior, system health වගේ දේවල් monitor කරන්න පුළුවන්.
  • Auditing: Security-sensitive applications වලදී, යම් යම් actions කවුද, කවදද කළේ කියලා record කරන්න logging පාවිච්චි කරනවා.
  • Understanding Application Flow: Application එකේ flow එක හරියටම සිද්ධ වෙනවද කියලා බලාගන්නත් logging උදව් වෙනවා.

Spring Boot වලදී SLF4J (Simple Logging Facade for Java) කියන abstraction layer එක තමයි default විදියට පාවිච්චි වෙන්නේ. ඒක ඇතුලෙන් Logback කියන logging implementation එක තමයි යූස් වෙන්නේ. මේකේ වාසිය තමයි අපිට කැමති logging implementation එකක් (Logback, Log4j2 වගේ) පාවිච්චි කරන්න පුළුවන් SLF4J API එක වෙනස් නොකර.

2. Spring Boot වල Logging Settings

Spring Boot projects එකක් හදද්දි default විදියට Logback dependency එක add වෙනවා. ඒ නිසා අපිට වෙනම dependency add කරන්න ඕනේ නැහැ. Spring Boot automatically configure කරන නිසා අපිට කරන්න තියෙන්නේ පොඩි configuration changes විතරයි.

2.1 Default Console Logging

ඔබ Spring Boot application එකක් run කරපු ගමන්ම console එකේ log messages පෙන්වනවා නේද? ඒක default Logback configuration එක නිසා. මේවාට ගොඩක් වෙලාවට INFO level එකේ messages තමයි අඩංගු වෙන්නේ.

2.2 `application.properties` වලින් Configure කරමු

අපිට `src/main/resources/application.properties` file එකේ logging levels සහ file output වගේ දේවල් configure කරන්න පුළුවන්.

Log Level වෙනස් කිරීම:

Log levels කියන්නේ log message එකක වැදගත්කම. ප්‍රධාන වශයෙන් මේ levels තියෙනවා:

  • TRACE: සියල්ලටම වඩා විස්තරාත්මක logs (development වලදී ගොඩක් පාවිච්චි වෙනවා)
  • DEBUG: Debugging වලදී ප්‍රයෝජනවත් වෙන විස්තරාත්මක logs.
  • INFO: Application එකේ සාමාන්‍ය flow එක පෙන්වන logs (production වලදී සාමාන්‍යයෙන් පාවිච්චි වෙනවා).
  • WARN: යම්කිසි අවදානම් තත්වයක් හෝ ගැටලුවක්, නමුත් application එකේ ක්‍රියාකාරීත්වයට බාධාවක් නැති අවස්ථා.
  • ERROR: Serious errors, application එකේ කොටසක් වැරදියට ක්‍රියා කරන අවස්ථා.
  • FATAL: Application එක සම්පූර්ණයෙන්ම crash වෙනවා වගේ ඉතා දරුණු errors.

අපිට package එකකට හෝ class එකකට වෙන් වෙන් වශයෙන් log levels define කරන්න පුළුවන්:


# Global logging level to INFO
logging.level.root=INFO

# Set logging level for a specific package to DEBUG
logging.level.com.example.myproject=DEBUG

# Set logging level for a specific class to TRACE
logging.level.com.example.myproject.MyService=TRACE

Log File එකකට ලිවීම:

Console එකට විතරක් නෙවෙයි, log messages file එකකට ලියන්නත් පුළුවන්. ඒකට `logging.file.name` හෝ `logging.file.path` පාවිච්චි කරන්න පුළුවන්.


# Logs will be written to a file named 'my-app.log' in the default log directory
logging.file.name=my-app.log

# Or specify a full path and file name
# logging.file.path=/var/log/my-app/
# logging.file.name=/var/log/my-app/application.log

# Maximum file size for log files before rolling (e.g., 10MB)
logging.file.max-size=10MB

# Maximum number of archived log files to keep
logging.file.max-history=7

3. SLF4J/Logback වලින් Custom Log Messages

දැන් අපි බලමු අපේ application code එක ඇතුලෙන් custom log messages print කරගන්නේ කොහොමද කියලා. මේක හරිම ලේසියි.

Logger instance එකක් ලබා ගැනීම

ඕනෑම Class එකක් ඇතුලට `Logger` instance එකක් inject කරගන්න පුළුවන්. මේකට SLF4J API එකේ `LoggerFactory` class එක පාවිච්චි කරනවා.


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    // Get a Logger instance for this class
    private static final Logger logger = LoggerFactory.getLogger(MyService.class);

    public void performTask(String taskName) {
        logger.info("Starting task: {}", taskName);
        try {
            // Simulate some work
            Thread.sleep(100);
            logger.debug("Task '{}' is processing...", taskName);

            if (taskName.contains("error")) {
                throw new RuntimeException("Simulated error during task: " + taskName);
            }

            logger.info("Task '{}' completed successfully.", taskName);

        } catch (InterruptedException e) {
            logger.warn("Task '{}' was interrupted.", taskName);
            Thread.currentThread().interrupt();
        } catch (RuntimeException e) {
            logger.error("Error performing task '{}': {}", taskName, e.getMessage(), e);
            // It's good practice to log the exception object itself for stack trace
        }
    }

    public void doSomethingElse() {
        logger.trace("Entering doSomethingElse method.");
        // More code
        logger.debug("Debug info inside doSomethingElse.");
    }
}

මේ example එකේදී අපි `logger.info()`, `logger.debug()`, `logger.warn()`, `logger.error()`, `logger.trace()` කියන methods පාවිච්චි කරලා විවිධ levels වල log messages add කරලා තියෙනවා.

  • {} (placeholders) පාවිච්චි කිරීම ගොඩක් වැදගත්. මේකෙන් String concatenation වලට වඩා performance වැඩි වෙනවා. මොකද message එක format වෙන්නේ ඒ log level එක active නම් විතරයි.
  • `logger.error()` වගේ methods වලට exception object එක දෙන්න පුළුවන්. ඒකෙන් stack trace එකත් log එකට add වෙනවා. ඒක troubleshooting වලදී අත්‍යවශ්‍යයි.

4. Logback Custom Configuration (`logback-spring.xml`)

`application.properties` වලින් කරන්න බැරි advanced logging configurations වලට අපිට `src/main/resources/logback-spring.xml` කියන file එක පාවිච්චි කරන්න පුළුවන්. මේකෙන් අපිට custom appenders (console, file, database, remote server වගේ), log patterns, log rolling policies වගේ දේවල් define කරන්න පුළුවන්.

මෙන්න සරල `logback-spring.xml` file එකක උදාහරණයක්:


<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!-- Include Spring Boot's default logging configuration -->
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <!-- Define a custom File Appender -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- Directory and file name -->
        <file>./logs/my-custom-app.log</file>

        <!-- Rolling policy: archive daily and keep a maximum of 7 days -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>./logs/my-custom-app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>7</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
            <!-- For example, 10MB per file before index rollover -->
            <!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy> -->
        </rollingPolicy>

        <!-- Log message pattern -->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- Root logger configuration -->
    <root level="INFO">
        <!-- Add the FILE appender to the root logger -->
        <appender-ref ref="FILE"/>
        <!-- Also keep the default CONSOLE appender -->
        <appender-ref ref="CONSOLE"/>
    </root>

    <!-- Specific logger for a package with a different level -->
    <logger name="com.example.myproject" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </logger>

</configuration>

මේ XML file එකෙන් අපිට පුළුවන් daily log files generate වෙන්න, ඒ වගේම යම්කිසි size එකකට reach වුනාම අලුත් file එකකට ලියවෙන්න (rolling), පැරණි files ටිකක් archive කරලා තියාගන්න (maxHistory) වගේ advanced දේවල් කරන්න. `encoder` එකෙන් log message එකේ format එක define කරන්න පුළුවන්.

Exercise: ඔබේ Spring Boot App එකට Custom Log Messages Add කරන්න

දැන් ඔයාගේ අතේ තියෙන Spring Boot project එකක් open කරගන්න. නැත්නම් අලුත් එකක් හදාගන්න. ඊට පස්සේ මේ පියවර ටික follow කරන්න:

  1. application.properties file එකට ගිහින් `logging.level.root=INFO` කියලා දාන්න.
  2. ඔබේ project එකේ Controller හෝ Service class එකක් තෝරාගන්න.
  3. දැන් Methods ඇතුලේ විවිධ අවස්ථා වලදී `logger.info()`, `logger.debug()`, `logger.warn()`, `logger.error()` වගේ methods පාවිච්චි කරලා custom log messages add කරන්න. විශේෂයෙන්, යම්කිසි process එකක ආරම්භය, අවසානය, critical data manipulation වගේ තැන් වලට `INFO` logs දාන්න. Error situation එකකදී `ERROR` log එකක් සහ exception object එකත් එක්ක log කරන්න.
  4. Application එක run කරලා console එකේ log messages බලන්න.
  5. application.properties එකේ `logging.level.com.example.yourpackage=DEBUG` කියලා දාලා, ඔබේ package එකේ log level එක DEBUG වලට වෙනස් කරලා ආයෙත් run කරලා බලන්න. දැන් DEBUG messages පේනවද?
  6. Optional: logback-spring.xml file එකක් හදලා custom file appender එකක් add කරලා, logs files වලට ලියවෙනවද කියලා බලන්න.

ඒ class එක ඇතුලට `Logger` instance එක add කරගන්න:

private static final Logger logger = LoggerFactory.getLogger(YourClassName.class);

අවසාන වශයෙන්

Spring Boot වල Logging කියන්නේ application development වලදී නැතුවම බැරි දෙයක්. හරියට configure කරගත්තොත් අපිට debugging, monitoring, සහ production support කියන හැම දේටම ලොකු උදව්වක් වෙනවා. SLF4J/Logback combination එක powerful වගේම customize කරන්නත් ලේසියි.

මතක තියාගන්න, `System.out.println()` අමතක කරලා, හැම වෙලේම logging framework එකක් පාවිච්චි කරන්න පුරුදු වෙන්න. Production applications වලදී මේකෙන් ගොඩක් වාසි ගන්න පුළුවන්.

මේ article එක ගැන අදහස්, ප්‍රශ්න තියෙනවා නම් පහළින් comment එකක් දාන්න. ඔයාලට මේක ප්‍රයෝජනවත් වුණාද කියලා දැනගන්න මම ආසයි! ඊළඟ article එකෙන් හම්බවෙමු! තෙරුවන් සරණයි!