Hi Andriy, I couldn't get filtering to work correctly since I didn't know the correct name of the Logger category within which the REQ/RESP message is logged. But checking the event data showed the logger category and they all have a naming like ' log4j.logger.org.apache.cxf.services.<ServiceName>'. So basically I can do:
log4j.additivity.org.apache.cxf.services=false log4j.logger.org.apache.cxf.services.<ServiceName>=INFO,<appender> where: <ServiceName> Is the name of the interface (i.e. of JAX-RSclient) or the implementation (in case of a JAX-RS service endpoint) class <appender> The name of the appender where to log the REQ/RESP message Knowing the exact logger category makes the use of a filter obsolete. Regards, J.P. Urkens -----Original Message----- From: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com> Sent: maandag 13 november 2023 9:19 To: 'Andriy Redko' <drr...@gmail.com>; 'dev@cxf.apache.org' <dev@cxf.apache.org> Subject: RE: Apache CXF JAXRS Logging questions Hi Andriy, Unfortunately it is a legacy application which is still using log4j v1.x. I don't think it supports scripting but it does have some filtering capabilities, maybe I could use org.apache.log4j.varia.StringMatchFilter for this purpose. It will check the event.getRenderedMessage() of a 'string to match'. If a match is found the log event can either be accepted or denied: public int decide(LoggingEvent event) { String msg = event.getRenderedMessage(); if (msg == null || stringToMatch == null) return Filter.NEUTRAL; if (msg.indexOf(stringToMatch) == -1) { return Filter.NEUTRAL; } else { // we've got a match if (acceptOnMatch) { return Filter.ACCEPT; } else { return Filter.DENY; } } } However I've no idea how the Apache CXF Log event looks like. Does the event.getRenderedMessage() contains the hostname of the target endpoint? If so I could 'string match' on that. I am giving it a try and let you know the result. Regards, J.P. Urkens -----Original Message----- From: Andriy Redko <drr...@gmail.com> Sent: zaterdag 11 november 2023 3:31 To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>; dev@cxf.apache.org Subject: Re: Apache CXF JAXRS Logging questions Hi Jean, Hm, the logMultipart is indeed enabled by default and should lead to message content being logged, looks like a bug, I will try to reproduce it (my apologies, haven't had time for that). I will get back to you on this subject. Regarding your other question, is it possible to get REST messages for different endpoints to be logged to different files, I believe the AbstractLoggingInterceptor has no support for that but I think you could use Log4j scripting capabilities [1] to select the right appender based on log event properties (fe address which is somewhat equivalent to endpoint). [1] https://logging.apache.org/log4j/2.x/manual/configuration.html Thank you. Best Regards, 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 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> 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