Hi Jean,

Thanks a lot for the update, I think it is a viable option for
your context, thank you.

Best Regards,
    Andriy Redko

JPU> Hi Andriy,

JPU> I couldn't get filtering to work correctly since I didn't know the correct
JPU> name of the Logger category within which the REQ/RESP message is logged.
JPU> But checking the event data showed the logger category and they all have a
JPU> naming like ' log4j.logger.org.apache.cxf.services.<ServiceName>'. So
JPU> basically I can do:

JPU>         log4j.additivity.org.apache.cxf.services=false
JPU>         log4j.logger.org.apache.cxf.services.<ServiceName>=INFO,<appender>

JPU> where:
JPU>         <ServiceName>           Is the name of the interface (i.e. of 
JAX-RSclient) or the
JPU> implementation (in case of a JAX-RS service endpoint) class
JPU>         <appender>              The name of the appender where to log the 
REQ/RESP message

JPU> Knowing the exact logger category makes the use of a filter obsolete.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <[email protected]>
JPU> Sent: maandag 13 november 2023 9:19
JPU> To: 'Andriy Redko' <[email protected]>; '[email protected]'
JPU> <[email protected]>
JPU> Subject: RE: Apache CXF JAXRS Logging questions

JPU> Hi Andriy,

JPU> Unfortunately it is a legacy application which is still using log4j v1.x. I
JPU> don't think it supports scripting but it does have some filtering
JPU> capabilities, maybe I could use org.apache.log4j.varia.StringMatchFilter 
for
JPU> this purpose.
JPU> It will check the event.getRenderedMessage() of a 'string to match'. If a
JPU> match is found the log event can either be accepted or denied:

JPU>    public int decide(LoggingEvent event) {
JPU>         String msg = event.getRenderedMessage();
JPU>         if (msg == null || stringToMatch == null)
JPU>             return Filter.NEUTRAL;
JPU>         if (msg.indexOf(stringToMatch) == -1) {
JPU>             return Filter.NEUTRAL;
JPU>         } else { // we've got a match
JPU>             if (acceptOnMatch) {
JPU>                 return Filter.ACCEPT;
JPU>             } else {
JPU>                 return Filter.DENY;
JPU>             }
JPU>         }
JPU>     }

JPU> However I've no idea how the Apache CXF Log event looks like. Does the
JPU> event.getRenderedMessage() contains the hostname of the target endpoint? If
JPU> so I could 'string match' on that.
JPU> I am giving it a try and let you know the result.

JPU> Regards,

JPU> J.P. Urkens



JPU> -----Original Message-----
JPU> From: Andriy Redko <[email protected]>
JPU> Sent: zaterdag 11 november 2023 3:31
JPU> To: Jean Pierre URKENS <[email protected]>; 
[email protected]
JPU> Subject: Re: Apache CXF JAXRS Logging questions

JPU> Hi Jean,

JPU> Hm, the logMultipart is indeed enabled by default and should lead to 
message
JPU> content being logged, looks like a bug, I will try to reproduce it (my
JPU> apologies, haven't had time for that). I will get back to you on this
JPU> subject.

JPU> Regarding your other question, is it possible to get REST messages for
JPU> different endpoints to be logged to different files, I believe the
JPU> AbstractLoggingInterceptor has no support for that but I think you could 
use
JPU> Log4j scripting capabilities [1] to select the right appender based on log
JPU> event properties (fe address which is somewhat equivalent to endpoint).

JPU> [1] https://logging.apache.org/log4j/2.x/manual/configuration.html

JPU> Thank you.

JPU> Best Regards,
JPU>     Andriy Redko

JPU>>  Apache CXF JAXRS Logging questions

JPU>> Hi Andriy,

JPU>> When sending a multipart/form-data request to a service endpoint I
JPU>> see the following in the message log:

JPU>>    2023-11-10 13:27:37,578 [T8N1TP1-4] INFO
JPU>>       (SID=D04AF2A21B0DCEFFE4724AEF745B5BDF)
JPU>>       (org.apache.cxf.ext.logging.slf4j.Slf4jEventSender:84) -
JPU>> REQ_OUT

JPU>>           Address: *http://L-P53-008:8085/dosis-server/csv*
JPU>>       <http://L-P53-008:8085/dosis-server/csv>

JPU>>           HttpMethod: POST

JPU>>           Content-Type: multipart/form-data;charset=UTF-8;
JPU>>       boundary="uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b"

JPU>>           ExchangeId: d87098e4-fe86-4a42-8985-37a6ccc90b1d

JPU>>           Headers: {Authorization=Bearer
JPU>>       11a5b872-be3f-49f8-a26f-fbeb9be56a66, Accept=*/*}

JPU>>           Payload:

JPU>>       *--uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b*

JPU>>       *--- Content suppressed ---*

JPU>>       *----uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b*

JPU>>       2023-11-10 13:27:37,661 [T8N1TP1-4] INFO
JPU>>       (SID=D04AF2A21B0DCEFFE4724AEF745B5BDF)
JPU>>       (org.apache.cxf.ext.logging.slf4j.Slf4jEventSender:84) -
JPU>> RESP_IN

JPU>>           Address: *http://L-P53-008:8085/dosis-server/csv*
JPU>>       <http://L-P53-008:8085/dosis-server/csv>

JPU>>           ResponseCode: 200

JPU>>           ExchangeId: d87098e4-fe86-4a42-8985-37a6ccc90b1d

JPU>>           Headers: {transfer-encoding=chunked, Date=Fri, 10 Nov 2023
JPU>>       12:27:37 GMT}

JPU>> I.e. the logging of the multipart form-data gets suppressed. I
JPU>> tried enabling it by setting the LoggingFeature (although according
JPU>> to the Javadoc ‘logMultipart defaults to true’) on the
JPU> JAXRSClientFactoryBean e.g.:


JPU>>        * public* Response* dossiersOpladen*(List<Dossier> dossiers,
JPU>> String
JPU>> filename)* throws* GeneralSecurityException,
JPU>> AuthorizationException, DosisCommunicationException,
JPU>> BusinessException {

JPU>>                * try* {

JPU>>                         //Create the web client

JPU>>                         String* baseAddress* =
JPU>> Configuration.*getInstance*
JPU>> ().*getItem**(**"dosis.service.base.uri"**)*;

JPU>>                        * clientProxy* =*
JPU>> getThreadsafeProxy*(baseAddress+ "/csv");

JPU>>                         Client* client* =
JPU>> WebClient.*client*(*clientProxy*);

JPU>>                         WebClient* webClient* =
JPU>> WebClient.*fromClient* (client);

JPU>>                         WebClient.*getConfig*
JPU>> (webClient).getHttpConduit().getClient().setReceiveTimeout(60000L);

JPU>>
JPU>> webClient.type(MediaType.*MULTIPART_FORM_DATA_TYPE*
JPU>> .withCharset(StandardCharsets.*UTF_8*.name()));



JPU>>                         //Authorize API client by adding an
JPU>> appropriate authorization header

JPU>>                         authorizationHandler.authorize(webClient);



JPU>>                         //POST the request

JPU>>                        * log*.info("Uploading dossiers from csv");

JPU>>                         ContentDisposition* cd* =* new*
JPU>> ContentDisposition( "form-data;name=file-0;filename="+filename);

JPU>>                         InputStream* is* =* new*
JPU>>
JPU> ByteArrayInputStream(Dossier.*toCSV*(dossiers).getBytes(StandardCharsets.
JPU>> *UTF_8*));

JPU>>                         Attachment* att* =* new*
JPU>> Attachment("root",is, cd);

JPU>>                        * return* webClient.post(*new*
JPU>> MultipartBody(att));

JPU>>                 }* catch* (JsonProcessingException* e*) {

JPU>>                        * throw** new* BusinessException("Exception
JPU>> using REST service: "+e.getMessage(),e);

JPU>>                 }

JPU>>         }

JPU>>        * private** static* DosisService* getThreadsafeProxy*(String
JPU>> baseAddress)* throws* GeneralSecurityException {

JPU>>                 JacksonJsonProvider* jjProvider* =* new*
JPU>> JacksonJsonProvider(*new* CustomObjectMapper());

JPU>>                 List<Object>* providers* = Arrays.*asList*(*new*
JPU>> MultipartProvider(), jjProvider);



JPU>>                * final* JAXRSClientFactoryBean* factory* =* new*
JPU>> JAXRSClientFactoryBean();

JPU>>                 factory.setAddress(baseAddress);

JPU>>                 factory.setServiceClass(DosisService.*class*);

JPU>>                 factory.setProviders(providers);

JPU>>                 factory.getOutInterceptors().add(*new*
JPU>> LoggingOutInterceptor());

JPU>>                 factory.getInInterceptors().add(*new*
JPU>> LoggingInInterceptor());

JPU>>                 factory.setThreadSafe(*true*);



JPU>>                 LoggingFeature* feature* =* new* LoggingFeature();

JPU>>                 feature.setLogMultipart(*true*);

JPU>>                 feature.setLogBinary(*true*);

JPU>>                 factory.setFeatures(Arrays.*asList*(feature));

JPU>>                 DosisService* api* =
JPU>> factory.create(DosisService.*class*);

JPU>>                * return* api;

JPU>>         }

JPU>> But still it doesn’t show anything. So how can I get this logged
JPU>> (for testing purposes)?

JPU>> *Another question*: Is it possible to get REST messages for
JPU>> different endpoints to be logged to different files?

JPU>> Currently I just include the Logging[In|Out]Interceptor and have
JPU>> logging set through Log4J:

JPU>>    # Logging for CXF webservices

JPU>>       log4j.appender.WS=org.apache.log4j.DailyRollingFileAppender

JPU>>
JPU>> log4j.appender.WS.File=${catalina.base}/logs/kmopFrontend-ws.log

JPU>>       log4j.appender.WS.encoding=UTF-8

JPU>>       log4j.appender.WS.datePattern=yyyy-MM-dd

JPU>>       log4j.appender.WS.layout=org.apache.log4j.PatternLayout

JPU>>       log4j.appender.WS.layout.ConversionPattern=%d{ISO8601} [%t] %-5p
JPU>>       %X{sessionId} (%C:%L) - %m%n

JPU>>       log4j.additivity.org.apache.cxf=false

JPU>>       log4j.logger.org.apache.cxf=INFO,WS

JPU>> This however doesn’t allow me to differentiate between (completely
JPU>> different and unrelated) service endpoints. Everything gets logged
JPU>> in the same file.

JPU>> Regards,

JPU>> J.P. Urkens

Reply via email to