在磁盘上实现固定大小的日志文件或循环缓冲区

发布于 2024-08-12 05:34:54 字数 284 浏览 5 评论 0原文

我检查了这个问题,但这不是我要找的。

我正在尝试弄清楚如何限制日志文件的大小(例如 10MB),并且一旦命中,要么:

  • 开始写入开头,而不是附加,或者
  • 继续附加,但从开头删除内容正如我所做的那样,

并不真正关心语言 - 只要可能就行:)


注意:我知道滚动日志文件方法(达到目标大小、重命名并继续记录)。我希望避免这样的情况发生。

I checked this question, but it's not what I'm looking for.

I'm trying to figure out how to cap a log file's size (say, 10MB), and as soon as it's hit, either:

  • start writing to the beginning, rather than appending, or
  • keep appending, but delete the contents from the beginning as I do so

Don't really care about language - as long as it's possible :)


Note: I am aware of the rolling log files approach (hit a target size, rename, and continue logging). I am looking to avoid such a roll.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲性难收 2024-08-19 05:34:54

如果您同时实现写入器和读取器,那么您可以执行以下操作:

struct logentry {
    timestamp  ts;
    char       msg [4000];
};

class logger {
private:
    int write_recordnum;  // next record number to write
    int max_recordnum;  // controls maximum size of file
    FILE    *logfile;

public:
    logger (const char *filename, int max_records)
    {
        max_recordnum = max_records;
        logfile = fopen (filename, "a+");
    }

    void write_next_entry (const char *msg, ...)
    {
        struct logentry ent;
        // format message into entry
        va_list ap;
        va_start (ap, msg);
        vsnprintf (ent.msg, sizeof(ent.msg), msg, ap);
        va_end (ap);
        ent.ts = gettimestamp();

        // position logfile
        if (write_recordnum > max_recordnum)
            write_recordnum = 0;

        fseek (logfile, write_recordnum * sizeof (ent), 0);
        fwrite (&ent, 1, sizeof(ent), logfile);
    }

    bool read_entry (int recnum, char *msg)
    {
        struct logentry ent;
        if (recnum >= max_recordnum)
            return false;
        fseek (logfile, recnum * sizeof (ent), 0);
        fread (&ent, 1, sizeof(ent), logfile);
        strcpy (msg, ent.msg);
        return true;
    }
};

这个想法是通过显式固定大小的记录号来管理循环缓冲区。需要的是管理记录 N 是否存在以及检查错误的逻辑。

If you are implementing both the writer and the reader, then you can do something like this:

struct logentry {
    timestamp  ts;
    char       msg [4000];
};

class logger {
private:
    int write_recordnum;  // next record number to write
    int max_recordnum;  // controls maximum size of file
    FILE    *logfile;

public:
    logger (const char *filename, int max_records)
    {
        max_recordnum = max_records;
        logfile = fopen (filename, "a+");
    }

    void write_next_entry (const char *msg, ...)
    {
        struct logentry ent;
        // format message into entry
        va_list ap;
        va_start (ap, msg);
        vsnprintf (ent.msg, sizeof(ent.msg), msg, ap);
        va_end (ap);
        ent.ts = gettimestamp();

        // position logfile
        if (write_recordnum > max_recordnum)
            write_recordnum = 0;

        fseek (logfile, write_recordnum * sizeof (ent), 0);
        fwrite (&ent, 1, sizeof(ent), logfile);
    }

    bool read_entry (int recnum, char *msg)
    {
        struct logentry ent;
        if (recnum >= max_recordnum)
            return false;
        fseek (logfile, recnum * sizeof (ent), 0);
        fread (&ent, 1, sizeof(ent), logfile);
        strcpy (msg, ent.msg);
        return true;
    }
};

The idea is to manage a circular buffer by explicit fixed-size record numbers. Needed is logic to manage whether record N exists, and to check errors.

嘦怹 2024-08-19 05:34:54

为什么不滚动日志文件?它必须正好是 10MB 吗?如果您的配额为 10MB,常见的做法是写入 blah.log,当达到 1MB 时,将文件重命名为 blah.log.1 并开始写入 blah.log。更简单,也是一种非常常见的做法。事实上,在Linux中,如果你使用syslog,它是免费的。

Why not do rolling logfiles? Does it have to be precisely 10MB? If 10MB is your quota, a common practice would be to write to blah.log, and when it hits, say 1MB, rename file to blah.log.1 and start writing to blah.log. Much simpler, and a very common practice. In fact, in Linux, if you use syslog, it's free.

箹锭⒈辈孓 2024-08-19 05:34:54

如果您使用 Log4[j/net],则可以选择滚动日志。请参阅 RollingFileAppender。此外,在指定日志文件的属性时,还有一个选项可以设置日志的最大文件大小。 (参数:最大文件大小)

If you are using Log4[j/net] there are options for a rolling log. See the RollingFileAppender. Also, there is an option when specifying the attributes of the log file to set the maximum file size for the log. (Param: MaxFileSize)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文