I have been struggling with getting log4net working with PowerShell. I have the following PowerShell code that pulls in log4net with a configuration file and then attempts to make a simple log file entry but which errors out.
Clear-History
Clear-Host
#
Write-Host "BEGIN: Importing module psm_logger.psm1"
Import-Module "C:\Users\Administrator\Desktop\ps\IIS\psm_logger.psm1" -Force
Write-Host "BEGIN: log4net configuration definition"
$log = New-Logger -Configuration "C:\Users\Administrator\Desktop\ps\IIS\logging\log4net.config" -Dll "C:\Users\Administrator\Desktop\ps\IIS\logging\log4net.dll"
Write-Host "END: log4net configuration definition"
Write-Host "BEGIN: log4net configuration DEBUG definition"
#$log.DebugFormat("Logger configuration file is : '{0}'", (Resolve-Path "C:\Users\Administrator\Desktop\ps\IIS\logging\log4net.config"))
Write-Host "END: log4net DEBUG configuration definition"
#======================
$ThisHostname = $env:COMPUTERNAME
#======================
Write-Host "BEGIN: Module/Snapin import/addition"
Write-Host ""
$log.Info("BEGIN: Module/Snapin import/addition")
#======================
The above referenced psm_logger.psm1 file contains:
function New-Logger
{
#Write-Host "BEGIN: New-Logger"
<#
.SYNOPSIS
This function creates a log4net logger instance already configured
.OUTPUTS
The log4net logger instance ready to be used
#>
[CmdletBinding()]
Param
(
[string]
# Path of the configuration file of log4net
$Configuration,
[Alias("Dll")]
[string]
# Log4net dll path
$log4netDllPath
)
Write-Verbose "[New-Logger] Logger initialization"
$log4netDllPath = Resolve-Path $log4netDllPath -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err)
{
throw "Log4net library cannot be found on the path $log4netDllPath"
}
else
{
Write-Verbose "[New-Logger] Log4net dll path is : '$log4netDllPath'"
[void][Reflection.Assembly]::LoadFrom($log4netDllPath) | Out-Null
# Log4net configuration loading
$log4netConfigFilePath = Resolve-Path $Configuration -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err)
{
throw "Log4Net configuration file $Configuration cannot be found"
}
else
{
Write-Verbose "[New-Logger] Log4net configuration file is '$log4netConfigFilePath' "
$FileInfo = New-Object System.IO.FileInfo($log4netConfigFilePath)
[log4net.Config.XmlConfigurator]::Configure($FileInfo)
$script:MyCommonLogger = [log4net.LogManager]::GetLogger("root")
Write-Verbose "[New-Logger] Logger is configured"
return $MyCommonLogger
}
}
}
The configuration file for log4net looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" **requirePermission="false"**/>
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="C:\Users\Administrator\Desktop\ps\IIS\LOGS\LogTest2.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n" />
<param name="Footer" value="[Footer]\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
When run the output AND error produced is:
BEGIN: Importing module psm_logger.psm1 BEGIN: log4net configuration definition END: log4net configuration definition BEGIN: log4net configuration DEBUG definition END: log4net DEBUG configuration definition BEGIN: Module/Snapin import/addition
Method invocation failed because [System.Object[]] doesn't contain a method named 'Info'. At C:\Users\Administrator\Desktop\ps\IIS\IIS_localLogs.ps1:18 char:10 + $log.Info <<<< ("BEGIN: Module/Snapin import/addition") + CategoryInfo : InvalidOperation: (Info:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound
Any help would be greatly appreciated!
(FYI: I originally got this code from a best practices blog entry here: http://blog.octo.com/en/powershell-v2-my-best-practices/ which I found very helpful)
Found the solution...
The config file was corrupted by the presence of some asterisks towards the top. Removing those fixed the issue. Thank you to anybody who may have started to look at this and I hope this helps somebody else in the future.
The configuration file now looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="C:\Users\Administrator\Desktop\ps\IIS\LOGS\LogTest2.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n" />
<param name="Footer" value="[Footer]\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
New-Logger is such a useful cmdlet, it's worth updating for newer versions of Powershell. psm_logger.psm1 currently gives a System.Void error under PS V3 and later. Changing the assembly load to
[Reflection.Assembly]::LoadFrom($log4netDllPath) | Out-Null
without the [Void] sorts out the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With