Can built-in logging messages be turned off? - servicestack

Once logging is configured with
LogManager.LogFactory = new Log4NetFactory(configureLog4Net: true);
it can be used anywhere with
ILog log = LogManager.GetLogger("foo);
log.Error("foo");
I get it. The problem is that Service Stack uses the same logger for various built-in internal messages. For example, if request is submitted for a non-existing route, Service Stack logs "ServiceStack.Host.Handlers.NotFoundHttpHandler - ::1 Request not found:".
Is there a way to disable or turn off those internal messages?

If you're using Log4Net you should be able to filter Log messages by type, otherwise some of ServiceStack's internal logging can be controlled in your AppHost by overriding:
public override void OnLogError(Type type, string message, Exception innerEx=null)
{
if (!SuppressLogs(type))
base.OnLogError(type, message, innerEx);
}
I've also just changed NotFoundHttpHandler to route messages to route error messages to OnLogError() from this commit so you'll be able to suppress messages by overriding the above method.
This change is available from v4.0.61 that's now available on MyGet.

Related

How do we check a message that caused a SessionLockLostException error in the service bus?

I am getting a few sessionlostlock exceptions while sending some messages to our SB triggered function app. We've set up alerts to check whenever such an error occurs. Although these messages do get retried and there no messages are sent to the DLQ. How do I find out which messages gave these exceptions in the first place.
How do I find out which messages gave these exceptions in the first place?
According to documentation:
You can use MessagingException.Detail Property to get the detail information on the messaging exception.
public Microsoft.ServiceBus.Messaging.MessagingExceptionDetail Detail { get; }
References: Cause and resolution of SessionLockLostException, Class SessionLockLostException and SessionLockLostException(String, Exception)

Automatically publish errors from errorChannel to the specific destination

This documentation says, that it is possible to automatically send error messages from global errorChannel to specific destination, the only thing needed is to set the following property:
spring.cloud.stream.bindings.error.destination
I am really confused with this part. Just adding property doesn't work (I use RabbitMQ, Exchange and Queue are configured). So I can see error handled by #ServiceActivator in my application, but it is not sent to "myErrors" exchange in RabbitMQ. Looks like this property does not define outbound binding for errorChannel.
If I create output "error" channel explicitly in my application,
/**
* Error channel name.
*/
String ERROR_ONE = "error";
#Output(MySink.ERROR_ONE)
MessageChannel errorOne();
and explicitly send error message to it from my global handler, for example by declaring outputChannel:
#ServiceActivator(inputChannel = "errorChannel", outputChannel = "error")
public ErrorMessage errorGlobal(ErrorMessage message) {
System.out.println("Handling ERROR GLOBAL SA: " + message);
return message;
}
it will work. But this can be done to binding-specific handlers also, so there is nothig errorChannel-specific here.
The question: Do I miss something? Can publish be done without defining outbound channels explicitly?
That documentation about ...binding.errors... is obsolete and needs to be fixed.
You should use auto-bind-dlq and republish-to-dlq instead and the framwork will publish the failed message to the dlq, with additional headers with information about the failure.

SmppInboundChannelAdapter AbstractReceivingMessageListener

In the SmppInboundChannelAdapter the declaration of the AbstractReceivingMessageListener has a no-op for the onDeliveryReceipt method.
I however am setting the registered_delivery token in the outbound smpp gateway and would like to receive the delivery receipt. If I add an implementation of MessageReceiverListener to the set of listeners in the outbound gateway will that get the delivery receipt or will the inbound adapter get it first?
Well, looking to SmppInboundChannelAdapter and SmppOutboundGateway we see that they uses the same ExtendedSmppSession instance (if you do that from the config, of course).
Now let's take a look to the DelegatingMessageReceiverListener used from the ExtendedSmppSessionAdaptingDelegate. It just iterates and invokes all the configured listeners:
public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException {
for (MessageReceiverListener l : this.messageReceiverListenerSet)
l.onAcceptDeliverSm(deliverSm);
}
And from here it does not have a value that an internal SmppInboundChannelAdapter AbstractReceivingMessageListener implementation does nothing in its onDeliveryReceipt, because your custom listener on the session can handle that.

Spring JMS Outbound Gateway receive timeout being ignored

I have a Spring Integration flow which sends a message out via a JMS Outbound Gateway which is configured to have a receive timeout of 45 seconds. I am trying to test the receive timeout period by sending a message out in a setup where the message is never consumed on the other side (therefore a response doesn't come back). However, when I run the test, the message is placed in the outbound queue but, the Outbound Gateway's receive timeout never occurs (after 45 seconds). Any ideas what reasons there could be for this happening (not happening)?
My stack is:
o.s.i:spring-integration-java-dsl:1.0.0.M3
o.s.i:spring-integration-jms:4.0.4.RELEASE
My IntegrationgConfig.class:
#Configuration
#EnableIntegration
public class IntegrationConfig {
...
#Bean
public IntegrationFlow testFlow() {
return IntegrationFlows
.from("test.request.ch")
.handle(Jms.outboundGateway(connectionFactory)
.receiveTimeout(45000)
.requestDestination("REQUEST_QUEUE")
.replyDestination("RESPONSE_QUEUE")
.correlationKey("JMSCorrelationID"))
.handle("testService",
"testMethod")
.channel("test.response.ch").get();
}
...
}
In terms of JMS configuration, the connection factory used is a standard CachingConnectionFactory which targets an MQConnectionFactory.
Thanks in advance for any help on this.
PM
--- UPDATE ---
I have turned on debugging and I can see that when the timeout occurs the following message is logged:
AbstractReplyProducingMessageHandler - handler 'org.springframework.integration.jms.JmsOutboundGateway#0' produced no reply for request Message: [Payload byte[835]][...]
Just need to find out how to capture this event in the flow?
--- UPDATE 2 ---
The message being sent out has an ERROR_CHANNEL header set on it to which I would expect the timeout exception to be routed to - but this routing does not happen?
Is it possible that the CachingConnectionFactory is handling the exception and not passing it back to the flow?
To make it working you need to add the second Lambda to the .handle() with Jms:
.handle(Jms.outboundGateway(connectionFactory)
.receiveTimeout(45000)
.requestDestination("REQUEST_QUEUE")
.replyDestination("RESPONSE_QUEUE")
.correlationKey("JMSCorrelationID"),
e -> e.requiresReply(true))
By default AbstractReplyProducingMessageHandler doesn't require reply even if receiveTimeout is exhausted, and we see that by logs shown by you.
However, I see that we should revise all MessageHandlerSpecs, because XML support changes the requires-reply for some components to true by default.
Feel free to raise a JIRA issue on the matter and we'll address it soon, because the GA release for Java DSL is planned over a week or two: https://spring.io/blog/2014/10/31/spring-integration-java-dsl-1-0-rc1-released
Thank you for the attention to this stuff!

How to trace log level changes caused by .ConfigureAndWatch

Using .ConfigureAndWatch we have configured log4net to reconfigure its logging level without restarting application processes.
A process start we trace the currently configured log level to our trace file.
How can we detect and trace to our trace files the log level changes happening through .ConfigureAndWatch?
I just (re)discovered that ILoggerRepository has a ConfigurationChanged event.
Tracing log level changes from there works fine.
private static void repository_ConfigurationChanged(object sender, System.EventArgs e)
{
var currentTracelLevel = ((log4net.Repository.Hierarchy.Logger)_trace.Logger).EffectiveLevel;
_trace.InfoFormat("----------------------------- log4net level={0}", currentTracelLevel);
}
You can activate the log4net internal debugging, then you will receive messages from the ConfigureAndWatchHandler class when a change occurs, either on the console or in the trace output (see link for more information)
re your comment: In order to pull back the event into your own code and not rely on the console or trace output I'd recommend creating a custom trace appender that loops back into log4net. This way you can filter out messages you want to bring back into your own logs.

Resources