阅读背景:

如何重定向AWS sdk日志输出

来源:互联网 

I keep getting those on STDOUT even though I'm using logback and configured it. I'm not able to get AWS stuff out of the console.

尽管我使用了logback并对其进行了配置,但我还是继续把那些放在STDOUT上。我没法把AWS的东西从控制台弄出来。

Jun 19, 2014 3:46:40 PM com.amazonaws.http.AmazonHttpClient executeHelper
INFO: Unable to execute HTTP request: The target server failed to respond
org.apache.http.NoHttpResponseException: The target server failed to respond
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:95)
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
        at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
        at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
        at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)  
        at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)   
        at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
        at com.amazonaws.http.protocol.SdkHttpRequestExecutor.doReceiveResponse(SdkHttpRequestExecutor.java:66)
        at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
        at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:713)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:518)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:402)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:245)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3573)
        at com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:990)
        at com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:970)
        at com.here.prime.cdtfilter.S3MapStore$$anonfun$1.apply(S3MapStore.scala:49)
        at com.here.prime.cdtfilter.S3MapStore$$anonfun$1.apply(S3MapStore.scala:48)
        at com.here.prime.utils.Utils$.retry(Utils.scala:26)

This is my logback configuration:

这是我的logback配置:

<configuration debug="false" scan="true" scanPeriod="30 seconds">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>cdtxfilter.log</file>
        <append>true</append>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.amazonaws.request" level="WARN">
    </logger>

    <root level="DEBUG">
        <!--<appender-ref ref="STDOUT" />-->
        <appender-ref ref="FILE" />
    </root>
</configuration>

Solution:

解决方案:

Force logging through logback, instead of commons-logging:

通过回签强制日志记录,而不是常规日志记录:

In build.sbt added:

在构建。sbt补充道:

resolvers ++= Seq(
  "version99 Empty loggers" at "https://version99.qos.ch",
)

libraryDependencies ++= Seq(
  "org.slf4j" % "jcl-over-slf4j" % "1.7.7",
  "commons-logging" % "commons-logging" % "99-empty",
  "ch.qos.logback" % "logback-classic" % "1.0.13",
)

In logback.xml, fine tune the log level for the noisy classes inside AWS SDK:

在logback。xml,微调AWS SDK中嘈杂类的日志级别:

<configuration...
[..]
    <logger name="com.amazonaws" level="ERROR"/>
    <logger name="org.apache.http" level="INFO" />
</configuration>

2 个解决方案

#1


10  

First that I'd like to tell is that, because of historical reasons, logging in java is a mess and you should be ready to put some effort into making it right.

首先,我想说的是,由于历史原因,在java中进行日志记录是一种混乱,您应该准备好投入一些精力使它正确。

Now, to your problem.

现在,你的问题。

First of all it really seems like logs you are getting in your STDOUT bypass logback (at least they do not follow any of the patterns defined in your logback configuration).

首先,似乎您正在进行STDOUT旁路登录(至少它们不遵循您的logback配置中定义的任何模式)。

There may be 2 reasons of that:

这可能有两个原因:

  1. You've misconfigured logback in some way which is less likely (verify this by checking whether any log entries end up in the files you've configured logback write them to).

    您已经以某种不太可能的方式错误配置了logback(通过检查是否有任何日志条目出现在您配置的logback写入的文件中来验证这一点)。

  2. Logs form AWS sdk getting handled by commons logging (most likely, since this is the logging system that is used by AWS sdk) or something that mimics commons logging to redirect logs to, for example, SLF4J (less likely, since this requires some explicit configuration of the classpath).

    由commons logging处理的AWS sdk生成的日志(很可能是AWS sdk使用的日志系统),或者模仿commons logging将日志重定向到SLF4J(不太可能,因为这需要对classpath进行一些显式的配置)。

Now to deal with this I would suggest you to start with this article to get an overview of the java's logging zoo.

现在,为了解决这个问题,我建议您从本文开始了解java的日志动物园。

Next, to solve your problem I would suggest you to configure popular logging systems (commons logging, log4j, etc) to direct their logs to SLF4j and use logback as SLF4j implementation.

接下来,为了解决您的问题,我建议您配置流行的日志系统(commons logging, log4j,等等),将它们的日志指向SLF4j,并使用logback作为SLF4j实现。

Read this, and this (if you use maven, otherwise find a way to exclude jcl and log4j relevant to your build system) to understand what should and what should not be placed into your classpath.

读这篇文章,再读这篇文章(如果您使用maven,可以找到一种排除与构建系统相关的jcl和log4j的方法),以了解应该将哪些内容和哪些内容不应该放在类路径中。

One of my projects use AWS sdk and has logging set up as proposed above.

我的一个项目使用AWS sdk,并按照上面的建议设置了日志记录。

In my pom.xml I set up dependencies like this:

我砰的一声。xml I设置依赖关系如下:

...

<repositories>
    <repository>
        <id>version99</id>
        <url>https://version99.qos.ch/</url>
    </repository>
</repositories>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>99-empty</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>99-empty</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>
        <version>1.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.7.7</version>
    </dependency>

    ...

</dependencies>

...

... and also in my classpath I have logback.xml like this:

…我的类路径中也有logback。xml是这样的:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>logs.log</file>
    <append>false</append>
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

<root level="debug">
    <appender-ref ref="FILE" />
</root>

... and and all logs end up written to my log file.

…所有的日志都写到我的日志文件中。

This should give you some idea on how dependencies/logging should be configured.

这将使您了解应该如何配置依赖项/日志记录。

Feel free to clarify unclear moments in comments.

请随意澄清评论中不清晰的时刻。

#2


3  

You are getting messages to STDOUT most likely because you have something in your classpath at runtime, which is logging to STDOUT (f.ex. a class which is using apache commons logging like suggested in earlier post). Not alone that you are using logback, means that all logging goes through logback.

您将消息发送到STDOUT的可能性最大,因为您在运行时的类路径中有一些内容,这些内容将记录到STDOUT (f.ex)。使用apache commons日志记录的类(如前面文章中建议的)。并非只有您在使用logback,这意味着所有日志记录都要经过logback。

To get control over all logging in your application, you have to:

要控制应用程序中的所有登录,您必须:

A) Check your classpath and remove all other binaries of logging libraries (commons-logging, log4j etc.) If you are using maven, run mvn dependency:tree -X, then use exlusion to remove dependencies to logging libraries.

A)检查类路径并删除日志库的所有其他二进制文件(common -logging, log4j等)如果使用maven,运行mvn依赖项:tree -X,然后使用exlusion删除日志库的依赖项。

B) Replace these libraries with bridges to direct your logging to SLF4J

B)将这些库替换为指向SLF4J的桥梁

C) Direct your logging from source code via SLF4J to Logback. There is a migrator to mitigate your work. Check if it can help you.

C)通过SLF4J将您的日志从源代码引导到Logback。有一个迁移器可以减轻您的工作。检查一下是否对你有帮助。

D) Configure your logback, either in logback.xml or logback.groovy.

D)配置您的logback,或者在logback中。xml或logback.groovy。


分享到: