特定时间间隔 C++ 上的读写日志
Read & write log on specific time interval c++
我想写入带有时间戳的日志文件。时间戳应表示从应用程序开始的时间间隔,如下所示:
1:此日志消息在启动应用程序 1 秒后到达
5:此日志消息在启动应用程序 5 秒后到达
然后我想在该确切的时间间隔内读取日志消息。就像在 1s 之后,我将阅读第一条消息,然后当 5s 通过时,我将阅读第二条消息。
有没有可以做到这一点的库?我找到了一些像easyloggingcpp这样的库,它可以使用时间戳保存日志文件。但时间戳是相应的时间。我也没有找到任何方法如何在特定的时间间隔内阅读消息。
有什么办法可以做到吗?
因此,您需要在生产者中有一个能够识别应用程序启动时间的日志记录类。
class Logger {
static std::chrono::steady_clock::time_point start; // program start
std::ofstream out; // log file stream
public:
Logger(const char *filename): out(filename) {}
void log(const char *msg) { // log function
std::chrono::steady_clock::time_point cur = std::chrono::steady_clock::now();
std::chrono::duration<double> d = cur - start; // delta time since program start
// prepend text message with delta time
out << int(d.count()) << " - " << msg << std::endl;
}
~Logger() {
out.close();
}
};
以下部分是一个定义规则定义,该定义应在程序中恰好出现一次。即使类的定义在包含文件中,也应该将其写入主源代码
// definition of static member
std::chrono::steady_clock::time_point Logger::start = std::chrono::steady_clock::now();
您可以简单地在生产者程序中使用它:
int main() {
Logger log("foo.log");
std::chrono::duration<int> d = std::chrono::duration<int>(1);
// sleep for 1 second
std::this_thread::sleep_for(d);
log.log("After 1s");
// sleep for 4 seconds more
d = std::chrono::duration<int>(4);
std::this_thread::sleep_for(d);
log.log("After 5s");
return 0;
}
然后,您需要一个读取器从日志文件中读取每一行,从开头提取延迟,并从最后一条消息开始计算延迟(从开始的延迟随着构造而增加(,并在这段时间内休眠:
int main() {
std::ifstream in("foo.log"); // log file input stream
// store program start time
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
std::string line;
while (std::getline(in, line)) { // read log file one line at a time
std::stringstream ss(line); // parse line to extract delay
int delay;
if (! (ss >> delay)) break;
std::chrono::duration<int> d(delay);
std::this_thread::sleep_until(start + d); // wait until approriate time
// message processing (here simple display on stdout)
std::cout << line << std::endl;
}
return 0;
}
您可以使用std::chrono库来实现时间目的。你基本上在代码的开头获取时间并将其保存在变量中。之后,您可以在需要时间间隔时获取当前时间,并找到以前和当前时间之间的差异,如下所示。
#include <iostream>
#include <chrono>
#include <ctime>
int main()
{
auto start = std::chrono::system_clock::now();
// Some time consuming operations ...
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "elapsed time: " << elapsed_seconds.count() << "sn";
// Some another time consuming operations ...
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "elapsed time: " << elapsed_seconds.count() << "sn";
}
对于日志消息传递,它只是写入文件。因此,您可以创建自定义Logger类并编写特定于它的解析器,以便按特定时间间隔读取消息。另一种选择是使用您所说的easyloggingcpp。您可以在此处找到具体示例
全局变量保证在运行 main 之前初始化。
所以首先创建一个全局const
变量app_start_time
用值初始化
const auto app_start_time = std::chrono::system_clock::now();
然后在log
函数中使用以下代码计算秒数:
auto time_since_start = std::chrono::system_clock::now() - app_start_time;
auto seconds_since_start= std::chrono::seconds(time_since_start).count();
我有一个简单的演示应用程序。我使用ctime
获取时间戳std::time(0)
。这段代码不应该被重用,它使用简单的队列(不是线程安全的(,只是为了让它变得简单演示。
#include <iostream> // std::cout
#include <thread> // std::thread
#include <cstdio> // printf, scanf, puts, NULL
#include <cstdlib> // srand, rand
#include <ctime> // time
#include <chrono> // std::chrono::seconds, std::this_thread::sleep_for
#include <queue> // std::ueue
std::queue<int> queue;
void producer() {
srand(time(NULL));
while (1) {
int message = rand();
queue.push(message);
int sleep = rand() % 5;
std::this_thread::sleep_for(std::chrono::seconds(sleep));
}
}
void consumer()
{
int start_time = std::time(0);
while(1) {
printf("waitingn");
while (queue.empty()); // busy waiting
int timestamp = std::time(0);
int message = queue.front();
int arrival_time_from_start = (timestamp - start_time);
queue.pop();
printf("message %d arrive at %d (unix timestamp), %d second after app start.n", message, timestamp, arrival_time_from_start);
}
}
int main()
{
std::thread first(producer);
std::thread second(consumer);
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
return 0;
}
生产者线程产生一些整数来queue
,然后等待随机秒 [0-5]。然后是消费线程,等待queue
填满。当queue
填满时,它会消耗(queue.pop()
(并使用其unix时间戳(自1970年1月1日以来的秒数(打印到屏幕上。
它将产生如下内容:
waiting
message 1611033160 arrive at 1527496314 (unix timestamp), 0 second after app start.
waiting
message 1055908354 arrive at 1527496318 (unix timestamp), 4 second after app start.
waiting
message 788236843 arrive at 1527496320 (unix timestamp), 6 second after app start.
waiting
message 1849353197 arrive at 1527496323 (unix timestamp), 9 second after app start.
waiting
message 62004690 arrive at 1527496326 (unix timestamp), 12 second after app start.
waiting
message 1668815337 arrive at 1527496326 (unix timestamp), 12 second after app start.
waiting
message 533376047 arrive at 1527496330 (unix timestamp), 16 second after app start.
- 用C++快速读写文件
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 在一个读写器队列中,我可以用volatile替换原子吗
- C++套接字对不读/写父/子
- 如何调试读写器锁的死锁?
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- Linux 挂载使用重新挂载以允许读写
- C++中读/写二进制文件
- 如何读/写或遍历 std::array 中的特定元素范围?
- 内存排序或读取-修改-写入操作,仅(读/写)内存顺序
- USB-HID 读/写(重叠)等待单个对象不返回C++
- 为什么使用_access时只读测试对读写文件有效
- Boost::Asio串行读/写打开:参数不正确
- 读/写 OpenMP 中的共享向量会减慢程序速度
- 谷歌测试读写同一文件失败
- Android USB 附件模式无法使用 libusb 与主机 PC 一起读/写
- 特定时间间隔 C++ 上的读写日志
- SQLite - C++中的多线程读写
- 如何读写Qt集合类