gpt4 book ai didi

.net - 使用 log4Net 在单个进程中记录多个客户端的帮助

转载 作者:行者123 更新时间:2023-12-01 11:58:05 25 4
gpt4 key购买 nike

经过深思熟虑后,我选择了 log4Net 作为我的日志记录应用程序,因此请不要争论

好吧,听听是我的问题

  • 我有一个连接到多个客户端的进程
  • 每个客户端都有一个唯一的 ID,以字符串的形式存储在自己单独的线程中
  • 每个具有相同唯一 ID 的客户端可以连接多次

  • 我想在不同的 .txt 文件中为每个客户创建一个日志文件。

  • 在每次新连接时,我想创建一个日志文件,其中客户端 ID 附加日期时间和秒数

这种情况让我感到困惑,因为我之前也没有任何应用程序的日志记录经验。

我希望我已经把我的场景说得足够清楚了:)

最佳答案

这不会回答您有关如何将请求写入自己的文件的问题,但 log4net 帮助特别推荐了一种更简单的方法。使用 ThreadContext.Properties 对象和其他属性来修饰日志消息,以便可以区分来自每个请求的消息。

http://logging.apache.org/log4net/release/faq.html

请参阅“多个客户端请求的输出可以转到不同的日志文件吗?”

如果您有客户端 ID,您当然可以这样做:

log4net.ThreadContext.Properties["ClientID"] = GetTheClientId();

在你的模式布局中,你可以做这样的事情:

<conversionPattern value="%date [%thread] %-5level %logger [%property{ClientID}] - %message%newline" />

%property{ClientID} 将从 ThreadContext 中提取您的 ClientID。

这将使每条记录的消息都标记有相关的 ClientID。

有关使用 log4net 上下文对象的良好教程,请参阅此链接:

http://www.beefycode.com/post/Log4Net-Tutorial-pt-6-Log-Event-Context.aspx

整个 log4net 教程非常好,特别是如果您刚开始使用 log4net。

这是第 1 部分:

http://www.beefycode.com/post/Log4Net-Tutorial-pt-1-Getting-Started.aspx

综上所述,人们确实经常使用 GlobalContext 对象来命名他们的输出文件,如此链接中所述:

http://geekswithblogs.net/rgupta/archive/2009/03/03/dynamic-log-filenames-with-log4net.aspx

每当我看到通过 GlobalContext 命名输出文件的过程时,建议的解决方案总是说一定要在 log4net 实际启动之前设置 GlobalContext.Properties["whatever"] 值。这让我相信,即使不是不可能,也很难根据动态存储在 ThreadContext 中的信息创建单独的日志文件,因为这些信息可能在 log4net 运行之前是未知的。

[更新]

这是 SO 上的另一个链接,说明如何为 GlobalContext 中的值命名输出文件。再次注意,在配置 log4net 之前和检索记录器之前,必须将文件名所基于的值设置到 GlobalContext 中。

How do I use a GlobalContext property in a log4net appender name?

正如我在上面和我的评论中所说,我不确定 log4net 是否有可能创建多个输出文件(对于相同的 FileAppender 配置),输出文件名由 ThreadContext 中的值或由线程 id 属性。也许其他更熟悉 log4net 的人可以权衡一下。

话虽如此,在 NLog 中完全可以做到这一点。这是一个 NLog 配置,它定义了一个文件目标,其名称部分来自线程 ID(注意配置的文件名部分中的 ${threadid}):

<targets>
<target name="file" xsi:type="File" layout="${longdate} | ${processid} | ${threadid} | ${logger} | ${level} | ${message}" fileName="${basedir}/log_${threadid}.txt" />
</targets>

使用以下代码:

  class Program
{
public static Logger logger = LogManager.GetCurrentClassLogger();

static void Main(string[] args)
{

int totalThreads = 20;
TaskCreationOptions tco = TaskCreationOptions.None;
Task task = null;

logger.Info("Enter Main");

Task[] allTasks = new Task[totalThreads];
for (int i = 0; i < totalThreads; i++)
{
int ii = i;
task = Task.Factory.StartNew(() =>
{
logger.Info("Inside delegate. i = {0}", ii);
});

allTasks[i] = task;
}

logger.Info("Wait on tasks");

Task.WaitAll(allTasks);

logger.Info("Tasks finished");

logger.Info("Exit Main");
}
}

我有 4 个日志文件,每个文件的名称都包含线程 ID,每个文件仅包含来自单个线程的消息。

类似地,使用此配置(注意 ${mdc:item=id}):

<targets>
<target name="file" xsi:type="File" layout="${longdate} | ${processid} | ${threadid} | ${logger} | ${level} | ${message}" fileName="${basedir}/log_${mdc:item=id}.txt" />
</targets>

还有这段代码:

  class Program
{
public static Logger logger = LogManager.GetCurrentClassLogger();

static void Main(string[] args)
{

int totalThreads = 20;
TaskCreationOptions tco = TaskCreationOptions.None;
Task task = null;

logger.Info("Enter Main");

Task[] allTasks = new Task[totalThreads];
for (int i = 0; i < totalThreads; i++)
{
int ii = i;
task = Task.Factory.StartNew(() =>
{
MDC.Set("id",Thread.CurrentThread.ManagedThreadId.ToString());
logger.Info("Inside delegate. i = {0}", ii);
});

allTasks[i] = task;
}

logger.Info("Wait on tasks");

Task.WaitAll(allTasks);

logger.Info("Tasks finished");

logger.Info("Exit Main");
}
}

我能够根据存储在 MDC 中的值(相当于 log4net 的 ThreadContext.Properties 对象的 NLog)获得多个输出文件。

关于.net - 使用 log4Net 在单个进程中记录多个客户端的帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4850837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com