简体   繁体   English

C++ - 即使在突然断电的情况下,如何将应用程序日志写入磁盘

[英]C++ - How to make application-logs written to disk even in case of a sudden power down

A short background:简短的背景:

I'm developing an embedded Linux application on a drone.我正在无人机上开发嵌入式 Linux 应用程序。 In the last field test we had, the battery juice ran out without any warning during the flight.在我们进行的最后一次现场测试中,电池电量在飞行过程中没有任何警告就耗尽了。 The drone had a rough landing.这架无人机艰难着陆。 When I restarted it in the lab, out of 20 log files (*CSV and *TXT of different application modules), only 3 had data, and the rest were completely empty, but obviously, they had.当我在实验室重新启动它时,在 20 个日志文件(不同应用程序模块的 *CSV 和 *TXT)中,只有 3 个有数据,而 rest 完全是空的,但显然它们有。 to have data and lots of it, (14 minutes flight = 840 seconds, and at 50Hz frequency. we are expected to have 10ths of thousands of data lines in our logs).拥有大量数据(14 分钟飞行 = 840 秒,频率为 50Hz。我们的日志中预计会有千分之一的数据行)。

So I have 2 questions:所以我有两个问题:

  1. Is it possible that while some of the logs flushed every few seconds (or less - maybe every write command), other logs are kept in a big buffer that is being flushed to memory only on a clean power down or when the buffer is getting exhausted?是否有可能,虽然某些日志每隔几秒(或更少 - 可能是每个写入命令)刷新一次,但其他日志保存在一个大缓冲区中,仅在干净断电或缓冲区耗尽时才刷新到 memory ?

  2. Given that we are using C++, what is the best practice to make all logs being flushed more frequently to the disk (so in case of a sudden power down, I still have some logs to inspect), and still have as little as possible impact on performance?鉴于我们使用的是 C++,让所有日志更频繁地刷新到磁盘的最佳做法是什么(所以在突然断电的情况下,我仍然有一些日志要检查),并且仍然具有尽可能小的影响关于性能?

thanks谢谢

The fundamental issue here is your program, your language, your operating system, and your hardware may each be buffering writes in order to delay them until the most opportune time.这里的基本问题是您的程序、您的语言、您的操作系统和您的硬件可能都在缓冲写入,以便将它们延迟到最合适的时间。

Are you REALLY having performance problems with flushing each write?你真的有刷新每次写入的性能问题吗? Or is that just theoretical?或者这只是理论上的?

Use one or more of the following recommendations as appropriate to your situation.根据您的情况使用以下一项或多项建议。

  1. Optimize your logging.优化您的日志记录。 Do you really need to log that much?你真的需要记录那么多吗? Remove debugging stuff that should only be in there when you are doing development, not when doing testing or production work.删除仅在您进行开发而不是在进行测试或生产工作时应该存在的调试内容。 Wait for times when the processor isn't busy to flush queued logs.等待处理器不忙的时间刷新排队的日志。 Use a separate thread for logging (threads add too much hassle to be worth the effort unless there is no other way around the problem).使用单独的线程进行日志记录(线程增加了太多的麻烦而不值得付出努力,除非没有其他方法可以解决问题)。 Maybe write to syslog instead?也许改为写入系统日志? (I don't know if syslog has awesome log flushing capabilities or not). (我不知道 syslog 是否有很棒的日志刷新功能)。 Since the drone is in contact with a base station or controller, can you just log over the wireless connection, and have the actual disk storage of the logs not even being done in the drone?由于无人机与基站或controller接触,是否可以只通过无线连接登录,并且在无人机中甚至不进行日志的实际磁盘存储?
  2. If you have actually tried flushing every write (or every now and then) and it slowed your application down too much, make sure there isn't some other junk running on your Linux environment that is stealing CPU or adding disk read/writes and that you aren't even using.如果您实际上尝试刷新每次写入(或不时地)并且它使您的应用程序减慢了太多,请确保在您的 Linux 环境中没有运行其他垃圾,这些垃圾正在窃取 CPU 或添加磁盘读/写,并且你甚至没有使用。
  3. Always write a complete record (or multiple joined records) with a single function call.始终使用单个 function 调用写入完整记录(或多个连接记录)。 Don't write separate parts of the record with separate functions.不要使用单独的函数编写记录的单独部分。 If something fails you will end up with a partially written record.如果某些事情失败了,您最终会得到部分书面记录。 Combine all the elements of your record first, in memory, then write the entire thing, boom, done.首先在 memory 中组合您记录的所有元素,然后编写整个内容,繁荣,完成。 Linux writes seem to be atomic. Linux 写入似乎是原子的。 Once started, they will be fully done and nobody else will interrupt them BUT make sure you open the files in append mode to avoid confusion about where the writes will occur.一旦开始,它们将完全完成,没有其他人会打断它们,但请确保您以 append 模式打开文件,以避免混淆将发生写入的位置。 With append mode, a write will always be at the end of the file, even if someone else slips a write in before you do.使用 append 模式,写入将始终在文件末尾,即使其他人在您之前滑入写入。 Multiple writers does not sound like a problem you have to deal with.多个作家听起来不像是你必须处理的问题。
  4. Don't buffer in your application for speed (you may have other reasons).不要在您的应用程序中缓冲速度(您可能有其他原因)。 That's old fashioned crap probably taught to you by a professor whose knowledge is outdated.那是老派的废话,可能是知识过时的教授教给你的。 Your operating system probably has a write buffer already.您的操作系统可能已经有一个写缓冲区。 You don't need to do it yourself and in fact, that will cause a lot of problems if multiple processes need to share the file.你不需要自己做,事实上,如果多个进程需要共享文件,那会导致很多问题。
  5. Don't use 50 year old C functions from the 1970s like fwrite or the iostreams >> abominations (they are just proofs of concept that somehow got adapted as a standard).不要使用 1970 年代的 50 年历史的 C 函数,如 fwrite 或 iostreams >> 可憎(它们只是以某种方式被改编为标准的概念证明)。 They may do their own internal buffering.他们可能会做自己的内部缓冲。 Use the operating system write() function.使用操作系统 write() function。 If your OS is Linux, do "man 2 write".如果您的操作系统是 Linux,请执行“man 2 write”。 Of course, you have to open and close the files with the other OS-level functions too.当然,您也必须使用其他操作系统级别的功能打开和关闭文件。 Do "man 2 open".做“man 2 open”。 Thre are all sorts of options to control disk caching etc. You can open a file with the attribute O_DIRECT meaning, "ask the operating system to minimize caching" and O_DSYNC which means your write won't return until it's been fully flushed to disk.有各种各样的选项来控制磁盘缓存等。您可以打开一个带有属性 O_DIRECT 的文件,“要求操作系统最小化缓存”和 O_DSYNC,这意味着您的写入在完全刷新到磁盘之前不会返回。 This will bypass the OS level write buffer as much as possible.这将尽可能绕过操作系统级别的写入缓冲区。 It's up to you and what you require.这取决于您和您的要求。
  6. There are "async" functions sometimes available (do "man aio") where you don't have to wait for the write to complete.有时可以使用“异步”功能(执行“man aio”),您不必等待写入完成。 The operating system will manage those for you and at least keep up the best it can.操作系统将为您管理这些,并且至少保持最佳状态。 Even if it falls behind, as long as you write a full record at a time, it will minimize corruption if something goes wrong.即使它落后了,只要你一次写一个完整的记录,如果出现问题,它将最大限度地减少损坏。
  7. You want to use a "journaled" file system like Linux ext4 that doesn't actually append writes to the file until they are confirmed to have been fully written to disk.您想使用像 Linux ext4 这样的“日志式”文件系统,它实际上不会将 append 写入文件,直到它们被确认已完全写入磁盘。 And if something goes wrong, when the disk is remounted, it will repair itself (as best it can).如果出现问题,重新安装磁盘时,它会自行修复(尽其所能)。

I had to write an application with file integrity and I did need to buffer writes (because an event during processing could tell the application "don't write those queued up writes, we change our mind").我必须编写一个具有文件完整性的应用程序,并且我确实需要缓冲写入(因为处理期间的事件可以告诉应用程序“不要写那些排队的写入,我们改变主意”)。 To avoid complications everything is combined into a single string then written with a single write() function when the time comes.为避免复杂性,所有内容都组合成一个字符串,然后在时机成熟时使用单个 write() function 写入。 I've never had a corrupt file even when the app was shutdown will kill -9.即使应用程序关闭会杀死-9,我也从来没有损坏过文件。 HOWEVER, it's never had power failures.但是,它从未出现过电源故障。 (UPS backed up). (UPS 备份)。

If you are working with a very underpowered platform, then a lot of the above may not be useful.如果您正在使用一个功能非常不足的平台,那么上面的很多内容可能没有用。 Sorry, there wasn't enough detail in what you had to work with.抱歉,您必须处理的内容不够详细。

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

相关问题 如何在用C ++编写的控制台应用程序中制作加载动画? - How to make a loading animation in Console Application written in C++? 在未处理的异常情况下如何确保转储文件由C ++应用程序编写 - How to ensure a dump file is written by C++ application in case of unhandled exception 我怎样才能找到可以写为 2 的幂、3 的幂和 5 的幂之和的整数? C++ - How can i find the integers that can be written as a sum of a power of 2, a power of 3 and a power of 5? C++ 如何保护用C ++ .NET编写的应用程序 - How to protect application written in C++ .NET 如何为我用 c 编写的队列代码制作测试用例? - How to make test case for my queue code written in c? 如何清除用 C++ 编写的控制台应用程序中的屏幕? - How do you clear the screen in a console application written in C++? Linux上C ++应用程序的磁盘IO分析器 - Disk IO profiler for a C++ application on Linux 配置用C ++编写的现有应用程序 - configuring an existing application written in C++ idl 中 COM 的 C++ 公开属性“突然”显示为小写 - C++ Exposed property for COM in idl is showing as lower case "all of a sudden" 在使用Borland C ++编程时突然关闭窗口,然后出现蓝屏! - Sudden windows shut down during programming with Borland C++ followed by a blue screen!
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM