首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >归档日志文件

归档日志文件
EN

Stack Overflow用户
提问于 2014-09-16 12:11:06
回答 1查看 1.4K关注 0票数 0

我刚刚重写了一个windows服务进程,它将重要信息调试输出到/programdata/myservice/文件夹中的一个日志文件中。

然而,在午夜时分,我有一个任务,它应该接受当前的日志文件并删除它的内容,然后创建一个包含日期的归档日志文件,日期为3天,例如LogfileArchived15092014.log。

然后运行一些代码来删除比这个日期更早的日志文件,所以我今天只有当前的日志文件,还有两个存档的日志文件,用于调试旧的问题等等。

现在,我已经从正在工作的旧服务中复制了执行此操作的代码,并将日志文件归档并删除旧的日志文件。但是,由于某些原因,当这个新作业运行时,我会得到I/O错误,如以下(来自事件查看器)

运行系统作业: I/O错误归档日志文件: C:\ProgramData\Brainiac\LogfileArchived;进程无法访问文件'C:\ProgramData\Brainiac\Logfile.log‘,因为它正在被其他进程使用。

现在,第一条路径没有扩展名(例如C:\ProgramData\Brainiac\LogfileArchived )的原因是,在文件日期被创建以附加到文件名(例如)之前,它显然被抛出了一个错误。

代码语言:javascript
运行
复制
// 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);

所以我怀疑它是在这条线上爆炸

代码语言:javascript
运行
复制
string content = this.ReadFileString(this.logFilePath);

由于错误消息中没有扩展名。所以也许我需要一种不同的方式来访问内容?

现在我不知道它还锁定了什么进程(我能不知怎么发现吗?)但我试过以下几种方法。

  1. 确保我自己的电脑上没有打开文件。
  2. 添加一个标志,其中应该阻止任何日志记录到日志文件。就像你在顶部看到的,我去 //设置锁以防止其他进程锁定this.Locked = true;

在我进行日志记录的方法中,我检查它是否能够尽快退出,例如

代码语言:javascript
运行
复制
// 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;
  1. 我还在3 try/catch语句中包装了对ArchiveLogFile()方法的调用,每个语句之间都有一个Thread.Sleep,如果还在日志记录的话,间隔会更长。
  2. 我也尝试过使用DB锁。

因此,我有一个名为LOCKS的表和用来插入/删除一个锁记录的方法,还有一个检查不存在的方法。

因此,如果多个进程尝试从不同的应用程序同时运行相同的代码,那么它就不应该能够运行,因为数据库中将存在锁记录,该数据库将在作业开始运行之前插入并在作业完成后删除(正在运行的锁)。

此外,一旦完成,将插入一个LOGFILE_ARCHIVED锁记录,以便相同或不同的作业知道日志文件已经归档,并且不再试图将其存档。

我在锁文件中使用计算机名称,因为进程可以在任何时候在多台服务器/计算机上运行。

那么,我还能做些什么来解决这个问题呢?

我是否应该使用不同的方法来获取不会被锁定文件所阻止的日志文件内容(我不知道锁在做什么,但是this.Locked = True应该防止在归档工作期间记录到文件中的任何内容),但是文件上的“锁”显然比我的代码要高。

这是在Win 7机器上用C# .NET 4.5编写的windows服务。

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2014-09-17 16:45:10

我让它起作用了。我刚刚遇到了一个问题,this.Locked在Helper类中,以及调用DLL的其他并发实例中,忽略了它(多线程问题),所以我将我的DB检查放到了帮助类的类中,所以

代码语言:javascript
运行
复制
this.Locked = this.GetCurrentLockedStatus();

然后任何进程都会得到相同的值。这意味着在文件传输期间没有日志记录,因为在尝试执行该记录和退出任何LogMsg方法之前,我都会在其中添加锁记录。

代码语言:javascript
运行
复制
this.Locked = true;

现在它就像一种魅力。我真的不知道为什么旧的服务是有效的。我可以在事件日志中看到很多I/O错误,但最终它只是出于某种原因成功地做到了这一点。这种使用DB维护锁的方法似乎更好、更快。

谢谢你的帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25868412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档