mayho33
Goto Top

NLog callsite und callsite-linenumber in Powershell verwenden

Hi @ All

Ich möchte in Powershell Nlog ${callsite} und ${callsite-linenumber} verwenden und habe die Funktionalität aus meinem C#-Projekt übernommen. Leider funktioniert es nicht. Ich bekomme immer nur sowas in meinem Log:
05-06-2020 21:07:01.489 :: (WARN) :: <no type>.CallSite.Target :: 0 :: message

In C# funktioniert das einwandfrei. NLog schreibt, dass auch Powershell bis auf kleinere Einschränkungen voll unterstützt wird. Bin etwas ratlos und wäre froh, wenn jemand den zündenden Hinweis liefern kann.

hier meine Methode und eine kurze Erklärung dazu:
2 Logger. der erste schreibt in ein normales Log und gleichzeitig in die Console. Der zweite wird nur beschrieben, wenn in einem try-catch Fehler auftreten.
Function Initialize-Nlog()
{
    [CmdletBinding()]
    Param 
    (
        [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName = $true, Position=0, ParameterSetName = "INIT")][switch]$Initialize,  
        [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName = $true, Position=1, ParameterSetName = "INIT")][ValidateNotNullOrEmpty()][string]$LoggingFileName,  
        [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName = $true, Position=2,ParameterSetName = "GETLOGGER")][switch]$GetLoggerI,  
        [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName = $true, Position=3,ParameterSetName = "GETLOGGER")][switch]$GetLoggerF  
    )

    process {

        if(!$LoggingFileName.ToLower().Contains(".log"))  
        {
            $LoggingFileName += ".log"  
        }

        if($Initialize.IsPresent)
        {
            [Void] [System.Reflection.Assembly]::LoadFile("$env:windir\NLog.dll")  

            $logLayout_NORMAL = [string]::Format("{0}", '${message}')  
            $logLayout_INTERN = [string]::Format("{0} :: {1} :: {2} :: Zeile {3} :: {4}", '${date:format=dd\-MM\-yyyy HH\:mm\:ss\.fff}', '(${uppercase:${level}})', '${callsite}', '${callsite-linenumber}',  '${message} ${exception}')  


            #region NORMAL to Console
            $tagetC_INFO                  = New-Object NLog.Targets.ConsoleRowHighlightingRule
            $tagetC_INFO.Condition        = [NLog.Conditions.ConditionParser]::ParseExpression("level == LogLevel.Info")  
            $tagetC_INFO.ForegroundColor  = [NLog.Targets.ConsoleOutputColor]::White

            $tagetC_DEBUG                 = New-Object NLog.Targets.ConsoleRowHighlightingRule
            $tagetC_DEBUG.Condition       = [NLog.Conditions.ConditionParser]::ParseExpression("level == LogLevel.Debug")  
            $tagetC_DEBUG.ForegroundColor = [NLog.Targets.ConsoleOutputColor]::Green

            $tagetC_WARN                  = New-Object NLog.Targets.ConsoleRowHighlightingRule
            $tagetC_WARN.Condition        = [NLog.Conditions.ConditionParser]::ParseExpression("level == LogLevel.Warn")  
            $tagetC_WARN.ForegroundColor  = [NLog.Targets.ConsoleOutputColor]::Yellow

            $tagetC_TRACE                 = New-Object NLog.Targets.ConsoleRowHighlightingRule
            $tagetC_TRACE.Condition       = [NLog.Conditions.ConditionParser]::ParseExpression("level == LogLevel.Trace")  
            $tagetC_TRACE.ForegroundColor = [NLog.Targets.ConsoleOutputColor]::Gray

            $tagetC_ERROR                 = New-Object NLog.Targets.ConsoleRowHighlightingRule
            $tagetC_ERROR.Condition       = [NLog.Conditions.ConditionParser]::ParseExpression("level == LogLevel.Error")  
            $tagetC_ERROR.ForegroundColor = [NLog.Targets.ConsoleOutputColor]::Red

            $targetC                      = New-Object NLog.Targets.ColoredConsoleTarget
            $targetC.Name                 = "console"  
            $targetC.Layout               = $logLayout_NORMAL

            $targetC.RowHighlightingRules.Add($tagetC_INFO)
            $targetC.RowHighlightingRules.Add($tagetC_DEBUG)
            $targetC.RowHighlightingRules.Add($tagetC_WARN)
            $targetC.RowHighlightingRules.Add($tagetC_TRACE)
            $targetC.RowHighlightingRules.Add($tagetC_ERROR)
            #endregion

            #region INTERN for Internal Error log
            $targetI                         = New-Object NLog.Targets.FileTarget
            $targetI.Name                    = "intern"  
            $targetI.Encoding                = [System.Text.Encoding]::UTF8
            $targetI.FileName                = [System.IO.Path]::Combine($env:LoggingDirectory, "InstallTools_ERROR.log")  
            $targetI.ConcurrentWrites        = $true
            $targetI.ArchiveOldFileOnStartup = $false
            $targetI.KeepFileOpen            = $false
            $targetI.CreateDirs              = $true
            $targetI.DeleteOldFileOnStartup  = $false
            $targetI.MaxArchiveFiles         = 0
            $targetI.Layout                  = $logLayout_INTERN
            #endregion

            #region NORMAL to File
            $targetF                         = New-Object NLog.Targets.FileTarget
            $targetF.Name                    = "file"  
            $targetF.Encoding                = [System.Text.Encoding]::UTF8
            $targetF.ArchiveOldFileOnStartup = $true
            $targetF.ArchiveNumbering        = [NLog.Targets.ArchiveNumberingMode]::Date
            $targetF.FileName                = [System.IO.Path]::Combine($env:LoggingDirectory, $LoggingFileName)
            $targetF.ArchiveDateFormat       = "yyyy.MM.dd HH.mm.ss"  
            $targetF.ArchiveFileName         = [System.IO.Path]::Combine($env:LoggingDirectory, [System.IO.Path]::GetFileNameWithoutExtension($filePath) + '__{#}.log')  
            $targetF.ConcurrentWrites        = $true
            $targetF.ArchiveOldFileOnStartup = $true
            $targetF.KeepFileOpen            = $false
            $targetF.MaxArchiveFiles         = -1
            $targetF.CreateDirs              = $true
            $targetF.Layout                  = $logLayout_NORMAL
            #endregion

            #region LoggingRules
            $LoggingRuleF = New-Object NLog.Config.LoggingRule
            $LoggingRuleF.LoggerNamePattern = "logNormal"  
            $LoggingRuleF.SetLoggingLevels([NLog.LogLevel]::Trace, [NLog.LogLevel]::Fatal)
            $LoggingRuleF.Targets.Add($targetF)
            $LoggingRuleF.Targets.Add($targetC)

            $LoggingRuleI = New-Object NLog.Config.LoggingRule
            $LoggingRuleI.LoggerNamePattern = "logIntern"  
            $LoggingRuleI.SetLoggingLevels([NLog.LogLevel]::Trace, [NLog.LogLevel]::Fatal)
            $LoggingRuleI.Targets.Add($targetI)

            $LoggingConfig = New-Object NLog.Config.LoggingConfiguration
            $LoggingConfig.AddTarget("normal", $targetF)  
            $LoggingConfig.LoggingRules.Add($LoggingRuleF)
            $LoggingConfig.AddTarget("intern", $targetI)  
            $LoggingConfig.LoggingRules.Add($LoggingRuleI)
            #endregion

            [NLog.LogManager]::Configuration = $LoggingConfig
        }

        if($GetLoggerI.IsPresent)
        {
            return [NLog.LogManager]::GetLogger("logIntern")  
        }

        if($GetLoggerF.IsPresent)
        {
            return [NLog.LogManager]::GetLogger("logNormal")  
        }
    }
}

und so initialisiere ich das ganze um zu simmulieren, dass der Fehler in einer Methode auftritt (Beispiel):
function Test-Me() {

[string]$env:Publisher      = 'Citrix'  
[string]$env:DisplayName    = 'WebSpinner'  
[string]$env:DisplayVersion = '1.3.4.675'  


$env:LoggingDirectory = "C:\Logs"  
$env:LogFileName = $($env:Publisher + " " + $env:DisplayName + " " + $env:DisplayVersion)  

Initialize-Nlog -Initialize -LoggingFileName $env:LogFileName
$log = Initialize-Nlog -GetLoggerF
$logError = Initialize-Nlog -GetLoggerI

$log.Info("Eintrag 1")  
$log.Info("Eintrag 2")  

$logError.Debug("blabla")  
$logError.Info("blabla")  
$logError.Warn("blabla")  
$logError.Error("blabla")  
}

Test-Me

Vielen Dank für eure Unterstützung!

Mayho

Content-Key: 577335

Url: https://administrator.de/contentid/577335

Printed on: May 18, 2024 at 07:05 o'clock

Mitglied: 144260
144260 Jun 06, 2020 updated at 11:21:09 (UTC)
Goto Top
$logLayout_NORMAL = [string]::Format("{0}", '${message}')
$logLayout_INTERN = [string]::Format("{0} :: {1} :: {2} :: Zeile {3} :: {4}", '${date:format=dd\-MM\-yyyy HH\:mm\:ss\.fff}', '(${uppercase:${level}})', '${callsite}', '${callsite-linenumber}', '${message} ${exception}')


Subexpressions $() innerhalb von Single Quotes (') funktionieren in PS nicht, die funktionieren nur innerhalb von Double Quotes (").
Und das date:format geht so auch nicht geht so (get-date -F 'xxxxxxxxxxxxx').
Member: mayho33
mayho33 Jun 06, 2020 at 17:23:48 (UTC)
Goto Top
Ich habe keine Fehler. Das Date-Format funktiiniert einwandfrei(siehe oben).

Was nicht funktioniert ist, dass callsite nicht die Methode anzeigt und callsite-linenumber immer 0 ist.
Mitglied: 144260
Solution 144260 Jun 06, 2020 updated at 18:23:56 (UTC)
Goto Top
Uups da habe ich die Klammern verwechselt , sorry.

Die Abhängigkeiten die hier zusätzlich eingebunden werden fehlen bei dir ...
https://gist.github.com/dbl4ck/7e392efd8357a1f422ca7d115b068234
Vielleicht wird eine/mehrere davon noch benötigt.
Member: mayho33
mayho33 Jun 08, 2020 updated at 15:24:24 (UTC)
Goto Top
Zitat von @144260:
Die Abhängigkeiten die hier zusätzlich eingebunden werden fehlen bei dir ...
https://gist.github.com/dbl4ck/7e392efd8357a1f422ca7d115b068234
Vielleicht wird eine/mehrere davon noch benötigt.

Eine Schande, dass NLog Powershell immer noch nicht voll unterstützt und externe Tools notwendig sind. Ist ja nicht so, dass PS noch besonders jung wäre und die Verbreitung ist ebenfalls hoch.

Danke jedenfalls! Werde das alsbald ausprobieren.

Bei Durchsicht meines Log Layouts ist mir aber tatsächlich einen unnötige Klammerung aufgefallen:

Das...
'(${uppercase:${level}})'  

...funktioniert auch so:
'${uppercase:${level}}'