阅读&在特定时间间隔c ++上写日志

时间:2018-05-28 07:48:16

标签: c++ c++11

我想用时间戳写入日志文件。时间戳应表示从应用程序开始的时间间隔,如下所示:

  

1:此日志消息在启动应用程序1秒后到达

     

5:此日志消息在启动应用程序5秒后到达

然后我想在那个确切的时间间隔内读取日志消息。就像1s之后我将读取第一条消息,然后当5s通过时,我将读取第二条消息。

有没有我能做到的图书馆?我找到了像easyloggingcpp这样的库,可以使用时间戳保存日志文件。但时间戳是相应的时间。此外,我还没有找到任何方式如何在特定的时间间隔内阅读消息。

我有什么方法可以做到吗?

4 个答案:

答案 0 :(得分:1)

保证在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();

答案 1 :(得分:1)

您可以将 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() << "s\n";

    // 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() << "s\n";

}

对于日志消息传递,它只是写入文件。因此,您可以创建自定义 Logger 类并编写特定于其的解析器,以便在特定时间间隔内读取消息。如你所说,另一种选择是使用easyloggingcpp。您可以找到具体示例here

答案 2 :(得分:1)

我有一个简单的演示应用程序。我使用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("waiting\n");

    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.

答案 3 :(得分:1)

因此,您需要生产者中的日志类,以了解应用程序的开始时间。

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;
}