![]() |
VOOZH | about |
dotnet add package ZidUtilities.CommonCode.Log4Net --version 1.0.2
NuGet\Install-Package ZidUtilities.CommonCode.Log4Net -Version 1.0.2
<PackageReference Include="ZidUtilities.CommonCode.Log4Net" Version="1.0.2" />
<PackageVersion Include="ZidUtilities.CommonCode.Log4Net" Version="1.0.2" />Directory.Packages.props
<PackageReference Include="ZidUtilities.CommonCode.Log4Net" />Project file
paket add ZidUtilities.CommonCode.Log4Net --version 1.0.2
#r "nuget: ZidUtilities.CommonCode.Log4Net, 1.0.2"
#:package ZidUtilities.CommonCode.Log4Net@1.0.2
#addin nuget:?package=ZidUtilities.CommonCode.Log4Net&version=1.0.2Install as a Cake Addin
#tool nuget:?package=ZidUtilities.CommonCode.Log4Net&version=1.0.2Install as a Cake Tool
Log4Net configuration helper library for programmatically generating log4net XML configuration files with support for console, rolling file, and JSON appenders.
Main helper class for building and saving log4net configuration files.
Properties:
RootLevel - Root logging level (ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF)Appenders - List of IAppender objects to include in configurationMethods:
SaveConfigToFile(string filePath) - Generates and saves the XML configuration fileGetConfigXmlString(List<string> appenderNames) - Returns the XML configuration as a stringConsoleAppender - Colored console output
GetDefault() - Returns pre-configured console appenderDefaultMappings() - Returns default color mappings for log levelsDefaultLayout() - Returns default pattern layoutRollingFileAppender - File logging with rolling capabilities
FilePath, AppendToFile, RollingStyle, MaxFileSize, MaxSizeRollBackups, DatePatternGetDefault() - Returns pre-configured file appenderDefaultLayout() - Returns default pattern layoutJsonFileAppender - JSON-formatted file logging
FilePath, AppendToFile, RollingStyle, DatePattern, MembersGetDefault() - Returns pre-configured JSON appenderGetDefaultJsonMembers() - Returns default JSON member listGetMembersFromPattern(string pattern) - Converts pattern layout to JSON membersLog4NetLayout - Layout configuration for text-based appenders
Type - Layout type (e.g., "log4net.Layout.PatternLayout")ConversionPattern - Pattern string for formatting log messagesLog4NetJsonMember - JSON member configuration
Name - Member name in JSON outputValue - Value pattern (can be log4net pattern tokens or literal values)Log4NetMapping - Color mapping for console appender
Level - Log level (DEBUG, INFO, WARN, ERROR, FATAL)ForeColor - Foreground colorBackColor - Background color.NET Framework 4.8
Install log4net NuGet package:
Install-Package log4net
For JSON logging support, install:
Install-Package log4net.Ext.Json
Add reference to CommonCode.Log4Net.dll in your project
using log4net;
using log4net.Config;
using ZidUtilities.CommonCode.Log4Net;
// Create configuration helper
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Add console appender using defaults
config.Appenders.Add(ConsoleAppender.GetDefault());
// Save configuration to file
config.SaveConfigToFile("log4net.config");
// Load configuration into log4net
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
// Get logger and start logging
ILog log = LogManager.GetLogger(typeof(Program));
log.Debug("This is a debug message");
log.Info("This is an info message");
log.Warn("This is a warning message");
log.Error("This is an error message");
log.Fatal("This is a fatal message");
using log4net;
using log4net.Config;
using ZidUtilities.CommonCode.Log4Net;
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Create rolling file appender
RollingFileAppender rollingFileAppender = new RollingFileAppender()
{
Name = "RollingFileAppender",
LoggingLevel = "ALL",
FilePath = "logs/application.log",
AppendToFile = true,
RollingStyle = "Date", // Date-based rolling
DatePattern = "yyyyMMdd", // Creates new file each day
Layout = new Log4NetLayout
{
Type = "log4net.Layout.PatternLayout",
ConversionPattern = "[%date] [%thread] [%-5level] %message%newline%exception"
}
};
config.Appenders.Add(rollingFileAppender);
// Save and load configuration
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
// Use logger
ILog log = LogManager.GetLogger("MyApp");
log.Info("Application started");
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Size-based rolling
RollingFileAppender sizeRollingAppender = new RollingFileAppender()
{
Name = "SizeRollingAppender",
LoggingLevel = "ALL",
FilePath = "logs/app.log",
AppendToFile = true,
RollingStyle = "Size",
MaxFileSize = "10MB",
MaxSizeRollBackups = 5, // Keep 5 backup files
Layout = RollingFileAppender.DefaultLayout()
};
config.Appenders.Add(sizeRollingAppender);
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
using log4net;
using log4net.Config;
using ZidUtilities.CommonCode.Log4Net;
using System.Collections.Generic;
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Create JSON appender
JsonFileAppender jsonAppender = new JsonFileAppender()
{
Name = "JsonFileAppender",
LoggingLevel = "ALL",
FilePath = "logs/application.json",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Members = JsonFileAppender.GetDefaultJsonMembers()
};
config.Appenders.Add(jsonAppender);
// Save and load configuration
//FROM FILE
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
//OR
//FROM STREAM
//XmlConfigurator.Configure(l4Config.GetConfigXmlStream());
ILog log = LogManager.GetLogger("MyApp");
log.Info("User logged in");
log.Error("Payment failed", new Exception("Insufficient funds"));
// JSON output format:
// {"date":"2024-01-15 10:30:45","level":"INFO","logger":"MyApp","message":"User logged in","exception":""}
// {"date":"2024-01-15 10:30:46","level":"ERROR","logger":"MyApp","message":"Payment failed","exception":"System.Exception: Insufficient funds..."}
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Define custom JSON structure
List<Log4NetJsonMember> customMembers = new List<Log4NetJsonMember>
{
new Log4NetJsonMember { Name = "timestamp", Value = "date" },
new Log4NetJsonMember { Name = "severity", Value = "level" },
new Log4NetJsonMember { Name = "source", Value = "logger" },
new Log4NetJsonMember { Name = "text", Value = "messageObject" },
new Log4NetJsonMember { Name = "error", Value = "exception" },
new Log4NetJsonMember { Name = "thread_id", Value = "thread" },
new Log4NetJsonMember { Name = "user", Value = "username" }
};
JsonFileAppender jsonAppender = new JsonFileAppender()
{
Name = "CustomJsonAppender",
LoggingLevel = "ALL",
FilePath = "logs/custom.json",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Members = customMembers
};
config.Appenders.Add(jsonAppender);
XmlConfigurator.Configure(config.GetConfigXmlStream());
The JsonFileAppender.GetMembersFromPattern() method automatically converts a pattern layout string into JSON members:
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Define your desired pattern
string pattern = "%date [%thread] [%username] [%identity] %level [%location] [%file] [%line] [%class] [%method] %logger - %message%newline%exception";
// Automatically convert pattern to JSON members
JsonFileAppender jsonAppender = new JsonFileAppender()
{
Name = "AutoJsonAppender",
LoggingLevel = "ALL",
FilePath = "logs/auto.json",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Members = JsonFileAppender.GetMembersFromPattern(pattern)
};
config.Appenders.Add(jsonAppender);
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
// The generated JSON will include all fields from the pattern:
// date, thread, username, identity, level, location, file, line, class, method, logger, message, exception
using log4net;
using log4net.Config;
using ZidUtilities.CommonCode.Log4Net;
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// 1. Console appender for immediate feedback
config.Appenders.Add(ConsoleAppender.GetDefault());
// 2. Rolling file appender for text logs
RollingFileAppender textAppender = new RollingFileAppender()
{
Name = "TextFileAppender",
LoggingLevel = "ALL",
FilePath = "logs/app.log",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Layout = new Log4NetLayout
{
Type = "log4net.Layout.PatternLayout",
ConversionPattern = "[%date] [%thread] [%-5level] %logger - %message%newline%exception"
}
};
config.Appenders.Add(textAppender);
// 3. JSON appender for structured logging
string jsonPattern = "%date [%thread] %level %logger - %message%exception";
JsonFileAppender jsonAppender = new JsonFileAppender()
{
Name = "JsonFileAppender",
LoggingLevel = "ALL",
FilePath = "logs/app.json",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Members = JsonFileAppender.GetMembersFromPattern(jsonPattern)
};
config.Appenders.Add(jsonAppender);
//load configuration
XmlConfigurator.Configure(config.GetConfigXmlStream());
// All appenders will receive log messages
ILog log = LogManager.GetLogger("MyApp");
log.Info("This message goes to console, text file, and JSON file");
using ZidUtilities.CommonCode.Log4Net;
using System.Collections.Generic;
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Create custom color mappings
List<Log4NetMapping> customColors = new List<Log4NetMapping>
{
new Log4NetMapping { Level = "DEBUG", ForeColor = "Cyan", BackColor = "Black" },
new Log4NetMapping { Level = "INFO", ForeColor = "Green, HighIntensity", BackColor = "Black" },
new Log4NetMapping { Level = "WARN", ForeColor = "Yellow, HighIntensity", BackColor = "Black" },
new Log4NetMapping { Level = "ERROR", ForeColor = "Red, HighIntensity", BackColor = "Black" },
new Log4NetMapping { Level = "FATAL", ForeColor = "White, HighIntensity", BackColor = "Red" }
};
ConsoleAppender consoleAppender = new ConsoleAppender
{
Name = "CustomConsoleAppender",
LoggingLevel = "ALL",
Mappings = customColors,
Layout = new Log4NetLayout
{
Type = "log4net.Layout.PatternLayout",
ConversionPattern = "[%date{HH:mm:ss}] [%-5level] %message%newline"
}
};
config.Appenders.Add(consoleAppender);
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
using System;
using log4net;
using log4net.Config;
using ZidUtilities.CommonCode.Log4Net;
public class Program
{
private static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
// Configure logging first
ConfigureLogging();
log.Info("Application started");
try
{
// Your application logic
DoWork();
log.Info("Application completed successfully");
}
catch (Exception ex)
{
log.Fatal("Application crashed", ex);
throw;
}
}
private static void ConfigureLogging()
{
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Console appender
config.Appenders.Add(ConsoleAppender.GetDefault());
// Rolling file appender
RollingFileAppender fileAppender = new RollingFileAppender()
{
Name = "RollingFileAppender",
LoggingLevel = "ALL",
FilePath = "logs/application.log",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Layout = new Log4NetLayout
{
Type = "log4net.Layout.PatternLayout",
ConversionPattern = "[%date] [%thread] [%-5level] %logger - %message%newline%exception"
}
};
config.Appenders.Add(fileAppender);
// JSON appender
JsonFileAppender jsonAppender = new JsonFileAppender()
{
Name = "JsonFileAppender",
LoggingLevel = "ALL",
FilePath = "logs/application.json",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Members = JsonFileAppender.GetDefaultJsonMembers()
};
config.Appenders.Add(jsonAppender);
// Save configuration and load it
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
}
private static void DoWork()
{
log.Debug("Starting work process");
for (int i = 0; i < 10; i++)
{
log.InfoFormat("Processing item {0} of {1}", i + 1, 10);
try
{
ProcessItem(i);
}
catch (Exception ex)
{
log.ErrorFormat("Error processing item {0}: {1}", i, ex.Message);
}
}
log.Debug("Work process completed");
}
private static void ProcessItem(int itemId)
{
if (itemId == 5)
{
log.Warn("Item 5 requires special handling");
}
// Simulate work
System.Threading.Thread.Sleep(100);
if (itemId == 7)
{
throw new InvalidOperationException("Item 7 processing failed");
}
}
}
Log4NetConfigHelper config = new Log4NetConfigHelper();
// Set root level to INFO - DEBUG messages won't be logged
config.RootLevel = "INFO";
config.Appenders.Add(ConsoleAppender.GetDefault());
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
ILog log = LogManager.GetLogger("MyApp");
log.Debug("This will NOT be logged"); // Below INFO level
log.Info("This will be logged"); // INFO level
log.Warn("This will be logged"); // WARN level
log.Error("This will be logged"); // ERROR level
log.Fatal("This will be logged"); // FATAL level
// Root levels: ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// General log - all levels
RollingFileAppender generalLog = new RollingFileAppender()
{
Name = "GeneralLog",
LoggingLevel = "ALL",
FilePath = "logs/general.log",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Layout = RollingFileAppender.DefaultLayout()
};
config.Appenders.Add(generalLog);
// Error log - only errors and fatal
RollingFileAppender errorLog = new RollingFileAppender()
{
Name = "ErrorLog",
LoggingLevel = "ERROR", // Only ERROR and FATAL
FilePath = "logs/errors.log",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Layout = new Log4NetLayout
{
Type = "log4net.Layout.PatternLayout",
ConversionPattern = "[%date] [%-5level] %logger - %message%newline%exception"
}
};
config.Appenders.Add(errorLog);
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
ILog log = LogManager.GetLogger("MyApp");
log.Info("This goes only to general.log");
log.Error("This goes to both general.log and errors.log");
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
// Build pattern based on requirements
string pattern = "%date";
bool includeThread = true;
bool includeUsername = false;
bool includeLevel = true;
bool includeLogger = true;
bool includeLocation = false;
if (includeThread)
pattern += " [%thread]";
if (includeUsername)
pattern += " [%username]";
if (includeLevel)
pattern += " [%-5level]";
if (includeLogger)
pattern += " %logger";
if (includeLocation)
pattern += " [%location]";
pattern += " - %message%newline%exception";
// Apply to rolling file
RollingFileAppender appender = new RollingFileAppender()
{
Name = "DynamicAppender",
LoggingLevel = "ALL",
FilePath = "logs/dynamic.log",
AppendToFile = true,
RollingStyle = "Date",
DatePattern = "yyyyMMdd",
Layout = new Log4NetLayout
{
Type = "log4net.Layout.PatternLayout",
ConversionPattern = pattern
}
};
config.Appenders.Add(appender);
config.SaveConfigToFile("log4net.config");
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
You can retrieve the XML configuration as a string without saving to a file:
Log4NetConfigHelper config = new Log4NetConfigHelper();
config.RootLevel = "ALL";
config.Appenders.Add(ConsoleAppender.GetDefault());
// Get appender names
List<string> appenderNames = config.Appenders.Select(a => a.Name).ToList();
// Get XML string
string xmlConfig = config.GetConfigXmlString(appenderNames);
Console.WriteLine(xmlConfig);
// Output:
// <log4net>
// <root>
// <level value="ALL" />
// <appender-ref ref="ConsoleAppender" />
// </root>
// <appender name="ConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
// ...
// </appender>
// </log4net>
Use these tokens in your ConversionPattern:
%date or %date{format} - Log timestamp (e.g., %date{yyyy-MM-dd HH:mm:ss})%thread - Thread ID%level or %-5level - Log level (padded to 5 characters)%logger - Logger name%message - Log message%exception - Exception information with stack trace%newline - Platform-specific line separator%username - Current Windows username%identity - Current thread identity%location - Full location (class.method:line)%class - Class name%method - Method name%file - Source file name%line - Line number%property{name} - Custom property valueFrom least to most restrictive:
When you set a level, all levels above it are also logged. For example, setting INFO will log INFO, WARN, ERROR, and FATAL, but not DEBUG.
%exception in your patternRecommended folder structure:
YourApp/
├── bin/
│ └── log4net.config (generated config file)
├── logs/
│ ├── application.log (rolling text logs)
│ ├── application.20241201.log
│ ├── application.20241202.log
│ ├── errors.log (error-only logs)
│ ├── application.json (JSON logs)
│ └── application.20241201.json
└── Program.cs
config.RootLevel = "DEBUG";
config.Appenders.Add(ConsoleAppender.GetDefault());
// Shows all debug info in console
config.RootLevel = "INFO";
// Rolling file for general logs
// Separate file for errors
// JSON for log aggregation
config.RootLevel = "WARN";
// Only warnings and errors during tests
Logs not appearing:
XmlConfigurator.Configure() is called before loggingJSON appender not working:
log4net.Ext.Json NuGet package.json extensionConfiguration errors:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET Framework | net48 net48 is compatible. net481 net481 was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
Updated reference to CommonCode 1.0.2