正在存档日志文件
本文关键字:日志 文件 | 更新日期: 2023-09-27 18:21:59
我刚刚重写了一个windows服务进程,该进程将重要的信息调试输出到/programdata/myservice/文件夹中的日志文件中。
然而,在午夜的晚上,我有一项工作,应该获取当前日期的日志文件并删除其内容,然后创建一个存档的日志文件,其中包含3天的日期,例如LogfileArchived15092014.log。
然后运行一些代码来删除比这个日期更早的日志文件,所以我只有今天的当前日志文件和2个存档的日志文件用于调试旧问题等。
现在,我已经从一个正在运行的旧服务中复制了执行此操作的代码,它会归档日志文件并删除旧文件。然而,由于某些原因,当这个新作业运行时,我会收到I/O错误,例如(来自事件查看器)
运行系统作业时出错:I/O存档日志文件时出错:C:''ProgramData''Brainiac''LogfileArchived;进程无法访问文件"C:''ProgramData''Brainiac''Logfile.log",因为另一个进程正在使用该文件。
现在,第一个路径上没有扩展名的原因,例如C:''ProgramData''Brainiac''LogfileArchived,是因为在到达创建文件日期的部分之前,它显然抛出了一个错误,以附加到文件名中,例如
// set a lock up to prevent other processes locking
this.Locked = true;
// wrap in try as it keeps failing!!!!
try
{
// take contents of current log file - the daily one I have been logging to all day
// I guess this is where the error is being raised due to the absence
// of a .log extension in the error message when mentioning the filename
string content = this.ReadFileString(this.logFilePath);
// for some reason todays log file was empty
// why would this be unless loggging was disabled?
if (!String.IsNullOrEmpty(content))
{
// create a new log file with date stamp of yesterday added to the filename and guff removed to make it valid
string file_date = DateTime.Now.Date.AddDays(-1).ToString().Replace("/", "").Replace("-", "");
// remove time part - should be done at midnight but if not ensure colons and spaces are removed
file_date = file_date.Replace("00:00:00", "").Replace(":", "").Replace(" ", "");
// append .log to it
this.logfilearchivepath += file_date + ".log";
//Append all the contents of my daily log file to this new file
File.AppendAllText(this.logfilearchivepath, content, Encoding.UTF8);
所以我怀疑这是在轰炸
string content = this.ReadFileString(this.logFilePath);
由于错误消息中没有扩展名。所以,也许我需要一种不同的方式来访问内容?
现在我不知道还有哪个进程被锁定了(我能以某种方式找到吗?)但我已经尝试了以下操作。
- 确保我没有在自己的电脑上打开文件
在日志文件中添加一个标志,在该标志中应该阻止ANY日志记录。正如你在顶部看到的,我去
//设置锁定以防止其他进程锁定这Locked=true;
在我进行日志记录的方法中,我要检查它是否尽快退出,例如
// log to our application data folder - unless locked for some reason
public void LogMsg(string msg, string debugLevel = "HIGH")
{
// we are prevented from logging at this point in time
if (this.Locked) return;
我还将对ArchiveLogFile()方法的调用封装在3个try/catch语句中,每个语句都有一个Thread。在更长的间隔之间休眠,以防有东西仍在记录。
我也尝试过使用DB锁。
所以我有一个名为LOCKS的表和插入/删除锁定记录的方法,还有一个检查不存在的方法。
因此,如果多个进程试图同时从不同的应用程序运行相同的代码,那么它就不可能了,因为锁定记录将存在于数据库中,在作业开始运行之前插入,并在作业完成后删除(running锁定)
此外,一旦完成,将插入LOGFILE_ARCHIVED锁定记录,以便同一作业或不同作业知道日志文件已存档,并且不会再次尝试存档。
我在锁定文件中使用计算机名称,因为进程可以同时在多台服务器/计算机上运行。
那么,我还能做什么其他解决方案来解决这个问题呢?
我是否应该使用不同的方法来获取不会被锁定文件的东西阻止的日志文件内容(我不知道是什么在进行锁定,但我不知道这一点。Locked=True应该可以防止在存档作业期间将任何内容记录到文件中),但显然文件上的"锁定"比我的代码更高。
这是一个在Win7机器上用C#.NET 4.5编写的windows服务。
谢谢你的帮助。
我让它工作起来了。我只是对此有意见。锁定在Helper类中,调用DLL的其他并发实例忽略它(多线程问题),所以我只是将DB锁定检查放入Helper类的Init中,所以它是
this.Locked = this.GetCurrentLockedStatus();
然后任何过程都会得到相同的值。这意味着在文件传输过程中没有日志记录,因为我在尝试之前添加了LOCK记录,并在的情况下退出任何LogMsg方法
this.Locked = true;
现在它就像一个符咒。我真的不知道为什么旧的服务会起作用。我可以在它的事件日志中看到很多I/O错误,但由于某种原因,它最终还是成功地做到了。这种使用DB来维护锁的方法似乎更好、更快。
谢谢你的帮助。