С какой точностью обычно работает логирование временных меток в C++?

Ответ

Точность временных меток в логах зависит от используемых API и требований системы. В современном C++ для этого чаще всего применяют <chrono>.

Типичные уровни точности:

  1. Секунды/Миллисекунды: Достаточно для логирования событий приложения (запросы пользователя, этапы работы). Достигается с помощью std::chrono::system_clock.
  2. Микросекунды/Наносекунды: Требуется для профилирования, high-frequency trading (HFT) или embedded-систем. Используется std::chrono::high_resolution_clock или платформо-специфичные вызовы.

Практический пример с <chrono>:

#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>

std::string get_current_timestamp() {
    // Получаем текущее время с точностью до микросекунд
    auto now = std::chrono::system_clock::now();
    auto now_time_t = std::chrono::system_clock::to_time_t(now);
    auto now_ms = std::chrono::duration_cast<std::chrono::microseconds>(
                    now.time_since_epoch()) % 1000000;

    std::stringstream ss;
    ss << std::put_time(std::localtime(&now_time_t), "%Y-%m-%d %H:%M:%S.")
       << std::setfill('0') << std::setw(6) << now_ms.count();
    return ss.str();
}

int main() {
    std::cout << "[" << get_current_timestamp() << "] Application started.n";
    // ... выполнение работы
    std::cout << "[" << get_current_timestamp() << "] Task completed.n";
    return 0;
}
// Пример вывода: [2023-10-26 14:30:15.123456] Application started.

Важные замечания:

  • std::chrono::high_resolution_clock может быть псевдонимом для system_clock или steady_clock, его реальное разрешение зависит от реализации компилятора и ОС.
  • Для максимальной точности и минимальных накладных расходов в performance-critical коде иногда приходится использовать платформо-специфичные API, такие как clock_gettime(CLOCK_MONOTONIC, ...) на Linux или QueryPerformanceCounter на Windows, и затем интегрировать их в C++-код.

Ответ 18+ 🔞

А, ну это ж про временные метки в логах! Ёпта, тема-то какая житейская, но тут столько подводных камней, что овердохуища просто. Слушай, как есть.

Вот представь себе: пишешь ты логи, а там время указано хуй с горы — "сегодня, где-то днём". Ну и кому такой лог нужен, а? Это ж пизда рулю, а не отладка. Так что точность — это святое, но и перебарщивать тоже не надо.

Смотри, какие вообще бывают уровни точности, чтобы не облажаться:

  1. Секунды/Миллисекунды. Это для большинства нормальных приложений — пользователь кнопку нажал, запрос ушёл, ответ пришёл. Тут std::chrono::system_clock — твой лучший друг, всё покажет. Хуй с ним, что до микросекунд, главное — порядок событий понятен.
  2. Микросекунды/Наносекунды. А вот это уже серьёзный разговор. Это когда твоё приложение торгует акциями или управляет станком, где каждая микросекунда на счету. Тут уже std::chrono::high_resolution_clock в дело идёт, а то и вовсе нативные системные вызовы, потому что доверия ебать ноль к абстракциям, когда речь о такой точности.

Держи рабочий пример, чтоб не быть голословным. Смотри, как это обычно выглядит в коде:

#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>

std::string get_current_timestamp() {
    // Хватаем текущее время, да поточнее, до микросекунд
    auto now = std::chrono::system_clock::now();
    auto now_time_t = std::chrono::system_clock::to_time_t(now);
    auto now_ms = std::chrono::duration_cast<std::chrono::microseconds>(
                    now.time_since_epoch()) % 1000000;

    std::stringstream ss;
    ss << std::put_time(std::localtime(&now_time_t), "%Y-%m-%d %H:%M:%S.")
       << std::setfill('0') << std::setw(6) << now_ms.count();
    return ss.str();
}

int main() {
    std::cout << "[" << get_current_timestamp() << "] Application started.n";
    // ... тут какая-то полезная работа происходит
    std::cout << "[" << get_current_timestamp() << "] Task completed.n";
    return 0;
}
// На выходе будет что-то вроде: [2023-10-26 14:30:15.123456] Application started.

Но вот тут, чувак, внимание, важный момент! Не обольщайся.

  • Этот std::chrono::high_resolution_clock — он хитрая жопа. В одном компиляторе он может давать наносекунды, а в другом быть такой же, как обычный system_clock. Так что если тебе реально надо выжимать максимум, подозрение ебать чувствую к стандартным библиотекам.
  • Для самого жёсткого перформанс-критичного кода (типа HFT или embedded) часто приходится лезть в системное нутро. На Linux это clock_gettime(CLOCK_MONOTONIC, ...), на Windows — QueryPerformanceCounter. Да, это боль, да, это не кроссплатформенно, но зато ты будешь точно знать, что твои метки — не манда с ушами, а реальное время. Просто потом эту нативную хрень нужно аккуратно завернуть в C++, чтобы не облажаться с типами.