简体   繁体   English

旋转日志而不重新启动,多进程问题

[英]Rotating logs without restart, multiple process problem

Here is the deal: I have a multiple process system (pre-fork model, similar to apache). 交易如下:我有一个多进程系统(前叉模型,类似于Apache)。 all processes are writing to the same log file (in fact a binary log file recording requests and responses, but no matter). 所有进程都写入相同的日志文件(实际上是二进制日志文件,记录请求和响应,但是没关系)。

I protect against concurrent access to the log via a shared memory lock, and when the file reach a certain size the process that notices it first roll the logs by: 我防止通过共享内存锁并发访问日志,并且当文件达到一定大小时,会注意到该过程首先通过以下方式滚动日志:

  1. closing the file. 关闭文件。
  2. renaming log.bin -> log.bin.1, log.bin.1 -> log.bin.2 and so on. 重命名log.bin-> log.bin.1,log.bin.1-> log.bin.2等。
  3. deleting logs that are beyond the max allowed number of logs. 删除超出最大允许日志数的日志。 (say, log.bin.10) (例如,log.bin.10)
  4. opening a new log.bin file 打开一个新的log.bin文件

The problem is that other processes are unaware, and are in fact continue to write to the old log file (which was renamed to log.bin.1). 问题是其他进程不知道,并且实际上仍在继续写入旧的日志文件(已重命名为log.bin.1)。

I can think of several solutions: 我可以想到几种解决方案:

  1. some sort of rpc to notify other processes to reopen the log (maybe even a singal). 某种rpc通知其他进程重新打开日志(甚至可能是单个)。 I don't particularly like it. 我不太喜欢
  2. have processes check the file length via the opened file stream, and somehow detect that the file was renamed under them and reopen log.bin file. 让进程通过打开的文件流检查文件长度,并以某种方式检测到文件在其下已重命名,然后重新打开log.bin文件。

None of those is very elegant in my opinion. 我认为这些都不是很优雅。

thoughts? 有什么想法吗? recommendations? 建议?

Your solution seems fine, but you should store an integer with inode of current logging file in shared memory (see stat(2) with stat.st_ino member). 您的解决方案看起来不错,但是您应该在共享内存中存储一​​个包含当前日志文件的inode的整数(请参阅带有stat.st_ino成员的stat(2) )。

This way, all process kept a local variable with the opened inode file. 这样,所有进程都使用打开的inode文件保留局部变量。

The shared var must be updated when rotating by only one process, and all other process are aware by checking a difference between the local inode and the shared inode. 仅通过一个进程旋转时,必须更新共享var,并且通过检查本地inode和共享inode之间的差异,可以识别所有其他进程。 It should induce a reopening. 它应该引起重新开放。

  1. What about opening the file by name each time before writing a log entry? 每次在写日志条目之前按名称打开文件怎么办?

    1. get shared memory lock 获取共享内存锁
    2. open file by name 按名称打开文件
    3. write log entry 写日志条目
    4. close file 关闭档案
    5. release lock 释放锁
  2. Or you could create a logging process, which receives log messages from the other processes and handles all the rotating transparently from them. 或者,您可以创建一个日志记录进程,该进程从其他进程接收日志消息并透明地处理所有轮换。

You don't say what language you're using but your processes should all log to a log process and the log process abstracts the file writing. 您没有说使用什么语言,但是您的进程应全部登录到日志进程,并且日志进程将文件写入抽象化。

Logging client1 ->  |
Logging client2 ->  |
Logging client3 ->  | Logging queue (with process lock) -> logging writer -> file roller
Logging client4 ->  |

You could copy log.bin to log.bin.1 and then truncate the log.bin file. 您可以 log.bin 复制到log.bin.1, 然后截断 log.bin文件。 So the problems can still write to the old file pointer, which is empty now. 因此,问题仍然可以写入旧文件指针,该文件指针现在为空。

See also man logrotate : 另见man logrotate

  copytruncate Truncate the original log file to zero size in place after cre‐ ating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncat‐ ing it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place. 

Since you're using shared memory, and if you know how many processes are using the log file. 由于您正在使用共享内存,因此您是否知道有多少进程正在使用日志文件。 You can create an array of flags in shared memory, telling each of the processes that the file has been rotated. 您可以在共享内存中创建一个标志数组,告诉每个进程文件已旋转。 Each process then resets the flag so that it doesn't re-open the file continuously. 然后,每个进程都会重置该标志,以使其不会连续重新打开文件。

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

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