如何在Asp.net core 2.0中使用log4net

65

我按照这篇文章链接中提到的方式,在我的asp.net core 2.0应用程序中配置了log4net

program.cs

public static void Main(string[] args)
{
    var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
    XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));

    BuildWebHost(args).Run();
}

首页控制器

public class HomeController : Controller
{
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(HomeController));

    public IActionResult Error()
    {
        log.Info("Hello logging world!");
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

log4net.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <log4net>
    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFile" />
    </root>
    <appender name="RollingFile" type="log4net.Appender.FileAppender">
      <file value="‪C:\Temp\app.log" /> 
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%-5p %d{hh:mm:ss} %message%newline" />
      </layout>
    </appender>
  </log4net>
</configuration>

不幸的是,我没有看到任何文件在‪C:\Temp\app.log目录下生成。可能犯了什么错误?如何为asp.net core 2.0配置log4net


1
在这方面有任何进展吗?我想要达到类似的目标。 - shiva
你遇到了同样的问题吗? - k11k2
我还没有开始。我只是四处看看,看看是否可能。我不确定log4net是否支持Core2。 - shiva
1
是的,它支持! - k11k2
3
注意,根据文档 https://logging.apache.org/log4net/release/framework-support.html,在ASP.NET Core 2.0中,log4net没有可用的ADO.NET Appender,因此如果要将日志记录到数据库,请尝试其他方法。虽然这与原来的问题有点无关,但可能对其他人有帮助。 - gdyrrahitis
4
接受的答案是错误的。 正确的答案是使用 https://www.nuget.org/packages/Microsoft.Extensions.Logging.Log4Net.AspNetCore/ 的任何一个。 - Ian Kemp
9个回答

82

4
好的,但是您如何使用这个记录器?我在提供的链接中也没有找到使用示例。有示例吗? - Przemek
2
@Przemek。一旦您完成此操作,然后在需要的任何地方注入ILoggerILogger<T>,所有调用都将转发到log4net实现。https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1 - Jan Muncinsky
Log4Net中是否提供了对.NetCore3.0的EventLogAppender支持? - Ranvijay Singh
你如何基于开发或生产环境拥有多个log4net配置文件并在它们之间进行切换? - red888
从log4net.config中删除<configuration>部分。如果您正在使用现有的log4net.config文件。 - ahsant

38

使用以下代码,我能够成功地记录文件

public static void Main(string[] args)
{
    XmlDocument log4netConfig = new XmlDocument();
    log4netConfig.Load(File.OpenRead("log4net.config"));
    var repo = log4net.LogManager.CreateRepository(Assembly.GetEntryAssembly(),
               typeof(log4net.Repository.Hierarchy.Hierarchy));
    log4net.Config.XmlConfigurator.Configure(repo, log4netConfig["log4net"]);

    BuildWebHost(args).Run();
}

在网站根目录下的log4net.config文件

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    <file value="C:\Temp\" />
    <datePattern value="yyyy-MM-dd.'txt'"/>
    <staticLogFileName value="false"/>
    <appendToFile value="true"/>
    <rollingStyle value="Date"/>
    <maxSizeRollBackups value="100"/>
    <maximumFileSize value="15MB"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level App  %newline %message %newline %newline"/>
    </layout>
  </appender>
    <root>
      <level value="ALL"/>
      <appender-ref ref="RollingLogFileAppender"/>
    </root>
</log4net>

根记录器设置正确,但任何子记录器的级别为空,并且没有设置附加器。 - The Muffin Man
我不知道子记录器,你能分享一下代码和示例,这样我就可以在我的回答中包含它。 - Irfan Ashraf
6
仍然不能工作(指的是ASP.NET Core 2.1框架)。日志文件没有被创建。log4.net.config文件已经被读取,但是附加器似乎没有被创建(日志中Appenders列表为空)。XmlConfigurator已被调用。log4net.config文件与原始帖子中的完全相同。有任何想法吗? - Radek Strugalski

11

还在寻找解决方案吗?我是从这个链接中获得的。

我所做的就是在“程序类”的“public static void Main”方法顶部添加这两行代码。

 var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
 XmlConfigurator.Configure(logRepo, new FileInfo("log4net.config"));

是的,你需要添加:

  1. Microsoft.Extensions.Logging.Log4Net.AspNetCore 通过NuGet安装。
  2. 一个名为log4net.config的文本文件,并将文件的属性(Copy to Output Directory)更改为"Copy if Newer"或"Copy always"。

你还可以配置你的asp.net core应用程序,使所有在输出控制台中记录的内容都记录在你选择的appender中。 你也可以从github下载这个示例代码,并查看我如何配置它。


在.NET Core 3.0上,这仍然是最好的(并且必需的)解决方案吗? - David Thielen
对我来说非常好用,不需要像下一个答案中所示那样去处理ServiceCollections。 - ckapilla

8

您需要安装Microsoft.Extensions.Logging.Log4Net.AspNetCore NuGet包,并向应用程序添加log4net.config文件。然后,就可以运行此操作:

public class Program
{
    private readonly ILogger<Program> logger;

    public Program()
    {
        var services = new ServiceCollection()
            .AddLogging(logBuilder => logBuilder.SetMinimumLevel(LogLevel.Debug))
            .BuildServiceProvider();


        logger = services.GetService<ILoggerFactory>()
            .AddLog4Net()
            .CreateLogger<Program>();
    }

    static void Main(string[] args)
    {
        Program program = new Program();

        program.Run();

        Console.WriteLine("\n\nPress any key to continue...");
        Console.ReadKey();
    }

    private void Run()
    {
        logger.LogInformation("Logging is working");
    }
}

3

继承Irfan的答案,我在OSX上使用.NET Core 2.1.300有以下XML配置,可以正确记录并附加到./log文件夹和控制台。注意log4net.config必须存在于解决方案根目录(而在我的情况下,我的应用程序根目录是一个子文件夹)。

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
      <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %-5level %logger - %message%newline" />
      </layout>
  </appender>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    <file value="logs/" />
    <datePattern value="yyyy-MM-dd.'txt'"/>
    <staticLogFileName value="false"/>
    <appendToFile value="true"/>
    <rollingStyle value="Date"/>
    <maxSizeRollBackups value="100"/>
    <maximumFileSize value="15MB"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level App  %newline %message %newline %newline"/>
    </layout>
  </appender>
    <root>
      <level value="ALL"/>
      <appender-ref ref="RollingLogFileAppender"/>
      <appender-ref ref="ConsoleAppender"/>
    </root>
</log4net>

另外需要注意的是,传统的在app.config中设置XML的方式不起作用:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net> ...

由于某些原因,在通过log4netConfig["log4net"]访问XMLDocument时未找到log4net节点。

注意,调试器会在子文件夹中查找文件,而不是根目录。 - Shanerk

1
我已经找到问题所在,loggerFactory.AddLog4Net()中的命名空间不明确。以下是我如何将log4Net添加到我的Asp.Net Core项目的简要概述。
  1. 添加nugget包Microsoft.Extensions.Logging.Log4Net.AspNetCore
  2. 在根应用程序文件夹中添加log4net.config文件
  3. 打开Startup.cs文件并更改Configure方法,使用此行loggerFactory.AddLog4Net添加log4net支持。
首先,您必须使用using语句导入Microsoft.Extensions.Logging;包。这是整个方法,您必须使用命名空间前缀ILoggerFactory接口。
 public void Configure(IApplicationBuilder app, IHostingEnvironment env, NorthwindContext context, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
        {
            loggerFactory.AddLog4Net();
            ....
        }

1
您可以在 https://www.techjunkieblog.com/2019/08/hour-17-aspnet-core-add-log4net-support.html 查看完整的实现。 - techjunkie

1
我能够用以下方法进行回应:

1-Install-Package log4net

2-Install-Package MicroKnights.Log4NetAdoNetAppender

3-Install-Package System.Data.SqlClient

首先,我使用以下代码创建数据库和表:

CREATE DATABSE Log4netDb
CREATE TABLE [dbo].[Log] (
    [Id] [int] IDENTITY (1, 1) NOT NULL,
    [Date] [datetime] NOT NULL,
    [Thread] [varchar] (255) NOT NULL,
    [Level] [varchar] (50) NOT NULL,
    [Logger] [varchar] (255) NOT NULL,
    [Message] [varchar] (4000) NOT NULL,
    [Exception] [varchar] (2000) NULL
)

其次,我在程序中创建了log4net.config文件。 这是一个简单的配置,没有对日志消息进行任何自定义:
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
  <!-- definition of the RollingLogFileAppender goes here -->
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="Logs/WebApp.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
      <!-- Format is [date/time] [log level] [thread] message-->
      <conversionPattern value="[%date] [%level] [%thread] %m%n" />
    </layout>
  </appender>
  <appender name="AdoNetAppender" type="MicroKnights.Logging.AdoNetAppender, MicroKnights.Log4NetAdoNetAppender">
    <bufferSize value="1" />
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data" />
    <connectionStringName value="log4net" />
    <connectionStringFile value="appsettings.json" />
    <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />
    <parameter>
      <parameterName value="@log_date" />
      <dbType value="DateTime" />
      <layout type="log4net.Layout.RawTimeStampLayout" />
    </parameter>
    <parameter>
      <parameterName value="@thread" />
      <dbType value="String" />
      <size value="255" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%thread" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@log_level" />
      <dbType value="String" />
      <size value="50" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%level" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@logger" />
      <dbType value="String" />
      <size value="255" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%logger" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@message" />
      <dbType value="String" />
      <size value="4000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%message" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@exception" />
      <dbType value="String" />
      <size value="2000" />
      <layout type="log4net.Layout.ExceptionLayout" />
    </parameter>
  </appender>
  <root>
    <level value="ALL" />
    <appender-ref ref="RollingLogFileAppender" />
    <appender-ref ref="AdoNetAppender" />
  </root>
</log4net>

第三步,用“IHostBuilder”替换下面的代码:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureLogging(logging =>
    {
        // clear default logging providers
        logging.ClearProviders();
        logging.AddConsole();  
        logging.AddDebug();
        logging.AddEventLog();
        // add more providers here
    })
    .UseStartup<Startup>();

第四步,在appsettings.json中插入以下代码:

{
  "connectionStrings": {
    "log4net": "Server=MICKO-PC;Database=Log4netDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

最后, 使用以下命令享受登录体验

public class ValuesController : Controller
{
    private static readonly ILog log = LogManager.GetLogger(typeof(ValuesController));
    
    [HttpPost]
    public async Task<IActionResult> Login(string userName, string password)
    {
        log.Info("Action start");
        
        // More code here ...
        log.Info("Action end");
    }
    
    // More code here...
} 

祝你好运。


对于 .Net Core 3.1,connectionType 显然已更改为:<connectionType value="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient, Version=1.0.0.0,Culture=neutral,PublicKeyToken=23ec7fc2d6eaa4a5"/>。 - WillC
这对我有用。请参见Darios在以下链接中的答案:https://dev59.com/6Lroa4cB1Zd3GeqPcAf8 - WillC

0

点击这里学习如何在.NET Core 2.2中实现log4net。

以下步骤摘自上述链接,介绍如何将log4net添加到.NET Core 2.2项目中。

首先,在Package-Manager控制台中运行以下命令:

Install-Package Log4Net_Logging -Version 1.0.0

然后添加一个包含以下信息的 log4net.config 文件(请编辑以匹配您的设置):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="logfile.log" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d [%t] %-5p - %m%n" />
      </layout>
    </appender>
    <root>
      <!--LogLevel: OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -->
      <level value="ALL" />
      <appender-ref ref="FileAppender" />
    </root>
  </log4net>
</configuration>

然后,将以下代码添加到控制器中(这是一个示例,请在添加到控制器之前进行编辑):

public ValuesController()
{
    LogFourNet.SetUp(Assembly.GetEntryAssembly(), "log4net.config");
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
    LogFourNet.Info(this, "This is Info logging");
    LogFourNet.Debug(this, "This is Debug logging");
    LogFourNet.Error(this, "This is Error logging");    
    return new string[] { "value1", "value2" };
}

接着调用相关控制器操作(使用上面的示例,使用 HTTP GET 调用 /Values/Get),您将收到与下面匹配的输出:

2019-06-05 19:58:45,103 [9] INFO-[Log4NetLogging_Project.Controllers.ValuesController.Get:23] - 这是 Info 日志记录


0

我正在将一个 .Net Framework 控制台应用程序移植到 .Net Core,并发现在某些情况下日志文件没有被创建的类似问题。

当使用 "CreateRepository" 时,.net framework 和 .net standard 之间似乎存在差异。

在 .Net Framework 下,使用相同的 log4net.config 属性可以创建一个具有自己文件名的唯一日志实例。

GlobalContext.Properties["LogName"] = LogName;
var loggerRepository = LogManager.CreateRepository(LogName);
XmlConfigurator.Configure(loggerRepository);

在 .Net Standard 下,这并不起作用,如果您打开跟踪功能,您会发现它找不到配置文件“.config”。 它没有加载先前已知的配置文件。 一旦我将配置添加到配置器中,它仍然无法记录,但也没有抱怨。
为了在 .Net Standard 下使其像以前那样工作,这就是我所做的。
var loggerRepository = LogManager.CreateRepository(LogName);
XmlConfigurator.Configure(loggerRepository,new FileInfo("log4net.config"));
var hierarchy = (Hierarchy) loggerRepository;
var appender = (RollingFileAppender)hierarchy.Root.GetAppender("RollingLogFileAppender");
appender.File = Path.Combine(Directory.GetCurrentDirectory(), "logs", $"{LogName}.log");

我不想为每个存储库创建配置文件,所以这样做是可行的。也许有更好的方法来获得之前的 .Net Framework 行为,如果有,请在下面让我知道。

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