代码之家  ›  专栏  ›  技术社区  ›  The.Anti.9

C#单例日志类

  •  6
  • The.Anti.9  · 技术社区  · 14 年前

    我正在尝试找出登录我正在使用的异步ioweb服务器的最佳策略。我认为最简单的方法是使用一个singleton类,该类使Filestreams为适当的日志文件打开,这样我就可以执行以下操作:

    Util.Logger.GetInstance().LogAccess(str);
    

    我的班级是这样的:

    public sealed class Logger {
       private static StreamWriter sw;
       private static readonly Logger instance = new Logger();
       private Logger() {
          sw = new StreamWriter(logfile);
       }
       public static Logger GetInstance() {
          return instance;
       }
       public void LogAccess(string str) {
          sw.WriteLine(str);
       }
    }
    

    这一切都只是在我的脑海里真的,我正在寻找如何使它更好的建议,并确保我做得很好。最重要的是我需要它是线程安全的,这显然不是它的当前状态。不知道最好的方法。

    7 回复  |  直到 14 年前
        1
  •  5
  •   Drew Hoskins    14 年前

    有一种方法 TextWriter.Synchronized 生成线程安全版本的TextWriter。试试看。

        2
  •  8
  •   GrayDwarf    5 年前

    NLog -您可以在一个.config文件中定义所有的记录器,然后通过静态LogManager类(一个单例)访问它们。

    下面的示例说明了NLog的线程安全特性:

    https://github.com/nlog/nlog/wiki/Tutorial#Adding_NLog_to_an_application

        3
  •  4
  •   jgauffin    14 年前

    b) 创建写入日志的后台线程。

    c) 将日志记录方法中的条目排队,并向工作线程发送信号。

    d) 使用(我不知道我是否正确地记住了方法名)

    var methodInfo = new StackFrame(1).GetMethod();
    var classAndMethod = methodInfo.DeclaringType.Name + "." + methodInfo.Name;
    

    获取调用方法。

        4
  •  2
  •   fengd    14 年前

    也许你应该试试NLog或者Log4net。它们都是很好的日志框架。

    但如果您确实想编写自己的日志组件,则在输出日志消息时必须使用锁。 在内存中缓冲日志消息并一次将它们写入文件是很常见的。

        5
  •  1
  •   S. Mills    14 年前

    为您解决这些问题的另一个框架是 the Object Guy's logging framework . 它可以选择在后台登录。多个线程可以登录到同一个文件。多个进程可以登录到同一个文件。

        6
  •  0
  •   EMP    14 年前

    如果您想从多个线程写入同一个文件,我认为没有任何简单的锁定方法。

    所以简单的解决方法是添加一个 lock StreamWriter . 或者,您可以将输出缓冲在内存中,偶尔只将其写入文件中一次,这仍然需要锁定,但锁定争用将大大降低。但是,如果您达到这个长度,那么最好使用一个适当的日志框架,如 log4net, which is thread-safe .

        7
  •  0
  •   Alex Rouillard    14 年前

    Imports System.Threading
    
    Public Class Logger
        Private Shared ReadOnly syncroot As New Object
    
        Public Shared Sub log(ByVal vInt As Integer)
            ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf logThread), CStr(vInt))
        End Sub
    
        Public Shared Sub log(ByVal vStr As String)
            ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf logThread), vStr)
        End Sub
    
        Private Shared Sub logThread(ByVal o As Object)
            Dim str As String = CStr(o)
            SyncLock syncroot
                Using objWriter As New System.IO.StreamWriter(GetLogPath, True)
    
                    objWriter.WriteLine(str)
                    objWriter.Close()
    
                End Using
            End SyncLock
        End Sub
    
        Private Shared Function GetLogPath() As String
            Return "logs.txt"
        End Function
    End Class
    

    我发现这样比使用单例更有用:

    Logger.log("Something to log")