我正在尝试使Serilog日志框架可用于VB6应用程序通过TCP Token输入写入Logentries.com。我用JaminSehic Com Logger作为基础来创建Serilog的包装。当我尝试调用SetupWithLogEntries方法时,我得到一个错误,指出Serilog或它的某个依赖项无法找到或加载。我找到了描述如AnyCPU的文章,以确保包装以.net编译为x86。但我仍然遇到这个问题。Serilog Logentries:通过Com Interop发送TCP Token输入给Logentries - Serilog依赖错误
现在,vb6应用程序可以看到dll。它可以实例化对象。当对SetupWithLogEntries进行调用时发生此依赖性错误。
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));
}
}
}
建立时请确保签署程序集并将其编译到x86目标cpu。 regasm dll并创建一个tlb。
然后在vb应用: 参考所述TLB
放置在一个VB6应用程序下面的代码。 Log.SetupWithLogEntries会抛出一个Serilog依赖项错误。如果我调用Log.Setup,则不会引发错误并创建日志文件。 (这似乎是LogEntires接收器的问题。)
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)