I'm trying to log my errors/warnings... in my DB using log4net (.NET 6).
I've tried even with different packages (Microknights) but it still won't save anything in my database.
Am I missing something?
When I'm debugging it seems to be hitting the right methods all the right times, with no exceptions raised.
This is the config file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<root>
<level value="ALL"></level>
<appender-ref ref="AdoNetAppender"></appender-ref>
</root>
<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="ConnectionStringDB" />
<commandText value="INSERT INTO dbo.Log4NetLog ([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>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\web-log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="50000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
</layout>
</appender>
</log4net>
<connectionStrings>
<add name="ConnectionStringDB" connectionString="Data Source=mydatabase;Initial Catalog=mycatalog;User Id=user;Password=password;TrustServerCertificate=true" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
And this is what I have in Program.cs:
var builder = WebApplication.CreateBuilder(args);
XmlConfigurator.Configure(new FileInfo("log4net.config"));
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddMemoryCache();
builder.Services.AddHttpContextAccessor();
builder.Host.ConfigureServices(services =>
{
//...services configuration
.
});
// Log4Net
builder.Host.ConfigureLogging(log =>
{
log.AddLog4Net("log4net.config");
log.SetMinimumLevel(LogLevel.Warning);
});
Here are a few things for you to check/fix...
In the database check that you have the correct table schema specified. The older AdoNetAppendeder class documentation shows the following table definition without an Exception column:
CREATE TABLE [dbo].[Log] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[Date] [datetime] NOT NULL ,
[Thread] [varchar] (255) NOT NULL ,
[Level] [varchar] (20) NOT NULL ,
[Logger] [varchar] (255) NOT NULL ,
[Message] [varchar] (4000) NOT NULL
) ON [PRIMARY]
To be current (and also using your custom table name) it should instead be:
CREATE TABLE [dbo].[Log4NetLog] (
[Id] [int] IDENTITY (1, 1) NOT NULL,
[Date] [datetime] NOT NULL,
[Thread] [varchar] (255) NOT NULL,
[Level] [varchar] (50) NOT NULL,
[Logger] [varchar] (255) NOT NULL,
[Message] [varchar] (4000) NOT NULL,
[Exception] [varchar] (2000) NULL
)
Also your configuration is formatted as though it's intended to be in an App.config or Web.config file but your program code is loading it from log4net.config instead. To use a standalone .config file like that you need to have <log4net> as the root element, i.e.:
<?xml version="1.0"?>
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender" />
</root>
<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="ConnectionStringDB" />
<commandText value="INSERT INTO dbo.Log4NetLog ([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>
Note that there's no <connectionStrings> element nor any other ASP.NET Core configuration in the above. To work around that you also need to replace the <connectionStringName> element with a <connectionString> element, i.e.:
<!-- ... --->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!-- NOPE: <connectionStringName value="ConnectionStringDB" /> -->
<connectionString value="Data Source=mydatabase;Initial Catalog=mycatalog;User Id=user;Password=password;TrustServerCertificate=true" />
<commandText value="INSERT INTO dbo.Log4NetLog ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception)" />
<!-- ... --->
Related
In properties of log I noticied all the level logs (IsErrorEnabled) have value false, in log.Logger.Repository.Configured has value false.
I dont know if LogManager can't find the log4net node in app.config or there's something wrong in xml.
I'm trying:
[TestMethod]
public void TestLog()
{
ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
log.Debug("teste");
}
Before, I used Sql and all worked perfectly, but since I changed to MySql the logs dont work anymore.
Can anyone help me?
This is my XML
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="Server=localserver;Database=DataBaseName;Uid=user;Pwd=pass;" />
<commandText value="INSERT INTO LogServico ([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" />
</root>
</log4net>
I'm find the errors.
Thanks [stuartd] for reply.
First I forget the XmlConfigurator.Configure()
After I enable the log4net debug by:
<add key="log4net.Internal.Debug" value="true"/>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
So Log4net logged the error:
The command text was wrong
"INSERT INTO LogServico ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception);"
The rigth way is:
"INSERT INTO LogServico (Date,Thread,Level,Logger,Message,Exception) VALUES (?log_date, ?thread, ?log_level, ?logger, ?message, ?exception);"
And change all parameter name to ?name like:
<parameterName value="?log_date" />
So my final app.config is:
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="Server=127.0.0.1;Database=dbname;Uid=user;Pwd=pass;" />
<commandText value="INSERT INTO LogServico (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" />
</root>
</log4net>
My funcional method test:
[TestMethod]
public void TestLog()
{
log4net.Config.XmlConfigurator.Configure();
ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
log.Error("test", new Exception("test"));
}
It's important remember all that is to log in mysql. In Sql the command text can use [namecolumn] and the parameter has #nameparameter
There are a number of possible reasons:
Your log4net config file is not set to "Copy Local" on build
You are not initialising log4net (ie calling XmlConfigurator.Configure or using an assembly attribute).
Your config is invalid.
As you say this worked previously, then it seems probable that it is 3, and your config is invalid.
I have Web API that needs to write log data, both to a file and to the database.
Is it possible to configure such a setup? I am trying to understand ILoggerRepository but I am confused.
Can someone give me the some tips on how to configure it and how to use it in application?
It sounds to me like you want to write to two different style appenders at the same time.
The good news is that this is built right into the log4Net library.
What you want to do so configure you configuration file to two different appenders. A file Appender and a Database appender.
Examples of the different appenders can be found here.
http://logging.apache.org/log4net/release/config-examples.html
Here is an example of an web.config that i whipped together. You are going to have to tweak it to get it to work for you, but it will get you on the right start.
One last point, your log4net configuration does not have to be in your web.config but IMHO it just makes things easier to get started. Worry about breaking it out once your web.config starts to get a little cluttered.
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />
<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="INFO" />
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
</configuration>
I am using log4net for my c# code to insert log into database using the configuration,
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection,
System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=[database server];
initial catalog=[database name];integrated security=false;
persist security info=True;User ID=[user];Password=[password]" />
<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>
So i just need to use their inbuilt functions for inserting data to table. Now i need to retrieve data from the log table. Is log4net providing any functions for retrieving data from table? Or the only way to retrive data from this table is writing my own query? Anyone please help me.
I haven't tried it, but a simple Google search got me to http://code.google.com/p/log4net-db-viewer/ and some other results.
It does not look like there is any built in reader for any appender.
Log4net does not give you any tools to read your logs. Its only for making logs and it depends on the appenders to format and save the logs somewhere. There are many projects and samples which can read your logs depending on your appender:
read log4net logs
I have an AdoNetAppender setup like this:
<log4net>
<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
<connectionStringName value="DefaultConnection" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (#log_date, #thread, #log_level, #logger, #message)" />
<useTransactions value="false" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout" value="%thread" />
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout" value="%level" />
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout" value="%logger" />
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout" value="%message" />
</parameter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="AdoNetAppender_SqlServer" />
</root>
</log4net>
And technically it works because when I stop the website that's running on IIS 8 Express locally the records show up. However, that's exactly the problem, the records don't show up until I stop the website.
I've tried with useTransactions on and off.
Can somebody help with this?
Try setting the buffer size to one:
<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
<connectionStringName value="DefaultConnection" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (#log_date, #thread, #log_level, #logger, #message)" />
<useTransactions value="false" />
<bufferSize value="1" />
Some more details: http://weblogs.asp.net/drnetjes/archive/2005/02/16/374780.aspx
in this time I try to log into a DB whit L4N, this is the struct of the table:
[TcpClientTracer]
[ID] [int] IDENTITY(1,1) NOT NULL,
[Date] [datetime] NOT NULL,
[Thread] [varchar](20) NOT NULL,
[EventType] [varchar](20) NOT NULL,
[ClientId] [int] NOT NULL,
[ModemId] [varchar](128) NOT NULL,
[EventText] [varchar](2000) NOT NULL
to fill this table I use this appender:
<appender name="TcpAdoNetAppender" type="log4net.Appender.AdoNetAppender,log4net">
<bufferSize value="50" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="Data Source=[IPADDRES]; Initial Catalog=XYXY; User Id=username;Password=password" />
<commandText value="INSERT INTO TcpClientTracer ([Date],[Thread],[EventType],[ClientId],[ModemId],[EventText]) VALUES (#log_date, #thread, #eventtype, #clientid, #modemid, #eventtext)" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="20" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="#eventtype" />
<dbType value="String" />
<size value="20" />
<layout type="log4net.Layout.RawPropertyLayout">
<key value="eventtype" />
</layout>
</parameter>
<parameter>
<parameterName value="#clientid"/>
<dbType value="Int32"/>
<layout type="log4net.Layout.RawPropertyLayout">
<key value="clientid" />
</layout>
</parameter>
<parameter>
<parameterName value="#modemid" />
<dbType value="String" />
<size value="128" />
<layout type="log4net.Layout.RawPropertyLayout">
<key value="modemid" />
</layout>
</parameter>
<parameter>
<parameterName value="#eventtext" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.RawPropertyLayout">
<key value="eventtext" />
</layout>
</parameter>
</appender>
the logger is this:
<logger name="TcpClientTracer" additivity="false">
<level value="ALL"/>
<appender-ref ref="TcpAdoNetAppender" />
</logger>
and...to pass the data from C# I use this method:
public static void writeLog(GroupType mGrupo, Hashtable mValues)
{
ILog Logger = oLogger.GetLoggerByGroup(mGrupo);
Type declaringType = typeof(log4net.LogManager);
LoggingEvent loggingEvent = new LoggingEvent(declaringType, Logger.Logger.Repository, Logger.Logger.Name, Level.All, null, null);//null = Message, Exception
foreach (DictionaryEntry CurrentEntry in mValues)
{
loggingEvent.Properties[CurrentEntry.Key.ToString()] = CurrentEntry.Value;
}
Logger.Logger.Log(loggingEvent);
}
I don't know how works the LoggingEvent, but I use it to fill other table and work perfectly.
If somebody can help me with this issue, I apreciate!!
Thanks to read my bad english!!
I am not 100% sure what you are asking. What I can tell you for sure is this: If you want to log custom properties, you need to use RawPropertyLayout and specify property name. Example:
<parameter>
<parameterName value="#clientid"/>
<dbType value="Int32"/>
<layout type="log4net.Layout.RawPropertyLayout">
<key value="clientid" />
</layout>
</parameter>