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