Skip to content

Instrumenting Servlets

Karsten Schnitter edited this page Jul 2, 2018 · 12 revisions

Introduction

Servlet instrumentation is implemented as a standard servlet filter as defined in the Java Servlet Specification, Version 3.0 .

Enabling the Feature

Maven Dependency

In order to make this feature available in your application, you need to add the corresponding library to your Maven dependencies in your application's pom.xml like this, assuming that you've also defined a property cf-logging-version that refers to the latest version of this feature:

<!-- We're using the Servlet Filter instrumentation -->
<dependency>
   <groupId>com.sap.hcp.cf.logging</groupId>
   <artifactId>cf-java-logging-support-servlet</artifactId>
   <version>${cf-logging-version}</version>
</dependency>

Registering the Servlet Filter

The servlet filter is enabled by registering com.sap.hcp.cf.logging.servlet.filter.RequestLoggingFilter as filter in a servlet context. It should be registered for the dispatch type request to function properly. See the examples below for more details.

Using web.xml

The easiest way to enable that servlet filter is to declare it in your application's web.xml file. To do so, add the following lines to that file, as we've done in the sample application:

<filter-name>request-logging</filter-name>
   <filter-class>com.sap.hcp.cf.logging.servlet.filter.RequestLoggingFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>request-logging</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

FilterRegistrationBean in Spring (Boot)

You can use FilterRegistrationBean to enable the servlet filter in Spring Boot. Add the following bean to your @Configuration file:

@Bean
public FilterRegistrationBean loggingFilter() {
	FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
	filterRegistrationBean.setFilter(new RequestLoggingFilter());
	filterRegistrationBean.setName("request-logging");
	filterRegistrationBean.addUrlPatterns("/*");
	filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
	return filterRegistrationBean;
}

Support for Asynchronous Requests

The Java Servlet API 3.0 introduced asynchronous request handling. This feature is supported by cf-java-logging-support from version 2.2.0.

The main distinction of asynchronous request handling is, that requests are no longer handled by the same Java thread in which was assigned on request dispatch. Logging usually leverages a context (MDC) bound to the current thread to manage metadata. cf-java-logging-support uses the MDC for request tracking such as request id and further CF metadata. When changing threads this context may be lost. Our current implementation ensures that the context is properly migrated within the threads of the servlet container.

To enable custom thread models or asynchronous execution the servlet filter will add the MDC context map as a request attribute with the key org.slf4j.MDC. If necessary you can set the MDC in any custom thread by calling

MDC.setContextMap(httpRequest.getAttribute(MDC.class.getName()));

Note: This is only necessary when you create own threads, e.g. using custom Executors. One such case would be the @Async support in Spring.

Clone this wiki locally