Logging what’s happening in your application is something necessary and useful for your debugging sessions. As .NET Core is a fair new technology, you’re going to find a lot of guides on how to configure log4net for a .NET Framework application but it’s far less clearer for a .NET Core one.
In this guide, we’re going to create a new solution with multiple projects that will use our logging object. The goal is to never depend from the log4net package in any project but, instead, to depend on a local library that will present a Logger
object with static methods to log. Thus, we will only have to add an using
and to call Logger.Log()
to log something.
The simpler, the better, huh? Let’s go!
You can download the example solution at the end of this guide! 😊
Create a new project
Create a new solution with a Console App (.NET Core)
project and call it whatever you want, I chose Banana
because why not.
Then add a new Class Library (.NET Core)
project and call it the same name with a .Toolbox
appended at the end (Banana.Toolbox
for me).
I use the “Toolbox” name because I use this kind of project as a… Toolbox, where I have the logger object, some extensions methods, … that I can reuse between multiple projects (like a NuGet package). Don’t forget to delete the useless Class1.cs
file.
You should have this:
Adding Log4net to the tools
Prepare the static object
I love my solutions well sorted so, in the toolbox project, add a new Logger
folder. You will place all the needed files for the logging there.
In this folder, add a new C# file and name it Logger.cs
. Make this a public and static class…
1 | using System; |
Now we need to download the log4net NuGet package in the Toolbox
project (this will be the only project where log4net is downloaded):
Log4Net instantiation
We now have Log4Net and a static object ready to use it. How are we going to do it? Simple: with static methods!
But before logging anything, we need to instantiate log4net somewhere. Add a new static property to your Logger class:
1 | namespace Banana.Toolbox.Logger |
Visual Studio will complain that it does’t find the “ILog” interface. Let VS add itself the right using
or write it manually: using log4net;
Then, add a new static method to instantiate the new logger object:
1 | private static void EnsureLogger() |
ILog
is the interface provided by Log4Net to use their logger object. To instantiate a new Log4Net logger, we’re going to use the GetLogger
method from the LogManager
object with this signature :
1 | LogManager.GetLogger(Assembly repositoryAssembly, string name) |
The repositoryAssembly property is the “Assembly” object that represents the project that is currently executed. The name property is the name to show in the log file.
To instantiate a new logger in our _log
class property, add this code to EnsureLogger
:
1 | private static void EnsureLogger() |
First, we check if the logger is already created, it this is the case we don’t need to continue so we exit the method immediatly.
Then, as the logger is not instantiated, we first get the “Entry Assembly” (the project that has been executed first) and we use this assembly to create a new Log4Net logger.
We also remove the “.dll” from the project filename and the others “.” because Log4Net will not write what’s after the first dot. This is not useful in this specific case but you should keep it in mind for your next projects.
Log4Net configuration file
ATM the logger won’t work. We still need to configure it to tell Log4Net where and how to save the log files. Each executing project will need its own Log4Net configuration file, here we only have one executing project (Banana) so we’ll only need one file.
In the Banana
project, add a Config
folder then create a new log4net.config
file (you can add any type of file and rename to .config later). This will contains the Log4Net configuration for this project:
Put the following in this file:
1 | <log4net debug="true"> |
You can find more informations on this file here.
With this config, Log4Net will create a new “Banana.log” file in a “LOGS” folder, relative to the execute working directory. When this log file will exceeds 25MB, a new one will be create and the old one will be keeped on its side. A maximum of 10 files will be saved. And the minimum log level to write in the file is “DEBUG”, the lowest one.
Feel free to adapt this file to your taste. Note that you can also use an absolute path instead of the relative one.
One important step than can be overlooked is to specify to Visual Studio that we need to copy this file with the binaries when we build our solution.
Right click on log4net.config
, click on Properties
and be sure to select Copy if newer
(or copy always) for the Copy to Output Directory
option.
Log4Net configuration
In Logger.cs
, add a new method that will read the config file, call it GetConfigFile
:
1 | private static FileInfo GetConfigFile() |
This method try to read “Config/log4net.config” then “log4net.config” (all relative to the current working directory of the executed project) and will throw an exception if nothing has been found.
In EnsureLogger
, save the config file in a new variable:
1 | var configFile = GetConfigFile(); |
To configure Log4Net, we also need a “Repository”. To get one, simply write the following:
1 | var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly()); |
LogManager is a class provided by Log4Net and GetRepository
will provides us a Log4Net repository from our executing project.
Now we only need to call XmlConfigurator
that provides the needed configuration to Log4Net:
1 | // Configure Log4Net |
Your Logger.cs
file should look like this:
1 | private static void EnsureLogger() |
The configuration is now completed but we still can’t log anything. Let’s add some logging methods!
Add logging methods
In Logger.cs
, add a new Log
method with a string parameter that will be the message to log:
1 | public static void Log(string message) |
We call EnsureLogger to be sure to have the logger ready to use then we call the “Debug” method (from Log4Net) that will write the given message to the log file.
In the Program.cs
file in the Banana
project, call this method with a message that you choose:
1 | using Banana.Toolbox.Logger; |
Don’t forget to add a reference to the logger from the Toolbox project with an using
as shown above
Now, execute the project and check that you have a new line in your log file (Banana\bin\Debug\netcoreapp2.1\LOGS
in my case):
1 | DEBUG 2018-10-23 15:34:40,689 435ms Banana - Test log: Message from the main program |
You now have everything you need to start to log everything you want! 😊 But we can improve the Logger by adding more information and methods, please check the second article: [.NET Core] Easy logging with log4net - Make logging even better.
Download the example solution here: https://github.com/MayakoLyyn/Log4Net-dotnetcore