Как просматривать логи приложения в C++ без графического интерфейса (GUI)?

Ответ

Да, конечно. В C++ логи обычно пишутся в стандартные потоки вывода (std::cout, std::cerr) или в файлы. Для просмотра используются консольные утилиты.

1. Запись логов в C++:

#include <iostream>
#include <fstream>
#include <chrono>
#include <iomanip>

void log_to_file(const std::string& message) {
    std::ofstream log_file("app.log", std::ios::app); // Открываем для добавления
    if (log_file.is_open()) {
        auto now = std::chrono::system_clock::now();
        auto now_time = std::chrono::system_clock::to_time_t(now);
        log_file << std::put_time(std::localtime(&now_time), "%Y-%m-%d %H:%M:%S")
                 << " | " << message << std::endl;
    }
}

int main() {
    std::cout << "Информационное сообщениеn"; // stdout
    std::cerr << "Сообщение об ошибкеn";       // stderr
    log_to_file("Запуск приложения");
    return 0;
}

2. Просмотр логов в Linux/Unix:

  • cat app.log – вывести весь файл.
  • tail -f app.log – выводить новые записи в реальном времени (слежение).
  • grep "ERROR" app.log – фильтрация по ключевому слову.
  • less app.log – постраничный просмотр с поиском.

3. Перенаправление потоков при запуске:

# Все выводы (stdout и stderr) в файл
./my_app > output.log 2>&1

# stdout в один файл, stderr в другой
./my_app > stdout.log 2> stderr.log

# stdout в файл, stderr в консоль
./my_app > output.log

4. Использование системного журнала (syslog):

#include <syslog.h>

int main() {
    openlog("my_cpp_app", LOG_PID | LOG_CONS, LOG_USER);
    syslog(LOG_INFO, "Приложение запущено (PID = %d)", getpid());
    syslog(LOG_ERR, "Критическая ошибка!");
    closelog();
    return 0;
}

Просмотр: journalctl -t my_cpp_app или tail -f /var/log/syslog.

Ответ 18+ 🔞

А, ну вот, про логи. Тема, в принципе, простая, но если не знать, как подступиться, можно охуеть от количества вариантов. Сейчас разложу по полочкам, чтобы ты не бздел.

1. Как эти логи вообще писать?

Ну, самый простой способ — это тупо лить всё в консоль, через cout и cerr. Это как кричать в пустоту, но иногда хватает. А если хочешь по-взрослому, чтобы всё в файлик аккуратненько падало, вот тебе пример, который не стыдно показать.

#include <iostream>
#include <fstream>
#include <chrono>
#include <iomanip>

void log_to_file(const std::string& message) {
    std::ofstream log_file("app.log", std::ios::app); // Открываем для добавления
    if (log_file.is_open()) {
        auto now = std::chrono::system_clock::now();
        auto now_time = std::chrono::system_clock::to_time_t(now);
        log_file << std::put_time(std::localtime(&now_time), "%Y-%m-%d %H:%M:%S")
                 << " | " << message << std::endl;
    }
}

int main() {
    std::cout << "Информационное сообщениеn"; // stdout
    std::cerr << "Сообщение об ошибкеn";       // stderr
    log_to_file("Запуск приложения");
    return 0;
}

Видишь? Всё чётко, с таймстампами. Теперь у тебя не просто «что-то упало», а «что-то упало в 14:30, и я знаю, что именно».

2. Как потом это говно смотреть?

Тут, чувак, вся мощь консоли тебе в руки. Если ты на Линуксе, то у тебя овердохуища инструментов.

  • cat app.log – вывалит весь файл тебе в терминал. Если логов немного — ок. Если много — готовься к скроллу до потери пульса.
  • tail -f app.log – вот это магия. Команда показывает конец файла и висит, выводя каждую новую строчку в реальном времени. Пока ты смотришь, как логи летят, чувствуешь себя хакером из 90-х, ёпта. Идеально для отладки.
  • grep "ERROR" app.log – твой лучший друг. Не хочешь читать тонну инфы — отфильтруй только ошибки. Вместо «ERROR» можешь писать что угодно.
  • less app.log – для ценителей. Постраничный просмотр, можно искать по тексту. Как будто читаешь книгу, только про твои косяки.

3. А если я запускаю программу и хочу сразу всё в файл?

Да без проблем, это же шелл умеет. Запоминай эти заклинания:

# Всё подряд — и обычный вывод, и ошибки — летит в один файл. 2>&1 — это магия перенаправления stderr в stdout.
./my_app > output.log 2>&1

# А вот это хитрая жопа: нормальные сообщения в один файл, ошибки — в другой. Удобно, когда ищешь иголку в стоге сена.
./my_app > stdout.log 2> stderr.log

# А можно ошибки оставить в консоли, чтобы сразу видеть, а всё остальное — в файл. Так часто делают.
./my_app > output.log

4. Ну и на десерт — системный журнал (syslog).

Это когда твои логи не в отдельном файлике валяются, а в общей куче системных сообщений. Выглядит солиднее.

#include <syslog.h>

int main() {
    openlog("my_cpp_app", LOG_PID | LOG_CONS, LOG_USER);
    syslog(LOG_INFO, "Приложение запущено (PID = %d)", getpid());
    syslog(LOG_ERR, "Критическая ошибка!");
    closelog();
    return 0;
}

А смотреть потом это дело можно через journalctl -t my_cpp_app или заглянув в /var/log/syslog. Выглядит профессионально, но если система накроется медным тазом, есть риск потерять логи вместе с ней. Так что думай, где что применять.

Вот и вся наука. Главное — начать логировать, а там уже по обстоятельствам. А то бывает, программа падает, а ты сидишь и гадаешь, какого хуя, а в логах пусто.