My organization is migrating from Log4j1 to Log4j2. We have a custom rolling file appender that changes the filename that it logs to at runtime when a certain event occurs in the application. This is implemented so that it's easy to find the log file in the log directory. For example the log file directory might look like this;
mylog-2021-08-02.log
mylog-2021-08-03.log
SPECIAL_EVENT_mylog-2021-08-03.log
mylog-2021-08-04.log
mylog-2021-08-05.log
Based on the research I've done it appears that Appender filenames are immutable and I'd have to create a new Appender and add it to the configuration when the event occurs, then when the triggering policy is signaled remove this Appender and add back a new Appender for the original configuration? Is there a more elegant solution than this? Do I need to write a custom appender and handle the file naming/rollover logic myself?
Update 9/2/2021
Thanks for the answer @D.B. this helped me learn quite a bit about Log4j2. The question that you reference is very similar to my situation. We have many devices, and each device needs to log to its own file. I do have some additional requirements though. We have many threads in each device which need to log to the same device log file and many devices that each need their own log file. Additionally, I need to handle the special rollover file naming requirement (original post) when a particular event occurs in the device. Finally, the name assigned to each device is not known until runtime (its defined in another configuration file we have). I could use markers, like you suggest, but this can quickly become difficult to maintain since developers would need to know they have to pass a marker with every logging statement and the entire existing code base would need to be updated to pass the appropriate marker. I also could use a context map as you suggest but the application has many threads and again developers would need to know they have to set the context data appropriately before logging from any thread.
With Log4j1 these requirements were met by:
- A custom appender class derived from RollingFileAppender that handled the special event file naming rollover logic.
- A custom filter that accepted events that met the following criteria: a. The thread name the event came from included “device name” of the device b. The event message included “device name”
- When a new device is instantiated in the system: a. A new custom filter is created with the “device name” string to filter on. b. A new custom appender is created that logs to a file named “device name”.log. This appender is created with the custom filter. c. The appender is added as reference to the Root logger
- This results in all log events being sent to the new appender (and every other device appender that is created) but the log events are filter based on the “device name”. This results in a device specific log file.
I could implement a custom filter and appender like we did with Log4j1 but I’d prefer not to be dependent upon the logging core classes. Any additional recommendations you have would be greatly appreciated.