From 20a6846755696bfd73a4312e3008edb1b8e27252 Mon Sep 17 00:00:00 2001 From: Arunan Sugunakumar Date: Tue, 11 Jun 2024 16:28:49 +0530 Subject: [PATCH] Disable default access logger and utilize log4j2 for http access logs Related to https://github.com/wso2/micro-integrator/issues/3281 Currently, HTTP Access logs use a custom implementation to write the logs to the file. This has a request and response queue to hold the logs and write them to the file using a Timer task. In a high-traffic scenario, this becomes a bottleneck because the Heap memory easily fills up because of the logs added to the queuea. This commit disables the current implementation and utilizes log4j2 to write the access logs to the file system which is more efficient. Also, timer tasks are removed and LinkedBlockingQueue is used to handle logs asynchronously in a timely manner. --- .../synapse/transport/http/access/Access.java | 56 ++++++++++--------- .../transport/http/access/AccessLogger.java | 2 +- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/Access.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/Access.java index cf277f5d4a..4eeed48b3a 100644 --- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/Access.java +++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/Access.java @@ -25,6 +25,7 @@ import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.params.HttpParams; +import org.apache.synapse.transport.http.conn.LoggingUtils; import org.apache.synapse.transport.http.wrapper.HttpRequestWrapper; import org.apache.synapse.transport.http.wrapper.HttpResponseWrapper; @@ -32,9 +33,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; /** * The class to handle the HTTP Access Logs, patterns and the major functionality. @@ -43,6 +42,7 @@ */ public class Access { private static Log log = LogFactory.getLog(Access.class); + private final Log accesslog = LogFactory.getLog(LoggingUtils.ACCESS_LOG_ID); /** * Array of AccessLogElement, they will be used to make log message. @@ -53,10 +53,8 @@ public class Access { private static AccessLogger accessLogger; - private static ConcurrentLinkedQueue requestQueue; - private static ConcurrentLinkedQueue responseQueue; - - private static final int LOG_FREQUENCY_IN_SECONDS = 30; + private static LinkedBlockingQueue requestQueue; + private static LinkedBlockingQueue responseQueue; private Date date; @@ -70,8 +68,8 @@ public Access(final Log log, AccessLogger accessLogger) { super(); Access.log = log; Access.accessLogger = accessLogger; - requestQueue = new ConcurrentLinkedQueue(); - responseQueue = new ConcurrentLinkedQueue(); + requestQueue = new LinkedBlockingQueue(); + responseQueue = new LinkedBlockingQueue(); logElements = createLogElements(); logAccesses(); } @@ -104,30 +102,36 @@ public void addAccessToQueue(HttpResponse response) { * logs the request and response accesses. */ public void logAccesses() { - TimerTask logRequests = new LogRequests(); - TimerTask logResponses = new LogResponses(); - Timer requestTimer = new Timer(); - Timer responseTimer = new Timer(); - // Retry in 30 seconds - long retryIn = 1000 * LOG_FREQUENCY_IN_SECONDS; - requestTimer.schedule(logRequests, 0, retryIn); - responseTimer.schedule(logResponses, 0, retryIn); + Thread logRequests = new LogRequests(); + Thread logResponses = new LogResponses(); + logRequests.start(); + logResponses.start(); } - private class LogRequests extends TimerTask { + private class LogRequests extends Thread { public void run() { - while (!requestQueue.isEmpty()) { - HttpRequestWrapper req = requestQueue.poll(); - log(req, null); + while (true) { + HttpRequestWrapper req = null; + try { + req = requestQueue.take(); + log(req, null); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } } - private class LogResponses extends TimerTask { + private class LogResponses extends Thread { public void run() { - while (!responseQueue.isEmpty()) { - HttpResponseWrapper res = responseQueue.poll(); - log(null, res); + while (true) { + HttpResponseWrapper res = null; + try { + res = responseQueue.take(); + log(null, res); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } } @@ -874,7 +878,7 @@ public void log(HttpRequestWrapper request, HttpResponseWrapper response) { } } String logString = result.toString(); - log.debug(logString); //log to the console + accesslog.info(logString); //log to the console if (accessLogger.isLoggingEnabled) { accessLogger.log(logString); //log to the file } diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/AccessLogger.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/AccessLogger.java index 46d525d9bb..e2304c707a 100644 --- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/AccessLogger.java +++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/http/access/AccessLogger.java @@ -121,7 +121,7 @@ public AccessLogger(final Log log) { /** * Enable logging. */ - public boolean isLoggingEnabled = getBooleanValue(CONFIG_ENABLE_LOGGING, true); + public boolean isLoggingEnabled = getBooleanValue(CONFIG_ENABLE_LOGGING, false); /** * Log the specified message to the log file, switching files if the date