Trying to get log4net working with PowerShell (with a log4net config file in the mix)
Asked Answered
C

2

6

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)

Cocktail answered 21/11, 2012 at 15:21 Comment(1)
PowerGui shows the variable $log as having the following error: {log4net:ERROR XmlConfigurator: Error while loading XML configuration, log4net.Core.LogImpl}Cocktail
C
3

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>
Cocktail answered 21/11, 2012 at 15:46 Comment(0)
C
2

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.

Cecum answered 5/11, 2014 at 13:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.