我正在嘗試使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)