【问题标题】:Logging without a logging library没有日志库的日志记录
【发布时间】:2011-04-06 00:17:53
【问题描述】:

这里是“问题”。我开发的每个库都会记录一些内容,但是我不想要求库用户知道这一点并安装 log4net 或我将使用的类似日志记录实现。聪明人是如何创建独立程序集的?

日志输出对于库用户来说并不重要,除非他或她真的想查看调试/信息输出。在这种情况下,他将安装 log4net 并通过配置文件告诉库以某种方式使用它。否则,我想在没有任何不相关依赖项的情况下运送我的库。这可能吗?有哪些选择?

在 C++ 中,我会简单地创建几个 dll/so(带和不带日志记录)将它们与所需的库集静态链接,如果有人需要启用日志记录的库,他只需用另一个版本覆盖它。

【问题讨论】:

  • 那么您在内部使用 log4net 吗?为什么不允许用户指定他/她想要使用的日志记录方法?
  • 是的,它确实隐含地引用了它。一般来说,我使用自己的抽象日志接口。所以也许我可以动态加载一个合适的日志库,比如 log4net。同样,我需要在我开发的所有库之间共享 ILog 接口,所以我必须至少发布 MyLibrary.dll + MyCompany.Logging.dll :(

标签: .net architecture logging


【解决方案1】:

好主意;这些细节让图书馆的作者和消费者的生活更轻松!

DotNetOpenAuth 这样做

我知道 DotNetOpenAuth 库的行为方式与您描述的方式相同。它使用 log4net,但前提是它存在并由消费程序集配置。来自其 README.Bin.html:

log4net.dll 如果存在且 v1.2.10, 将允许记录日志消息 这个库发出。

在您自己的应用中还有an informative page on how to configure DotNetOpenAuth logging

[编辑] 我检查了他们的源代码,他们动态检查 log4net 程序集并加载+连接它(如果存在)(在 Log4NetLogger.cs 和 Logger.cs 中)。正如您在下面的评论中提到的,他们在编译期间需要 log4net,因为它在多个地方被引用。聪明之处在于因为检查失败时会跳过所有 log4net 特定的代码,所以当 log4net 程序集丢失时不会出现 runtime 问题

DotNetOpenAuth 是一个开源项目,因此您应该能够通过浏览他们的初始化代码来模仿他们的方法。

【讨论】:

  • 我刚刚查看了github,项目文件确实引用了log4net:... False ... 库从 log4net.dll 导入类型。我没有检查如果没有 log4net.dll 存在并且没有在运行时创建 log4net 记录器是否有效。是吗?
【解决方案2】:

这是一个很好的跟踪介绍,这是我更喜欢使用的,你的程序集的消费者也可以使用它。

http://www.devx.com/codemag/Article/22040

【讨论】:

  • 同意,不使用Trace 确实没有什么价值,但像往常一样无知统治着这一天。 CodePlex 上甚至还有一个包,您可以将其用于更多跟踪提供程序。
  • 好主意,谢谢。我认为大多数人都忽略了这一点,因为它更容易登录到控制台(无需配置跟踪),或者因为与 log4net 相比,内置跟踪功能没有那么强大。
【解决方案3】:

我能看到的唯一选择是用你的应用程序完全封装一些东西;两种选择:

  • 采用开源日志记录框架并将其源代码烘焙到您的应用程序中(因此,当有人安装您的应用程序时,他们也会无意中安装记录器)。这里的假设是您的安装过程将涵盖所有需要的东西,或者,您以一种没有任何(重要)暴露于它们的方式烘烤它。
  • 采用一个日志框架并将其添加到您的项目中,但只是作为一个干净的依赖项 - 而不是在代码级别“嵌入”这么多。例如,您可以使用 MS EntLib 执行此操作,并且通过提供默认配置(并在安装过程中包括 EntLib DLL),您可以成功地保护用户不必做任何事情。

但底线(据我所知)是日志记录(配置)通常是人们在某些时候需要处理的事情,因为它通常是特定于环境的,所以我怀疑你是否可以保护所有用户不必一直都知道。

【讨论】:

    【解决方案4】:

    我刚刚遇到了同样的问题。我的库只有 78KB,但需要 238KB 的 log4net 依赖项。所以我写了一个抽象类来动态加载log4net,只有当它像这样存在时:

    static Logger() {
            try {
                Assembly.Load("log4net");
                _loggingIsOff = false;
            } catch {}
        }
    
        public static ILog CreateLog() {
            var frame = new System.Diagnostics.StackFrame(1, false);
            var type = frame.GetMethod().DeclaringType;
            return _loggingIsOff ? (ILog)new NoLog() : new Log4NetLogger(type);
        }
        ...
    }
    

    完整代码的链接是here

    【讨论】:

      【解决方案5】:

      您可以考虑包含一个具有足够广泛的再分发许可证的日志库,该许可证允许您将其与源代码一起分发。大多数基于 BSD 的许可证都允许您这样做。

      我有偏见,但 http://www.logog.org 可能会根据一些相当广泛的许可条款重新分发,并且可能符合您的要求。

      【讨论】:

        猜你喜欢
        • 2021-05-11
        • 2018-08-12
        • 2015-12-21
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多