Installing a Log Appender in EzyPlatform
Updated at 1774881591000In EzyPlatform, Logback remains the core logging system, while the platform adds a small extension layer so you can plug in your own Java-based appenders. The nice part of this approach is that you do not need to replace the whole
logback.xml; you only need to add EzyPlatform’s composite appender and register your custom appender in application code.This article briefly explains how Logback works in EzyPlatform, then walks through how to implement a custom
LogbackAppender.How Logback Works in EzyPlatform
From the current source code, EzyPlatform uses Logback in the following way:
- The
root loggerstill handles logs as usual. - In
logback.xml, besides standard appenders such asconsoleorfile, EzyPlatform adds one more appender namedcomposite. - The
compositeappender points toorg.youngmonkeys.ezyplatform.logback.CompositeLogbackAppender. - Whenever Logback produces an
ILoggingEvent, thecompositeappender forwards that event to all Java appenders registered inLogbackAppenderManager.
The runtime flow looks like this:
Logger -> Root Logger -> console / file / composite
|
v
CompositeLogbackAppender
|
v
LogbackAppenderManager
|
+--------------+--------------+
| |
v v
CustomAppenderA CustomAppenderB
In short, EzyPlatform does not replace Logback. It adds one extra distribution layer so your application can process log events in Java code.
The Three Important Classes
There are three main classes in EzyPlatform’s common SDK:
LogbackAppender- This is the base class for custom appenders.
- It extends
AppenderBase<ILoggingEvent>. - Its constructor sets
started = true, so the appender is considered ready to receive log events immediately after instantiation. - You only need to override
append(ILoggingEvent event).
CompositeLogbackAppender
- This is the appender declared in
logback.xml. - Its job is to receive each
ILoggingEventfrom Logback and dispatch it to all appenders registered in the manager.
LogbackAppenderManager
- This is the registry that holds custom appenders.
- It uses a
ConcurrentHashMap, so basic concurrent access is safe. - Appenders are stored by
Class<?>, which means only one instance per appender type is registered. - If you call
addAppendermultiple times with the same class, the manager keeps the first one.
This is an important detail: based on the current source code, EzyPlatform does not automatically scan and register
LogbackAppender implementations. If you want your appender to run, you must register it explicitly.
What Your Custom Appender Needs to Work
For a custom
LogbackAppender to actually receive log events, two conditions must be met:-
logback.xmlmust includeCompositeLogbackAppenderin the root logger. - Your custom appender must be added to
LogbackAppenderManager.
If either step is missing, your appender will never be called.
Configuring logback.xml
In EzyPlatform’s deployment configuration, the essential part looks like this:
<appender name="composite" class="org.youngmonkeys.ezyplatform.logback.CompositeLogbackAppender" /> <root level="info"> <appender-ref ref="console"/> <appender-ref ref="file"/> <appender-ref ref="composite"/> </root>
If your system does not yet have the
composite appender, add it to the root logger.Creating a LogbackAppender
A simple example is an appender that sends only critical errors to a separate channel:
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import org.youngmonkeys.ezyplatform.logback.LogbackAppender; public class ErrorNotifyLogbackAppender extends LogbackAppender { @Override protected void append(ILoggingEvent event) { if (!Level.ERROR.equals(event.getLevel())) { return; } String loggerName = event.getLoggerName(); String message = event.getFormattedMessage(); String threadName = event.getThreadName(); // Example: send to Slack, Telegram, webhook, queue, etc. System.out.println( "[ERROR-NOTIFY] [" + threadName + "] " + loggerName + " - " + message ); } }
Here, you receive the full
ILoggingEvent, so you can access:- log level
- logger name
- thread name
- formatted message
- exception
- timestamp
- MDC values if present
For example, to extract exception details:
if (event.getThrowableProxy() != null) {
String exceptionClass = event.getThrowableProxy().getClassName();
String exceptionMessage = event.getThrowableProxy().getMessage();
}
Registering the Appender in EzyPlatform
Because the current source code does not show any built-in auto-registration mechanism, the safest approach is to register the appender manually in a singleton that runs during application startup.
An EzyPlatform-style example:
import com.tvd12.ezyfox.bean.annotation.EzyPostInit; import com.tvd12.ezyfox.bean.annotation.EzySingleton; import lombok.AllArgsConstructor; import org.youngmonkeys.ezyplatform.logback.LogbackAppenderManager; @EzySingleton @AllArgsConstructor public class LogbackAppenderBootstrap { private final ErrorNotifyLogbackAppender errorNotifyLogbackAppender; @EzyPostInit public void postInit() { LogbackAppenderManager .getInstance() .addAppender(errorNotifyLogbackAppender); } }
Your appender should also be declared as a bean/singleton so it can be injected:
import com.tvd12.ezyfox.bean.annotation.EzySingleton; @EzySingleton public class ErrorNotifyLogbackAppender extends LogbackAppender { @Override protected void append(ILoggingEvent event) { // handle the log event here } }
Once the application starts:
- Logback sends events to
CompositeLogbackAppender -
CompositeLogbackAppendercallsLogbackAppenderManager - the manager invokes
ErrorNotifyLogbackAppender - your appender receives the log event
When This Mechanism Is Useful
This approach works well for use cases such as:
- sending error logs to a webhook or chat system
- counting logs by level
- extracting specific log groups and forwarding them elsewhere
- adding alerting logic without heavily modifying
logback.xml
It is especially useful when you want the logic in Java instead of trying to force everything into Logback XML configuration.
Important Notes
append(...) runs on the logging thread-
CompositeLogbackAppenderis attached directly to the root logger. - That means your custom appender usually runs on the same thread that produced the log event.
- If you make HTTP calls, write to a database, or do heavy processing there, the current request may slow down.
Avoid logging too much from inside the appender itself
- If
append(...)writes logs back into the same logging system, you can easily create a recursive logging loop. - It is better to keep internal logging minimal or add loop protection.
Each appender class is registered only once
-
LogbackAppenderManagerusesputIfAbsent. - This prevents duplicate registration, but it also means that if you want to replace an instance at runtime, you need to design for that explicitly.
Custom appenders do not replace standard appenders
-
consoleandfileappenders continue to work independently. -
compositeis only an additional branch that allows EzyPlatform to dispatch log events to custom Java appenders.
Quick Installation Steps
- Create a class that extends
LogbackAppender. - Override
append(ILoggingEvent event). - Declare the class as a singleton bean in your application.
- In a startup bean, call
LogbackAppenderManager.getInstance().addAppender(...). - Make sure
logback.xmlincludesCompositeLogbackAppenderin the root logger.
Conclusion
In EzyPlatform, the custom Logback mechanism is intentionally simple: Logback stays as the core engine, while
CompositeLogbackAppender acts as the bridge between Logback and application-defined Java appenders. To install a LogbackAppender, you only need to remember two things: add composite to logback.xml, and register your appender in LogbackAppenderManager.