以下代码将在Dropwizard 0.9.2和1.0.2中打印JSON服务器响应:
return ClientBuilder
.newBuilder()
.build()
.register(new LoggingFilter(Logger.getLogger(LoggingFilter.class.getName()), true))例如:
Oct 21, 2016 7:57:42 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Client response received on thread main
1 < 401
1 < Connection: keep-alive
1 < Content-Length: 49
1 < Content-Type: text/plain
1 < Date: Fri, 21 Oct 2016 07:57:42 GMT
1 < Server: […]
1 < WWW-Authenticate: Basic realm="[…]"
Credentials are required to access this resource.
javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized但是,在1.0.2中不推荐使用LoggingFilter,建议使用LoggingFeature。在LoggingFeature文档中,它说默认的详细内容是LoggingFeature.Verbosity.PAYLOAD_TEXT,所以我希望下面的代码仍然在Dropwizard 1.0.2中打印JSON服务器响应:
return ClientBuilder
.newBuilder()
.build()
.register(new LoggingFeature(Logger.getLogger(getClass().getName())))相反,日志只包含以下内容:
javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized发布于 2016-10-21 13:15:40
这就是诀窍:
new LoggingFeature(Logger.getLogger(getClass().getName()), Level.OFF, LoggingFeature.Verbosity.PAYLOAD_TEXT, 8192)我猜客户机中的日志功能就像一个过滤器,而不是像预期的那样作为一个包含。
发布于 2017-11-06 23:20:01
举一个简单的例子来说明一个常见的问题,它会让开发人员认为日志功能不起作用。
private static final LOG = Logger.getLogger(getClass().getName());
public void test() {
Client client = ClientBuilder.newBuilder()
.register(new LoggingFeature(LOG, Level.FINE, LoggingFeature.Verbosity.PAYLOAD_ALL, 8192))
.build();
// all requests and responses using this client will now be logged
// with the log-level FINE to the logger LOG, but the logger
// will simply ignore them, because it's default level is INFO
}创建的记录器实例LOG使用默认日志级别,即INFO。这意味着它将接受至少为INFO或更高级别的所有日志消息(警告,严重,.),但它将忽略所有级别较低的消息,比如罚款。(它仍然将消息传递给它的父记录器,如果有)
注意:处理程序的默认日志级别是Level.ALL,它们不应该拒绝任何日志记录,只要您不修改它们的级别。
因此,您需要提高LoggingFeatures级别或降低记录器级别来查看消息。
解决方案1:提高LoggingFeature的级别:
new LoggingFeature(LOG, Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ALL, 8192)解决方案2:降低日志的级别:
LOG.setLevel(Level.FINE)发布于 2018-07-20 12:56:46
要使用LoggingFeature记录服务器和客户端请求/响应的自定义日志,您需要创建一个扩展LoggingFeature并实现ContainerRequestFilter、ContainerResponseFilter、ClientRequestFilter、ClientResponseFilter和WriterInterceptor的自定义类。
您需要重写LoggingFeature方法public boolean configure(FeatureContext context)并将CustomLoggingFeature对象注册到上下文中。
@Override
public boolean configure(FeatureContext context) {
context.register(this);
return true;
}ContainerRequestFilter和ContainerResponseFilter接口有用于记录服务器请求和响应的方法。
ClientRequestFilter和ContainerResponseFilter接口有用于记录客户端请求和响应的方法。
另外,您需要实现WriterInterceptor来记录客户端请求和服务器响应主体。
最后在泽西注册了你的CustomLoggingFeature课程。
environment.jersey().register(new CustomLoggingFeature(Logger.getLogger(getClass().getName()), Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 8192));我使用的是Dropwizard v1.3.5。
这是我的实现。
public class CustomLoggingFeature extends LoggingFeature implements ContainerRequestFilter, ContainerResponseFilter,
ClientRequestFilter, ClientResponseFilter, WriterInterceptor {
private static final boolean printEntity = true;
private static final int maxEntitySize = 8 * 1024;
private final Logger logger = Logger.getLogger("CustomLoggingFeature");
private static final String ENTITY_LOGGER_PROPERTY = CustomLoggingFeature.class.getName();
private static final String NOTIFICATION_PREFIX = "* ";
private static final String REQUEST_PREFIX = "> ";
private static final String RESPONSE_PREFIX = "< ";
private static final String AUTHORIZATION = "Authorization";
private static final String EQUAL = " = ";
private static final String HEADERS_SEPARATOR = ", ";
private static List<String> requestHeaders;
static {
requestHeaders = new ArrayList<>();
requestHeaders.add(AUTHORIZATION);
}
public CustomLoggingFeature(Logger logger, Level level, Verbosity verbosity, Integer maxEntitySize) {
super(logger, level, verbosity, maxEntitySize);
}
@Override
public boolean configure(FeatureContext context) {
context.register(this);
return true;
}
@Override
public void filter(final ClientRequestContext context) {
final StringBuilder b = new StringBuilder();
printHeaders(b, context.getStringHeaders());
printRequestLine(b, "Sending client request", context.getMethod(), context.getUri());
if (printEntity && context.hasEntity()) {
final OutputStream stream = new LoggingStream(b, context.getEntityStream());
context.setEntityStream(stream);
context.setProperty(ENTITY_LOGGER_PROPERTY, stream);
// not calling log(b) here - it will be called by the interceptor
} else {
log(b);
}
}
@Override
public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) throws IOException {
final StringBuilder b = new StringBuilder();
printResponseLine(b, "Client response received", responseContext.getStatus());
if (printEntity && responseContext.hasEntity()) {
responseContext.setEntityStream(logInboundEntity(b, responseContext.getEntityStream(),
MessageUtils.getCharset(responseContext.getMediaType())));
}
log(b);
}
@Override
public void filter(final ContainerRequestContext context) throws IOException {
final StringBuilder b = new StringBuilder();
printHeaders(b, context.getHeaders());
printRequestLine(b, "Server has received a request", context.getMethod(), context.getUriInfo().getRequestUri());
if (printEntity && context.hasEntity()) {
context.setEntityStream(logInboundEntity(b, context.getEntityStream(), MessageUtils.getCharset(context.getMediaType())));
}
log(b);
}
@Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) {
final StringBuilder b = new StringBuilder();
printResponseLine(b, "Server responded with a response", responseContext.getStatus());
if (printEntity && responseContext.hasEntity()) {
final OutputStream stream = new LoggingStream(b, responseContext.getEntityStream());
responseContext.setEntityStream(stream);
requestContext.setProperty(ENTITY_LOGGER_PROPERTY, stream);
// not calling log(b) here - it will be called by the interceptor
} else {
log(b);
}
}
@Override
public void aroundWriteTo(final WriterInterceptorContext writerInterceptorContext) throws IOException, WebApplicationException {
final LoggingStream stream = (LoggingStream) writerInterceptorContext.getProperty(ENTITY_LOGGER_PROPERTY);
writerInterceptorContext.proceed();
if (stream != null) {
log(stream.getStringBuilder(MessageUtils.getCharset(writerInterceptorContext.getMediaType())));
}
}
private static class LoggingStream extends FilterOutputStream {
private final StringBuilder b;
private final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
LoggingStream(final StringBuilder b, final OutputStream inner) {
super(inner);
this.b = b;
}
StringBuilder getStringBuilder(Charset charset) {
// write entity to the builder
final byte[] entity = byteArrayOutputStream.toByteArray();
b.append(new String(entity, 0, Math.min(entity.length, maxEntitySize), charset));
if (entity.length > maxEntitySize) {
b.append("...more...");
}
b.append('\n');
return b;
}
public void write(final int i) throws IOException {
if (byteArrayOutputStream.size() <= maxEntitySize) {
byteArrayOutputStream.write(i);
}
out.write(i);
}
}
private void printHeaders(StringBuilder b, MultivaluedMap<String, String> headers) {
for (String header : requestHeaders) {
if (Objects.nonNull(headers.get(header))) {
b.append(header).append(EQUAL).append(headers.get(header)).append(HEADERS_SEPARATOR);
}
}
int lastIndex = b.lastIndexOf(HEADERS_SEPARATOR);
if (lastIndex != -1) {
b.delete(lastIndex, lastIndex + HEADERS_SEPARATOR.length());
b.append("\n");
}
}
private void log(final StringBuilder b) {
String message = Util.mask(b.toString());
if (logger != null) {
logger.info(message);
}
}
private void printRequestLine(final StringBuilder b, final String note, final String method, final URI uri) {
b.append(NOTIFICATION_PREFIX)
.append(note)
.append(" on thread ").append(Thread.currentThread().getId())
.append(REQUEST_PREFIX).append(method).append(" ")
.append(uri.toASCIIString()).append("\n");
}
private void printResponseLine(final StringBuilder b, final String note, final int status) {
b.append(NOTIFICATION_PREFIX)
.append(note)
.append(" on thread ").append(Thread.currentThread().getId())
.append(RESPONSE_PREFIX)
.append(Integer.toString(status))
.append("\n");
}
private InputStream logInboundEntity(final StringBuilder b, InputStream stream, final Charset charset) throws IOException {
if (!stream.markSupported()) {
stream = new BufferedInputStream(stream);
}
stream.mark(maxEntitySize + 1);
final byte[] entity = new byte[maxEntitySize + 1];
final int entitySize = stream.read(entity);
b.append(new String(entity, 0, Math.min(entitySize, maxEntitySize), charset));
if (entitySize > maxEntitySize) {
b.append("...more...");
}
b.append('\n');
stream.reset();
return stream;
}https://stackoverflow.com/questions/40171273
复制相似问题