How to Use Log4Net with VB.NET - A Simple Step-By-Step Guide






4.90/5 (17 votes)
A Beginner's Guide to Using Log4net with VB.NET
Introduction
Integrating an effective logging solution into your applications is an essential part of the development process. Not only does logging allow you to debug more effectively, but if it is used in the right manner it can also help to prove that your applications are functioning as intended.
There are two main approaches to implementing a logging solution. Firstly you can spend a lot of time and effort writing your own custom logging application or, as this article explains, you can use an existing logging framework.
The logging framework I use is called log4Net and is a free open source solution provided by Apache. Although there is lots of documentation on the log4net project homepage, it's not particularly helpful for a beginner trying to understand the basic concepts. Moreover, most of the examples on the web are written in C# as Log4Net seems to appeal more to those developers who recognize Java syntax (it originates from a Java framework called log4j).
The aim of this article is to provide some VB.NET example code and to show Log4Net beginners how to use the framework by means of a step-by-step guide.
Part I - Basic Logging
- Create two new folders called ‘C:\Log4NetExamples’ and 'C:\Log4Net'.
- Download ‘incubating-log4net-1.2.10.zip’ (or whatever is the latest version) file from http://logging.apache.org/log4net/download.html.
- Extract ‘incubating-log4net-1.2.10.zip’ file (or whatever is the latest version) to 'C:\Log4Net'.
- Open Visual Studio and create a new VB.NET ‘Windows Form Application’ project called ‘
Log4NetAssembly1
’. - On the right-hand side of the Visual Studio IDE, you should see the 'Solution Explorer' window. If you can't see this window, then hit the Ctrl+Alt+L keys.
- From within the 'Solution Explorer' window, click on the 'Show All Files' button:
- Right-click on ‘References’ and select ‘Add New Reference’:
- Browse to ‘C:\Log4Net\log4net-1.2.10\bin\net\2.0\release’ and select ‘Log4net.dll’, then click on the ‘OK’ button.
- Right-click on the project name and then click on ‘Add => New Item’:
- Add a new text file to the project called ‘Log4NetAssembly1.exe.log4net’:
- Open the ‘Log4NetAssembly1.exe.log4net’ file and add the following code:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <log4net> <appender name="ExampleAppender" type="log4net.Appender.RollingFileAppender"> <file value="C:\Log4NetExamples\Example.log" /> <appendToFile value="false" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="3" /> <maximumFileSize value="100KB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level - [%logger] %message%newline" /> </layout> </appender> <logger name="Log4NetAssembly1"> <level value="ALL" /> <appender-ref ref="ExampleAppender" /> </logger> </log4net> </configuration>
XML Explained
<appender name="ExampleAppender" type="log4net.Appender.RollingFileAppender">
An appender defines HOW log4Net is going to log application information. The
RollingFileAppender
defined above writes logging events to a file in the file system and automatically creates additional log files when certain configurable criteria are met such as the maximum log file size. For a list of all the log4Net appenders, please see http://logging.apache.org/log4net/release/features.html.<appendToFile value="false" />
Sets a flag that indicates whether the file should be appended to or overwritten. So, for example, if it's set to '
true
' and the application is stopped and started, then log4Net will attempt to reuse the same log file.<rollingStyle value="Size" />
Sets the rolling style. In the example above, I've set this to "
Size
" which means that the appender will 'rollover' the existing log file by renaming it and create an additional new log file when the existing file reaches a defined size.<maxSizeRollBackups value="3" />
Sets the maximum number of backup (rollover) files that are kept before the oldest is erased.
<maximumFileSize value="100KB" />
Sets the maximum size that the log file is allowed to reach before being rolled over to backup files.
<staticLogFileName value="true" />
Sets a value indicating whether to always log to the same file name.
<layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level - [%logger] %message%newline" /> </layout>
Formats the logging event as a
string
. Details of how to use thePatternLayout
class can be found here.<logger name="Log4NetAssembly1">
The logger is the main component with which your application interacts. You can call it anything you want but remember that this is the name you will use in your code to refer to the logger. As you will see, you can have more than one logger defined per application.
<level value="ALL" />
Defines the logging level for application events, e.g.
ERROR
,DEBUG
,INFO
. For a full list, please see here. In the example code, I have told the logger to capture 'ALL
' events to keep it simple.Additional appender options can be found here.
- Select the ‘Log4NetAssembly1.exe.log4net’ file within ‘Solution Explorer’ and set the ‘Copy to Output Directory’ option to ‘Copy if Newer’. This will copy the file to the same directory as the ‘Log4NetAssembly1.exe’ file when the project is built:
- Expand ‘My Project’ and double-click on ‘AssemblyInfo.vb’:
- Add the following line of code to the ‘AssemblyInfo.vb’ file and Save:
<Assembly: log4net.Config.XMLConfigurator (ConfigFile:="Log4NetAssembly1.exe.log4net", Watch:=True)>
Code Explained
<Assembly: log4net.Config.XMLConfigurator (ConfigFile:="Log4NetAssembly1.exe.log4net", Watch:=True)>
The
XMLConfigurator
is responsible for parsing the log4Net XML configuration file. SettingWatch:=True
means that log4Net will 'watch' the configuration file to see if it has changed and if it has, it will load the changes. This means that you can amend and deploy a new configuration file while your application is running. - Click on ‘
Form1
’ within the design window to make sure it is selected. Then click on the ‘Events’ button and double-click on theLoad
event: - Add the following code to Form1.vb:
Public Class Form1 Public Shared logger As log4net.ILog Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Try 'Get the logger as named in the configuration file. logger = log4net.LogManager.GetLogger("Log4NetAssembly1") logger.Info("Form1_Load() - Start") logger.Debug("Form1_Load() - Code Implementation goes here......") Catch ex As Exception logger.Error("Form1_Load() - " & ex.Message) Finally logger.Info("Form1_Load() - Finish") End Try End Sub End Class
- Hit the ‘F5’ key to run the project and then open ‘C:\Log4NetExamples\Example.log’ in Notepad. If everything has worked correctly, you should see the following text within the log file:
2009-09-03 11:15:00,525 [10] INFO - [Log4NetAssembly1] Form1_Load() - Start 2009-09-03 11:15:00,525 [10] DEBUG - [Log4NetAssembly1] Form1_Load() - Code Implementation goes here...... 2009-09-03 11:15:00,525 [10] INFO - [Log4NetAssembly1] Form1_Load() - Finish
Part II - Logging Errors
The following steps simulate an error to show how easy it is to log errors using Log4Net:
- Amend Form1.vb code so that it looks as follows::
Public Class Form1 Public Shared logger As log4net.ILog Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Try Dim arrError(1) As String 'Get the logger as named in the configuration file. logger = log4net.LogManager.GetLogger("Log4NetAssembly1") logger.Info("Form1_Load() - Start") logger.Debug("Form1_Load() - Code Implementation goes here......") arrError(3) = "Error Simulated here...." Catch ex As Exception logger.Error("Form1_Load() - " & ex.Message) Finally logger.Info("Form1_Load() - Finish") End Try End Sub End Class
- Hit the ‘F5’ key to run the project and then open ‘C:\Log4NetExamples\Example.log’ in Notepad. If everything has worked correctly, you should see the following text within the log file:
2009-09-03 16:34:41,576 [9] INFO - [Log4NetAssembly1] Form1_Load() - Start 2009-09-03 16:34:41,591 [9] DEBUG - [Log4NetAssembly1] Form1_Load() - Code Implementation goes here...... 2009-09-03 16:34:41,607 [9] ERROR - [Log4NetAssembly1] Form1_Load() - Index was outside the bounds of the array. 2009-09-03 16:34:41,607 [9] INFO - [Log4NetAssembly1] Form1_Load() - Finish
Part III - Multiple Assemblies
Most applications these days consist of multiple assemblies. For example most of my applications consist of a Front-End GUI assembly and several *.dll assemblies. It makes sense for me to direct all logging statements for these assemblies to the same logging file.
To show you how this is done, follow the steps below:
- Open Visual Studio and create a new VB.NET ‘Class Library’ project called ‘
Log4NetAssembly2
’. - From within the “Solution Explorer” window, click on the “Show All Files” button.
- Add the following line of code to the ‘AssemblyInfo.vb’ file and Save:
<Assembly: log4net.Config.XMLConfigurator (ConfigFile:="Log4NetAssembly1.exe.log4net", Watch:=True)>
- Right-click on ‘References’ and select ‘Add New Reference’.
- Browse to ‘C:\Log4Net\log4net-1.2.10\bin\net\2.0\release’ and select ‘Log4net.dll’, then click on the ‘OK’ button.
- Within ‘Solution Explorer’, right-click on ‘Class1.vb’ and rename it to ‘clsAssembly2’:
- Double-click on ‘clsAssembly2.vb’ and amend it so that it looks like the following:
Public Class clsAssembly2 Public Shared logger As log4net.ILog Public Sub New() Try 'Notice that we are using a different logger name here... 'This logger will need to be defined in the 'original configuration file for this to work logger = log4net.LogManager.GetLogger("Log4NetAssembly2") logger.Info("New() - Start") logger.Debug("New() - Code Implementation goes here......") Catch ex As Exception logger.Error("New() - " & ex.Message) Finally logger.Info("New() - Finish") End Try End Sub End Class
- Right-click on ‘
Log4NetAssembly2
’ within ‘Solution Explorer’ and select ‘Properties’. - Select the ‘Compile’ tab and set the ‘Output Path’ to ‘C:\Log4NetExamples’:
- From the ‘Build’ menu, select ‘Build
Log4NetAssembly2
’. This should create a new file called ‘Log4NetAssembly2.dll’ in ‘C:\Log4NetExamples’. - Switch back to the ‘
Log4NetAssembly1
’ project. - Right-click on ‘References’ and select ‘Add New Reference’.
- Browse to ‘C:\Log4NetExamples\' and select the newly created ‘Log4NetAssembly2.dll’ file, then click on the ‘OK’ button.
- Double-click on ‘Log4NetAssembly1.exe.log4net’ and add the following lines:
<logger name="Log4NetAssembly2" > <level value="ALL" /> <appender-ref ref="ExampleAppender" /> </logger>
XML Explained
We have now added a second logger for use with the additional assembly. Notice how it points to the same appender reference? This means that all messages will be logged to the same log file as the original assembly.
- Double-click on ‘Form1.vb’ and amend it so that it looks like the following:
Public Class Form1 Public Shared logger As log4net.ILog Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Try Dim arrError(1) As String logger = log4net.LogManager.GetLogger("Log4NetAssembly1") logger.Info("Form1_Load() - Start") logger.Debug("Form1_Load() - Code Implementation goes here......") 'Create a new assembly object 'The logging statements in the class constructor should 'be written to the log file. Dim objTest As New Log4NetAssembly2.clsAssembly2 arrError(3) = "Error Simulated here...." Catch ex As Exception logger.Error("Form1_Load() - " & ex.Message) Finally logger.Info("Form1_Load() - Finish") End Try End Sub End Class
- Hit the ‘F5’ key to run the project and then open ‘C:\Log4NetExamples\Example.log’ in Notepad. If everything has worked correctly, you should see the following text within the log file:
2009-09-03 17:09:10,578 [10] INFO - [Log4NetAssembly1] Form1_Load() - Start 2009-09-03 17:09:10,594 [10] DEBUG - [Log4NetAssembly1] Form1_Load() - Code Implementation goes here...... 2009-09-03 17:09:10,594 [10] INFO - [Log4NetAssembly2] New() - Start 2009-09-03 17:09:10,594 [10] DEBUG - [Log4NetAssembly2] New() - Code Implementation goes here...... 2009-09-03 17:09:10,594 [10] INFO - [Log4NetAssembly2] New() - Finish 2009-09-03 17:09:10,594 [10] ERROR - [Log4NetAssembly1] Form1_Load() - Index was outside the bounds of the array. 2009-09-03 17:09:10,594 [10] INFO - [Log4NetAssembly1] Form1_Load() - Finish
Additional Information
Log4Net is a fairly extensive framework and I've barely scratched the surface. To find out what else is possible, I recommend looking at the documentation on the log4net homepage.
There is also quite a good introductory article here.
History
- 10th September, 2009: Initial version