简体   繁体   中英

How to follow a request in the logs when using Restlet?

What is the best way of tracking a specific request in a log file of a Restlet servlet?

If there are multiple requests at the same time, I would like to be able to follow a single request in the logfile.

Since I use the slf4j Restlet extension, I thought about using a slf4j.MDC and adding a hash of the source-IP+port+timestamp to it. Or a number which increases with every request.

But perhaps there is another, easier way?

Probably easier to use the thread ID, and ensure that you log the start and end of each request. That gives you what you want without any additional coding (or CPU cycles).

Update :

If you're running multiple requests per thread then you should probably just generate a random ID and use that for tracking. Something like:

import java.security.SecureRandom;

public class StringUtils
{
  private static final SecureRandom RANDOMSOURCE;
  private static String CANDIDATES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  static
  {
    RANDOMSOURCE = new SecureRandom();
  }

 /**
  * Generate a random string of alphanumeric characters.
  * <p>
  * The string returned will contain characters randomly
  * selected from upper- and lower-case a through z as
  * well as the digits 0 through 9.
  * @param length the length of the string to generate
  * @return a string of random alphanumeric characters of the requested length
  */
  public static String generateRandomString(int length)
  {
    final StringBuffer sb = new StringBuffer(length);
    for (int i = 0; i < length; i++)
    {
      sb.append(CANDIDATES.charAt(RANDOMSOURCE.nextInt(62)));
    }
    return sb.toString();
  }
}

And then, as you say, you can use MDC to create your request ID for each request and log the details in a filter (this is a Jersey filter but should look similar for Restlet):

  ...
  private static final String REQUESTHIDEADER = "Request-ID";
  private static final String REQUESTID = "REQUESTID";
  private static final String REQUESTSTARTTIME = "RSTARTTIME";

  @Override
  public ContainerRequest filter(final ContainerRequest request)
  {
    final String requestid = Long.toHexString(Double.doubleToLongBits(Math.random()));
    MDC.put(REQUESTID, requestid);
    MDC.put(REQUESTSTARTTIME, String.valueOf(System.currentTimeMillis()));
    if (LOGGER.isInfoEnabled())
    {
      LOGGER.info("Started: {} {} ({})", request.getMethod(), request.getPath(), requestid);
    }

    return request;
  }

  @Override
  public ContainerResponse filter(final ContainerRequest request, final ContainerResponse response)
  {
    try
    {
      final Long startTime = Long.parseLong(MDC.get(REQUESTSTARTTIME));
      final String rid = MDC.get(REQUESTID);
      final long duration = System.currentTimeMillis() - startTime;
      response.getHttpHeaders().add(REQUESTHIDEADER, rid);
      LOGGER.info("Finished: {} {} ({} ms)", request.getMethod(), request.getPath(), String.valueOf(duration));
    }
    catch (Exception e)
    {
      LOGGER.warn("Finished {} {}", request.getMethod(), request.getPath());
    }
    return response;
  }

As a bonus this also passes the request ID back to the requestor to allow for tracking in case of problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM