So, we had a little ETL app that had some issues with updates. Which were nicely solved in an afternoon sprint with nHibernate. But this app relied upon log4net to push logging output to a few different destinations based upon command line switches. Once we got nHibernate wrapped into the app, it ETL'd flawlessly. But the logging functions failed completely. From the debugger's point of view, any of our loggers have all log4net's levels disabled.
Here's the log4net config:
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="import-" />
<staticLogFileName value="false" />
<appendToFile value="false" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="5" />
<datePattern value="yyyyMMdd-HHmm".log"" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level - %message%newline" />
</layout>
</appender>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level : %message%newline" />
</layout>
</appender>
<appender name="Email" type="log4net.Appender.SmtpAppender">
<to value="wwb#example.com" />
<from value="PeepsImporter#example.com" />
<subject value="Cte Importer Error" />
<smtpHost value="smtp.example.com" />
<bufferSize value="512" />
<lossy value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date %-5level : %message%newline%newline%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
</root>
<logger name="Console">
<level value="INFO" />
<appender-ref ref="Console" />
</logger>
<logger name="File">
<level value="INFO" />
<appender-ref ref="RollingFile" />
</logger>
<logger name="DebugConsole">
<level value="DEBUG" />
<appender-ref ref="Console" />
</logger>
<logger name="DebugFile">
<level value="DEBUG" />
<appender-ref ref="RollingFile" />
</logger>
<logger name="EmailErrors">
<level value="ERROR" />
<appender-ref ref="Email" />
</logger>
</log4net>
Not sure what other code would help, but I'm happy to post anything else from this app.
What version of NHibernate are you using? Builds older than 1.0-RC1 turned logging on internally. In 1.0-RC1 they changed this so you have to manually call log4net.XmlConfigurator.Configure(). This was done to give developers more control over logging.
You could try turning on the internal debugging in log4net: See this section in the following link:
"How do I enable log4net internal debugging?"
http://logging.apache.org/log4net/release/faq.html
Related
This is configuration
<log4net debug="true">
<appender name="RFileAppender" type="log4net.Appender.RollingFileAppender, log4net">
<File value="logs/file.txt" />
<AppendToFile value="true" />
<DatePattern value="_yyyyMMdd" />
<RollingStyle value="Date" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %date ==> %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RFileAppender" />
</root>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="mail" />
<from value="mail" />
<subject value="Service Error Log" />
<smtpHost value="SMTPServer.domain.com" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
</layout>
</appender>
<root>
<level value="Error" />
<appender-ref ref="SmtpAppender" />
</root>
</log4net>
This is the method I use to send the email
private void SendErrorLogByMail(string error)
{
mailLogger.Error(error);
}
I think it is the configuration, maybe something is missing or some wrong data but I don't know what, what did I do wrong? I put two appenders because the info and warning log levels must be written in the file, while the error levels in both the file and the mail
UPDATE
<log4net debug="true">
<appender name="RFileAppender" type="log4net.Appender.RollingFileAppender, log4net">
<File value="log.txt"/>
<AppendToFile value="true"/>
<DatePattern value="_yyyyMMdd"/>
<RollingStyle value="Date"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %date ==> %message%newline"/>
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="RFileAppender"/>
</root>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="from" />
<from value="to" />
<subject value="Error Log" />
<bufferSize value="512" />
<smtpHost value="smtp.gmail.com" />
<port value="587" />
<authentication value="Basic" />
<username value="***" />
<password value="***" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
</layout>
</appender>
<root>
<level value="Error" />
<appender-ref ref="SmtpAppender" />
</root>
</log4net>
Now when log4net is configured this error is returned:
log4net: ERROR [SmtpAppender] ErrorCode: GenericFailure. Error occurred while sending e-mail notification.
System.Net.Mail.SmtpException: The SMTP server requires a secure connection or the client has not been authenticated. Server response: 5.7.0 Must issue a STARTTLS command first. v18sm36645763edx.30 - gsmtp
in System.Net.Mail.MailCommand.CheckResponse (SmtpStatusCode statusCode, String response)
in System.Net.Mail.MailCommand.Send (SmtpConnection conn, Byte [] command, String from)
in System.Net.Mail.SmtpTransport.SendMail (MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException & exception)
in System.Net.Mail.SmtpClient.Send (MailMessage message)
in log4net.Appender.SmtpAppender.SendEmail (String messageBody)
in log4net.Appender.SmtpAppender.SendBuffer (LoggingEvent [] events)
Look. I'm just seeing your configuration and did you try to change tag value for another host, like Gmail?
I don't have experience with log4net but sometimes when something is wrong to send an email, probably can be the SMTP host, port.
Make senses ?
This is how I create Session Factory using Fluent Nhibernate
public static ISessionFactory CreateSessionFactory()
{
FluentNHibernate.Cfg.FluentConfiguration fconfig;
fconfig = FluentNHibernate.Cfg.Fluently.Configure()
.Cache(c=>c.UseQueryCache())
.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.FromConnectionStringWithKey("Database"))
.ProxyFactoryFactory<NHibernate.ByteCode.LinFu.ProxyFactoryFactory>()
.Mappings(
m => m.FluentMappings
.AddFromAssemblyOf<NHibernateRepositoryRegistry>()
.Conventions.Add<Conventions.PrimaryKeyConvention>()
.Conventions.Add<Conventions.IdForeignKeyConvention>()
.Conventions.Add<Conventions.ReferenceForeignKeyConstraintNameConvention>()
)
// i have tried this but it did not work
//.ExposeConfiguration(config=>{config.SetProperty("show_sql", "false");});
return fconfig.BuildSessionFactory();
}
This is my log4net config inside Web.config
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="nhibernate.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %thread %logger - %message%newline" />
</layout>
</appender>
<appender name="RollingFile2" type="log4net.Appender.RollingFileAppender">
<file value="nhibernatesql.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %thread %logger - %message%newline" />
</layout>
</appender>
<logger name="NHibernate">
<level value="INFO" />
<appender-ref ref="RollingFile" />
</logger>
<logger name="NHibernate.SQL">
<level value="ALL" />
<appender-ref ref="RollingFile2" />
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
I had ShowSql() setup perviously
and I was trying to set it via web.config appsettings so i can turn on or off based on configuration
so I removed ShowSql() and tried following ( right now i am just passing "false" value )
.ExposeConfiguration(config=>{config.SetProperty("show_sql", "false");});
also tried
.ExposeConfiguration(config=>{config.SetProperty("hibernate.show_sql", "false");});
but I am still getting sql generated in nhibernatesql.log file
I am using NHibernate v3.1.0.4000 and FluentNHibernate v1.2.0.712 and ASP.NET MVC3
does anyone know why sql is still generating?
does show_sql or ShowSql() is only meant for Console.output purpose and sql is sent to log4net regardless ?
my main concern is slow performance if ShowSQL is set to true
not sure whether I am setting ShowSql somewhere else
ok I think I got the answer
based on http://www.davesquared.net/2008/01/viewing-sql-generated-by-nhibernate.html
show_sql is used of Console.out purpose only and sql is sent to log4net regardless.. and that is why I am seeing sql in the logs
I need to show the previous 10 events when a particular logger is triggered. The goal is to show what previous steps occurred immediately before NHibernate.SQL logging was issued.
Currently, I am logging NHibernate sql to a separate file - this is working correctly.
<appender name="NHibernateSqlAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\NHibernate.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{dd/MM/yy HH:mm:ss,fff} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<logger name="NHibernate.SQL" additivity="false">
<level value="ALL"/>
<appender-ref ref="NHibernateSqlAppender"/>
</logger>
<logger name="NHibernate" additivity="false">
<level value="WARN"/>
<appender-ref ref="NHibernateSqlAppender"/>
</logger>
But this only outputs SQL, without context. I would like all previous logs within a specified namespace to also be logged, but only when the HNibernate.SQL appender is triggered.
I have investigated the use of BufferingForwardingAppender as a means to collect all events, and then filter them within the NHibernateSqlAppender, but this is not working. I have read about the LoggerMatchFilter class, which seems like it is going to help, but I'm not sure where to put it.
<appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender" >
<bufferSize value="10" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ALL"/>
</evaluator>
<appender-ref ref="NHibernateSqlAppender" />
</appender>
<appender name="NHibernateSqlAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\NHibernate.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000KB" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="NHibernate.SQL" />
<loggerToMatch value="Laan" />
</filter>
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="NHibernate" />
<acceptOnMatch value="false"/>
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{dd/MM/yy HH:mm:ss,fff} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="BufferingForwardingAppender"/>
</root>
The idea is that buffering appender will store all events, but then the NHibernateSqlAppender will only flush when an NHibernate.SQL event fires, plus it will flush the buffer (of 10 previous items, within the specified logger level, which in this example is Laan.*).
I would implement ITriggeringEventEvaluator that returns true in the IsTriggeringEvent() method when a certain logger (ideally configurable) fires. Have a look a the implementation of the LevelEvaluator class, it should be quite easy. The code would look like this:
public bool IsTriggeringEvent(LoggingEvent loggingEvent)
{
if (loggingEvent == null)
{
throw new ArgumentNullException("loggingEvent");
}
return (loggingEvent.LoggerName == triggeringLoggerName);
}
With this new evaluator your configuration should work though you should remove the filters (I guess).
I am using log4Net in my application which also uses nHibernate. Now my eventlogger is flooded with nHibernate messages which I want to suppress.
I have tried this but it did not work.
<log4net>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<param name="LogName" value="App Log" />
<param name="ApplicationName" value="DataService" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="NHibernate*" />
<acceptOnMatch value="false" />
</filter>
</appender>
<root>
<priority value="ALL"/>
<appender-ref ref="EventLogAppender"/>
</root>
</log4net>
You can add a logger for nHibernate and set up a different level:
<logger name="NHibernate" additivity="false">
<level value="WARN"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
you should use
<loggerToMatch value="NHibernate.*" /> or <loggerToMatch value="NHibernate" />
not
<loggerToMatch value="NHibernate*" />
you can find details in regex rules
I have this in my web.config file (edited to reflect some changes):
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net debug="true">
<appender name="DebugAppender" type="log4net.Appender.AspNetTraceAppender">
<layout type="log4net.Layout.PatternLayout, log4net">
<param name="ConversionPattern" value="%d %p %m%n" />
</layout>
</appender>
<appender name="DataLog" type="log4net.Appender.RollingFileAppender">
<file value="c:\temp\nhlog.txt" />
<appendToFile value="true" />
<maximumFileSize value="100MB" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<priority value="DEBUG" />
<appender-ref ref="DebugAppender" />
</root>
<logger name="NHibernate" additivity="false">
<level value="INFO"/>
<appender-ref ref="DebugAppender"/>
</logger>
</log4net>
I'm calling log4net.Config.XmlConfigurator.Configure() from Application_Start().
I have [assembly: log4net.Config.XmlConfigurator(Watch = true)] in the AssemblyInfo.cs file in my web project.
Why do I get no NHibernate debugging messages in my output window? (I trying to get ALL of the messages that NHibernate spits out.) If I use the RollingFileAppender it works fine. I've tried the DebugAppender, TraceAppender, OutputDebugStringAppender, and AspNetTraceAppender and none of them output stuff to the output window.
Try using a different appender.
ConsoleAppenders probably don't work for web applications. Use something like a FileAppender.
See this for examples on configuraiton.
Similar to quip's answer, ConsoleAppender is not the right appender to use in a web application. An OutputDebugStringAppender will give you messages in your debug window. You may also want to look into AspNetTraceAppender.
You could try to associate the specific NHibernate logger with a log4net appender.
If you want to log all the generated sql, try adding this to your log4net config section:
<logger name="NHibernate.SQL" additivity="false">
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</logger>
If, for some reason, you only wanted to log Select statements and diagnostic info, you could use NHibernate.Loader.Loader, like this:
<logger name="NHibernate.Loader.Loader" additivity="false">
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
</logger>