How to get responseBody string for logging purpose in HttpSupportFilter?
Common log solution is create wrapper and insert it to the standar filter
If we use standar filter we cannot access activejdbc db connection layer
I tried to apply wrapper but it does not work, the string is still empty
public class HTTPLogFilter extends HttpSupportFilter {
private static ThreadLocal<Long> start = new ThreadLocal<>();
@Override
public void before() {
start.set(System.currentTimeMillis());
}
@Override
public void after() {
if(Configuration.HTTPLOGS_ENABLE) {
Registry.instance().getStatisticsQueue().enqueue(
new QueryExecutionEvent(getRoute().getController().getClass().getName() +
"#" + getRoute().getActionName() + ":" + method(), System.currentTimeMillis() - start.get()));
HttpLog httpLog = new HttpLog();
String username ="TEST";
Map request = new HashMap<String, Object>();
request.put("requestUrl", url());
request.put("contextPath", context());
request.put("uriFullPath", uri());
request.put("uriPath", path());
request.put("method", method());
request.put("requestHeaders", headers());
request.put("requestParams", params());
request.put("queryString", queryString());
request.put("requestBody", getRequestString());
Map response = new HashMap<String, Object>();
response.put("responseHeaders", getResponseHeaders());
try {
// BUG ! this responseBody still empty
response.put("responseBody", getHttpServletResponse().getWriter().toString());
} catch (IOException e) {
e.printStackTrace();
}
httpLog.setCreatedby(username);
httpLog.setCreateddt(new Date());
httpLog.setUsername(username);
String remoteAddr = ipForwardedFor() != null ? ipForwardedFor() : remoteAddress();
httpLog.setIpaddress(remoteAddr );
httpLog.setUseragent(userAgent());
httpLog.setControllername(getRoute().getController().getClass().getName() + "." + getRoute().getActionName());
httpLog.setHttpmethod(method());
httpLog.setHttpexceptions("");
httpLog.setExecutiondt(new Date(start.get()));
httpLog.setExecutiondur(System.currentTimeMillis() - start.get());
httpLog.setHttpurl(url());
httpLog.setHttprequest(JsonHelper.toJson(request));
httpLog.setHttpresponse(JsonHelper.toJson(response));
httpLog.setHttpstatuscode(getHttpServletResponse().getStatus());
httpLog.saveIt();
}
}
}
generally, you are on the right path. It is my understanding that HttpLog
is a model, and you want to store the request values that to database, correct?
You write:
if we use standar filter we cannot access activejdbc db connection layer
So, the ActiveWeb filters have ordering, which is documented here: https://javalite.io/controller_filters#filter-ordering
This means that if you want a database connection available in the HTTPLogFilter
, you have to register the DBConnectionFilter
before the HTTPLogFilter
, example:
public class AppControllerConfig extends AbstractControllerConfig {
public void init(AppContext appContext) {
add(new DBConnectionFilter(), new HTTPLogFilter());
}
}
This way, the DBConnectionFilter.before()
will be called before the HTTPLogFilter.before()
and will open a DB connection accordingly.
On the side note: you will be filling your database pretty quickly, and a recommendation is to simply log all this data to a log file and use a log analyzer like Splunk or Graylog.