如何重定向AWS sdk日志记录输出

时间:2014-06-19 15:49:43

标签: java scala logging amazon-web-services logback

即使我使用了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)

这是我的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>

解决方案:

强制通过logback进行日志记录,而不是commons-logging:

在build.sbt中添加:

resolvers ++= Seq(
  "version99 Empty loggers" at "http://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",
)

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

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

2 个答案:

答案 0 :(得分:13)

首先我要说的是,由于历史原因,登录java是一团糟,你应该准备好做一些努力使它正确。

现在,问题。

首先,它看起来像是你的STDOUT旁路回溯中的日志(至少它们不遵循你的logback配置中定义的任何模式)。

可能有两个原因:

  1. 您以某种方式错误配置了回溯的可能性较小(通过检查您配置的文件中是否有任何日志条目最终将其写入来验证这一点。)

  2. AWS sdk的日志由commons日志记录处理(很可能,因为这是AWS sdk使用的日志记录系统)或模仿公共日志记录重定向日志的东西,例如SLF4J(不太可能) ,因为这需要对类路径进行一些明确的配置。)

  3. 现在要处理这个问题,我建议你先从this article开始,了解java的伐木动物园。

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

    阅读thisthis(如果你使用maven,否则找到一种方法来排除与你的构建系统相关的jcl和log4j),以了解应该和什么不应该被放入你的类路径。

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

    在我的pom.xml我设置了这样的依赖关系:

    ...
    
    <repositories>
        <repository>
            <id>version99</id>
            <url>http://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>
    
    ...
    

    ...而且在我的类路径中我有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>
    

    ...并且所有日志最终写入我的日志文件。

    这可以让您了解应如何配置依赖项/日志记录。

    随意澄清评论中不明确的时刻。

答案 1 :(得分:3)

您最有可能收到STDOUT的消息,因为您在运行时在类路径中有一些东西,它正在记录到STDOUT(f.ex。正在使用apache commons logging的类,就像之前的帖子中所建议的那样)。不仅仅是您使用的是logback,意味着所有日志记录都会通过logback。

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

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

B)将这些库替换为bridges,以将您的日志记录定向到SLF4J

C)通过SLF4J将源代码的日志记录指向Logback。有migrator可以缓解您的工作。检查它是否可以帮助你。

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