Как да регистрирате Apache CXF Soap Request и Soap Response с помощта на 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
Същият проблем беше обсъден тук: 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 jar. След като създадете структурата на директорията и поставите файла, трябва ли да конфигурирам нещо във файла 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> в моята конфигурация на bean, съобщенията се отпечатват с форматиране (но знам, че отговорът е на 2 години). - person Betlista; 10.10.2013
comment
Вижте за допълнителни опции за красив печат: github.com/greenbird/xml- formatter-components/tree/master/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 szenario:

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 Grant, къде да добавя това? - 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 регистратор. По този начин настройвате регистриране за цялото приложение, без да се налага да променяте кода, войната, 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