I am planning to migrate a previously created Java web application to Azure. The application previously used log4j
for application level logs that where saved in a locally created file. The problem is that with the Azure Role having multiple instances I must collect and aggregate these logs and also make sure that they are stored in a persistent storage instead of the virtual machines hard drive.
Logging is a critical component of the application but it must not slow down the actual work. I have considered multiple options and I am curious about the best practice, the best solution considering security, log consistency and performance in both storage-time and by later processing. Here is a list of the options:
Appender
to store information in Azure SQL.Appender
to store information in Azure Tables storage.Is there any other method or are there any complete solutions for this problem for Java? Which of the above would be best considering the above mentioned criteria?
Finally I decided to write a Log4J Appender
. I didn't need to gather diagnostics information, my main goal was only to gather the log files in an easily exchangeable way. My first fear was that it would slow down the application, but with by writing only to memory and only periodically writing out the log data to Azure tables it works perfectly without making too many API calls.
Here are the main steps for my implementation:
First I created an entity class to be stored in Azure Tables, called LogEntity
that extends com.microsoft.windowsazure.services.table.client.TableServiceEntity
.
Next I wrote the appender that extends org.apache.log4j.AppenderSkeleton
containing a java.util.List<LogEntity>
.
From the overrided method protected void append(LoggingEvent event)
I only added to this collection and then created a thread that periodically empties this list and writes the data to Azure tables.
Finally I added the newly created Appender
to my log4j configuration file.