像 Log4j 这样的日志记录框架如何保证日志语句的顺序?

How do logging frameworks like Log4j guarantee log statement ordering?

这个问题困扰了我一段时间,像 Log4j 这样的流行日志记录框架如何允许并发、异步记录顺序保证日志顺序没有性能瓶颈,即如果日志statement L1 was invoked before log statement L2, L1 保证在 L2.

之前的日志文件中

我知道 Log4j2 使用环形缓冲区和序列号,但解决问题的方式仍然不直观。

任何人都可以给出直观的解释或向我指出做同样事情的资源吗?

这完全取决于您所说的“记录顺序”是什么意思。在谈论单个线程时,记录顺序会被保留,因为每个记录调用都会导致写入。

异步记录时,每个日志事件都按照接收顺序添加到队列中,并按 First-in/First-out 顺序处理,无论它是如何到达那里的。这真的不是很有挑战性,因为编写器是单线程的。

但是,如果您谈论的是跨线程的记录顺序,那是永远无法保证的——即使是同步记录——因为它不能保证。线程 1 可以在线程 2 之前开始记录,但线程 2 可以在线程 1 之前的写入中到达同步点。同样,将事件添加到队列时也会发生同样的情况。在日志记录方法中锁定日志记录调用将保持顺序,但几乎没有任何好处,而且会带来灾难性的性能后果。

在多线程环境中,您完全有可能看到时间戳乱序的日志记录事件,因为线程 1 解析了时间戳,被线程 2 中断,线程 2 随后解析了时间戳并记录了事件。但是,如果您将日志写入诸如 ElasticSearch 之类的东西,您将永远不会注意到,因为它按 timestmap 对它们进行排序。