Как зарегистрировать запрос мыла Apache CXF и ответ мыла с помощью Log4j?

Я использую Apache CXF Framework. Внутри моей клиентской программы мне нужно регистрировать запросы CXF SOAP и ответы SOAP. Когда я использовал

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(host);
factory.setServiceClass(MyService.class);
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());

Я получил эти запросы SOAP и ответы SOAP в консоли:

Nov 9, 2011 6:48:01 PM org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
INFO: Outbound Message
---------------------------
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns4:MYResponse
--------------------------------------

Но мое фактическое требование состоит в том, что вместо того, чтобы печатать их на консоли сервера, мне нужно, чтобы они были внутри файла журнала.

Когда я использовал log4j напрямую, как показано

log4j(factory.getInInterceptors().add(new LoggingInInterceptor()));
log4j(factory.getOutInterceptors().add(new LoggingOutInterceptor()));

Он печатает только true и true внутри файла журнала.

Может кто-нибудь, пожалуйста, дайте мне знать, как настроить это?


person Pawan    schedule 09.11.2011    source источник
comment
Та же проблема обсуждалась здесь: с apache cxf как xml"> stackoverflow.com/questions/4592422/   -  person Mike    schedule 31.07.2013


Ответы (10)


Вам необходимо создать файл с именем org.apache.cxf.Logger (то есть файл org.apache.cxf с расширением Logger) под /META-INF/cxf/ со следующим содержимым:

org.apache.cxf.common.logging.Log4jLogger

Ссылка: Использование Log4j вместо java.util.logging .

Также, если вы замените стандартный:

<cxf:bus>
  <cxf:features>
    <cxf:logging/>
  </cxf:features>
</cxf:bus>

с гораздо более подробным:

<bean id="abstractLoggingInterceptor" abstract="true">
    <property name="prettyLogging" value="true"/>
</bean>
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" parent="abstractLoggingInterceptor"/>
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" parent="abstractLoggingInterceptor"/>

<cxf:bus>
    <cxf:inInterceptors>
        <ref bean="loggingInInterceptor"/>
    </cxf:inInterceptors>
    <cxf:outInterceptors>
        <ref bean="loggingOutInterceptor"/>
    </cxf:outInterceptors>
    <cxf:outFaultInterceptors>
        <ref bean="loggingOutInterceptor"/>
    </cxf:outFaultInterceptors>
    <cxf:inFaultInterceptors>
        <ref bean="loggingInInterceptor"/>
    </cxf:inFaultInterceptors>
</cxf:bus>

Apache CXF будет красиво печатать XML-сообщения, форматируя их с правильными отступами и разрывами строк. Очень полезно. Подробнее об этом здесь.

person Tomasz Nurkiewicz    schedule 09.11.2011
comment
Привет, Томас, в настоящее время в папке META-INF у меня есть файл с именем MANIFEST.MF. Вы имеете в виду добавить папку cxf в META-INF?? а подскажите пожалуйста как создать этот файл org.apache.cxf.Logger?? - person Pawan; 09.11.2011
comment
Да, создайте папку /cxf в /META-INF и поместите туда файл с именем org.apache.cxf файл с расширением Logger. Также смотрите мои обновления. - person Tomasz Nurkiewicz; 09.11.2011
comment
см. изображение tinypic.com/view.php?pic=adouue&s=5 я создал папки - person Pawan; 09.11.2011
comment
Только один правильный вопрос, вы имеете в виду создать структуру папок как META-INF\cxf\org\apache\cxf\Logger, это то, что вы имеете в виду ?? - person Pawan; 09.11.2011
comment
Файл должен называться org.apache.cxf с расширением Logger. Насколько я вижу, вы создали файл \META-INF\cxf\org\apache\cxf\Logger.class, а не \META-INF\cxf\org.apache.cxf.Logger. Я никогда не говорил, что вам нужно создать структуру каталогов \org\apache\cxf. Это имя файла (неудобное, надо признать). - person Tomasz Nurkiewicz; 09.11.2011
comment
Я не знаю, нужно ли вам это или нет, но все же, где я могу найти этот файл org.apache.cxf.Logger, потому что я вижу файлы как org\apache\log4j - person Pawan; 09.11.2011
comment
Хорошо, взгляните на Использование Log4j вместо java.util.logging, на самом деле это вопрос создания однострочного файла в вашем проекте... - person Tomasz Nurkiewicz; 09.11.2011
comment
Спасибо за ссылку, это помогло начать работу, я скачал Log4jLogger из банки cxf. После создания структуры каталогов и вставки файла мне нужно что-то настраивать внутри файла log4j.properties?? - person Pawan; 09.11.2011
comment
Если сейчас в консоли ничего не появляется, то да, вам нужно настроить log4j.properties файл. Но это выходит за рамки данного вопроса. - person Tomasz Nurkiewicz; 09.11.2011
comment
Я уже настроил log4j. На самом деле, мои другие запуски отладки журнала идут, но не это. любая идея ?? - person Pawan; 09.11.2011
comment
Убедитесь, что для регистратора org.apache.cxf установлено значение ALL или DEBUG. - person Tomasz Nurkiewicz; 09.11.2011
comment
У меня нигде нет файла org.apache.cxf.Logger. И имея только <cxf:bus><cxf:features><cxf:logging/></cxf:features></cxf:bus> в моей конфигурации компонента, сообщения печатаются с форматированием (но я знаю, что этому ответу 2 года). - person Betlista; 10.10.2013
comment
См. дополнительные параметры красивой печати: github.com/greenbird/xml- форматтер-компоненты/дерево/мастер/cxf - person ThomasRS; 30.04.2015

Еще один простой способ — настроить регистратор следующим образом: убедитесь, что вы сделали это перед загрузкой классов, связанных с веб-службой cxf. Вы можете использовать его в некоторых статических блоках.

YourClientConstructor() {

  LogUtils.setLoggerClass(org.apache.cxf.common.logging.Log4jLogger.class);

  URL wsdlURL = YOurURL;//

  //create the service
  YourService = new YourService(wsdlURL, SERVICE_NAME);
  port = yourService.getServicePort(); 

  Client client = ClientProxy.getClient(port);
  client.getInInterceptors().add(new LoggingInInterceptor());
  client.getOutInterceptors().add(new LoggingOutInterceptor());
}

Затем входящие и исходящие сообщения будут выводиться в файл Log4j, а не в консоль. Убедитесь, что ваш log4j настроен правильно

person Vins    schedule 02.02.2012
comment
Я рекомендую также включить красивое ведение журнала с помощью: AbstractLoggingInterceptor.setPrettyLogging(true) - person kevinarpe; 21.12.2017

Самый простой способ добиться красивой регистрации в сценарии Preethi Jain:

LoggingInInterceptor loggingInInterceptor = new LoggingInInterceptor();
loggingInInterceptor.setPrettyLogging(true);
LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor();
loggingOutInterceptor.setPrettyLogging(true);
factory.getInInterceptors().add(loggingInInterceptor);
factory.getOutInterceptors().add(loggingOutInterceptor);
person dpa    schedule 16.11.2012
comment
LoggingInInterceptor и LoggingOutInterceptor устарели: вместо этого используйте модуль ведения журнала rt/features/logging. - person Sergey Ponomarev; 09.08.2018

Это сработало для меня.

Настройте log4j как обычно. Затем используйте этот код:

    // LOGGING 
    LoggingOutInterceptor loi = new LoggingOutInterceptor(); 
    loi.setPrettyLogging(true); 
    LoggingInInterceptor lii = new LoggingInInterceptor(); 
    lii.setPrettyLogging(true); 

    org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(isalesService); 
    org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 

    cxfEndpoint.getOutInterceptors().add(loi); 
    cxfEndpoint.getInInterceptors().add(lii);
person Al Grant    schedule 08.02.2018
comment
@AI Грант, куда это добавить? - person Anand; 01.08.2018

В вашем весеннем контексте настройка ниже будет регистрировать мыльное сообщение запроса и ответа.

<bean id="loggingFeature" class="org.apache.cxf.feature.LoggingFeature">
    <property name="prettyLogging" value="true" />
</bean>

<cxf:bus>
    <cxf:features>
        <ref bean="loggingFeature" />
    </cxf:features>
</cxf:bus>
person Manjunath    schedule 25.06.2015

При настройке log4j.properties достаточно установить уровень ведения журнала org.apache.cxf на INFO, чтобы увидеть простые сообщения SOAP:

log4j.logger.org.apache.cxf=INFO

DEBUG слишком многословен.

person dpinya    schedule 23.07.2013
comment
Установка org.apache на TRACE была первой, что я попробовал, и сообщения SOAP не регистрируются. Единственное, что загружается, это что-то вроде TRACE [http-8080-1] [org.apache.cxf.service.invoker.AbstractInvoker] Invoking method ..., но это слишком поздно, потому что при сбое синтаксического анализа запрос вообще не регистрируется... - person Betlista; 10.10.2013

Попробуйте этот код:

EndpointImpl impl = (EndpointImpl)Endpoint.publish(address, implementor);
    impl.getServer().getEndpoint().getInInterceptors().add(new LoggingInInterceptor());
    impl.getServer().getEndpoint().getOutInterceptors().add(new LoggingOutInterceptor());

Внутри logback.xml вам нужно указать имя интерфейса для веб-сервиса:

<appender name="FILE" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator
        class="com.progressoft.ecc.integration.logging.ThreadNameDiscriminator">
        <key>threadName</key>
        <defaultValue>unknown</defaultValue>
    </discriminator>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>logger.contains("InterfaceWebServiceSoap")</expression>
        </evaluator>
        <OnMismatch>DENY</OnMismatch>
        <OnMatch>NEUTRAL</OnMatch>
    </filter>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>TRACE</level>
    </filter>
    <sift>
        <appender name="FILE-${threadName}"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>${LOGGING_PATH}/${threadName}.log</File>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${ARCHIVING_PATH}/%d{yyyy-MM-dd}.${threadName}%i.log.zip
                </FileNamePattern>
                <MaxHistory>30</MaxHistory>
                <TimeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <MaxFileSize>50MB</MaxFileSize>
                </TimeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <Pattern>%date{dd-MM-yyyy HH:mm:ss.SSS} | %5level | %-60([%logger{53}:%line]): %msg %ex{full} %n</Pattern>
            </encoder>
        </appender>
    </sift>
</appender>

<root>
    <level value="ALL" />
    <appender-ref ref="FILE" />
</root>
person Ahmad Alhaj Hussein    schedule 01.12.2015

cxf.xml

<cxf:bus>
    <cxf:ininterceptors>
        <ref bean="loggingInInterceptor" />
    </cxf:ininterceptors>
    <cxf:outinterceptors>
        <ref bean="logOutInterceptor" />
    </cxf:outinterceptors>
</cxf:bus>

org.apache.cxf.Logger

org.apache.cxf.common.logging.Log4jLogger

Пожалуйста, проверьте скриншот здесь

person Jose    schedule 15.02.2014

Если кто-то захочет это сделать, используя Play Framework (и используя LogBack http://logback.qos.ch/), то вы можете настроить application-logger.xml с помощью этой строки:

 <logger name="org.apache.cxf" level="DEBUG"/>

Для меня это помогло ;)

person Sebastián Vásquez    schedule 13.04.2017
comment
Это поместит в DEBUG каждый журнал службы мыла, если у вас есть 3, и вы хотите включить журнал только для 1 из них, это не применимо... - person Phate; 16.06.2020
comment
Ты прав. Но наверняка вы будете регистрировать запросы CXF SOAP и ответы SOAP, как задает вопрос. - person Sebastián Vásquez; 16.06.2020

Процедура глобальной настройки протоколирования клиентом/сервером запросов/ответов SOAP/REST с помощью log4j регистратора. Таким образом, вы настраиваете ведение журнала для всего приложения без необходимости изменения кода, war, jar-файлов и т. д.

  1. установить файл cxf-rt-features-logging-X.Y.Z.jar на свой CLASS_PATH

  2. создать файл (например, путь: /opt/cxf/cxf-logging.xml):

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    <cxf:bus>
     <cxf:features>
     <bean class="org.apache.cxf.ext.logging.LoggingFeature">
     <property name="prettyLogging" value="true"/>
     </bean>
     </cxf:features>
     </cxf:bus>
     </beans>
    
  3. установить ведение журнала для org.apache.cxf (log4j 1.x) log4j.logger.org.apache.cxf=INFO,YOUR_APPENDER

  4. установить эти свойства при запуске Java

java ... -Dcxf.config.file.url=file:///opt/cxf/cxf-logging.xml -Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true -Dcom.sun.xml.internal.ws.transport.http.HttpAdapter.dump=true ...

Не знаю зачем, но переменные тоже надо задавать com.sun.xml.*

person Richard Kotal    schedule 14.07.2020