Как перенаправить вывод журнала AWS sdk
Я продолжаю получать их на STDOUT, даже если я использую logback и настроил его. Я не могу извлечь 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)
Это моя конфигурация журнала:
<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>
Ответы
Ответ 1
Сначала я хотел бы сказать, что из-за исторических причин регистрация в java - это беспорядок, и вы должны быть готовы приложить некоторые усилия, чтобы сделать это правильно.
Теперь, к вашей проблеме.
Прежде всего, это действительно похоже на журналы, которые вы получаете в своем обходном журнале STDOUT (по крайней мере, они не соответствуют ни одному из шаблонов, определенных в вашей конфигурации журнала).
Могут быть две причины:
-
Вы неправильно сконфигурировали logback, что менее вероятно (проверьте это, проверив, попадают ли какие-либо записи в файлы, в которые вы настроили logback, записываете их в).
-
Журналы формируют AWS sdk, обрабатывая ведение журналов сообщества (скорее всего, поскольку это система протоколирования, используемая AWS sdk) или что-то, что имитирует ведение журнала Commons для перенаправления журналов, например, SLF4J (менее вероятно, так как для этого требуется некоторая явная конфигурация пути к классам.)
Теперь, чтобы разобраться с этим, я предлагаю вам начать с этой статьи, чтобы получить обзор зоопарка java logging.
Затем, чтобы решить вашу проблему, я бы предложил вам настроить популярные системы ведения журналов (commons logging, log4j и т.д.), чтобы направлять свои журналы на SLF4j и использовать logback как реализацию SLF4j.
Прочитайте этот и этот (если вы используете 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>
... и все записи в конечном итоге записаны в файл журнала.
Это должно дать вам представление о том, как настроить зависимости/протоколирование.
Не стесняйтесь прояснять непонятные моменты в комментариях.
Ответ 2
Вы получаете сообщения в STDOUT, скорее всего, потому что у вас есть что-то в своем пути к классам во время выполнения, которое регистрируется в STDOUT (f.ex. класс, который использует apache commons logging, как это было предложено в предыдущей статье). Не только, что вы используете logback, означает, что все протоколирования проходят через logback.
Чтобы получить контроль над всеми входами в ваше приложение, вы должны:
A) Проверьте свой путь к классу и удалите все другие двоичные файлы журналов регистрации (commons-logging, log4j и т.д.). Если вы используете maven, запустите mvn dependency:tree -X
, затем используйте исключение, чтобы удалить зависимости для протоколирования библиотек.
B) Замените эти библиотеки на мосты, чтобы направить ваш журнал на SLF4J
C) Направьте свой журнал с исходного кода через SLF4J на Logback. Для смягчения вашей работы существует migrator. Проверьте, может ли он вам помочь.
D) Настройте свой логин в logback.xml или logback.groovy.