I'm trying to implement a fire-and-forget flow to log messages on a database by calling an Oracle procedure, everything works fine but I'd like to log any exception I get when, by any chance, I misconfigured the xml or whatever else could go wrong (any exception thrown by the procedure?).
I've searched for quite some time but I'm probably missing out something...
Here's the actual setting:
I've got a gateway interface
public interface gatewayInterfaceDEF{
void monitoring(Object payload);
}
XML definition of the gateway
<int:gateway service-interface="gatewayInterfaceDEF">
<int:method name="monitoring" request-channel="monitoringGatewayInbound" />
</int:gateway>
Then the JDBC-outbound-gateway xml configuration that calls an oracle procedure:
<int:channel id="monitoringGatewayInbound">
<int:dispatcher task-executor="monitoringTaskExecutor"/>
</int:channel>
<int-jdbc:stored-proc-outbound-gateway
id="monitoringGatewayProcedure" request-channel="monitoringGatewayInbound"
data-source="dataSource" stored-procedure-name="procedureName"
return-value-required="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition
someparameters />
<int-jdbc:parameter parameter mapping />
</int-jdbc:stored-proc-outbound-gateway>
Thanks in advance
I've found this: http://java.dzone.com/articles/spring-async-and-exception
But it's not working: could it be me not being able to implement it, but still.
UPDATE: the wrapped log I get.
|TEST|2014-10-17 17:09:08,999|||059EF53A6C4D2F67E0540003BA7A7C43|[monitoringTaskExecutor-1]|INFO |STDOUT|17:09:08,999 ERROR [LoggingHandler] org.springframework.integration.MessageHandlingException: error occurred in message handler [org.springframework.integration.jdbc.StoredProcOutboundGateway#0]
UPDATE2: the jboss-log4j.xml I'm using
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDFILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
<param name="append" value="true" />
<param name="file" value="/var/share/test/logs/test-ws_out.log" />
<param name="datePattern" value="yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="TEST|%d|%X{req.remoteHost}|%X{sessionid}|%X{lcontext}|[%t]|%-5p|%c|%m%n|" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="STDFILE" />
</root>
</log4j:configuration>
Since you are using ExcutorChannel, any Exception from the downstream flow is wrapped to the ErrorMessage and sent to the default errorChannel: http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/configuration.html#namespace-errorhandler
By default all those exceptions are looged by LoggingHandler under category org.springframework.integration.handler with ERROR level.
From other side you can add ExpressionEvaluatingRequestHandlerAdvice to the <int-jdbc:stored-proc-outbound-gateway>: http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/messaging-endpoints-chapter.html#expression-advice
And get deal with exception just only on that target MessageHandler
Related
I have NLog configuration that pushes data to Elastic. When the index pattern is static everything works fine. When I change it to be time-based, I can see messages coming to datastream (with the name of the index from configuration), but this datastream is creating .ds-* index which does not follow the name from the pattern. Therefore logs are not visible in Kibana. I have action.auto_create_index even set to true. What am I missing to have this working properly?
Here is NLog.config part related to elastic:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
<add assembly="NLog.Targets.ElasticSearch"/>
<add assembly="NLog.StructuredLogging.Json"/>
</extensions>
<variable name="AspData" value="${when:when=length('${aspnet-request-url}') > 0:inner=|url\: ${aspnet-request-url}}${when:when=length('${aspnet-mvc-action}') > 0:inner=|action\: ${aspnet-mvc-action}}" />
<variable name="ExceptionLayout" value="${onexception:${newline}EXCEPTION - ${exception:format=type,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}" />
<variable name="LoggingLayout" value="${longdate}|EV[${event-properties:item=EventId_Id}]|TH[${threadname:whenEmpty=${threadid}}]|${mdc:userId}|${uppercase:${level}}|${logger}|${message} ${AspData} ${ExceptionLayout}" />
<!-- the targets to write to -->
<targets>
<!--<default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>-->
<!-- write logs to file -->
<target name="asyncElastic" xsi:type="AsyncWrapper">
<target name="elasticLog" xsi:type="ElasticSearch" index="logs-${configsetting:item=ElasticLog.ServiceName}-${date:format=yyyy-MM-dd}"
uri="${configsetting:item=ElasticLog.ServerUrl}" requireAuth="true" username="${configsetting:item=ElasticLog.User}" password="${configsetting:item=ElasticLog.Password}"
layout ="${LoggingLayout}" >
<field name="data" layout="${structuredlogging.json}" layoutType="System.Object" />
<field name="serviceName" layout="${configsetting:item=ElasticLog.ServiceName}" layoutType="System.String" />
<field name="userId" layout="${mdc:userId}" layoutType="System.String" />
</target>
</target>
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.EntityFrameworkCore.Database.Command" maxlevel="Debug" final="true" />
<logger name="Microsoft.EntityFrameworkCore.Database.Command" maxlevel="Warning" writeTo="asyncElastic" final="true" />
<logger name="Elastic.Apm" maxlevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="asyncElastic" />
</rules>
</nlog>
Edit:
After further investigation I found out that default Kibana installation has index template called logs with pattern logs-*-*. This template treats this indice with that pattern as datastream and not index. So if I wanted to have indexes all I had to do is change my index name to not follow that pattern.
I am trying to configure my .NET Core Application with Graylog v2.5. I am using log4net to log messages.
I have used below configuration to setup the environment. I have intentionally raised exception in my WebAPI controller to validate Graylog setup.
<appender name="AsyncGelfUdpAppender" type="Gelf4Net.Appender.AsyncGelfUdpAppender, Gelf4Net">
<!-- Number of log lines to buffer for async send. Defaults to 10-->
<bufferSize value="20" />
<!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
<threads value="2" />
<remoteAddress value="127.0.0.1" />
<remotePort value="6789" />
<layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
<param name="AdditionalFields" value="app:AsyncUdpAppender,version:1.0,Environment:Dev,Level:%level" />
<param name="Facility" value="RandomPhrases" />
<param name="IncludeLocationInformation" value="true" />
<param name="SendTimeStampAsString" value="true" />
</layout>
I am not getting any error. At the same time, I am not getting any output. Below is the output shown in browser.
Can anyone please suggest me what I am doing wrong? What do I need to do to be able to show log messages in the Graylog interface? Where exactly I can see the log messages? I could not get any help from Google and I am pretty new to Graylog.
Make sure you are using the rules used by the Stream setup in Graylog.
For example, in this Stream, the property AppName must match exactly the same name as defined in Graylog (MyAppName).
Also, make sure your computer was given permission to write to that stream in Graylog.
Solution 1:
Add field to AdditionalFields
<log4net>
...
<param name="AdditionalFields" value="app:DotnetcoreUdpAppender,version:1.0,Environment:Dev,AppName:MyAppName" />
...
</log4net>
Solution 2: Add field to data object:
protected static readonly ILog log = LogManager.GetLogger("GelfUdpAppender");
Dictionary<string, string> logData = new Dictionary<string, string>
{
{"AppName", "MyAppName"}, // pass your property rule here
{"Message", message},
};
log.Info(logData);
<log4net>
<appender name="GelfUdpAppender" type="Gelf4Net.Appender.GelfUdpAppender, Gelf4Net.UdpAppender">
<remoteAddress value="server-name" />
<remotePort value="12201" />
<layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.UdpAppender">
<param name="AdditionalFields" value="app:DotnetcoreUdpAppender,version:1.0,Environment:Dev" />
<param name="Facility" value="test" />
<param name="IncludeLocationInformation" value="true" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="GelfUdpAppender" />
</root>
</log4net>
I am currently switching from static configs to using mod_xml_curl and have encountered a problem with setting up call groups.
Inside my dialplan (served dynamically, working as expected) I am bridging to a group:
<action application="bridge" data="${group_call(call-group#domain-a.com)}"/>
Freeswitch is making a request with section=directory&action=group_call to the web server, to which I respond with a chunk of the directory containing the group and all relevant users:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="freeswitch/xml">
<section name="directory">
<domain name="domain-a.com">
<params>
<param name="dial-string" value="{presence_id=${dialed_user}#${dialed_domain}}${sofia_contact(${dialed_user}#${dialed_domain})}" />
</params>
<variables>
<variable name="user_context" value="domain-a.com" />
</variables>
<group name="call-group">
<users>
<user id="john" number-alias="1000">
<params>
<param name="password" value="1234" />
<param name="vm-password" value="1000" />
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local" />
<variable name="accountcode" value="1000" />
<variable name="outbound_caller_id_name" value="John at domain-a.com" />
<variable name="outbound_caller_id_number" value="1234567" />
</variables>
</user>
<user id="lucy" number-alias="1001">
<params>
<param name="password" value="1234" />
<param name="vm-password" value="1000" />
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local" />
<variable name="accountcode" value="1001" />
<variable name="outbound_caller_id_name" value="Lucy" />
<variable name="outbound_caller_id_number" value="12345678" />
</variables>
</user>
</users>
</group>
</domain>
</section>
</document>
However, group_call() seems to fail and in the logs I get ``:
2016-02-24 10:42:14.249534 [DEBUG] mod_dptools.c:1498 SET sofia/internal/michael#domain-a.com [call_timeout]=[15]
2016-02-24 10:42:14.529107 [CONSOLE] mod_xml_curl.c:323 XML response is in /tmp/2f772a8a-4c3a-46f2-834f-b9ba2c735feb.tmp.xml
EXECUTE sofia/internal/michael#domain-a.com bridge(error/NO_ROUTE_DESTINATION)
Perhaps anyone has experience setting up group calls with mod_xml_curl and could explain what exactly Freeswitch is expecting in the response?
After a little gnashing of teeth, I got this working. The clue was here underneath the group_call description:
Please note: If you need to have outgoing user variables set in leg B,
make sure you don't have dial-string and group-dial-string in your
domain or dialed group variables list; instead set dial-string or
group-dial-string in the default group of the user. This way
group_call will return user/101 and user/ would set all your user
variables to the leg B channel.
So, when you receive an action of type group_call, move the dial-string param to the group level, so instead of
<domain name="domain-a.com">
<params>
<param name="dial-string" value="{presence_id=${dialed_user}#${dialed_domain}}${sofia_contact(${dialed_user}#${dialed_domain})}" />
</params>
<variables>
<variable name="user_context" value="domain-a.com" />
</variables>
<group name="call-group">
<users>
<user id="john" number-alias="1000">
...
send this
<domain name="domain-a.com">
<variables>
<variable name="user_context" value="domain-a.com" />
</variables>
<group name="call-group">
<params>
<param name="dial-string" value="{presence_id=${dialed_user}#${dialed_domain}}${sofia_contact(${dialed_user}#${dialed_domain})}" />
</params>
<users>
<user id="john" number-alias="1000">
...
After I made that change, everything was hunky dory. Cheers!
It's related to your dialplan.It's not generated perfectly. just check the domain-a.com context in the dialplan.
I'm interested in defining multiple event-types my app.config file but it doesn't appear to get loaded by default. Is there something that I'm doing wrong? The event type doesn't exist within com.espertech.esper.client.Configuration.
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net" />
<section name="esper-configuration" type="com.espertech.esper.util.EsperSectionHandler,NEsper" />
</configSections>
<esper-configuration>
<engine-settings>
<defaults>
<threading>
<listener-dispatch preserve-order="false" timeout-msec="2000" locking="suspend" />
<insert-into-dispatch preserve-order="false" timeout-msec="3000" locking="suspend" />
<internal-timer enabled="false" msec-resolution="1234567" />
<thread-local style="fast" />
</threading>
<event-meta>
<class-property-resolution style="distinct_case_insensitive" />
</event-meta>
<view-resources>
<share-views enabled="false" />
</view-resources>
<logging>
<execution-path enabled="true" />
</logging>
<variables>
<msec-version-release value="30000" />
</variables>
</defaults>
</engine-settings>
<event-type name="Products" class="ProtoProduct"/>
<event-type name="MarketDepths" class="ProtoDepth"/>
<event-type name="MarketTrades" class="ProtoTrade"/>
<event-type name="Orders" class="ProtoOrder"/>
<event-type name="Positions" class="ProtoPosition"/>
<auto-import import-name="org.mycompany.mypackage.MyUtility"/>
<auto-import import-name="org.mycompany.util.*"/>
</esper-configuration>
The most likely issue is that you haven't used the fully qualified name of the class. In your examples, the classes have no namespace. If your classes are in a namespace add those to the class attribute in your config. If for some reason that isn't the issue, it is most likely that the tips are not visible within the AppDomain. Just make sure they are built into your assembly.
I'm trying to set up a small app to experiment with NHibernate in visual studio but I'm not getting far.
The error I get is: "Could not find the dialect in the configuration".
I've tried specifying settings in both app.config and hibernate.cfg.xml but neither seems to work. These files are in the same directory as my app source (tried other directories too). I've tried setting the build action on hibernate.cfg.xml as "embedded resource" but that didn't help either. I get the same error message even if I completely remove these config files.
I've looked at various examples on the net but can't get it sorted ... Does anyone know what the problem could be?
Here is my application source,app.config and hibernate.cfg.xml
Application Source
using NHibernate;
using NHibernate.Cfg;
namespace Timer
{
public partial class Form1 : Form
{
Configuration cfg;
ISessionFactory factory;
ISession session;
ITransaction transaction;
public Form1()
{
cfg = new Configuration();
//cfg.AddAssembly("Timer");
//cfg.AddFile("WorkoutSet.hbm.xml");
factory = cfg.BuildSessionFactory();
session = factory.OpenSession();
transaction = session.BeginTransaction();
InitializeComponent();
}
}
}
App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="nhibernate"
type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
<section
name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"
/>
</configSections>
<nhibernate>
<add
key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"
/>
<add
key="hibernate.dialect"
value="NHibernate.Dialect.FirebirdDialect"
/>
<add
key="hibernate.connection.driver_class"
value="NHibernate.Driver.FirebirdClientDriver"
/>
<add
key="hibernate.connection.connection_string"
value="User=sysdba;Password=masterkey;Database=C:\X\Test\Timer\Timer.FDB;Dialect=3;ServerType=1;"
/>
</nhibernate>
<log4net debug="false">
<!-- Define some output appenders -->
<appender name="trace"
type="log4net.Appender.TraceAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern"
value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<appender name="console"
type="log4net.Appender.ConsoleAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern"
value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<appender name="rollingFile"
type="log4net.Appender.RollingFileAppender,log4net" >
<param name="File" value="h:\log.txt" />
<param name="AppendToFile" value="false" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="yyyy.MM.dd" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern"
value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default priority -->
<root>
<priority value="DEBUG" />
<appender-ref ref="console" />
</root>
<logger name="NHibernate">
<level value="DEBUG" />
</logger>
</log4net>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly partialName="FirebirdSql.Data.FirebirdClient"
fullName="FirebirdSql.Data.FirebirdClient, Version=2.0.1.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" />
</assemblyBinding>
</runtime>
</configuration>
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="nhibernate"
type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
</configSections>
<nhibernate>
<add
key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"
/>
<add
key="hibernate.dialect"
value="NHibernate.Dialect.FirebirdDialect"
/>
<add
key="hibernate.connection.driver_class"
value="NHibernate.Driver.FirebirdClientDriver"
/>
<add
key="hibernate.connection.connection_string"
value="User=sysdba;Password=masterkey;Database=C:\X\Test\Timer\Timer.FDB;Dialect=3;ServerType=1;"
/>
</nhibernate>
</configuration>
ok thanks everyone, I've got it sorted now. It seems I needed to call cfg.Configure() to process hibernate.cfg.xml ... once I did this there were a few other errors but they were all quite logical to fix up with error messages that made good sense.
Here's the initialization code that worked.
public Form1()
{
cfg = new Configuration();
cfg.Configure();
factory = cfg.BuildSessionFactory();
session = factory.OpenSession();
transaction = session.BeginTransaction();
InitializeComponent();
}
If you're using NHibernate 2.0, but following instructions referring to 1.2, the configuration xml has changed and this will be causing your issue.
Try (in app.config, omit the configSections for a standalone file):
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.FirebirdDialect</property>
<property name="connection.driver_class">NHibernate.Driver.FirebirdClientDriver</property>
<property name="connection.connection_string">User=sysdba;Password=masterkey;Database=C:\X\Test\Timer\Timer.FDB;Dialect=3;ServerType=1;</property>
</session-factory>
</hibernate-configuration>
cfg.Configure();
really helped...Thanks a lot.
Earlier i was using
cfg.AddAssembly(Assembly.GetCallingAssembly());
without success