简体   繁体   English

C#“缓存调试日志”

[英]C# “cached debug log”

I'd like to ask the C# experts here for an advice. 我想在这里向C#专家征求意见。 I have an issue with my debug log. 我的调试日志有问题。 I have a simple class that just opens a file, writes the provided string down and closes the file again. 我有一个简单的类,只打开一个文件,写下提供的字符串并再次关闭文件。 However, sometimes I need to use this debug log while I'm using the multithreading. 但是,有时我需要在使用多线程时使用此调试日志。 Thereby the troubles come. 从而麻烦来了。 I can't have the file opened more than once, so I recieve an exception because I simply try to open the locked file again. 我不能多次打开文件,所以我收到异常,因为我只是尝试再次打开锁定的文件。 For this purpose I'd like to have something like a "cached debug log" which would prevent this exception. 为此,我希望有一个类似“缓存的调试日志”的东西,它可以防止这种异常。 Is there any easy way to implement this? 有没有简单的方法来实现这个? Thanks a lot in advance. 非常感谢提前。

C# 4.0 provides thread-safe collections like System.Collections.Concurrent.ConcurrentQueue<T> . C#4.0提供了类似System.Collections.Concurrent.ConcurrentQueue<T>线程安全集合。 You could modify your logging class such that it runs in its own thread, and calls to log methods just add the message to such a queue. 您可以修改日志记录类,使其在自己的线程中运行,并且对日志方法的调用只是将消息添加到此类队列中。 That way, your logging thread can just read items out of the queue safely, and write to the file without interruption. 这样,您的日志记录线程可以安全地从队列中读取项目,并在不中断的情况下写入文件。

EDIT 编辑

Of course, the most expedient thing to do is to start using a pre-existing logging framework that already has this stuff taken care of. 当然,最有利的做法是开始使用已经存在这些东西的预先存在的日志框架。 I'd recommend NLog, though log4net is a worthy contender as well. 我推荐NLog,虽然log4net也是一个有价值的竞争者。

This is generally done by having a singleton logger that you call from all parts of your code; 这通常通过使用您从代码的所有部分调用的单例记录器来完成; the logger is the only thing that accesses the file directly. 记录器是唯一直接访问文件的东西。 There are a number of frameworks already in existence (nlog, log4net, enterprise library) that do this for you. 有许多框架已经存在(nlog,log4net,企业库),为您完成此任务。

You might want to check out .NET Tracing. 您可能想要查看.NET跟踪。 I prefer just using the built in TraceSource classes vs using a 3rd party logging framework like nlog. 我更喜欢使用内置的TraceSource类和使用像nlog这样的第三方日志框架。 I used to go down the road of even writing a facade around nlog, but then it seems rather silly to have so many dependencies and so many layers of abstraction, just to write a log message. 我曾经走过甚至围绕nlog写一个立面的道路,但是那么拥有如此多的依赖关系和如此多的抽象层似乎相当愚蠢,只是为了写一条日志消息。

You can see an overview of TraceSource here: http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx 您可以在此处查看TraceSource的概述: http//msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx

The idea is that you separate out the tracing from listening. 这个想法是你将追踪与听力区分开来。 Throughout your code, you can add trace calls, each with different log levels (Error, Verbose, Debug) and different sources. 在整个代码中,您可以添加跟踪调用,每个调用具有不同的日志级别(错误,详细,调试)和不同的源。 In your application configuration, you then configure different listeners. 在应用程序配置中,然后配置不同的侦听器。

<system.diagnostics>
    <sources>
      <source name="Source1" switchName="verboseSwitch">
        <listeners>
          <add name="console" />
        </listeners>
      </source>
      <source name="Source2" switchName="warningSwitch">
        <listeners>
          <add name="console" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="verboseSwitch" value="Verbose" />
      <add name="warningSwitch" value="Information" />
    </switches>
    <sharedListeners>
      <add name="console" type="System.Diagnostics.ConsoleTraceListener" initializeData="false"/>
    </sharedListeners>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="console" />
      </listeners>
    </trace>
  </system.diagnostics>


public void MethodOne()
{
     TraceSource ts = new TraceSource("Source1");

     ts.TraceEvent(TraceEventType.Verbose, 0, "Called MethodOne");

     // do something that causes an error
     ts.TraceEvent(TraceEventType.Error, 0, "MethodOne threw an error");
}

Here, MethodOne is set up to use the source "Source1". 这里,MethodOne设置为使用源“Source1”。 Source1 is currently configured above to listen to anything Verbose and higher. Source1目前在上面配置为侦听任何详细和更高版本。 So this means that 所以这意味着

Called MethodOne
MethodOne threw an error 

will both be written to the console 将被写入控制台

public void MethodTwo()
{
     TraceSource ts = new TraceSource("Source2");

     ts.TraceEvent(TraceEventType.Verbose, 0, "Called MethodTwo");

     // do something that causes a error
     ts.TraceEvent(TraceEventType.Error, 0, "MethodTwo threw an error");
}

Here though, MethodTwo is configured to use Source2, which is only set up to listen to Warning and above. 但是,MethodTwo配置为使用Source2,它仅设置为侦听警告及以上。

So, when the code runs, the output will be 因此,当代码运行时,输出将是

MethodTwo threw an error

What this allows you to do is control how much information you want to see for different parts of your program. 这允许您做的是控制您希望在程序的不同部分看到多少信息。 Perhaps if one day you start seeing errors in some library, you can turn the trace source for that library to verbose, and now see all your debugging information, without being overwhelmed with data from other parts of the program. 也许如果有一天你开始在某个库中看到错误,你可以将该库的跟踪源变为详细,现在可以查看所有调试信息,而不会被来自程序其他部分的数据所淹没。

I use different listeners like this to control the flow of critical errors. 我使用这样的不同监听器来控制关键错误的流动。 I have listeners for certain sources and certain error levels that will email me the moment an error gets written to the log. 我有一些侦听器用于某些来源和某些错误级别,这些错误级别会在错误写入日志时向我发送电子邮件。 I don't care about 404 errors, but I do care about anything that happens in the registration code, for example. 我不关心404错误,但我确实关心注册代码中发生的任何事情,例如。

You have the ConsoleTraceListener for writing to the console/debug window The FileLogTraceListener for writing to files Even the EventLogTraceListener 您有ConsoleTraceListener用于写入控制台/调试窗口FileLogTraceListener用于写入文件甚至EventLogTraceListener

You can see the full list of built in listeners here 您可以在此处查看内置侦听器的完整列表

Then there are third party listeners for sending emails on log events, storing in the database, writing to Azure table storage, etc. 然后有第三方侦听器用于在日志事件上发送电子邮件,存储在数据库中,写入Azure表存储等。

You can of course accomplish all of this with a framework like NLog. 您当然可以使用像NLog这样的框架来完成所有这些工作。 The .NET Trace methods are high performance and used all over the .NET Framework. .NET Trace方法具有高性能,可在整个.NET Framework中使用。 You can't go wrong choosing it IMHO. 你选择它不能出错恕我直言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM