不使用日志库进行日志记录

5
这里的“问题”是,我开发的每个库都会记录一些东西,但我不希望要求库用户知道这一点,并安装我使用的log4net或类似的日志记录实现。聪明的人们是如何创建独立的程序集的?
除非库用户真的想看调试/信息输出,否则记录输出对他或她来说并不重要。在这种情况下,他将安装log4net并通过配置文件告诉库如何使用它。否则,我希望发布我的库而没有任何无关的依赖项。这可能吗?有哪些选择?
在C++中,我只需创建几个dll/so(带有和不带有日志记录),静态链接它们与所需的库集,如果有人需要启用日志记录的库,他只需用另一个版本覆盖它。

你们内部使用log4net吗?为什么不允许用户指定他/她想要使用的日志记录方法呢? - Kyro
是的,它隐式地引用了它。通常我使用自己抽象化的日志记录接口。因此,也许我可以动态加载一个适当的日志记录库,比如log4net。再次强调,我需要ILog接口在我开发的所有库之间共享,因此我必须至少发布MyLibrary.dll + MyCompany.Logging.dll :( - Ivan G.
5个回答

4
优秀的想法;这些细节使得库的编写者和使用者更加方便!DotNetOpenAuth可以实现这一点。我知道DotNetOpenAuth库的行为符合您所描述的方式。它使用log4net,但仅在消费程序集存在并配置时才使用。从其README.Bin.html中可以看出:
"如果存在且版本为1.2.10的log4net.dll,将允许记录此库发出的日志消息。"
此外,他们的网页提供了有关如何在自己的应用程序中配置DotNetOpenAuth日志记录的详细信息。
[编辑]:我已经检查了他们的源代码,并动态检查了log4net程序集是否存在,如果存在,则会加载+连接它(在Log4NetLogger.cs和Logger.cs中)。正如您在下面的评论中提到的那样,他们在编译过程中需要log4net,因为它在多个地方被引用。聪明的部分是,当检查失败时,所有特定于log4net的代码都将被跳过,因此在缺少log4net程序集时不会有任何运行时问题。
DotNetOpenAuth是一个开源项目,因此您应该能够通过浏览其初始化代码来模仿他们的方法。

我刚刚查看了github,该项目文件确实引用了log4net:… <ItemGroup> <Reference Include =“log4net,Version=1.2.10.0,Culture=neutral,PublicKeyToken=1b44e1d426115821,processorArchitecture=MSIL”> <SpecificVersion> False </ SpecificVersion> </Reference> …并且该库从log4net.dll中导入类型。 我没有检查过在运行时没有log4net.dll存在和log4net日志记录器未创建的情况下是否可以正常工作。 是吗? - Ivan G.

3

同意,不使用“Trace”真的没有什么价值,但通常无知占据了主导地位。甚至在CodePlex上有一个包,您可以使用更多的跟踪提供程序。 - Mark Sowul
好主意,谢谢。我认为大多数人忽略了这一点,因为记录到控制台更容易(无需配置跟踪),或者因为内置跟踪与log4net相比不够强大。 - Ivan G.

1

我刚遇到了同样的问题。我的库只有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);
    }
    ...
}

点此链接以获取完整代码。


1

我唯一能看到的选择是完全封装应用程序中的某些内容,有两个选项:

  • 使用开源日志框架并将其源代码嵌入您的应用程序中(这样当某人安装您的应用程序时,他们也会无意中安装记录器)。假设您的安装过程将涵盖所需的任何内容,或者您以这种方式将其嵌入其中,以便没有(重要的)内容暴露给他们。
  • 将日志框架添加到您的项目中,但仅作为干净的依赖项 - 不要在代码级别上“嵌入”。例如,您可以使用MS EntLibs来完成此操作,并通过提供默认配置(并在安装过程中包括EntLib DLL)成功地使用户免于执行任何操作。

然而,总的来说(就我所知),日志记录(配置)通常是人们需要在某个时候处理的内容,因为它经常与环境有关,所以我怀疑您不能始终让所有用户都不必了解它。


0
你可能考虑使用一个具有足够广泛的再分发许可证的日志库,以便您可以将其与源代码一起分发。大多数基于BSD的许可证都允许您这样做。
我有点偏见,但http://www.logog.org可以在一些相当广泛的许可条款下重新分发,并且可能符合您的要求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接