保持一定规模下的日志文件

问题描述 投票:7回答:6

我有一个在亭(C#/ WPF)一个独立的平板电脑上运行的应用程序。它执行一些典型的伐木作业到一个文本文件中。该PC具有的磁盘空间,一些有限的,因为他们成长来存储这些日志。

我需要做的是能够指定一个日志文件,允许为最大尺寸。如果试图写入日志时,超过最大大小,新数据将被写入日志的末尾,最早的数据会从一开始就被清除。

获取文件的大小是没有问题的,但是否有任何典型的文件操作技术来保证文件一定规模下?

c# file logging filesize file-manipulation
6个回答
15
投票

处理这种情况的一个技术是有其各自的最大尺寸的一半两个日志文件。您只需在两者之间旋转,到达每个文件的最大尺寸。旋转到一个文件导致它与一个新的文件被覆盖。

日志框架,例如log4net的内置了这个功能。


5
投票

4
投票

有没有简单的方法来从文件开始剥离数据。所以,你有几种选择:

  1. 请在日志中几个较小的日志文件,并删除最早的“块”如果所有日志文件的总大小超过你的极限。这类似于你想做的事,但在不同程度上
  2. 重命名日志文件“log.date”,并开始一个新的日志。类似(1),而不是一个选项,如果你有有限的磁盘空间。
  3. 如果你有足够的RAM和你的日志文件的大小是比较小,适合在内存中,您可以执行以下操作:使用内存映射文件的整个文件映射到内存中,然后从文件中获取数据进行移动操作和他们移动到开始。然后截断该文件。这是很容易剥去从日志文件的开头中的数据,而无需创建一个副本的唯一途径。

2
投票

Linux操作系统:退房logrotate的 - http://www.cyberciti.biz/faq/how-do-i-rotate-log-files/

Windows操作系统:谷歌搜索尝试窗户logrotate的。例如:http://blog.arithm.com/2008/02/07/windows-log-file-rotation/


0
投票

我不会用这个意思是在一个文件说,1兆,这不是非常有效的,但如果您需要解决的,当你需要一个日志文件,你不能方便维护一个讨厌的问题,它的工作好。请确保您使用此之前,虽然日志文件存在......或者你可以为它添加代码以及检查位置存在,等等。

// This is how to call it
private void buttonLog_Click(object sender, EventArgs e)
{
    c_Log.writeToFile(textBoxMessages.Text, "../../log.log", 1);
}


public static class c_Log
{
    static int iMaxLogLength = 15000; // Probably should be bigger, say 200,000
    static int iTrimmedLogLength = -1000; // minimum of how much of the old log to leave

    static public void writeToFile(string strNewLogMessage, string strFile, int iLogLevel)
    {
        try
        {
            FileInfo fi = new FileInfo(strFile);

            Byte[] bytesSavedFromEndOfOldLog = null;

            if (fi.Length > iMaxLogLength) // if the log file length is already too long
            {
                using (BinaryReader br = new BinaryReader(File.Open(strFile, FileMode.Open)))
                {
                    // Seek to our required position of what you want saved.
                    br.BaseStream.Seek(iTrimmedLogLength, SeekOrigin.End);

                    // Read what you want to save and hang onto it.
                    bytesSavedFromEndOfOldLog = br.ReadBytes((-1 * iTrimmedLogLength));
                }
            }

            byte[] newLine = System.Text.ASCIIEncoding.ASCII.GetBytes(Environment.NewLine);

            FileStream fs = null;
            // If the log file is less than the max length, just open it at the end to write there
            if (fi.Length < iMaxLogLength) 
                fs = new FileStream(strFile, FileMode.Append, FileAccess.Write, FileShare.Read);
            else // If the log file is more than the max length, just open it empty
                fs = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.Read);

            using (fs)
            {
                // If you are trimming the file length, write what you saved. 
                if (bytesSavedFromEndOfOldLog != null)
                {
                    Byte[] lineBreak = Encoding.ASCII.GetBytes("### " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " *** *** *** Old Log Start Position *** *** *** *** ###");
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(lineBreak, 0, lineBreak.Length);
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(bytesSavedFromEndOfOldLog, 0, bytesSavedFromEndOfOldLog.Length);
                    fs.Write(newLine, 0, newLine.Length);
                }
                Byte[] sendBytes = Encoding.ASCII.GetBytes(strNewLogMessage);
                // Append your last log message. 
                fs.Write(sendBytes, 0, sendBytes.Length);
                fs.Write(newLine, 0, newLine.Length);
            }
        }
        catch (Exception ex)
        {
            ; // Nothing to do...
              //writeEvent("writeToFile() Failed to write to logfile : " + ex.Message + "...", 5);
        }
    }
}

0
投票

我想要一个简单的解决方案为好,但我不希望添加其他的依赖,所以我做了一个简单的方法。这有你需要比压缩旧文件到一个zip,你可以在这里找到的部分其他一切:Create zip file in memory from bytes (text with arbitrary encoding)

static int iMaxLogLength = 2000; // Probably should be bigger, say 200,000
static int KeepLines = 5; // minimum of how much of the old log to leave

public static void ManageLogs(string strFileName)
{
    try
    {
        FileInfo fi = new FileInfo(strFileName);
        if (fi.Length > iMaxLogLength) // if the log file length is already too long
        {
            int TotalLines = 0;
                var file = File.ReadAllLines(strFileName);
                var LineArray = file.ToList();
                var AmountToCull = (int)(LineArray.Count - KeepLines);
                var trimmed = LineArray.Skip(AmountToCull).ToList();
                File.WriteAllLines(strFileName, trimmed);
                string archiveName = strFileName + "-" + DateTime.Now.ToString("MM-dd-yyyy") + ".zip";
                File.WriteAllBytes(archiveName, Compression.Zip(string.Join("\n", file)));
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine("Failed to write to logfile : " + ex.Message);
    }
}

我有这个作为我的应用程序的初始化/重新初始化节的一部分,所以它得到了一天跑几次。

ErrorLogging.ManageLogs("Application.log");
© www.soinside.com 2019 - 2024. All rights reserved.