9 Commits

Author SHA1 Message Date
Jonathan Jenne
70bb33f823 Base: move Files 2023-09-05 10:25:49 +02:00
Jonathan Jenne
e63d1ea557 Logging: Improve json logging 2023-09-01 13:56:37 +02:00
Jonathan Jenne
2b80e8fa97 Jobs: Remove obsolete history function 2023-09-01 13:56:12 +02:00
Jonathan Jenne
9cab65f941 Jobs: Prepare Service Refactor, fix nullref error with emaildata, remove obsolete loops 2023-09-01 13:55:55 +02:00
Jonathan Jenne
4c8bdb27fd Jobs: add filename property MD5HashException, Add meaningful message to MissingValueException 2023-09-01 13:44:00 +02:00
Jonathan Jenne
b604ffcba2 Jobs: Only support one watch directory 2023-09-01 13:43:19 +02:00
Jonathan Jenne
6ef1e97deb Jobs: Add filename placeholder to EMAIL_MD5_ERROR 2023-09-01 13:42:53 +02:00
Jonathan Jenne
60bcf26379 Jobs: Add default Values to email data 2023-09-01 13:42:26 +02:00
Jonathan Jenne
a4a3dc4536 Restructure Base 2023-09-01 13:41:40 +02:00
21 changed files with 1366 additions and 586 deletions

View File

@@ -77,10 +77,12 @@
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="BaseClass.vb" />
<Compile Include="BaseUtils.vb" />
<Compile Include="Base\BaseClass.vb" />
<Compile Include="Base\BaseUtils.vb" />
<Compile Include="Encryption\Compression.vb" />
<Compile Include="Encryption\Encryption.vb" />
<Compile Include="Encryption\EncryptionLegacy.vb" />
<Compile Include="DatabaseEx.vb" />
<Compile Include="ECM\ECM.vb" />
<Compile Include="MimeEx.vb" />
<Compile Include="WindowsEx.vb" />
<Compile Include="ModuleExtensions.vb" />
@@ -88,9 +90,6 @@
<Compile Include="NativeMethods.vb" />
<Compile Include="ObjectEx.vb" />
<Compile Include="GraphicsEx.vb" />
<Compile Include="IDB\Attributes.vb" />
<Compile Include="IDB\Database.vb" />
<Compile Include="IDB\FileStore.vb" />
<Compile Include="LanguageEx.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
@@ -140,5 +139,8 @@
<Name>Logging</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Static\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>

View File

@@ -1,7 +0,0 @@
Public Class ECM
Public Enum Product
ProcessManager
GlobalIndexer
ClipboardWatcher
End Enum
End Class

View File

@@ -0,0 +1,70 @@
Imports System.IO
Imports System.IO.Compression
Imports DigitalData.Modules.Logging
Public Class Compression
Private ReadOnly _logger As Logger
Public Sub New(LogConfig As LogConfig)
_logger = LogConfig.GetLogger()
End Sub
Public Async Function CompressAsync(data As Byte()) As Task(Of Byte())
Return Await Task.Run(Function() As Byte()
Return Compress(data)
End Function)
End Function
Public Function Compress(data As Byte()) As Byte()
Try
' ByteArray in Stream umwandeln
Using originalStream As New MemoryStream(data)
' Ziel Stream erstellen
Using compressedStream As New MemoryStream()
' Gzip-Stream erstellen, der alle Daten komprimiert und zu compressedStream durchleitet
'
' > MemoryStream > GzipStream > MemoryStream
' originalStream --> compressionStream --> compressedFileStream
'
Using compressionStream As New GZipStream(compressedStream, CompressionMode.Compress)
originalStream.CopyTo(compressionStream)
compressionStream.Close()
Return compressedStream.ToArray()
End Using
End Using
End Using
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Async Function DecompressAsync(data As Byte()) As Task(Of Byte())
Return Await Task.Run(Function() As Byte()
Return Decompress(data)
End Function)
End Function
Public Function Decompress(data As Byte()) As Byte()
Try
' ByteArray in Stream umwandeln
Using compressedStream As New MemoryStream(data)
' Ziel Stream erstellen
Using decompressedStream As New MemoryStream()
' Gzip-Stream erstellen, der alle Daten komprimiert und zu compressedStream durchleitet
'
' > MemoryStream > GzipStream > MemoryStream
' compressedStream --> decompressionStream --> decompressedStream
'
Using decompressionStream As New GZipStream(compressedStream, CompressionMode.Decompress)
decompressionStream.CopyTo(decompressedStream)
Return decompressedStream.ToArray()
End Using
End Using
End Using
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
End Class

View File

@@ -0,0 +1,148 @@
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text.Encoding
Imports DigitalData.Modules.Logging
''' <summary>
''' https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp
''' </summary>
Public Class Encryption
' This constant is used to determine the keysize of the encryption algorithm in bits.
' We divide this by 8 within the code below to get the equivalent number of bytes.
Private Const KEY_SIZE As Integer = 256
' This constant determines the number of iterations for the password bytes generation function.
Private Const DERIVATION_ITERATIONS As Integer = 1000
Private Const BLOCK_SIZE As Integer = 256
Private _paddingMode As PaddingMode = PaddingMode.Zeros
Private _cipherMode As CipherMode = CipherMode.CBC
Private ReadOnly _password As String
Private _logger As Logger
Public Sub New(LogConfig As LogConfig, Password As String)
_logger = LogConfig.GetLogger()
If IsNothing(Password) Then
Throw New ArgumentNullException("Password")
End If
_password = Password
End Sub
Public Async Function EncryptAsync(PlainTextBytes As Byte()) As Task(Of Byte())
Return Await Task.Run(Function() As Byte()
Return Encrypt(PlainTextBytes)
End Function)
End Function
Public Function Encrypt(PlainText As String) As String
Try
Dim oBytes As Byte() = UTF8.GetBytes(PlainText)
Dim oEncrypted As Byte() = Encrypt(oBytes)
Return UTF8.GetString(oEncrypted)
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Function Encrypt(PlainTextBytes As Byte()) As Byte()
Try
' Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
' so that the same Salt and IV values can be used when decrypting.
Dim oSaltStringBytes = Generate256BitsOfRandomEntropy()
Dim oIvStringBytes = Generate256BitsOfRandomEntropy()
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
Dim oKeyBytes = oPassword.GetBytes(KEY_SIZE / 8)
Using oSymmetricKey = New RijndaelManaged()
oSymmetricKey.BlockSize = BLOCK_SIZE
oSymmetricKey.Mode = _cipherMode
oSymmetricKey.Padding = _paddingMode
Using oEncryptor = oSymmetricKey.CreateEncryptor(oKeyBytes, oIvStringBytes)
Using oMemoryStream = New MemoryStream()
Using oCryptoStream = New CryptoStream(oMemoryStream, oEncryptor, CryptoStreamMode.Write)
oCryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length)
oCryptoStream.FlushFinalBlock()
' Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
Dim oCipherTextBytes = oSaltStringBytes
oCipherTextBytes = oCipherTextBytes.Concat(oIvStringBytes).ToArray()
oCipherTextBytes = oCipherTextBytes.Concat(oMemoryStream.ToArray()).ToArray()
oMemoryStream.Close()
oCryptoStream.Close()
Return oCipherTextBytes
End Using
End Using
End Using
End Using
End Using
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Async Function DecryptAsync(CipherTextBytesWithSaltAndIv As Byte()) As Task(Of Byte())
Return Await Task.Run(Function() As Byte()
Return Decrypt(CipherTextBytesWithSaltAndIv)
End Function)
End Function
Public Function Decrypt(CipherTextPlainWithSaltAndIv As String) As String
Try
Dim oBytes As Byte() = UTF8.GetBytes(CipherTextPlainWithSaltAndIv)
Dim oDecrypted As Byte() = Decrypt(oBytes)
Return UTF8.GetString(oDecrypted)
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Function Decrypt(CipherTextBytesWithSaltAndIv As Byte()) As Byte()
Try
' Get the complete stream of bytes that represent:
' [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
' Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
Dim oSaltStringBytes = CipherTextBytesWithSaltAndIv.Take(KEY_SIZE / 8).ToArray()
' Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
Dim oIvStringBytes = CipherTextBytesWithSaltAndIv.Skip(KEY_SIZE / 8).Take(KEY_SIZE / 8).ToArray()
' Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
Dim oCipherTextBytes = CipherTextBytesWithSaltAndIv.Skip((KEY_SIZE / 8) * 2).Take(CipherTextBytesWithSaltAndIv.Length - ((KEY_SIZE / 8) * 2)).ToArray()
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
Dim oKeyBytes = oPassword.GetBytes(KEY_SIZE / 8)
Using oSymmetricKey = New RijndaelManaged()
oSymmetricKey.BlockSize = BLOCK_SIZE
oSymmetricKey.Mode = _cipherMode
oSymmetricKey.Padding = _paddingMode
Using oDecryptor = oSymmetricKey.CreateDecryptor(oKeyBytes, oIvStringBytes)
Using oMemoryStream = New MemoryStream(oCipherTextBytes)
Using oCryptoStream = New CryptoStream(oMemoryStream, oDecryptor, CryptoStreamMode.Read)
Dim oPlainTextBytes = New Byte(oCipherTextBytes.Length - 1) {}
Dim oDecryptedByteCount = oCryptoStream.Read(oPlainTextBytes, 0, oPlainTextBytes.Length)
oMemoryStream.Close()
oCryptoStream.Close()
Return oPlainTextBytes
End Using
End Using
End Using
End Using
End Using
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Private Shared Function Generate256BitsOfRandomEntropy() As Byte()
Dim oRandomBytes = New Byte(31) {}
' 32 Bytes will give us 256 bits.
Using oRNGCsp = New RNGCryptoServiceProvider()
' Fill the array with cryptographically secure random bytes.
oRNGCsp.GetBytes(oRandomBytes)
End Using
Return oRandomBytes
End Function
End Class

View File

@@ -0,0 +1,85 @@
Imports System.Security.Cryptography
Imports System.Data
Imports System.Data.SqlClient
Public Class EncryptionLegacy
Private TripleDes As New TripleDESCryptoServiceProvider
Private DEFAULT_KEY As String = "!35452didalog="
Private SALT_VALUE As String = "!Didalog35452Heuchelheim="
Sub New()
TripleDes.Key = TruncateHash(DEFAULT_KEY, TripleDes.KeySize \ 8)
TripleDes.IV = TruncateHash("", TripleDes.BlockSize \ 8)
End Sub
Sub New(key As String)
' Initialize the crypto provider.
TripleDes.Key = TruncateHash(key, TripleDes.KeySize \ 8)
TripleDes.IV = TruncateHash("", TripleDes.BlockSize \ 8)
End Sub
Private Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte()
Dim sha1 As New SHA1CryptoServiceProvider
' Hash the key.
Dim keyBytes() As Byte =
System.Text.Encoding.Unicode.GetBytes(key)
Dim hash() As Byte = sha1.ComputeHash(keyBytes)
' Truncate or pad the hash.
ReDim Preserve hash(length - 1)
Return hash
End Function
<DebuggerStepThrough>
Public Function EncryptData(ByVal plaintext As String) As String
Try
' Convert the plaintext string to a byte array.
Dim plaintextBytes() As Byte =
System.Text.Encoding.Unicode.GetBytes(SALT_VALUE & plaintext)
' Create the stream.
Dim ms As New System.IO.MemoryStream
' Create the encoder to write to the stream.
Dim encStream As New CryptoStream(ms,
TripleDes.CreateEncryptor(),
System.Security.Cryptography.CryptoStreamMode.Write)
' Use the crypto stream to write the byte array to the stream.
encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
encStream.FlushFinalBlock()
' Convert the encrypted stream to a printable string.
Return Convert.ToBase64String(ms.ToArray)
Catch ex As Exception
Return plaintext
End Try
End Function
'Entschlüsselt die Zeichenfolge
<DebuggerStepThrough>
Public Function DecryptData(ByVal EncryptedText As String) As String
Try
' Convert the encrypted text string to a byte array.
Dim oEncryptedBytes() As Byte = Convert.FromBase64String(EncryptedText)
' Create the stream.
Dim oMemoryStream As New System.IO.MemoryStream
' Create the decoder to write to the stream.
Dim oCryptoStream As New CryptoStream(oMemoryStream,
TripleDes.CreateDecryptor(),
System.Security.Cryptography.CryptoStreamMode.Write)
' Use the crypto stream to write the byte array to the stream.
oCryptoStream.Write(oEncryptedBytes, 0, oEncryptedBytes.Length)
oCryptoStream.FlushFinalBlock()
Dim oResult = System.Text.Encoding.Unicode.GetString(oMemoryStream.ToArray)
oResult = oResult.Replace(SALT_VALUE, "")
' Convert the plaintext stream to a string.
Return oResult
Catch ex As Exception
Return EncryptedText
End Try
End Function
End Class

View File

@@ -1,15 +0,0 @@
Namespace IDB
Public Class Attributes
Public Const ATTRIBUTE_DOCTYPE = "Doctype"
Public Const ATTRIBUTE_DYNAMIC_FOLDER = "Dynamic Folder"
Public Const ATTRIBUTE_ORIGIN_FILENAME = "OriginFileName"
Public Const ATTRIBUTE_ORIGIN_CHANGED = "OriginChangedDatetime"
Public Const ATTRIBUTE_ORIGIN_CREATED = "OriginCreationDatetime"
Public Const ATTRIBUTE_DISPLAY_FILENAME = "DisplayFileName"
Public Const ATTRIBUTE_DISPLAY_FILENAME1 = "DisplayFileName1"
End Class
End Namespace

View File

@@ -1,11 +0,0 @@
Namespace IDB
Public Class Database
Public Enum NamedDatabase
ECM
IDB
End Enum
End Class
End Namespace

View File

@@ -1,20 +0,0 @@
Namespace IDB
Public Class FileStore
Public Const FILE_STORE_INVALID_OBEJCT_ID = 0
Public Const FILE_CHANGED_QUESTION = "QUESTION VERSION"
Public Const FILE_CHANGED_OVERWRITE = "AUTO REPLACE"
Public Const FILE_CHANGED_VERSION = "AUTO VERSION"
Public Const OBJECT_STATE_FILE_ADDED = "File added"
Public Const OBJECT_STATE_FILE_VERSIONED = "File versioned"
Public Const OBJECT_STATE_FILE_CHANGED = "File changed"
Public Const OBJECT_STATE_FILE_OPENED = "File opened"
Public Const OBJECT_STATE_FILE_DELETED = "File deleted"
Public Const OBJECT_STATE_METADATA_CHANGED = "Metadata changed"
Public Const OBJECT_STATE_ATTRIBUTEVALUE_DELETED = "Attributevalue deleted"
Public Const OBJECT_STATE_FILE_CHECKED_OUT = "File Checked Out"
Public Const OBJECT_STATE_FILE_CHECKED_IN = "File Checked In"
End Class
End Namespace

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Base")>
<Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("1.3.5.0")>
<Assembly: AssemblyTrademark("1.3.6.0")>
<Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' indem Sie "*" wie unten gezeigt eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.3.5.0")>
<Assembly: AssemblyFileVersion("1.3.5.0")>
<Assembly: AssemblyVersion("1.3.6.0")>
<Assembly: AssemblyFileVersion("1.3.6.0")>

View File

@@ -12,7 +12,7 @@ Public Class StringEx
''' And consecutive hyphens.
''' </summary>
''' <param name="s">The string to convert</param>
Public Shared Function ConvertTextToSlug(ByVal s As String) As String
Public Shared Function ConvertTextToSlug(s As String) As String
Dim oBuilder As New StringBuilder()
Dim oWasHyphen As Boolean = True
@@ -27,7 +27,7 @@ Public Class StringEx
oWasHyphen = True
ElseIf Char.IsWhiteSpace(oChar) AndAlso Not oWasHyphen Then
oBuilder.Append("-"c)
oBuilder.Append("_"c)
oWasHyphen = True
End If
Next

View File

@@ -9,7 +9,7 @@ Public Class Exceptions
Public ReadOnly File As FileInfo
Public Sub New(File As FileInfo)
MyBase.New()
MyBase.New($"Missing values in [{File.Name}]")
Me.File = File
End Sub
@@ -73,8 +73,11 @@ Public Class Exceptions
Public Class MD5HashException
Inherits ApplicationException
Public Sub New(pInfo As String)
MyBase.New(pInfo)
Public ReadOnly FileName As String
Public Sub New(pMessage As String, pFileName As String)
MyBase.New(pMessage)
FileName = pFileName
End Sub
End Class
End Class

View File

@@ -1,5 +1,5 @@
Public Class EmailData
Public Attachment As String = ""
Public Subject As String
Public From As String
Public Subject As String = ""
Public From As String = ""
End Class

View File

@@ -18,7 +18,7 @@
Public Const EMAIL_MISSINGPROPERTIES_1 = "<p>Die angehängte Datei entspricht nicht dem WISAG ZUGFeRD-Format: {0}</p>"
Public Const EMAIL_MISSINGPROPERTIES_2 = "<p>Die folgenden Eigenschaften wurden als ERFORDERLICH eingestuft, wurden aber nicht gefunden:<p/>"
Public Const EMAIL_MD5_ERROR = "<p>Die von Ihnen gesendete Rechnung wurde bereits von unserem System verarbeitet.</p>"
Public Const EMAIL_MD5_ERROR = "<p>Die von Ihnen gesendete Rechnung ({0}) wurde bereits von unserem System verarbeitet.</p>"
Public Const EMAIL_VALIDATION_ERROR = "
<p>Die von Ihnen gesendete Rechnung hat die ZUGFeRD Validierung nicht bestanden.</p>

View File

@@ -1,4 +1,5 @@
Imports System.Data.SqlClient
Imports System.ServiceModel.Channels
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports Microsoft.VisualBasic.FileIO
@@ -15,42 +16,30 @@ Namespace ZUGFeRD
_mssql = MSSQL
End Sub
Public Function Create_HistoryEntry(MessageId As String, MD5Checksum As String, Message As String, Transaction As SqlTransaction) As Boolean
Public Function Update_HistoryEntry(pMessageId As String, pMD5Checksum As String, pMessage As String) As Boolean
Try
_logger.Info("Creating History Entry for MessageId [{0}] with comment [{1}]", MessageId, Message)
Dim oSQL = $"INSERT INTO TBEMLP_HISTORY (COMMENT, MD5HASH, EMAIL_MSGID) VALUES ('{Message}', '{MD5Checksum}', '{MessageId}')"
Using oConnection = _mssql.GetConnection()
' 09.07.2021: This can't be in the transaction since the history
' Entry needs to be accessed by MoveAndRenameEmailToRejected shortly after
_mssql.ExecuteNonQueryWithConnectionObject(oSQL, oConnection)
If Message.Contains("REJECTED") Then
oSQL = $"UPDATE TBEMLP_HISTORY SET STATUS = 'REJECTED', COMMENT = '{Message}', CUST_REJECTED = 1,CUST_REJECTED_WHEN = GETDATE() WHERE EMAIL_MSGID = '{MessageId}'"
_mssql.ExecuteNonQueryWithConnectionObject(oSQL, oConnection)
End If
_logger.Debug("History Entry created!")
End Using
Return True
Catch ex As Exception
_logger.Warn("History Entry count not be created for message id [{0}] and md5 [{1}]", MessageId, MD5Checksum)
_logger.Error(ex)
Return False
End Try
End Function
Public Function Update_HistoryEntry(MessageId As String, MD5Checksum As String, Message As String, Transaction As SqlTransaction) As Boolean
Try
_logger.Info("Updating History Entry for MessageId [{0}] with comment [{1}]", MessageId, Message)
_logger.Info("Updating History Entry for MessageId [{0}] with comment [{1}]", pMessageId, pMessage)
' Only look for history entry by MessageId since the MD5 Hash might not be generated yet
Using oConnection = _mssql.GetConnection()
' 09.07.2021: This can't be in the transaction since the history
' Entry needs to be accessed by MoveAndRenameEmailToRejected shortly after
Dim oSQL = $"UPDATE TBEMLP_HISTORY SET COMMENT = '{Message}' WHERE EMAIL_MSGID = '{MessageId}'"
Dim oSQL = $"UPDATE TBEMLP_HISTORY SET
COMMENT = '{pMessage}',
MD5HASH = '{pMD5Checksum}'
WHERE EMAIL_MSGID = '{pMessageId}'"
If pMessage.Contains("REJECTED") Then
oSQL = $"UPDATE TBEMLP_HISTORY SET
COMMENT = '{pMessage}',
MD5HASH = '{pMD5Checksum}',
STATUS = 'REJECTED',
CUST_REJECTED = 1,
CUST_REJECTED_WHEN = GETDATE()
WHERE EMAIL_MSGID = '{pMessageId}'"
End If
_mssql.ExecuteNonQueryWithConnectionObject(oSQL, oConnection)
End Using
@@ -58,7 +47,7 @@ Namespace ZUGFeRD
Return True
Catch ex As Exception
_logger.Warn("History Entry count not be updated for message id [{0}] and md5 [{1}]", MessageId, MD5Checksum)
_logger.Warn("History Entry count not be updated for message id [{0}] and md5 [{1}]", pMessageId, pMD5Checksum)
_logger.Error(ex)
Return False

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ Imports DigitalData.Modules.Interfaces
Public Class WorkerArgs
' Directory Parameters
Public WatchDirectories As New List(Of String)
Public WatchDirectory As String = Nothing
Public SuccessDirectory As String = Nothing
Public ErrorDirectory As String = Nothing
Public OriginalEmailDirectory As String = Nothing

View File

@@ -527,13 +527,13 @@ Public Class LogConfig
#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("date", "${shortdate}"))
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=Message,StackTrace:innerFormat=Message:maxInnerExceptionLevel=3}"))
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),

9
Logging/LogEntry.vb Normal file
View File

@@ -0,0 +1,9 @@
Public Class LogEntry
Public Property Level As String
Public Property Message As String
Public Property Product As String
Public Property Time As Date
Public Property Suffix As String
Public Property [Module] As String
Public Property Exception As String
End Class

View File

@@ -74,6 +74,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="LogConfig.vb" />
<Compile Include="LogEntry.vb" />
<Compile Include="Logger.vb" />
<Compile Include="LogOptions.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />