什么';在C语言编写的服务器中,最有效的文件记录是什么?

什么';在C语言编写的服务器中,最有效的文件记录是什么?,c,logging,C,Logging,我想知道在用C编写的服务器中,最有效的文件日志记录策略是什么 我可以看到以下选项: fopen()追加数据,然后fwrite()将数据写入一个时间段,比如说1小时,然后fclose() 缓存数据,然后偶尔打开()追加写入()和关闭() 为什么不在事件发生时直接记录数据 如果服务器崩溃,您希望在服务器崩溃时检索这些数据。如果您每小时只刷新一次缓冲日志,您将错过有趣的日志 文件流通常由操作系统缓冲 如果你相信它会使你的服务器速度慢,因为硬盘写,你可能会考虑登录到一个单独的线程中。但我不知道这是

我想知道在用C编写的服务器中,最有效的文件日志记录策略是什么

我可以看到以下选项:

  • fopen()追加数据,然后fwrite()将数据写入一个时间段,比如说1小时,然后fclose()

  • 缓存数据,然后偶尔打开()追加写入()和关闭()


为什么不在事件发生时直接记录数据

  • 如果服务器崩溃,您希望在服务器崩溃时检索这些数据。如果您每小时只刷新一次缓冲日志,您将错过有趣的日志
  • 文件流通常由操作系统缓冲

如果你相信它会使你的服务器速度慢,因为硬盘写,你可能会考虑登录到一个单独的线程中。但我不知道这是否是问题所在。过早优化?

为什么不在事件发生时直接记录数据

  • 如果服务器崩溃,您希望在服务器崩溃时检索这些数据。如果您每小时只刷新一次缓冲日志,您将错过有趣的日志
  • 文件流通常由操作系统缓冲

如果你相信它会使你的服务器速度慢,因为硬盘写,你可能会考虑登录到一个单独的线程中。但我不知道这是否是问题所在。过早优化?

写入系统日志最慢的部分是对物理磁盘的输出操作


缓冲和校验日志记录是必要的,以确保不会丢失任何日志数据,并且日志数据在事后不会被篡改。

写入系统日志最慢的部分是对物理磁盘的输出操作


缓冲和校验日志记录是必要的,以确保您不会丢失任何日志数据,并且日志数据在事件发生后不会被篡改。

使用线程通常是一个很好的解决方案,我们采用了它并获得了有趣的结果。
需要记录日志的主线程准备日志字符串并将其传递给第二个线程。为了给第二个线程提供数据,我们使用一个无锁队列+一个循环内存,以最小化分配/空闲和等待时间。
secon线程等待无锁队列可用。当它发现有一些工作要做时,将使用无锁队列的新插槽并记录数据。
使用单独的线程可以节省大量时间

在我们决定使用secon线程之后,我们不得不面对另一个问题。同一程序(全文搜索引擎)的多个ISTANCE必须一起记录在同一个文件上,以便在服务器的每个实例之间定期共享资源。
我们可以决定使用信号量或其他同步方法,但我们找到了另一种解决方案:第二个线程向本地日志服务器发送UDP数据包,该服务器侦听已知端口。此服务器读取每条消息并将其记录到文件中(实际上,在写入文件时,服务器是唯一拥有该文件的服务器)。UDP套接字本身授予日志序列化

我已经使用这个解决方案10多年了,从来没有丢失过日志文件的一行,使用第二个线程,我还为每个操作节省了大量时间(我们用于记录服务器收到的任何单个命令的大量信息)


HTH

使用线程通常是一个很好的解决方案,我们采用了它并获得了有趣的结果。
需要记录日志的主线程准备日志字符串并将其传递给第二个线程。为了给第二个线程提供数据,我们使用一个无锁队列+一个循环内存,以最小化分配/空闲和等待时间。
secon线程等待无锁队列可用。当它发现有一些工作要做时,将使用无锁队列的新插槽并记录数据。
使用单独的线程可以节省大量时间

在我们决定使用secon线程之后,我们不得不面对另一个问题。同一程序(全文搜索引擎)的多个ISTANCE必须一起记录在同一个文件上,以便在服务器的每个实例之间定期共享资源。
我们可以决定使用信号量或其他同步方法,但我们找到了另一种解决方案:第二个线程向本地日志服务器发送UDP数据包,该服务器侦听已知端口。此服务器读取每条消息并将其记录到文件中(实际上,在写入文件时,服务器是唯一拥有该文件的服务器)。UDP套接字本身授予日志序列化

我已经使用这个解决方案10多年了,从来没有丢失过日志文件的一行,使用第二个线程,我还为每个操作节省了大量时间(我们用于记录服务器收到的任何单个命令的大量信息)


HTH

除非您已经进行了基准测试并发现这是一个瓶颈,否则请使用
fopen
fprintf
。没有理由把你自己的复杂缓冲层放在上面,除非<代码> STDIO 对你来说太慢了(如果它太慢了,你可能会考虑是否重新考虑你的服务器正在运行的OS/C库)。除非你已经标杆并发现它是一个瓶颈,使用<代码> fOpen< /COD>和<代码> fPrPtf。没有理由把你自己的复杂缓冲层放在上面,除非<代码> STDIO 对你来说太慢了(如果它太慢了,你可能会考虑是否重新考虑你的服务器正在运行的OS/C库)。它是将每个数据包写入()还是收集N个数据包,然后将它们作为一个大容量写入?它经常旋转日志文件,它什么时候打开/关闭它?如果你的目标平台是Windows,你喜欢这里提到的延迟方法,你应该考虑利用OutuxDebug()和DbgView()。否则,我建议追加到文件,并在每次调用时刷新