I'm trying to make Serilog log framework available to a VB6 application to write to Logentries.com via TCP Token input. I've used JaminSehic Com Logger as a base to create a wrapper to Serilog . When i try to call the SetupWithLogEntries method i get an error stating Serilog or one of it's dependencies cannot be found or loaded. I have found articles such as AnyCPU that describe to make sure that the wrapper is compiled in .net as x86. But i still run into this problem.
Now the dll is visible by the vb6 application. It can instantiate the object. It's when the call is made to SetupWithLogEntries that this dependency error occurs.
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Serilog;
using Serilog.Core;
using Serilog.Enrichers;
using Serilog.Events;
namespace Com.Logger
{
/// <summary>
/// A wrapper around Serilog logging API, used for writing log events.
/// </summary>
/// <remarks>
/// Contains wrapper methods for templated methods with implict log event level only
/// ParamArray (params) cannot be passed from VB6 as it is ByRef and in .NET ParamArray (params) as ByVal so had to pass optional object parameters which works well enough
/// Maximum of 10 parameters are allowed and only the primitive data types from VB6 are supported.
/// VB6 classes will show up as System.__ComObject
/// </remarks>
[Guid("293E7B05-9557-44D5-BF9B-B5F60B25574B")]
[ComVisible(true)]
[ProgId("Com Logger")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class LoggerWrapper
{
private ILogger _logger;
public LoggerWrapper()
{
_logger = Log.Logger;
}
[DispId(0)]
public void Setup(string serviceName, string serviceVersion, string machineName, string correlationId,
short restrictedToMinimumLevel = (short)LogEventLevel.Verbose,
//string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}",
string outputTemplate = "{Timestamp:O} {MachineName} {Service} {Version} {CorrelationId} [{Level}] ({Exception}) {Message}{NewLine}{Exception}",
int fileSizeLimitBytes = 1073741824, int retainedFileCountLimit = 31)
{
var ServiceDetailsEnricher = new ServiceDetailsEnricher
{
ServiceName = serviceName,
ServiceVersion = serviceVersion,
MachineName = machineName,
CorrelationId = correlationId
};
_logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.With(ServiceDetailsEnricher)
.WriteTo.ColoredConsole( outputTemplate: outputTemplate)
.WriteTo.RollingFile(pathFormat: GetLogFileName(serviceName),
restrictedToMinimumLevel: (LogEventLevel)restrictedToMinimumLevel,
outputTemplate: outputTemplate, fileSizeLimitBytes: fileSizeLimitBytes,
retainedFileCountLimit: retainedFileCountLimit)
.CreateLogger();
}
[DispId(1)]
public void SetupWithLogEntries(string serviceName, string serviceVersion, string machineName, string correlationId, string tokenId,
short restrictedToMinimumLevel = (short)LogEventLevel.Verbose,
string outputTemplate = "{Timestamp:O} {MachineName} {Service} {Version} {CorrelationId} [{Level}] ({Exception}) {Message}{NewLine}{Exception}",
int fileSizeLimitBytes = 1073741824, int retainedFileCountLimit = 31)
{
var ServiceDetailsEnricher = new ServiceDetailsEnricher
{
ServiceName = serviceName,
ServiceVersion = serviceVersion,
MachineName = machineName,
CorrelationId = correlationId
};
_logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.With(ServiceDetailsEnricher)
.Enrich.FromLogContext()
.WriteTo.RollingFile(pathFormat: GetLogFileName(serviceName),
restrictedToMinimumLevel: (LogEventLevel)restrictedToMinimumLevel,
outputTemplate: outputTemplate, fileSizeLimitBytes: fileSizeLimitBytes,
retainedFileCountLimit: retainedFileCountLimit)
.WriteTo.Console(Serilog.Events.LogEventLevel.Debug)
.WriteTo.Logentries(
token: tokenId,
outputTemplate: outputTemplate)
.CreateLogger();
}
[DispId(2)]
public void Verbose(string messageTemplate, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null, object arg4 = null, object arg5 = null, object arg6 = null, object arg7 = null, object arg8 = null, object arg9 = null)
{
_logger.Verbose(messageTemplate, RemoveMissingParams(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
}
[DispId(3)]
public void Debug(string messageTemplate, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null, object arg4 = null, object arg5 = null, object arg6 = null, object arg7 = null, object arg8 = null, object arg9 = null)
{
_logger.Debug(messageTemplate, RemoveMissingParams(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
}
[DispId(4)]
public void Information(string messageTemplate, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null, object arg4 = null, object arg5 = null, object arg6 = null, object arg7 = null, object arg8 = null, object arg9 = null)
{
_logger.Information(messageTemplate, RemoveMissingParams(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
}
[DispId(5)]
public void Warning(string messageTemplate, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null, object arg4 = null, object arg5 = null, object arg6 = null, object arg7 = null, object arg8 = null, object arg9 = null)
{
_logger.Warning(messageTemplate, RemoveMissingParams(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
}
[DispId(6)]
public void Error(string messageTemplate, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null, object arg4 = null, object arg5 = null, object arg6 = null, object arg7 = null, object arg8 = null, object arg9 = null)
{
_logger.Error(messageTemplate, RemoveMissingParams(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
}
[DispId(7)]
public void Fatal(string messageTemplate, object arg0 = null, object arg1 = null, object arg2 = null, object arg3 = null, object arg4 = null, object arg5 = null, object arg6 = null, object arg7 = null, object arg8 = null, object arg9 = null)
{
_logger.Fatal(messageTemplate, RemoveMissingParams(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
}
// legacy method helper
[DispId(8)]
public void WriteDebug(string message)
{
_logger.Debug(message);
}
private static object[] RemoveMissingParams(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9)
{
return new[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }.Where(a => a != null).ToArray();
}
private static string GetLogFileName(string serviceName)
{
var logFileName = Path.Combine(GetLogFilePath(), serviceName);
return string.Format("{0}_{1}{2}", logFileName, "{Date}", ".txt");
}
private static string GetBufferFileName(string serviceName)
{
return Path.Combine(GetLogFilePath(), serviceName);
}
private static string GetLogFilePath()
{
const string logSubFolder = "Logs";
var pathRoot = System.AppDomain.CurrentDomain.BaseDirectory; //Directory.GetCurrentDirectory();
return Path.Combine(pathRoot, logSubFolder);
}
}
internal class ServiceDetailsEnricher : ILogEventEnricher
{
public string ServiceName { get; set; }
public string ServiceVersion { get; set; }
public string MachineName { get; set; }
public string CorrelationId { get; set; }
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Service", ServiceName));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Version", ServiceVersion));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("MachineName", MachineName));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("CorrelationId", CorrelationId));
}
}
}
When building make sure to sign the assembly and compile it to x86 target cpu. regasm the dll and create a tlb.
then in vb application: reference the tlb
Place the code below in a vb6 application. The Log.SetupWithLogEntries will throw an error of a Serilog dependency that is missing. If I call Log.Setup then no error is thrown and the log file is created. (so seems to be an issue with the LogEntires Sink.)
Dim Log As Com_Logger.LoggerWrapper
Set Log = New Com_Logger.LoggerWrapper
'Log.Setup "VB6LoggerWrapperClient", "1.0.1.23", "test", "abc", LogEventLevel.Debug
Log.SetupWithLogEntries "VB6LoggerWrapperClient", "1.0.1.23", "test", "abc", "tokenABC", LogEventLevel.Debug
Dim x As Integer
Dim y As Currency
Dim z As Date
Dim a As String
Dim b As Boolean
Dim c As Long
Dim d As Double
Dim s As Single
Dim f As Byte
x = 23
y = 99.5654
z = Now()
a = "I am a STRING!"
b = True
c = 345345435
d = 343.343432
s = 1.2
f = 255
Call Log.Debug("This is debug {Integer} {Currency} {Date} {Stringy} {Boolean} {Long} {Double} {Single} {Byte}", x, y, z, a, b, c, d, s, f)
Call Log.Information("This is Info {Integer} {Currency} {Date} {Stringy} {Boolean} {Long} {Double} {Single} {Byte}", x, y, z, a, b, c, d, s, f)