For my NetApp Insight sessions, I had to create such a command, and I'm already posting it here.
Logging on 3 levels :
- Database
- Logfile
- Eventviewer
How to use :
- Type : debug, info, warn, error or fatal- Message : the actual logging message
- Cr : A Change Request, I thought it might come in handy, you could leave it out if you want
- LogToFile : boolean, if you want a logfile too
- LogToEventViewer : boolean, if you want to log to the eventviewer
- EventId : in case of eventviewer, you can set the eventid
- Category : in case of eventviewer, you can set the category (leave default, unless you know about this)
Testing
- $interactive : set to true if you want to test this in powershell first (run as admin !!)don't forget to set you shell in WFA debug mode.
http://www.wfaguy.com/2017/08/debug-wfa-in-your-powershell-editor.html
Scheme
now set to "log", so I assumed you have created the scheme "log" and dictionary "log".
The dictionary
- log
- timestamp (datetime)
- cr (string)
- message (string 8000)
- type (enum : debug,info,warn,error,fatal)
- workflowname
- jobid (integer)
- user (string)
The code :
param ( [parameter(Mandatory=$true, HelpMessage="Type")] [validateset('debug','info','warn','error','fatal')] [string]$Type, [parameter(Mandatory=$true, HelpMessage="Message")] [string]$Message, [parameter(Mandatory=$true, HelpMessage="Change Request")] [string]$Cr, [parameter(Mandatory=$false, HelpMessage="Log to local logfile ?")] [boolean]$LogToFile=$false, [parameter(Mandatory=$false, HelpMessage="Log to event viewer ?")] [boolean]$LogToEventViewer=$false, [parameter(Mandatory=$false, HelpMessage="Event viewer - Event id")] [int]$EventId=1, [parameter(Mandatory=$false, HelpMessage="Event view - Category")] [int]$Category=0 ) # Default credentials for playground database $MySQLAdminUserName = 'wfa' $MySQLAdminPassword = 'Wfa123' $MySQLDatabase = 'log' $MySQLHost = "localhost" # fix single quotes $SqlMessage = $Message -replace "'","''" # log message format $Message = "[$User][$Cr][$WorkflowName][$JobId] - $Message" [string]$mySqlDateTime = get-date -Format "yyyy-MM-dd HH:mm:ss" $interactive = $false # set this if your are running locally in the shell # ================================================================ # == Get Environment variables (script location, host & port) # == Note : set the datasource port to 1, to trigger debug mode # ================================================================ if(!$interactive){ Set-Variable -Name SCRIPT_PATH -Value (Split-Path (Resolve-Path $myInvocation.MyCommand.Path)) -Scope local $User = $(Get-WfaRestParameter "userName") $Workflowname = $(Get-WfaRestParameter "workflowName") $Jobid = $(Get-WfaRestParameter "jobId") }else{ # auto load wfa profile $profilecheck = Get-Item function: | ?{$_.Name -eq "Connect-WfaCluster"} if(-not $profilecheck){ Write-Host "Loading WFA profile..." -ForegroundColor Yellow cd 'C:\Program Files\NetApp\WFA\PoSH\' . '.\profile.ps1' } Set-Variable -Name SCRIPT_PATH -Value 'C:\Program Files\NetApp\WFA\jboss\standalone\tmp\wfa' -Scope local cd "$SRIPT_PATH" $User = "dummy_user" $Workflowname = "dummy_workflow_name" $Jobid = "123" } # store to db Get-WFALogger -Info -message $("Preparing Command") $cmd1 = "INSERT INTO $MySQLDatabase.log SET " + "User='$User',"+ "Workflowname='$Workflowname',"+ "Jobid=$Jobid,"+ "Type='$Type',"+ "Message='$SqlMessage'," + "Timestamp='$mySqlDateTime'," + "Cr='$Cr'" Get-WFALogger -Info -message $("Executing SQL: " + $cmd1) Invoke-MySqlQuery -query $cmd1 # Event Viewer Function function SetLog4NetEventLogEventId{ Param ( [Parameter(Mandatory=$true)] [int] $EventId, [Parameter(Mandatory=$true)] [int] $Category ) [log4net.ThreadContext]::Properties.Item("EventID") = $EventId [log4net.ThreadContext]::Properties.Item("Category") = $Category } if($LogToFile -or $LogToEventViewer){ $LoggerName = $MySQLDatabase $dllLocation = $SCRIPT_PATH + "\..\..\..\..\Posh\Modules\DataOntap\log4net.dll" $logfile = $SCRIPT_PATH + "\..\..\log.war\jboss\" + $LoggerName + ".logger.log" # Initialize log4net [Reflection.Assembly]::LoadFrom($dllLocation) | Out-Null #Reset the log4net configuration [log4net.LogManager]::ResetConfiguration() #Define new logger for this module only try{ [log4net.LogManager]::CreateRepository("$($LoggerName)Logger") }catch{ Get-WfaLogger -warn -message "[LOG] Repository already created" } [log4net.Repository.Hierarchy.Hierarchy]$repository = [log4net.LogManager]::GetRepository("$($LoggerName)Logger") # create new appenders $repository.Root.RemoveAllAppenders(); if($LogToFile){ # create rolling file logging Get-WfaLogger -info -message "[LOG] LogFile path is : '$logFile'" try{ New-Item -Path $logFile -type file -EA Stop }catch{ if($_.Exception -match "denied"){ Get-WfaLogger -warn -message "[LOG] No access to write log file" }else{ Get-WfaLogger -warn -message "[LOG] $($_.Exception)" } } $logPattern="%d %w %-5p %c : %m%n" $rollingLogAppender = new-object log4net.Appender.RollingFileAppender $rollingLogAppender.MaximumFileSize = "50MB" $rollingLogAppender.Name = "file" $rollingLogAppender.File = $logFile $rollingLogAppender.RollingStyle = "Size" $rollingLogAppender.StaticLogFileName = $true $rollingLogAppender.MaxSizeRollBackups = "20" $rollingLogAppender.Layout = new-object log4net.Layout.PatternLayout($logPattern) $rollingLogAppender.Threshold = [log4net.Core.Level]::Debug $rollingLogAppender.ActivateOptions() $repository.Root.AddAppender($rollingLogAppender) Get-WfaLogger -info -message "[LOG] File Logger initialized" } if($LogToEventViewer){ # create eventlog logging $eventAppender = new-object log4net.Appender.EventLogAppender $eventAppender.Name = "event" $eventAppender.ApplicationName = "$($LoggerName)" $eventAppender.EventId = 1 $eventAppender.Layout = new-object log4net.Layout.PatternLayout($eventPattern) $eventAppender.Threshold = [log4net.Core.Level]::Debug $eventAppender.ActivateOptions() $repository.Root.AddAppender($eventAppender) Get-WfaLogger -info -message "[LOG] Event viewer Logger initialized" } # mark as configured $repository.Configured = $true $logg=[log4net.LogManager]::GetLogger("$($LoggerName)Logger","$($LoggerName)") Get-WfaLogger -info -message "[LOG] Logger initialized" if($LogToEventViewer){ SetLog4NetEventLogEventId -EventId $EventId -Category $Category } switch($Type){ "Debug"{ $logg.Debug($Message) Get-WfaLogger -info -message "[LOG][$Type] - $Message" } "Info"{ $logg.Info($Message) Get-WfaLogger -info -message "[LOG][$Type] - $Message" } "Warn"{ $logg.Warn($Message) Get-WfaLogger -info -message "[LOG][$Type] - $Message" } "Error"{ $logg.Error($Message) Get-WfaLogger -info -message "[LOG][$Type] - $Message" } "Fatal"{ $logg.Fatal($Message) Get-WfaLogger -info -message "[LOG][$Type] - $Message" } } }Download dar
I'm trying to debug a problem with a PowerShell-based Command... When I run the PS script outside of WFA (but on the same host), the script works. When I run the PS Command as part of a WorkFlow, it fails with the following error:
ReplyDelete12:30:13.268 WARN [IBM Remove vdisk FC Mappings] ***DEBUG ***: fcMapInfo contains: id,4 name,fcmap4 source_vdisk_id,66 source_vdisk_name,RSTRATTON_0066 target_vdisk_id,73 target_vdisk_name,RSTRATTON_0066_01 group_id, group_name, status,idle_or_copied progress,0 copy_rate,50 start_time, dependent_mappings,0 autodelete,off clean_progress,100 clean_rate,50 incremental,on difference,100 grain_size,256 IO_group_id,0 IO_group_name,io_grp0 partner_FC_id, partner_FC_name, restoring,no rc_controlled,no keep_target,no type,generic restore_progress,0 fc_controlled,no
12:30:13.268 WARN [IBM Remove vdisk FC Mappings] Currently working on: id,4
12:30:13.315 ERROR [IBM Remove vdisk FC Mappings] Cannot bind argument to parameter 'Value' because it is an empty string.
The part of the script it is failing on is a part that takes an array that contains xxx,yyy pairs, and splits them out and uses xxx as the FieldName and yyy as the FieldValue.
I've modified the script to account for entries that may be blank for yyy (for example "start_time, " ... I have my script modify that item to be "start_time,EMPTY".
Again, the script works fine when run outside WFA, on the same host that WFA is installed on. Any ideas or suggestions?