代码之家  ›  专栏  ›  技术社区  ›  Clément

日志记录的最佳方法是什么?[关闭]

  •  6
  • Clément  · 技术社区  · 14 年前

    我的(本地,Windows/Mono)应用程序将重要事件记录到文本文件中。如果发生突然碰撞/故障/强制退出,任何数据都不应保持不成文(尽可能)。因此,我目前使用一种简单的附加到文本文件的方法:

    Public Shared Sub LogAppEvent(ByVal EventData As String)
        Dim Config As ConfigHandler = ConfigHandler.GetSingleton()
        Dim AppLog As New IO.StreamWriter(Config.GetUserFilesRootDir() & ConfigOptions.AppLogName, True)
        AppLog.WriteLine(String.Format("[{0}] {1}", Date.Now.ToString(), EventData))
        AppLog.Close()
    End Sub
    

    这是高度次优的,但是日志事件非常罕见。你能建议搬到 System.Diagnostics 日志记录类?

    或者你会建议另一个解决方案吗?

    5 回复  |  直到 7 年前
        1
  •  14
  •   Community CDub    8 年前

    如果这样的超基本方法在功能上足以满足您的需求,那么您可以坚持使用它。但是,你可能会问自己一些问题来确保:

    • 多个线程是否可以同时记录事件?此功能不是线程安全

    • 是否需要错误通知?

    • 在没有自动修剪的情况下,日志文件是否有无限增长的风险?

    • 您会从更广泛的日志记录中获益吗,这样您就可以获得更多关于导致错误的事件的信息?

    • 您是否可以从有关错误(堆栈跟踪、异常详细信息等)的更多详细信息中获益?

    • 你的程序在多台计算机上运行吗?如果是这样的话,日志是如何传递给你的?

    • 工具中是否有任何必要/价值来帮助分析日志文件(无论是单一的还是跨多个日志文件查找常见错误等模式)?

    如果您决定您有其他需求,那么有许多免费的日志框架,例如 NLog or log4net 这有助于记录更详细的日志,并且有几个商业产品,例如 GIBRALTAR SmartInspect 有助于日志管理和分析。

        2
  •  13
  •   wageoghe    14 年前

    如前所述,nlog和log4net都是很好的日志框架。正如Jeff上面提到的,System.Diagnostics也是一个合理的选择(不仅仅是记录到事件日志)。尝试给我的答案增加一些价值,而不仅仅是重复已经说过的话,你可以增强你的系统。 TraceSources 使用免费的 Ukadc.Diagnostics library from codeplex .

    使用tracesources,您可以创建“命名记录器”,类似于在nlog和log4net中如何创建。这些跟踪源可以配置为在特定级别记录(每个跟踪源不同),并且可以发送到不同的目标(跟踪侦听器)。所有跟踪源都可以记录到同一个监听器,或者有些可以记录到某些监听器,而另一些可以记录到其他监听器。任何跟踪源也可以发送到多个跟踪侦听器。

    下面是如何在代码中使用tracesources(假设tracesource“abc”已在app.config文件中配置为记录“info”和更高优先级的消息,并且已配置为记录到文件“log.txt”)。

    public class MyClass
    {
      static TraceSource ts = new TraceSource("abc"); //Common idiom for NLog and log4net, not sure if as common for TraceSource
    
      public void Func1(int x)
      {
        ts.Information("Entering Func1");
        ts.Verbose("x = {0}", x); //Won't log if "abc" is configured to log Info and HIGHER messgaes
        ts.Information("Exiting Func1");
      }
    }
    

    与“普通”跟踪源相比,UKADC.diagnostics的一个巨大好处是,您可以配置nlog/log4net样式的输出格式,这样您就可以对日志输出中显示的字段和格式有更多的控制。

    从nlog/log4net中有三个非常有用的东西在系统中不可用。诊断是:

    1. 能够自动记录调用站点信息(方法/功能)

    2. 其他日志记录上下文(gdc-全局日志记录属性,mdc-nlog/log4net术语中的线程日志记录属性)。system.diagnostics确实有trace.correlationmanager.logicalOperationstack,这与ndc类似。

    3. 教区记录员。

    层次式记录器意味着您可以配置“祖先”记录器,任何“后代”记录器都将继承这些设置。例如,假设您有一个类的完全(命名空间)限定类型名为Namespace1.Namespace2.Class。使用nlog/log4net,您可以为“namespace1”配置日志信息(级别、目标),如果您基于namespace1中任何类型的完全限定名请求日志记录器,它将继承namespace1的设置。通过查看 Castle implemented their TraceSource-based logging 抽象化。特别是,查看初始化函数。它非常容易工作(在您自己围绕tracesource的薄包装中),而且作为一个附带的好处,它使您的tracesource的配置稍微容易一点,因为您不必单独配置每个tracesource。请注意,通过配置一个名为“”的跟踪源,您可以轻松地添加具有“根”配置的功能。 “并在Castle方案中添加一些代码以默认到” “如果未找到实际祖先,则配置。例如,您可以将“*”配置为登录,例如verbose,然后具体地将某些跟踪源(按类或按命名空间)配置为关闭或处于不同的级别。如果没有层次记录器,要对tracesources执行相同的操作,需要配置每个tracesource以在verbose中所需的“verbose”登录。

    当我谈论了很多关于类和名称空间的记录器时,nlog、log4net和tracesources都允许您将记录器名称定义为任意字符串。因此,您可以按功能区而不是按命名空间/类冷定义记录器层次结构:

    Database
    Database.Connect
    Database.Query
    Database.Update
    Database.SQL
    Amazon
    Amazon.Books
    Amazon.Books.Fiction
    Amazon.Books.Nonfiction
    Amazon.Electronics
    Amazon.Electronics.Video
    Amazon.Electronics.Music
    Amazon.Electronics.Computer
    

    因此,您可以打开“Amazon”日志和所有Amazon资料日志(不必显式配置每个“子”跟踪源),而数据库资料不会。或者,你可以打开亚马逊和亚马逊,关闭电子设备,只有亚马逊,书籍(和儿童)才能登录。

    最后,如果您使用nlog或log4net,值得一提的是,nlog刚刚发布了一个新版本,nlog 2.0(beta版)。

        3
  •  2
  •   Matthieu kelly    14 年前

    Nlog log4Net 是登录.NET项目的常用选项。

        4
  •  1
  •   JeffFerguson    14 年前

    是的,您可以考虑System.Diagnostics。只要您不编写大量事件,Windows事件日志的优势就是管理员可以在一个位置查找所有应用程序中的所有事件。

    下面是一些VB.NET代码,可以帮助您决定走这条路:

    Imports System.Diagnostics
    
    Public Function WriteToEventLog(ByVal Entry As String, _
       Optional ByVal AppName As String = "VB.NET Application", _
       Optional ByVal EventType As _
       EventLogEntryType =  EventLogEntryType.Information, _
       Optional ByVal LogName As String = "Application") As Boolean
    
    '*************************************************************
     'PURPOSE: Write Entry to Event Log using VB.NET
     'PARAMETERS: Entry - Value to Write
     '            AppName - Name of Client Application. Needed 
     '              because before writing to event log, you must 
     '              have a named EventLog source. 
     '            EventType - Entry Type, from EventLogEntryType 
     '              Structure e.g., EventLogEntryType.Warning, 
     '              EventLogEntryType.Error
     '            LogName: Name of Log (System, Application; 
     '              Security is read-only) If you 
     '              specify a non-existent log, the log will be
     '              created
    
     'RETURNS:   True if successful, false if not
    
     'EXAMPLES: 
     '1. Simple Example, Accepting All Defaults
     '    WriteToEventLog "Hello Event Log"
    
     '2.  Specify EventSource, EventType, and LogName
     '    WriteToEventLog("Danger, Danger, Danger", "MyVbApp", _
     '                      EventLogEntryType.Warning, "System")
     '
     'NOTE:     EventSources are tightly tied to their log. 
     '          So don't use the same source name for different 
     '          logs, and vice versa
            '******************************************************
    
            Dim objEventLog As New EventLog()
    
            Try
                'Register the App as an Event Source
                If Not objEventLog.SourceExists(AppName) Then
    
                    objEventLog.CreateEventSource(AppName, LogName)
                End If
    
                objEventLog.Source = AppName
    
                'WriteEntry is overloaded; this is one
                'of 10 ways to call it
                objEventLog.WriteEntry(Entry, EventType)
                Return True
            Catch Ex As Exception
                Return False
    
            End Try
    
        End Function
    
        5
  •  0
  •   Alexander M.    12 年前

    我使用公共变量和计时器将新行附加到txt文件。

    例如。

    Public Class Form1
    
        Public WriteToLog = ""
    
        Dim LogFilePath As String = My.Application.Info.DirectoryPath & "\applog.txt"
    
    ....
    
        Public Function Log_to_txt(ByVal text As String)
    
            Dim CurDate As String
            CurDate = Format(Now, "General Date")
    
            WriteToLog = WriteToLog & "[" & CurDate & "] " & text & vbCrLf
    
            Return True
    
        End Function
    
    ...
    
    Log_to_txt("Application started...")
    
    ...
    
        Private Sub WriteToLogTimer_Tick(sender As Object, e As EventArgs) Handles WriteToLogTimer.Tick
    
            Dim CatchLog As String = WriteToLog
    
            WriteToLog = ""
    
            Try
    
                My.Computer.FileSystem.WriteAllText(LogFilePath, CatchLog, True)
    
            Catch ex As IOException
    
            End Try
    
        End Sub