615 lines
24 KiB
VB.net
615 lines
24 KiB
VB.net
Imports System.IO
|
|
Imports System.Reflection
|
|
Imports NLog
|
|
Imports NLog.Config
|
|
Imports NLog.Targets
|
|
|
|
''' <module>LogConfig</module>
|
|
''' <version>0.0.1.0</version>
|
|
''' <date>02.10.2018</date>
|
|
''' <summary>
|
|
''' Module that writes file-logs to different locations:
|
|
''' local application data, the current directory or a custom path.
|
|
''' Files and directories will be automatically created.
|
|
''' </summary>
|
|
''' <dependencies>
|
|
''' NLog, >= 4.5.8
|
|
''' </dependencies>
|
|
''' <example>
|
|
''' Imports DigitalData.Modules.Logging
|
|
'''
|
|
''' Class FooProgram
|
|
''' Private Logger as Logger
|
|
''' Private LogConfig as LogConfig
|
|
'''
|
|
''' Public Sub New()
|
|
''' LogConfig = new LogConfig(args)
|
|
''' Logger = LogConfig.GetLogger()
|
|
''' End Sub
|
|
'''
|
|
''' Public Sub Bar()
|
|
''' Logger.Info("Baz")
|
|
''' End Sub
|
|
''' End Class
|
|
'''
|
|
''' Class FooLib
|
|
''' Private Logger as NLog.Logger
|
|
'''
|
|
''' Public Sub New(LogConfig as LogConfig)
|
|
''' Logger = LogConfig.GetLogger()
|
|
''' End Sub
|
|
'''
|
|
''' Public Sub Bar()
|
|
''' Logger.Info("Baz")
|
|
''' End Sub
|
|
''' End Class
|
|
''' </example>
|
|
''' <remarks>
|
|
''' If logpath can not be written to, falls back to temp folder as defined in:
|
|
''' https://docs.microsoft.com/de-de/dotnet/api/system.io.path.gettemppath?view=netframework-4.7.2
|
|
'''
|
|
''' If used in a service, LogPath must be set to CustomPath, otherwise the Log will be written to System32!
|
|
'''
|
|
''' For NLog Troubleshooting, set the following Environment variables to write the NLog internal Log:
|
|
''' - NLOG_INTERNAL_LOG_LEVEL: Debug
|
|
''' - NLOG_INTERNAL_LOG_FILE: ex. C:\Temp\Nlog_Internal.log
|
|
''' </remarks>
|
|
Public Class LogConfig
|
|
#Region "Private Properties"
|
|
Private Const OPEN_FILE_CACHE_TIMEOUT As Integer = 30
|
|
Private Const OPEN_FILE_FLUSH_TIMEOUT As Integer = 5
|
|
Private Const AUTO_FLUSH As Boolean = False
|
|
|
|
Private Const KEEP_FILES_OPEN As Boolean = False
|
|
Private Const KEEP_FILES_OPEN_DEBUG As Boolean = True
|
|
|
|
' MAX_ARCHIVES_FILES works like this (in version 4.5.8):
|
|
' 0 = keep ALL archives files
|
|
' 1 = only keep latest logfile and NO archive files
|
|
' n = keep n archive files
|
|
Private Const MAX_ARCHIVE_FILES_DEFAULT As Integer = 0
|
|
Private Const MAX_ARCHIVE_FILES_DEBUG_DETAIL As Integer = 0
|
|
Private Const ARCHIVE_EVERY As FileArchivePeriod = FileArchivePeriod.Day
|
|
|
|
Private Const FILE_NAME_FORMAT_DEFAULT As String = "${shortdate}-${var:product}${var:suffix}${event-properties:item=ModuleName}.log"
|
|
Private Const FILE_NAME_FORMAT_DEBUG As String = "${shortdate}-${var:product}${var:suffix}${event-properties:item=ModuleName}-Debug.log"
|
|
Private Const FILE_NAME_FORMAT_TRACE As String = "${shortdate}-${var:product}${var:suffix}${event-properties:item=ModuleName}-Trace.log"
|
|
Private Const FILE_NAME_FORMAT_ERROR As String = "${shortdate}-${var:product}${var:suffix}${event-properties:item=ModuleName}-Error.log"
|
|
Private Const FILE_NAME_FORMAT_JSON As String = "${shortdate}-${var:product}${var:suffix}${event-properties:item=ModuleName}.log.json"
|
|
|
|
Private Const TARGET_DEFAULT As String = "defaultTarget"
|
|
Private Const TARGET_ERROR_EX As String = "errorExceptionTarget"
|
|
Private Const TARGET_ERROR As String = "errorTarget"
|
|
Private Const TARGET_DEBUG As String = "debugTarget"
|
|
Private Const TARGET_TRACE As String = "traceTarget"
|
|
Private Const TARGET_JSON As String = "jsonTarget"
|
|
'Private Const TARGET_MEMORY As String = "memoryTarget"
|
|
|
|
Private Const LOG_FORMAT_BASE As String = "${time}|${logger:shortName=True}|${level:uppercase=true}"
|
|
Private Const LOG_FORMAT_CALLSITE As String = "${callsite:className=false:fileName=true:includeSourcePath=false:methodName=true}"
|
|
'Private Const LOG_FORMAT_EXCEPTION As String = "${exception:format=Message,StackTrace:innerFormat=Message,StackTrace:maxInnerExceptionLevel=3}"
|
|
Private Const LOG_FORMAT_EXCEPTION As String = "${message}${onexception:${newline}${exception:format=Message,StackTrace:innerFormat=Message,StackTrace:maxInnerExceptionLevel=3}}"
|
|
|
|
Private Const LOG_FORMAT_DEFAULT As String = LOG_FORMAT_BASE & " >> ${message}"
|
|
Private Const LOG_FORMAT_ERROR As String = LOG_FORMAT_BASE & " >> " & LOG_FORMAT_EXCEPTION
|
|
Private Const LOG_FORMAT_DEBUG As String = LOG_FORMAT_BASE & " >> " & LOG_FORMAT_CALLSITE & " -> " & "${message}"
|
|
|
|
Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt"
|
|
Private Const FOLDER_NAME_LOG = "Log"
|
|
|
|
Private Const FILE_KEEP_RANGE As Integer = 30
|
|
'Private Const MAX_MEMORY_LOG_COUNT As Integer = 1000
|
|
|
|
Private ReadOnly _failSafePath As String = Path.GetTempPath()
|
|
Private ReadOnly _basePath As String = _failSafePath
|
|
|
|
Private _config As LoggingConfiguration
|
|
Private _EnableDebugLogging As Boolean = False
|
|
Private _EnableTraceLogging As Boolean = False
|
|
Private _EnableJsonLogging As Boolean = False
|
|
|
|
#End Region
|
|
#Region "Public Properties"
|
|
Public Enum PathType As Integer
|
|
AppData = 0
|
|
CurrentDirectory = 1
|
|
CustomPath = 2
|
|
Temp = 3
|
|
End Enum
|
|
|
|
''' <summary>
|
|
''' Returns the NLog.LogFactory object that is used to create Loggers
|
|
''' </summary>
|
|
''' <returns>LogFactory object</returns>
|
|
Public ReadOnly Property LogFactory As LogFactory
|
|
|
|
''' <summary>
|
|
''' Returns the path to the current default logfile
|
|
''' </summary>
|
|
''' <returns>Filepath to the logfile</returns>
|
|
Public ReadOnly Property LogFile As String
|
|
|
|
''' <summary>
|
|
''' Returns the path to the current log directory
|
|
''' </summary>
|
|
''' <returns>Directory path to the log directory</returns>
|
|
Public ReadOnly Property LogDirectory As String
|
|
|
|
''' <summary>
|
|
''' Determines if a debug log will be written
|
|
''' </summary>
|
|
''' <returns>True, if debug log will be written. False otherwise.</returns>
|
|
Public Property Debug As Boolean
|
|
Get
|
|
Return _EnableDebugLogging
|
|
End Get
|
|
Set(value As Boolean)
|
|
_EnableDebugLogging = value
|
|
ReloadConfig()
|
|
End Set
|
|
End Property
|
|
|
|
Public Property Trace As Boolean
|
|
Get
|
|
Return _EnableTraceLogging
|
|
End Get
|
|
Set(value As Boolean)
|
|
_EnableTraceLogging = value
|
|
ReloadConfig()
|
|
End Set
|
|
End Property
|
|
|
|
Public Property EnableJsonLog As Boolean
|
|
Get
|
|
Return _EnableJsonLogging
|
|
End Get
|
|
Set(value As Boolean)
|
|
_EnableJsonLogging = value
|
|
ReloadConfig()
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Returns Logs in Memory as List(Of String) if Debug is enabled
|
|
''' Returns an empty list if debug is disabled
|
|
''' </summary>
|
|
''' <returns>A list of log messages</returns>
|
|
Public ReadOnly Property Logs As List(Of String)
|
|
Get
|
|
'Dim oTarget = _config.FindTargetByName(Of MemoryTarget)(TARGET_MEMORY)
|
|
'Return oTarget?.Logs.ToList()
|
|
Return New List(Of String)
|
|
End Get
|
|
End Property
|
|
|
|
Public ReadOnly Property NLogConfig As LoggingConfiguration
|
|
Get
|
|
Return _config
|
|
End Get
|
|
End Property
|
|
|
|
#End Region
|
|
|
|
''' <summary>
|
|
''' Initializes a new LogConfig object with the options supplied as a LogOptions object
|
|
''' </summary>
|
|
''' <param name="Options"></param>
|
|
Public Sub New(Options As LogOptions)
|
|
MyClass.New(Options.LogPath, Options.CustomLogPath, Options.Suffix, Options.CompanyName, Options.ProductName, Options.FileKeepInterval)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Initializes a new LogConfig object with a logpath and optinally a filename-suffix.
|
|
''' </summary>
|
|
''' <param name="LogPath">The basepath to write logs to. Can be AppData, CurrentDirectory or CustomPath.</param>
|
|
''' <param name="CustomLogPath">If `logPath` is set to custom, this defines the custom logPath.</param>
|
|
''' <param name="Suffix">If set to anything other than Nothing, extends the logfile name with this suffix.</param>
|
|
''' <param name="CompanyName">CompanyName is used to construct log-path in when LogPath is set to PathType:AppData</param>
|
|
''' <param name="ProductName">ProductName is used to construct log-path in when LogPath is set to PathType:AppData</param>
|
|
''' <param name="FileKeepRangeInDays">Amount of days where files are kept and not deleted.</param>
|
|
Public Sub New(LogPath As PathType,
|
|
Optional CustomLogPath As String = Nothing,
|
|
Optional Suffix As String = Nothing,
|
|
Optional CompanyName As String = Nothing,
|
|
Optional ProductName As String = Nothing,
|
|
Optional FileKeepRangeInDays As Integer = FILE_KEEP_RANGE)
|
|
|
|
If LogPath = PathType.AppData And (ProductName Is Nothing Or CompanyName Is Nothing) Then
|
|
Throw New ArgumentException("Modules.Logging: PathType is AppData and either CompanyName or ProductName was not supplied!")
|
|
End If
|
|
|
|
If LogPath = PathType.CurrentDirectory Then
|
|
Throw New ArgumentException("Modules.Logging: LogPath.CurrentDirectory is deprecated. Please use LogPath.CustomPath!")
|
|
End If
|
|
|
|
If LogPath = PathType.AppData Then
|
|
Dim appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
|
|
_basePath = Path.Combine(appDataDir, CompanyName, ProductName, FOLDER_NAME_LOG)
|
|
ElseIf LogPath = PathType.Temp Then
|
|
_basePath = _failSafePath
|
|
Else 'Custom Path
|
|
_basePath = CustomLogPath
|
|
End If
|
|
|
|
' If directory does not exist, try to create it!
|
|
If Not Directory.Exists(_basePath) Then
|
|
Try
|
|
Directory.CreateDirectory(_basePath)
|
|
Catch ex As Exception
|
|
' If creation fails, use failSafe path
|
|
_basePath = _failSafePath
|
|
End Try
|
|
End If
|
|
|
|
' Try to create a file in `basePath` to check write permissions
|
|
Try
|
|
Dim fileAccessPath = Path.Combine(_basePath, FILE_NAME_ACCESS_TEST)
|
|
Using fs As FileStream = File.Create(fileAccessPath)
|
|
fs.WriteByte(0)
|
|
End Using
|
|
|
|
File.Delete(fileAccessPath)
|
|
Catch ex As Exception
|
|
' If creation fails, use failSafe path
|
|
_basePath = _failSafePath
|
|
End Try
|
|
|
|
' Set the suffix to the given string if it exists
|
|
Dim logFileSuffix As String = String.Empty
|
|
|
|
If Suffix IsNot Nothing AndAlso Suffix.Count > 0 Then
|
|
logFileSuffix = $"-{Suffix}"
|
|
End If
|
|
|
|
Dim oProductName As String = "Main"
|
|
|
|
If ProductName IsNot Nothing Then
|
|
oProductName = ProductName
|
|
End If
|
|
|
|
' Create config object and initalize it
|
|
_config = GetConfig(oProductName, logFileSuffix)
|
|
|
|
' Save config
|
|
LogFactory = New LogFactory With {
|
|
.Configuration = _config
|
|
}
|
|
|
|
' Save log paths for files/directory
|
|
LogDirectory = _basePath
|
|
LogFile = GetCurrentLogFilePath()
|
|
|
|
Dim oLogger = GetLogger()
|
|
oLogger.Info("Logging started for [{0}{1}] in [{2}]", oProductName, logFileSuffix, LogFile)
|
|
oLogger.Info("Logging Version [{0}]", Assembly.GetExecutingAssembly().GetName().Version)
|
|
|
|
' Clear old Logfiles as defined in `FileKeepInterval`
|
|
ClearOldLogfiles(FileKeepRangeInDays)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Clears old LogFiles from the configured logpath for compliance with the GDPR
|
|
''' </summary>
|
|
''' <param name="FileKeepRange">Days in which logfiles should be kept. All files older than `Now - FileKeepInterval` will be deleted.</param>
|
|
''' <returns>True, if files were deleted as expected or no files were deleted. Otherwise false.</returns>
|
|
Private Function ClearOldLogfiles(FileKeepRange As Integer) As Boolean
|
|
Dim oClassName As String = GetClassFullName()
|
|
Dim oLogger As Logger = GetLogger(oClassName)
|
|
|
|
Try
|
|
Dim oContinueOnError = True
|
|
Dim oUnableToDeleteCounter = 0
|
|
Dim oDirectory As New DirectoryInfo(LogDirectory)
|
|
Dim oDateLimit As Date = Date.Now.AddDays(-FileKeepRange)
|
|
Dim oFiles As List(Of FileInfo) = oDirectory.
|
|
EnumerateFiles().
|
|
Where(Function(oFileInfo As FileInfo) oFileInfo.Extension = ".log" And oFileInfo.LastWriteTime < oDateLimit).
|
|
ToList()
|
|
|
|
If oFiles.Count = 0 Then
|
|
oLogger.Info("No logfiles were marked for deletion in the range [last {0} days].", FileKeepRange)
|
|
Return True
|
|
End If
|
|
|
|
oLogger.Info("Deleting [{0}] old logfiles that are marked for deletion in the range [last {1} days].", oFiles.Count, FileKeepRange)
|
|
|
|
For Each oFile As FileInfo In oFiles
|
|
Try
|
|
oFile.Delete()
|
|
Catch ex As Exception
|
|
oUnableToDeleteCounter += 1
|
|
oLogger.Warn("File {0} could not be deleted!")
|
|
End Try
|
|
Next
|
|
|
|
If oUnableToDeleteCounter > 0 Then
|
|
oLogger.Info("Delete old logfiles partially. {0} files could not be deleted.", oUnableToDeleteCounter)
|
|
Else
|
|
oLogger.Info("Deleted [{0}] old logfiles.", oFiles.Count)
|
|
End If
|
|
|
|
Return True
|
|
Catch ex As Exception
|
|
oLogger.Error(ex)
|
|
|
|
Return False
|
|
End Try
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns the Logger for the calling class
|
|
''' </summary>
|
|
''' <returns>An object of Logging.Logger</returns>
|
|
<DebuggerStepThrough()>
|
|
Public Function GetLogger() As Logger
|
|
Dim oClassName As String = GetClassFullName()
|
|
Return GetLogger(oClassName, String.Empty)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns the Logger for the specified classname
|
|
''' </summary>
|
|
''' <returns>An object of Logging.Logger</returns>
|
|
<DebuggerStepThrough()>
|
|
Public Function GetLogger(ClassName As String) As Logger
|
|
Return GetLogger(ClassName, String.Empty)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns the Logger for the specified module using event-properties
|
|
''' </summary>
|
|
''' <remarks>
|
|
''' https://github.com/NLog/NLog/wiki/EventProperties-Layout-Renderer
|
|
''' https://stackoverflow.com/questions/31337030/separate-log-file-for-specific-class-instance-using-nlog/32065824#32065824
|
|
''' </remarks>
|
|
''' <returns>An object of Logging.Logger</returns>
|
|
<DebuggerStepThrough()>
|
|
Public Function GetLoggerFor(ModuleName As String) As Logger
|
|
Dim oClassName As String = GetClassFullName()
|
|
Return GetLogger(oClassName, ModuleName)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns the Logger for a class specified by `ClassName`
|
|
''' </summary>
|
|
''' <param name="ClassName">The name of the class the logger belongs to</param>
|
|
''' <returns>An object of Logging.Logger</returns>
|
|
Public Function GetLogger(ClassName As String, ModuleName As String) As Logger
|
|
Dim oLogger = LogFactory.GetLogger(Of Logger)(ClassName)
|
|
|
|
If ModuleName IsNot Nothing AndAlso ModuleName.Length > 0 Then
|
|
Return oLogger.WithProperty("ModuleName", $"-{ModuleName}")
|
|
End If
|
|
|
|
Return oLogger
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Clears the internal log
|
|
''' </summary>
|
|
Public Sub ClearLogs()
|
|
'Dim oTarget = _config.FindTargetByName(Of MemoryTarget)(TARGET_MEMORY)
|
|
'oTarget?.Logs.Clear()
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Gets the fully qualified name of the class invoking the calling method,
|
|
''' including the namespace but Not the assembly.
|
|
''' </summary>
|
|
''' <returns>The fully qualified class name</returns>
|
|
''' <remarks>This method is very resource-intensive!</remarks>
|
|
<DebuggerStepThrough()>
|
|
Public Shared Function GetClassFullName(Optional IncludeMethodNames As Boolean = False, Optional Parts As Integer = 0) As String
|
|
Dim oFramesToSkip As Integer = 2
|
|
Dim oClassName As String = String.Empty
|
|
Dim oStackTrace = Environment.StackTrace
|
|
Dim oStackTraceLines = oStackTrace.Replace(vbCr, "").Split({vbLf}, StringSplitOptions.RemoveEmptyEntries)
|
|
|
|
For i As Integer = 0 To oStackTraceLines.Length - 1
|
|
Dim oCallingClassAndMethod = oStackTraceLines(i).Split({" ", "<>", "(", ")"}, StringSplitOptions.RemoveEmptyEntries)(1)
|
|
Dim oMethodStartIndex As Integer = oCallingClassAndMethod.LastIndexOf(".", StringComparison.Ordinal)
|
|
|
|
If oMethodStartIndex > 0 Then
|
|
If IncludeMethodNames Then
|
|
oMethodStartIndex = oCallingClassAndMethod.Count
|
|
End If
|
|
|
|
Dim oCallingClass = oCallingClassAndMethod.Substring(0, oMethodStartIndex)
|
|
oClassName = oCallingClass.TrimEnd("."c)
|
|
|
|
If Not oClassName.StartsWith("System.Environment") AndAlso oFramesToSkip <> 0 Then
|
|
i += oFramesToSkip - 1
|
|
oFramesToSkip = 0
|
|
Continue For
|
|
End If
|
|
|
|
If Not oClassName.StartsWith("System.") Then Exit For
|
|
End If
|
|
Next
|
|
|
|
If Parts > 0 Then
|
|
Dim oParts = oClassName.
|
|
Split(".").
|
|
Reverse().
|
|
Take(Parts).
|
|
Reverse()
|
|
|
|
oClassName = String.Join(".", oParts)
|
|
End If
|
|
|
|
Return oClassName
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns the initial log configuration
|
|
''' </summary>
|
|
''' <param name="productName">The chosen productname</param>
|
|
''' <param name="logFileSuffix">The chosen suffix</param>
|
|
''' <returns>A NLog.LoggingConfiguration object</returns>
|
|
Private Function GetConfig(productName As String, logFileSuffix As String) As LoggingConfiguration
|
|
_config = New LoggingConfiguration()
|
|
_config.Variables("product") = productName
|
|
_config.Variables("suffix") = logFileSuffix
|
|
|
|
' Add default targets
|
|
_config.AddTarget(TARGET_ERROR_EX, GetErrorExceptionLogTarget(_basePath))
|
|
_config.AddTarget(TARGET_DEFAULT, GetDefaultLogTarget(_basePath))
|
|
_config.AddTarget(TARGET_DEBUG, GetDebugLogTarget(_basePath))
|
|
_config.AddTarget(TARGET_TRACE, GetTraceLogTarget(_basePath))
|
|
_config.AddTarget(TARGET_JSON, GetJsonLogTarget(_basePath))
|
|
|
|
|
|
' Add default rules
|
|
AddDefaultRules(_config)
|
|
|
|
Return _config
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Adds the default rules
|
|
''' </summary>
|
|
''' <param name="config">A NLog.LoggingConfiguration object</param>
|
|
Private Sub AddDefaultRules(ByRef config As LoggingConfiguration)
|
|
config.AddRuleForOneLevel(LogLevel.Error, TARGET_ERROR_EX)
|
|
config.AddRuleForOneLevel(LogLevel.Fatal, TARGET_ERROR_EX)
|
|
config.AddRuleForOneLevel(LogLevel.Warn, TARGET_DEFAULT)
|
|
config.AddRuleForOneLevel(LogLevel.Info, TARGET_DEFAULT)
|
|
'config.AddRuleForAllLevels(TARGET_MEMORY)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Returns the full path of the current default log file.
|
|
''' </summary>
|
|
''' <returns>Full path of the current default log file</returns>
|
|
Private Function GetCurrentLogFilePath()
|
|
Dim logEventInfo As New LogEventInfo() With {.TimeStamp = Date.Now}
|
|
Dim target As FileTarget = _config.FindTargetByName(TARGET_DEFAULT)
|
|
Dim fileName As String = target.FileName.Render(logEventInfo)
|
|
|
|
Return fileName
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Reconfigures and re-adds all loggers, optionally adding the debug rule.
|
|
''' </summary>
|
|
Private Sub ReloadConfig()
|
|
Dim oLogger = GetLogger()
|
|
|
|
' Clear Logging Rules
|
|
_config.LoggingRules.Clear()
|
|
|
|
' Add default rules
|
|
AddDefaultRules(_config)
|
|
|
|
' Add json rule, if configured
|
|
If _EnableJsonLogging = True Then
|
|
oLogger.Info("JSON Logging is now Enabled.")
|
|
_config.AddRule(LogLevel.Debug, LogLevel.Error, TARGET_JSON)
|
|
End If
|
|
|
|
' Add debug rule, if configured
|
|
If _EnableDebugLogging = True Then
|
|
_config.AddRule(LogLevel.Debug, LogLevel.Error, TARGET_DEBUG)
|
|
oLogger.Info("DEBUG Logging is now Enabled.")
|
|
Else
|
|
oLogger.Debug("DEBUG Logging is now Disabled.")
|
|
End If
|
|
|
|
' Add trace rule, if configured
|
|
If _EnableTraceLogging = True Then
|
|
_config.AddRule(LogLevel.Trace, LogLevel.Error, TARGET_TRACE)
|
|
End If
|
|
|
|
' Reload all running loggers
|
|
LogFactory.ReconfigExistingLoggers()
|
|
End Sub
|
|
|
|
#Region "Log Targets"
|
|
Private Function GetJsonLogTarget(basePath As String) As FileTarget
|
|
Dim oJsonLayout = New Layouts.JsonLayout
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Level", "${level}"))
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Message", "${message}"))
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Time", "${date}"))
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Product", "${var:product}"))
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Suffix", "${var:suffix}"))
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Module", "${event-properties:item=ModuleName}"))
|
|
oJsonLayout.Attributes.Add(New Layouts.JsonAttribute("Exception", "${exception:format=@,StackTrace:innerFormat=@:maxInnerExceptionLevel=3}"))
|
|
|
|
Dim jsonLog As New FileTarget() With {
|
|
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_JSON),
|
|
.Name = TARGET_JSON,
|
|
.Layout = oJsonLayout,
|
|
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEFAULT,
|
|
.ArchiveEvery = ARCHIVE_EVERY,
|
|
.KeepFileOpen = KEEP_FILES_OPEN,
|
|
.Encoding = Text.Encoding.Unicode
|
|
}
|
|
|
|
Return jsonLog
|
|
End Function
|
|
|
|
Private Function GetDefaultLogTarget(basePath As String) As FileTarget
|
|
Dim defaultLog As New FileTarget() With {
|
|
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_DEFAULT),
|
|
.Name = TARGET_DEFAULT,
|
|
.Layout = LOG_FORMAT_DEFAULT,
|
|
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEFAULT,
|
|
.ArchiveEvery = ARCHIVE_EVERY,
|
|
.KeepFileOpen = KEEP_FILES_OPEN,
|
|
.Encoding = Text.Encoding.Unicode
|
|
}
|
|
|
|
Return defaultLog
|
|
End Function
|
|
Private Function GetErrorExceptionLogTarget(basePath As String) As FileTarget
|
|
Dim errorLogWithExceptions As New FileTarget() With {
|
|
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_ERROR),
|
|
.Name = TARGET_ERROR_EX,
|
|
.Layout = LOG_FORMAT_ERROR,
|
|
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEFAULT,
|
|
.ArchiveEvery = ARCHIVE_EVERY,
|
|
.KeepFileOpen = KEEP_FILES_OPEN,
|
|
.Encoding = Text.Encoding.Unicode
|
|
}
|
|
|
|
Return errorLogWithExceptions
|
|
End Function
|
|
|
|
|
|
|
|
Private Function GetDebugLogTarget(basePath As String) As FileTarget
|
|
Dim debugLog As New FileTarget() With {
|
|
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_DEBUG),
|
|
.Name = TARGET_DEBUG,
|
|
.Layout = LOG_FORMAT_DEBUG,
|
|
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEBUG_DETAIL,
|
|
.ArchiveEvery = ARCHIVE_EVERY,
|
|
.KeepFileOpen = KEEP_FILES_OPEN_DEBUG,
|
|
.OpenFileCacheTimeout = OPEN_FILE_CACHE_TIMEOUT,
|
|
.AutoFlush = AUTO_FLUSH,
|
|
.OpenFileFlushTimeout = OPEN_FILE_FLUSH_TIMEOUT,
|
|
.Encoding = Text.Encoding.Unicode
|
|
}
|
|
|
|
Return debugLog
|
|
End Function
|
|
|
|
Private Function GetTraceLogTarget(basePath As String) As FileTarget
|
|
Dim traceLog As New FileTarget() With {
|
|
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_TRACE),
|
|
.Name = TARGET_TRACE,
|
|
.Layout = LOG_FORMAT_DEBUG,
|
|
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEBUG_DETAIL,
|
|
.ArchiveEvery = ARCHIVE_EVERY,
|
|
.KeepFileOpen = KEEP_FILES_OPEN_DEBUG,
|
|
.OpenFileCacheTimeout = OPEN_FILE_CACHE_TIMEOUT,
|
|
.AutoFlush = AUTO_FLUSH,
|
|
.OpenFileFlushTimeout = OPEN_FILE_FLUSH_TIMEOUT,
|
|
.Encoding = Text.Encoding.Unicode
|
|
}
|
|
|
|
Return traceLog
|
|
End Function
|
|
#End Region
|
|
End Class
|