NHibernate Doesn't Log Errors - nhibernate

I'm getting an NHibernate exception that I want to try to get more info on, but it doesn't seem to be logging errors. I was actually looking to get more granular error info, but discovered the initial problem of not logging errors at all.
Here's my log4net sectionf rom config file:
<log4net>
<appender name="NHibernateAppender" type="log4net.Appender.RollingFileAppender">
<file value=".\\Logs\\NHibernate.log" />
<appendToFile value="true" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000KB" />
<rollingStyle value="Size" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="[Header]
" />
<footer value="[Footer]
" />
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="NHibernateSQLAppender" type="log4net.Appender.RollingFileAppender">
<file value=".\\Logs\\NHibernate.Sql.log" />
<appendToFile value="true" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000KB" />
<rollingStyle value="Size" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="[Header]
" />
<footer value="[Footer]
" />
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<logger name="NHibernate" additivity="false">
<level value="ERROR" />
<appender-ref ref="NHibernateAppender" />
</logger>
<logger name="NHibernate.SQL" additivity="false">
<level value="ERROR" />
<appender-ref ref="NHibernateSQLAppender" />
</logger>
</log4net>
I've tried "ALL" as well; it writes "DEBUG" and "INFO", but no "ERROR" entries. Any suggestions? Thanks!

If you add this into your web.config:
<appSettings>
...
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
And:
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="log.txt" />
</listeners>
</trace>
</system.diagnostics>
This will show up any problems log4net may be having itself, e.g. trying to configure your appenders.

Related

Log4Net doesn't send e-mail

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 ?

Filter Asp.netcore logs in Log4Net

I am using ASP.NET Core and have created a Log4net logging provider.
My current log4net.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\\" />
<appendToFile value="true" />
<DatePattern value="yyyy\\\\MM\\\\dd'.inf.log'" />
<rollingStyle value="Date" />
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] <%property{auth}> - %message%newline" />
</layout>
</appender>
<appender ref="HangfireLoggerAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\HangfireLog.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<logger additivity="false" name="Hangfire">
<level value="INFO" />
<appender-ref ref="HangfireLoggerAppender" />
</logger>
</log4net>
The log is showing A LOT of asp.net core junk. SQL Logs ect.
I would like to filter out :
Microsoft.AspNetCore.*
Microsoft.EntityFrameworkCore.*
How do I do this with Log4net?
you need to configure logging on your WebHostBuilder as follows :
[Program.cs -> BuildWebHost(string[] args) ]
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
ConfigureLogging((hostingContext, logging) =>
{ logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddFilter("Microsoft.AspNetCore", LogLevel.Information);
logging.AddFilter(" Microsoft.EntityFrameworkCore", LogLevel.Information);
logging.AddConsole();
logging.AddDebug();
})
.Build();
You call the logging.AddFilter method specifying the namespace as first parameter and LogLevel as the second parameter.
This can be also done using configuration in appsettings.json file if you don't want to do in code. You can read more here

OAuthWebSecurity.VerifyAuthentication IsSuccessful returns false how do I to determine the reason?

I'm using DotNetOpenAuth with a MVC 4 application. All the sudden Google auth is failing (MS is working). The stock code does this:
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
var result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
I know that result.IsSuccessful is false, but how do I get the reason? result.Error is null.
I also looked at this page to use log4net. I do get a log on the local dev box but not when I deploy it to a remote server.
log4net webconfig:
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="RelyingParty.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="INFO" />
<appender-ref ref="RollingFileAppender" />
</root>
<!-- Specify the level for some specific categories -->
<logger name="DotNetOpenAuth">
<level value="ALL" />
</logger>
</log4net>
Edit I also tried log4net to a sql db but it still didn't log anything
I finally figured this out. The actual error message I was getting:
Protocol error: This message has a timestamp of 10/23/2012 12:19:33 PM,
which is beyond the allowable clock skew for in the future.
Turns out after a server crash the timezone didn't get set correctly. This caused the validation/token to fail from google's end.
The AdoNetAppender was "not working" because bufferSize was set to 100. After setting it to 1 it started getting logs. Here is the adonetappender I'm using
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionStringName value="CONNECTIONSTRINGNAME" />
<commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception)" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="Debug" />
<appender-ref ref="AdoNetAppender" />
</root>
<logger name="DotNetOpenAuth">
<level value="ALL" />
</logger>
</log4net>
You should set the bufferSize back to 100 when you get your issue worked out.

How can I get the previous logged events when a particular logger is triggered?

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).

nHibernate disables my log4net logs

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