简体   繁体   English

同一进程的许多实例写入同一日志文件

[英]Many instances of the same process writing to the same log file

I am kicking off a number of instances of the same process and the issue is that they all write to the same log file. 我启动了多个相同过程的实例,问题是它们都写入同一日志文件。 I know it is not a good practice and was wondering what can I do to avoid possible issues. 我知道这不是一个好习惯,并且在想如何避免可能出现的问题。 Here is the procedure I use to write to file: 这是我用来写入文件的过程:

Sub WriteToErrorLog(ByVal Msg As String)
    Dim path As String
    path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
    Dim strFile As String = System.IO.Path.Combine(path, "Log_" & DateTime.Today.ToString("dd-MMM-yyyy") & ".txt")


    Dim sw As StreamWriter
    Dim fs As FileStream = Nothing
    Try
        If (Not File.Exists(strFile)) Then
            fs = File.Create(strFile)
            fs.Close()
        End If
        sw = File.AppendText(strFile)

        sw.WriteLine(Msg & vbcrlf)

    Catch ex As Exception
        MsgBox("Error Creating Log File")
        MsgBox(ex.Message & " - " & ex.StackTrace)
    Finally
        sw.Close()
    End Try
End Sub

I would appreciate any suggestions/improvements. 我将不胜感激任何建议/改进。 thanks! 谢谢!

As I have said in my comment, the scenario of multiple access to the same file resource should be handled carefully and probably the best solution is to use a well tested log library like Log4Net or NLog . 正如我在评论中所说,应仔细处理多次访问同一文件资源的情况,最好的解决方案是使用经过良好测试的日志库,例如Log4NetNLog

In any case you could improve your code in a couple of point 无论如何,您可以在两点上改进代码

Sub WriteToErrorLog(ByVal Msg As String)
    Dim path As String
    path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
    Dim strFile As String = System.IO.Path.Combine(path, "Log_" & DateTime.Today.ToString("dd-MMM-yyyy") & ".txt")

    Dim retry as Integer = 3 ' this could be changed if you experience a lot of collisions.'
    Dim sw As StreamWriter = Nothing
    While retry > 0
        Try
            Using sw = File.AppendText(strFile)
               sw.WriteLine(Msg & vbcrlf)
            End Using
            Exit While
        Catch  ex as Exception        
           retry -= 1
        End Try
    End While
    ' If retry has reached zero then we have exausted our tentatives and give up....'
    if retry = 0 Then
        MessageBox.Show("Error writing to Log File")
    End if
End Sub

I have removed all the part that check if file exists and then create it. 我已经删除了检查文件是否存在然后创建它的所有部分。 This is not necessary because as the documentation explains, File.Append is the same that calling StreamWriter(file, true) and this means that if the file doesn't exist it will be created. 这不是必需的,因为如文档所述,File.Append与调用StreamWriter(file,true)相同,这意味着如果文件不存在,则会创建该文件。

Next, to try to handle possible collision with other process writing to the same file concurrently, I have added a retry loop that could get access to the log file just after another process finishes. 接下来,为尝试处理与同时写入同一文件的其他进程可能发生的冲突,我添加了一个重试循环,该循环可以在另一个进程完成后立即访问日志文件。 (this is really a poor-man solution but then it is better to use a well tested library) (这确实是一个穷人解决方案,但是最好使用经过良好测试的库)

It is important to enclose the opening and writing of the file inside a using statement that closes and disposes the Stream also in case of exceptions. 重要的是,将文件的打开和写入包含在using语句内,该语句在发生异常的情况下也会关闭和处理Stream。 This is mandatory to be sure to leave the file always closed for the other processes to work. 这是强制性的,以确保始终关闭文件以使其他进程正常工作。

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

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