Serilog Logentries:通过 Com Interop 将 TCP 令牌输入发送到 Logentries - Serilog 依赖错误

Serilog Logentries : Send TCP Token Input to Logentries via Com Interop - Serilog Dependency Error

我正在尝试使 Serilog 日志框架可用于 VB6 应用程序以通过 TCP 令牌输入写入 Logentries.com。我使用 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 来描述以确保包装器在 .net 中编译为 x86。但我仍然 运行 陷入这个问题。

现在 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。 重新加载 dll 并创建一个 tlb。

然后在 vb 应用程序中: 引用 tlb

将下面的代码放在 vb6 应用程序中。 Log.SetupWithLogEntries 将抛出缺少 Serilog 依赖项的错误。如果我调用 Log.Setup 则不会抛出任何错误并创建日志文件。 (这似乎是 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)

好的,所以我发现了问题所在。从使用 JaminSec 的原始项目开始,它需要升级,因为它使用的是旧组件。所以我将 Serilog 升级到当前的 v1.5x,并包含当前版本的 Serilog.Sinks.Logentries v1.5.8。由于依赖性问题,COM-Interop 会一直失败。然而 Logentries 表示它是兼容的.. 它在 .NET 中工作正常但不是作为 COM!!!

答案是将 Serilog 降级到 v1。4.x!!!并且它作为 COM-INTEROP 正常工作!