Subscribe

Logging for Script Based Datasources.

[ Edited ]

Logging for Script Based Datasources.
---------------

Problem Statement:
----------------
1. In WFA, the script based Datasource Types don't have Datasource specific logging mechanism the way command executions have in a workflow.

 

2. The WFA Powershell logging cmdlet Get-WfaLogger doesn't serve me well here. All the log data for all acquistion instances of all DataSources gets dumped into a common wfa.log with which apart from these log data has tons of other Java logs.

 

3. The wfa.log is a common logging file for a number of WFA activities. It just has too much data from everywhere. Its massive file and searching/debugging for anything is very diffcilut.

 

4. Its keeps getting archieved from time to time. This adds to the problem of digging out an execution instance specific log-data. One needs to hunt though multiple files.


Araprt from the above problems being solved, I wanted the following too:

 

1. Flexible and configurable logger for every single DataSource Type. I may not want one common logging configuration for all my Datasource Types.
2. Every single Data source instance for a given Datasource Type to have separate log files.
3. To be able to view the logs from WFA GUI.


Solution:

----------
WFA is a very flexible framework and allows multiple 3rd party powershell modules/snapins/dlls to be plugged in.

 

Download Apache Log4net
-----
Log4net is a very good logger for .NET platform. Download it from here: http://apache.bytenet.in//logging/log4net/binaries/log4net-1.2.13-bin-newkey.zip . Extracting it will have show numerous files but we need only 1, the log4net.dll . You can use the one at log4net-1.2.13\bin\net\3.5\release for you .NET version 3.5

 

Configuring log4net
-----
Most configurations for log4net are based on a common configuration file. But this can't serve my purpose. I wanted flexible configuration for every Datasource Type. So I need to set the configurations in the powershell code.

 

 

Here is an example logger definition inside a DataSource Type code.
-----

###### Create the Logger Configuration ######
#Load the assembley from your dll location
[void][Reflection.Assembly]::LoadFrom("C:\log4net\log4net.dll")

 

#Define your logging pattern. See more about it here: http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout.html
$pattern="%d %w %-5p %c : %m%n"

 

#Reset the log4net configuration
[log4net.LogManager]::ResetConfiguration()

 

#Create the Logging file for every single Datasource based on the Hostname.
$DSHostName = Get-WfaRestParameter "host"

$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$logFile=$PSScriptRoot.Substring(0, $($PSScriptRoot.Length - 8)) + "\log\" + $DSHostName +".log"

#Create the log4net config Appender
$Appender = new-object log4net.Appender.FileAppender
$Appender.File = $logFile
$Appender.Layout = new-object log4net.Layout.PatternLayout($pattern)
$Appender.Threshold = [log4net.Core.Level]::All
$Appender.ActivateOptions()
[log4net.Config.BasicConfigurator]::Configure($Appender)

 

#Create Logger for the DataSource Type Name. You can actually put anything
$logg = [log4net.LogManager]::GetLogger("[Person Data source with logging]")


####### Logger is Ready #########

 

$PersonFile = "./person.csv"
New-Item -Path $PersonFile -type file -Force

Add-Content $PersonFile ([Byte[]][Char[]] "`\N`tAron`tFinch`t011-12345678`n") -Encoding Byte
Add-Content $PersonFile ([Byte[]][Char[]] "`\N`tDavid`tWarner`t011-12345677`n") -Encoding Byte
Add-Content $PersonFile ([Byte[]][Char[]] "`\N`tSteven`tSmith`t011-12345676`n") -Encoding Byte


#Now log whatever you want.
$logg.Info("This is an info message on Host: $DSHostName")
$logg.Debug("This is a debug message")
$logg.Warn("This is a warning message")
$logg.Error("this is an error Message")
$logg.Fatal("this is a fatal error Message")

 

 

###### END Code #############

 

 

To view the logs fom WFA GUI, go to WFA Administration -> Log Viewer . You'll see a log file with name as the name of the Data Source host ( e.g. Host01.log ). Now every single DataSource  belonging to this Datasource type will have separate log file. 

 

DS_log viewer.png

 

 

DS_log viewer 2.png

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Re: Logging for Script Based Datasources.

[ Edited ]

WFA3.0 bundles log4net DLL with the WFA installer, so you don't need to downalod it from Apache website. I've added the .dar file for WFA3.0 as well.  Minior change in code to find and add the path to log4net.all as a part of the code. This code will work for both default and non-default installation locations. Just copy-paste the Create Logger Code in your DS script.

 

 

sinhaa

 

 

###### Create the Logger Configuration   ######
#Load the assembley from your dll location $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent $dllLocation=$PSScriptRoot.Substring(0, $($PSScriptRoot.Length - 24)) + "PoSH\Modules\DataONTAP\log4net.dll" [void][Reflection.Assembly]::LoadFrom($dllLocation) #Define your logging pattern. See more about it here: http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout.html $pattern="%d %w %-5p %c : %m%n" #Reset the log4net configuration [log4net.LogManager]::ResetConfiguration() #Create the Logging file for every single Datasource based on the Hostname. $DSHostName = Get-WfaRestParameter "host" $logFile=$PSScriptRoot.Substring(0, $($PSScriptRoot.Length - 8)) + "\log\" + $DSHostName +".log" New-Item -Path $logFile -type file -ErrorAction SilentlyContinue #Create the log4net config Appender $Appender = new-object log4net.Appender.FileAppender $Appender.File = $logFile $Appender.Layout = new-object log4net.Layout.PatternLayout($pattern) $Appender.Threshold = [log4net.Core.Level]::All $Appender.ActivateOptions() [log4net.Config.BasicConfigurator]::Configure($Appender)
#Create Logger for the DataSource Type Name. You can actually put anything

$FName = $MyInvocation.MyCommand.Name
$DSName = $FName.Substring(0, ($FName.Length - 23))
$logg = [log4net.LogManager]::GetLogger("[$DSName]") ####### Logger is Ready ######### $PersonFile = "./person.csv" New-Item -Path $PersonFile -type file -Force Add-Content $PersonFile ([Byte[]][Char[]] "`\N`tAron`tFinch`t011-12345678`n") -Encoding Byte Add-Content $PersonFile ([Byte[]][Char[]] "`\N`tDavid`tWarner`t011-12345677`n") -Encoding Byte Add-Content $PersonFile ([Byte[]][Char[]] "`\N`tSteven`tSmith`t011-12345676`n") -Encoding Byte #Now log whatever you want. $logg.Info("This is an info mssage on Host: $DSHostName") $logg.Debug("This is a debug message") $logg.Warn("This is a warning message") $logg.Error("this is an error Message") $logg.Fatal("this is a fatal error Message: $dllLocation")

 

 

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.