Log4Net 在单独的配置文件中

2024-04-17

我需要为新项目配置 log4net。当我将所有信息保存在 App.config 文件中时,一切都工作得很好。我想把log4net的配置放在一个单独的配置文件中(取App1.config)

这是我的 app.config 完美运行:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/>
      </layout>
    </appender>
    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="C:\Logs\MylogText.txt"/>
      <appendToFile value="true"/>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/>
      </layout>
    </appender>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="C:\Logs\RollinglogText.txt"/>
      <appendToFile value="true"/>
      <rollingStyle value="Size"/>
      <maximumFileSize value="10MB"/>
      <maxSizeRollBackups value="5"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/>
      </layout>
    </appender>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="ConsoleAppender"/>
      <appender-ref ref="FileAppender"/>
      <appender-ref ref="RollingFileAppender"/>
    </root>
  </log4net>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

我删除了除<startup>我的 app.config 中的元素并将其放入我的 app1.config 中:

  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/>
      </layout>
    </appender>
    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="C:\Logs\MylogText.txt"/>
      <appendToFile value="true"/>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/>
      </layout>
    </appender>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="C:\Logs\RollinglogText.txt"/>
      <appendToFile value="true"/>
      <rollingStyle value="Size"/>
      <maximumFileSize value="10MB"/>
      <maxSizeRollBackups value="5"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/>
      </layout>
    </appender>

    <root>
      <level value="DEBUG" />
      <appender-ref ref="ConsoleAppender"/>
      <appender-ref ref="FileAppender"/>
      <appender-ref ref="RollingFileAppender"/>
    </root>
  </log4net>

在我的 Program.cs 类中,我使用如下程序集调用配置:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "App1.config", Watch = true)]

但是当我使用App1.config时,我的文件中没有日志。


使用以下内容作为模板:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <configSections>    
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>

  <log4net configSource="log4net.config"/>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>

</configuration>

并将您的 log4net 配置放入 log4net 配置中,例如

<log4net>
    <!-- Configuration -->
</log4net>

如果您想监视文件中的更改,可以使用以下类来执行此操作(调用 LoggingConfiguration.ConfigureLogging()):

public static class LoggingConfigurator
{
    private const string DebugLoggingConfiguration = @"log4net.debug.config";

    /// <summary>
    /// Configures the logging.
    /// </summary>
    /// <exception cref="System.Configuration.ConfigurationErrorsException">Thrown if the logging configuration does not exist.</exception>
    [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Console.WriteLine(System.String)")]
    [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Console.WriteLine(System.String,System.Object)")]
    public static void ConfigureLogging()
    {
        try
        {
            string path = GetLogConfigurationPath();

            var fileInfo = new FileInfo(path);

            if (fileInfo.Exists)
            {
                log4net.Config.XmlConfigurator.ConfigureAndWatch(fileInfo);
                Console.WriteLine("Loaded logging configuration from: {0}", path);
            }
            else
            {
                var message = "Logging configuration does not exist: " + path;
                Console.WriteLine(message);
                throw new ConfigurationErrorsException(message);
            }
        }
        catch (ConfigurationErrorsException ex)
        {
            Console.WriteLine("log4net is not configured:\n{0}", ex);
        }
    }

    /// <summary>
    /// Gets the path to the logging configuration file.
    /// </summary>
    /// <returns>The path to the log configuration file.</returns>
    private static string GetLogConfigurationPath()
    {
        var path = GetPathFromAppConfig();
        var directory = Path.GetDirectoryName(path);

        if (directory != null)
        {
            var debugPath = Path.Combine(directory, DebugLoggingConfiguration);
            if (File.Exists(debugPath))
            {
                return debugPath;
            }
        }

        return path;
    }

    /// <summary>
    /// Gets the log4net configuration path file from the app.config.
    /// </summary>
    /// <returns>The path to the log4net configuration file if found, otherwise <c>null</c>.</returns>
    private static string GetPathFromAppConfig()
    {
        string appConfigPath;

        var xml = LoadAppConfig(out appConfigPath);
        var logSectionNode = GetSection(xml, "Log4NetConfigurationSectionHandler");

        if (logSectionNode == null || logSectionNode.Attributes == null)
        {
            return appConfigPath;
        }

        var attribute = logSectionNode.Attributes["configSource"];

        if (attribute == null || string.IsNullOrEmpty(attribute.Value))
        {
            return appConfigPath;
        }

        // Otherwise return the path to the actual log4net config file.
        return ToAbsolutePath(attribute.Value, appConfigPath);
    }

    /// <summary>
    /// Gets the node for a configurations section from an application configuration.
    /// </summary>
    /// <param name="configuration">The <see cref="XmlDocument"/> representing the application configuration.</param>
    /// <param name="type">The section type.</param>
    /// <returns>The node for the section.</returns>
    /// <exception cref="ArgumentNullException"><paramref name="configuration"/> is <c>null</c>.</exception>
    /// <exception cref="ArgumentNullException"><paramref name="type"/> is <c>null</c>.</exception>
    /// <exception cref="ArgumentException"><paramref name="type"/> is an empty string.</exception>
    /// <exception cref="ConfigurationErrorsException">The section could not be found in the application configuration.</exception>
    private static XmlNode GetSection(XmlDocument configuration, string type)
    {
        if (configuration == null)
        {
            throw new ArgumentNullException("configuration");
        }

        if (type == null)
        {
            throw new ArgumentNullException("type");
        }

        if (type.Length == 0)
        {
            throw new ArgumentException("'type' cannot be an empty string.");
        }

        // Get the name of the section from the type
        const string configSectionFormat = @"/configuration/configSections/section[contains(@type,'{0}')]/@name";

        var configSectionPath = string.Format(CultureInfo.InvariantCulture, configSectionFormat, type);
        var configSectionNode = configuration.SelectSingleNode(configSectionPath);

        if (configSectionNode == null)
        {
            throw new ConfigurationErrorsException("App.config does not have a section with a type attribute containing: " + type);
        }

        // Get the section from the name discovered above
        var sectionName = configSectionNode.Value;
        var sectionNode = configuration.SelectSingleNode(@"/configuration/" + sectionName);

        if (sectionNode == null)
        {
            throw new ConfigurationErrorsException("Section not found in app.config: " + sectionName);
        }

        return sectionNode;
    }

    /// <summary>
    /// Loads the application configuration.
    /// </summary>
    /// <param name="appConfigPath">The path to the application configuration.</param>
    /// <returns>The loaded application configuration as an <see cref="XmlDocument"/>.</returns>
    /// <exception cref="ConfigurationErrorsException">The application configuration could not be loaded.</exception>
    private static XmlDocument LoadAppConfig(out string appConfigPath)
    {
        try
        {
            var xml = new XmlDocument();
            appConfigPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            xml.Load(appConfigPath);
            return xml;
        }
        catch (Exception ex)
        {
            throw new ConfigurationErrorsException("Could not load app.config.", ex);
        }
    }

    /// <summary>
    /// Converts a path to an absolute path.
    /// </summary>
    /// <param name="path">The path (can be absolute or relative).</param>
    /// <param name="basePath">The base path (used for resolving absolute path).</param>
    /// <returns>The absolute path</returns>
    /// <exception cref="ArgumentException"><paramref name="basePath"/> does not contain a directory.</exception>
    private static string ToAbsolutePath(string path, string basePath)
    {
        if (Path.IsPathRooted(path))
        {
            return path;
        }

        var directory = Path.GetDirectoryName(basePath);

        if (directory == null)
        {
            throw new ArgumentException("'basePath' does not contain a directory.", "basePath");
        }

        return Path.GetFullPath(Path.Combine(directory, path));
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Log4Net 在单独的配置文件中 的相关文章

  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • XSD 嵌套元素

  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 如何从 Azure 云功能引用“可移植”.NET 程序集?

    我已通过 Nuget 和 project json 成功引用了一个 可移植 程序集 我的所有代码都在 Azure 函数中编译 但是当它运行时我得到 无法加载文件或程序集 System Net Version 2 0 5 0 Culture
  • 获取 v2 Google 地图 API 密钥

    看来在我的网站开发和上线 现在 之间 Google 已经逐步淘汰了 Google Maps v2 API 我完全支持进步 但重写我所有的地图代码似乎对我来说有点难以处理 是否仍然可以在网络的某个隐蔽角落获取 Google 地图 v2 API
  • Delphi组件spTbxToolbar换肤

    如何在运行时通过代码 不适用于 groupskintype 更改 sptbxtoolbar 组件的皮肤类型 您只能一次更改所有 SpTBXLib 组件的外观 使用此代码 SkinManager SetSkin Office 2007 Blu
  • 使用drawImage()在画布上输出固定大小的图像?

    我该如何使用drawImage 在a上输出全尺寸图像300px X 380px画布无论源图像大小如何 例子 1 如果有一个图像75px X 95px我希望能够将其绘制以适合300px X 380px帆布 2 如果有一个图像1500px X
  • 使用 CSS 扩展边框

    我一直在测试使用一些嵌套 div 扩展 投影边框的想法 下面有一个工作示例 基本上 我想要实现的是垂直和水平边框延伸到盒子外面 里面有内容 有点像起草的样子 如果可能的话 我希望它能够完全响应 在我的代码中 我设置了带有负边距的高度 以便获
  • 为桌面构建 flutter 应用程序

    我看到一些人成功地为除通常的 Android IOS 之外的其他操作系统构建了 flutter 应用程序 我的问题很简单 如何 目前为 mac windows 构建 flutter 应用程序的流程是什么 没有必要这样生产准备就绪 一些实验性
  • Pandas groupby 根据另一列中的值(0 或 1)选择最后一行或倒数第二行

    我有一个与客户的数据框 每个客户都有一些观察结果和变量 其中一些不再是客户 我的问题如下 我想按客户分组 如果客户仍然是客户 则选择最后一行 如果客户不再是客户 则选择倒数第二行 对于客户的所有观察 我有一个名为 churned 的列 如果
  • 获取 Android 操作系统中已注册的 Pending Intent 列表

    我注册了计划在给定时间执行的警报 并且根据计划列表的大小 可以有很多警报 但我有两个问题仍然不清楚 1 如何在操作系统中查询我注册的待处理意图 我需要这个来测试 我想要的伪代码是这样的 List
  • 如何向 ionic 4 应用程序添加和使用 bootstrap?

    我正在构建一个 ionic 4 应用程序 我想使用 bootstrap 而不使用 CDN 方法 我已经使用 npm install bootstrap 安装了 bootstrap 在 Ionic 4 中 可以通过使用 angular jso
  • 如何更改 PostgreSQL 中的最大列宽?

    我有一个简单的 SQL 查询 它从一个表中选择几行 其中一列包含很长的字符串 我想设置最大列宽 以便更容易阅读 我无法通过 pset 访问环境变量 None
  • 测试 SQL 查询的最佳方法[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我遇到了一个问题 复杂的 SQL 查询总是出错 从本质上讲 这会导致向错误的客户发送邮件以及其他类似的 问题 大家对于创建这样的 SQL 查询有
  • 如何在 Jetpack Compose Pager 中处理多个 TextField 焦点?

    我有一个寻呼机 每个页面上都有一个 TextField 我正在做过渡animateScrollToPage 如何让每个页面上的 TextField 获得焦点 当我给予Modifier focusRequster 到文本字段并检查index
  • 可选链的动态类型与赋值不同

    可选的链接返回always一个可选值 为了反映可以对 nil 值调用可选链接的事实 可选链接调用的结果始终是可选值 即使您正在查询的属性 方法或下标返回非可选值 Swift 编程语言 https developer apple com li
  • QComboBox 是否可以显示与其列表中不同的值?

    在 Linux 上使用 Qt 5 9 我有一个带有多个标签的 QComboBox qc new QComboBox qc gt addItem tr Red qc gt addItem tr Green qc gt addItem tr B
  • 用新的 Dataframe 替换一行

    我正在寻找一种更优雅的方法来从字典的值替换另一个数据帧中的数据帧 这是我必须使用的数据类型的示例 d 1 name bob age 22 Data 4 name sam age 30 Data 2 name tom age 20 Data
  • getDownloadUrl 是付费操作吗?

    我想知道是否getDownloadUrl在 Firebase 存储 Google Cloud Storage 上 一种获取存储上文件的公共 URL 的方法 是付费操作 即使读完之后文档 https cloud google com stor
  • DrawingPanel中刷新图片扩展了JPanel

    我必须在软件底部加载一个小图标 只是有一个加载 确定 错误图标 正如 http www article kth se lindsey JavaCourse Book Part1 Java Chapter06 images html 上的建议
  • 如何在服务器模式下运行H2数据库?

    我需要从我的应用程序以服务器模式启动 H2 数据库 尝试过以下代码 server Server createTcpServer start 这是连接的属性 javabase jdbc url jdbc h2 tcp localhost 90
  • Jekyll - 如何在根目录中创建页面?

    我正在使用 Jekyll 创建页面 文档建议 Jekyll 可以选择在根目录中创建页面 或为新页面创建新目录 From http jekyllrb com docs pages http jekyllrb com docs pages 页面
  • Log4Net 在单独的配置文件中

    我需要为新项目配置 log4net 当我将所有信息保存在 App config 文件中时 一切都工作得很好 我想把log4net的配置放在一个单独的配置文件中 取App1 config 这是我的 app config 完美运行