0

在 Restlet servlet 的日志文件中跟踪特定请求的最佳方法是什么?

如果同时有多个请求,我希望能够在日志文件中跟踪单个请求。

由于我使用的是 slf4j Restlet 扩展,所以我考虑使用 slf4j.MDC 并向其添加源 IP+端口+时间戳的哈希。或者随着每次请求而增加的数字。

但也许还有另一种更简单的方法?

4

1 回答 1

2

可能更容易使用线程 ID,并确保记录每个请求的开始和结束。无需任何额外的编码(或 CPU 周期)即可为您提供所需的东西。

更新

如果您在每个线程运行多个请求,那么您可能应该只生成一个随机 ID 并将其用于跟踪。就像是:

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();
  }
}

然后,正如您所说,您可以使用 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;
  }

作为奖励,这还将请求 ID 传递回请求者,以便在出现问题时进行跟踪。

于 2013-02-02T16:28:47.183 回答