使用DropWizard记录一些请求标头 [英] Logging some request headers with DropWizard

查看:75
本文介绍了使用DropWizard记录一些请求标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在尝试将一个自定义的http标头添加到dropwizard访问日志中.我们尝试了dropwizard 0.9.1和0.9.2,但是找不到实现此目的的方法.我们注意到以下情况:

We're trying to add a custom http header to dropwizard access logs. We tried dropwizard 0.9.1 and 0.9.2, but can't find a way to do this. We noticed the following:

  • server.requestlogs.appenders [file] .logFormat被忽略.它始终使用通用的日志记录格式进行记录.
  • logging.appenders [file] .logFormat受了尊敬,但特定于Web的内容会导致%header {HEADER-NAME},%A等类似的内容出现%PARSER_ERROR [..].

是否可以记录此类信息?

Is there a way to log such information?

推荐答案

可以使用自定义的org.eclipse.jetty.server.RequestLog实现,可以通过扩展io.dropwizard.jetty.RequestLogFactory并替换ServerFactory中的dropwizard实现来将其注册到码头.这里是一种可能的实现方式:

It is possible to use a custom org.eclipse.jetty.server.RequestLog implementation, which can be registered to jetty by extending io.dropwizard.jetty.RequestLogFactory and replacing the dropwizard implementation in the ServerFactory. Here one possible implementation:

import ch.qos.logback.classic.*;
import ch.qos.logback.classic.spi.*;
import ch.qos.logback.core.*;
import ch.qos.logback.core.spi.*;
import com.google.common.collect.ImmutableList;
import io.dropwizard.jetty.*;
import io.dropwizard.logging.*;
import org.eclipse.jetty.server.*;
import org.slf4j.LoggerFactory;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.Enumeration;
import java.util.TimeZone;

public class CustomRequestLogFactory extends RequestLogFactory {

    @NotNull
    private TimeZone timeZone = TimeZone.getTimeZone("UTC");

    @Valid
    @NotNull
    private ImmutableList<AppenderFactory> appenders = ImmutableList.<AppenderFactory>of(
        new ConsoleAppenderFactory()
    );

    private static class RequestLogLayout extends LayoutBase<ILoggingEvent> {
        @Override
        public String doLayout(ILoggingEvent event) {
            return event.getFormattedMessage() + CoreConstants.LINE_SEPARATOR;
        }
    }

    private static class CustomRequestLog extends Slf4jRequestLog {

        private static Logger logger = (Logger) LoggerFactory.getLogger(CustomRequestLog.class);
        private static ThreadLocal<StringBuilder> _buffers = new ThreadLocal<StringBuilder>() {
            @Override
            protected StringBuilder initialValue() {
                return new StringBuilder(256);
            }
        };

        public CustomRequestLog(AppenderAttachableImpl<ILoggingEvent> appenders, 
             TimeZone timeZone) {
            super(appenders, timeZone);
        }

        @Override
        public void log(Request request, Response response) {
            StringBuilder buf = _buffers.get();
            buf.setLength(0);
            buf.append(request.getServerName()).append('\n');
            Enumeration<String> headers = request.getHeaderNames();
            while (headers.hasMoreElements()) {
                String header = headers.nextElement();
                buf.append(header).append('=')
                   .append(request.getHeader(header)).append('\n');
            }
            try {
                write(buf.toString());
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public RequestLog build(String name) {
        final Logger logger = (Logger) LoggerFactory.getLogger("http.request");
        logger.setAdditive(false);
        final LoggerContext context = logger.getLoggerContext();
        final RequestLogLayout layout = new RequestLogLayout();
        layout.start();
        final AppenderAttachableImpl<ILoggingEvent> attachable = 
            new AppenderAttachableImpl<>();
        for (AppenderFactory output : this.appenders) {
            attachable.addAppender(output.build(context, name, layout));
        }
        return new CustomRequestLog(attachable, timeZone);
    }
}

在ServerFactory中设置RequestLogFactory:

Set the RequestLogFactory in the ServerFactory:

@Override
public void run(ApplicationConfiguration configuration,
                Environment environment) {
...
  ((DefaultServerFactory) configuration.getServerFactory())
        .setRequestLogFactory(new CustomRequestLogFactory());
}

这篇关于使用DropWizard记录一些请求标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆