Log4Net ADO.net Info Buffer - asp.net

Is there a way I can configure the AdoNetAppender to log every time a value of type 'Error' is reached, and log only the last 10 statements of lower threshold (i.e. info) prior to that statement.
Is that possible? I'm running up hundreds of .Info statements for each individual error and I don't need that many... just enough to see what happened right beforehand.
edit - here is my current appender configuration:
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="10" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXX" />
<connectionString value="Data Source=XXXXXXX; Database=XXXXXXXXXXX; User Id=XXXXXXX; Password=XXXXXXXX; Connection Timeout=30; Min Pool Size=10; Max Pool Size=200;" />
<commandText value="INSERT INTO Log ([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="ALL" />
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="AspNetTraceAppender" />
</root>
Thanks,
Kyle

Found the solution here:
http://www.beefycode.com/post/Log4Net-Tutorial-pt-8-Lossy-Logging.aspx
<lossy value="true"/>
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR" />
</evaluator>

Related

Migrating from older .NET Framework to .NET 6, log4net conversionPattern not working anymore

I'm trying to get the AUTH_USER, REMOTE_ADDR, HTTP_USER_AGENT, QUERY_STRING, REQUEST_METHOD like this, works fine in the older .NET Framework solution but it does not work in my .NET6 solution, the conversionpatterns do not convert it to any value, in the database for example the HTTP_USER_AGENT gets saved like this in my log database table: AddressFormspnet-request{HTTP_USER_AGENT} instead of converting it. Is there some other way I have to do it in .NET6?
<parameter>
<parameterName value="#username" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%aspnet-request{AUTH_USER}" />
</layout>
</parameter>
<parameter>
<parameterName value="#ipaddress" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%aspnet-request{REMOTE_ADDR}" />
</layout>
</parameter>
<parameter>
<parameterName value="#useragent" />
<dbType value="String" />
<size value="150" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%aspnet-request{HTTP_USER_AGENT}" />
</layout>
</parameter>
<parameter>
<parameterName value="#url" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%aspnet-request{URL} %aspnet-request{QUERY_STRING}" />
</layout>
</parameter>
<parameter>
<parameterName value="#method" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%aspnet-request{REQUEST_METHOD}" />
</layout>
</parameter>

Log4net AdoNetAppender Rolling table

I am using MicroKnights.Logging.AdoNetAppender for my .Net core 3.1 application.
I want rolling table name for log table (new table for every month's logs).
Is there any possibilities to achieve this by making any changes in log4net.config file?
My log4net.config looks like below
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
<appender name="DebugAppender" type="log4net.Appender.DebugAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="Log\logs_" />
<staticLogFileName value="false" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="yyyy-MM-dd'.log'" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>
</appender>
<appender name="AdoNetAppender" type="MicroKnights.Logging.AdoNetAppender, MicroKnights.Log4NetAdoNetAppender">
<bufferSize value="1" />
<connectionType value="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient, Version=1.0.0.0,Culture=neutral,PublicKeyToken=23ec7fc2d6eaa4a5"/>
<connectionStringName value="log4net" />
<connectionStringFile value="appsettings.json" />
<commandText value="INSERT INTO [Log_#TableName]
([ApiName]
,[RequestTimeUtc]
,[TimeElapsed]
,[Headers]
,[Body]
,[QueryString])
VALUES
(#ApiName
,#RequestTimeUtc
,#TimeElapsed
,#Headers
,#Body
,#QueryString)" />
<parameter>
<parameterName value="#TableName" />
<dbType value="String" />
<size value="10000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{TableName}" />
</layout>
</parameter>
<parameter>
<parameterName value="#ApiName" />
<dbType value="String" />
<size value="10000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{ApiName}" />
</layout>
</parameter>
<parameter>
<parameterName value="#RequestTimeUtc" />
<dbType value="DateTime" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{RequestTimeUtc}" />
</layout>
</parameter>
<parameter>
<parameterName value="#TimeElapsed" />
<dbType value="String" />
<size value="10000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{TimeElapsed}" />
</layout>
</parameter>
<parameter>
<parameterName value="#Headers" />
<dbType value="String" />
<size value="10000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Headers}" />
</layout>
</parameter>
<parameter>
<parameterName value="#Body" />
<dbType value="String" />
<size value="10000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Body}" />
</layout>
</parameter>
<parameter>
<parameterName value="#QueryString" />
<dbType value="String" />
<size value="10000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{QueryString}" />
</layout>
</parameter>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="DebugAppender" />
<appender-ref ref="RollingFile" />
<appender-ref ref="AdoNetAppender" />
</root>
</log4net>
Executing Stored Procedure looks last option to me.
Modify the config with
<commandText value="INSERT INTO {0}
([ApiName]
,[RequestTimeUtc]
,[TimeElapsed]
,[Headers]
,[Body]
,[QueryString])
VALUES
(#ApiName
,#RequestTimeUtc
,#TimeElapsed
,#Headers
,#Body
,#QueryString)" />
And init log4net as follow:
public IEnumerable<string> InitializeLog4Net()
{
var repository = LogManager.GetRepository(GetType().Assembly);
ConnectionString = _configuration.GetConnectionString("DefaultConnection");
if (string.IsNullOrWhiteSpace(ConnectionString))
throw new NullReferenceException($"Did not find the connectionString");
var log4NetConfigFilename = $"Logging\\log4net.config";
var fileInfo = new FileInfo(log4NetConfigFilename);
if (fileInfo.Exists == false)
throw new FileNotFoundException($"Did not find log4net configuration file \"{log4NetConfigFilename}\"");
XmlConfigurator.Configure(repository, fileInfo);
if (repository.Configured == false)
throw new InvalidOperationException("Repository not configured");
if (repository.ConfigurationMessages.Count != 0)
throw new InvalidOperationException($"Repository messages found: {string.Join(",", repository.ConfigurationMessages)}");
foreach (var appender in repository.GetAppenders())
{
if (appender is AdoNetAppender adoNetAppender)
{
adoNetAppender.CommandText = string.Format(adoNetAppender.CommandText, TableName);
adoNetAppender.ConnectionString = ConnectionString;
adoNetAppender.ErrorHandler = this;
adoNetAppender.ActivateOptions();
}
}
return _log4netErrors;
}
Generate problematically the TableName or take it from appsettings.json

Log4net RollingFileAppender missing entries logged from Web API async method

I'm finding that entries logged from an async Web API 2 method are not being logged by the RollingFileAppender, however they are being logged AdoNetAppender.
My log4net configuration is as follows:-
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="Log\\MyLog.log" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="500" />
<param name="MaximumFileSize" value="100KB" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %property{Url} %-5p %c - %m%n" />
</layout>
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<threshold value="INFO" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<commandText value="INSERT INTO tblErrorLog ([EventDate],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception)" />
<usetransactions value="false" />
<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">
<conversionPattern value="%exception" />
</layout>
</parameter>
</appender>
<root>
<!-- Setup the root category, add the appenders and set the default priority -->
<priority value="ALL" />
<appender-ref ref="RollingLogFileAppender" />
<appender-ref ref="AdoNetAppender" />
</root>
</log4net>
Whats the fix for this?

Need to understand Log4Net Configuration section WebForm

i was thinking to use Log4Net for our webform application in asp.net. so i checked few article on this but i saw all article not saying about each property regarding configuration.
so i apologized that i have to paste bit big config section here and looking for some one who can help me to understand each property usage.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<log4net>
<appender name="DbAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value="0" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="{auto}" />
<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="%t" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%p" />
</layout>
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="1000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%c" />
</layout>
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%m" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="DbAppender" />
</root>
</log4net>
</configuration>
please see the above config details and answer each property.
1) why <bufferSize value="0" /> is set to 0 ? when one should set other value to bufferSize property ?
2) <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
how do i know what PublicKeyToken value i need to use.
3) what is the meaning of connection string auto <connectionString value="{auto}" /> ?
4)
what is the meaning of conversionPattern or
5 what is ExceptionLayout <layout type="log4net.Layout.ExceptionLayout" />
6) what is the meaning of below xml
<root>
<level value="INFO" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="DbAppender" />
</root>
what is RollingFileAppender ?
what is DbAppender ?
please discuss about my each point & question. thanks
1/ bufferSize <= 1 means no buffering. Log is written instantly to the database.
http://logging.apache.org/log4net/release/sdk/log4net.Appender.BufferingAppenderSkeleton.BufferSize.html
2/ PublicKeyToken is not Log4net related. Have a look. Keep the given token.
3/ {auto} in connectionString seems to be custom code, maybe taken from here
4/ List of conversion patterns
5/ Exception layout: only the exception text from the logging event will be logged.
http://logging.apache.org/log4net/release/sdk/log4net.Layout.ExceptionLayout.html
6/
FileAppender -> log to file.
RollingFileAppender -> log to file with rotating logs (max N files of length L, then they are erased).
DbAppender -> log to database, that's why there is a connectionString.
More info: http://logging.apache.org/log4net/release/config-examples.html

Log4Net is not working with Sql Server 2005

I want to make Log4Net to enter logs in MS Sql Server 2005. I am using .NET 2.0.
Here is the code till now I have written:
Web.Config File
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<connectionStrings/>
<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" />
<connectionString value="Data Source=XYZ;Initial Catalog=ACC;Integrated Security=True" />
<commandText value="INSERT INTO Log ([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>
</log4net>
Global.asax
<%# Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
log4net.Config.XmlConfigurator.Configure();
}
Page_load
try
{
// There is no such Session, this is just to create error
if (Session["userName"].ToString() == "Admin")
{
}
}
catch(Exception ex)
{
log4net.ILog log =log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log4net.Config.XmlConfigurator.Configure();
log.Debug("log Debug",ex);
log.Info("log Info",ex);
log.Warn("log Warn",ex);
log.Error("log Error",ex);
log.Fatal("log Fatal",ex);
}
Actually I have tried it by storing lod details in Log folder in my directory, which was working fine. But I want to store information in Sql Server 2005.
Am I missing something? or I have to correct some where.
Please help.
Thanks in advance
Unless I made some mistake when I edited your question, then the problem is that you do not reference the appender like this:
<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender" />
</root>
Some further comments:
You do not need to call the Configure method twice
You do not need an exception to test logging

Resources