DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

  1. DZone
  2. Coding
  3. Frameworks
  4. Request Tracing Using Nginx and Spring Boot

Request Tracing Using Nginx and Spring Boot

Learn the simplest method for tracing dynamic content requests in an Nginx and Spring Boot-based application.

By 
Kuldeep Singh user avatar
Kuldeep Singh
·
Oct. 02, 18 · Tutorial
Likes (7)
Comment (2)

Save
Tweet
Share
22.18K Views

Join the DZone community and get the full member experience.

Join For Free

Most web applications are hosted behind a load balancer or web-server such as Nginx/HTTPD, which intercepts all the requests and directs dynamic content requests to the application server, such as Tomcat. Correlating requests traversing from the front-end server to the backend servers are general requirements. In this post, we will discuss tracing the request in the simplest way in an Nginx and Spring Boot-based application without using an external heavyweight library like Slueth.

Assign an Identifier to Each Request Coming Into Nginx

Nginx keeps request identifier for HTTP request in a variable $request_id, which is a 32 haxadecimal characters string. $request_idcan be passed to further downstream with request headers. Following configuration passes the $request_id as X-Request-ID HTTP request header to the application server.

1
server {
2
    listen 80;
3
    location / {
4
        proxy_pass http://apiserver;
5
        proxy_set_header X-Request-ID $request_id;
6
    }
7
}

Log the Request Identifier in Front-end Access Logs

Include the $request_id in the log format of the Nginx configuration file as follows.

​x
1
log_format req_id_log '$remote_addr - $remote_user [$time_local] $request_id "$request" '
2
                 '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
3
                 '"$http_x_forwarded_for"';
4
​
5
access_log  /dev/stdout req_id_log;

It will print the access logs in the following format:

1
1
172.13.0.1 - - [28/Sep/2018:05:28:26 +0000] 7f75b81cec7ae4a1d70411fefe5a6ace "GET /v0/status HTTP/1.1" 200 184 "http://localhost:80/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" "-"


Intercept the HTTP Request on the Application Server

Every HTTP request coming into the application server will now have the header X-Request-ID, which can be intercepted either in the interceptor or servlet filter. From there, it can be logged along with every log we print in the logs, as follows.

Define a Request Filter Using MDC

Define the following request filter, which reads the request header and puts it in the MDC (read about MDC here). It basically keeps the values in the thread local.

20
1
...
2
​
3
@Component
4
public class RegLogger implements Filter {
5
​
6
  @Override
7
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
8
        try {
9
            MDC.put("X-Request-ID", ((HttpServletRequest)servletRequest).getHeader("X-Request-ID"));
10
            filterChain.doFilter(servletRequest, servletResponse);
11
        } finally {
12
            MDC.clear();
13
        }
14
    }
15
​
16
  @Override
17
  public void init(FilterConfig filterConfig) throws ServletException {}
18
  @Override
19
  public void destroy() {}
20
}

Configure the Logger to Print the Request id

I have used logback, which can read MDC variables in the %X{variable_name} pattern. Update the logback pattern as follows:

11
1
<?xml version="1.0" encoding="UTF-8"?>
2
<configuration>    
3
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">        
4
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
5
      <Pattern>%d{HH:mm:ss.SSS} [%thread] %X{X-Request-ID} %-5level %logger{36} - %msg%n</Pattern>
6
    </encoder>    
7
  </appender>    
8
  <root level="info">        
9
    <appender-ref ref="STDOUT" />    
10
  </root>
11
</configuration>

It will print the following logs:

1
1
17:28:26.011 [http-nio-8090-exec-7] 7f75b81cec7ae4a1d70411fefe5a6ace INFO c.d.e.controllers.StatusController - received request

This way, you can see the request id in all the logs from the origin to the end. We can configure ELK to aggregate the logs and trace them in a nice user interface to help with troubleshooting.

Get the Generated Request id Back in the Response

Nginx can also add the request id in the response header with the following configuration:

5
1
server {
2
    listen 80;
3
    add_header X-Request-ID $request_id; # add to response header
4
​
5
    ....

As you see here:

Image title

Conclusion

We have explained a simple way to assign a unique identifier to each request, then trace the request end-to-end. You can get more details here.

Requests Spring Framework Spring Boot application

Opinions expressed by DZone contributors are their own.

Partner Resources

×

    Performance Spotlight October 12, 2018

  • Request Tracing Using Nginx and Spring Boot

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!