简体   繁体   English

使用Restlet时如何在日志中跟踪请求?

[英]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? 在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. 由于我使用slf4j Restlet扩展,我考虑使用slf4j.MDC并添加源-IP +端口+时间戳的哈希值。 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. 可能更容易使用线程ID,并确保记录每个请求的开始和结束。 That gives you what you want without any additional coding (or CPU cycles). 无需任何额外编码(或CPU周期)即可为您提供所需的功能。

Update : 更新

If you're running multiple requests per thread then you should probably just generate a random ID and use that for tracking. 如果您为每个线程运行多个请求,那么您应该只生成一个随机ID并将其用于跟踪。 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): 然后,正如您所说,您可以使用MDC为每个请求创建请求ID,并在过滤器中记录详细信息(这是一个Jersey过滤器,但对于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. 作为奖励,这也将请求ID传递回请求者以允许在出现问题时进行跟踪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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