Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/newyaroslav/log-it-cpp

LogIt++ is a flexible and versatile C++ logging library with support for various backends and stream-based output.
https://github.com/newyaroslav/log-it-cpp

cpp cpp11 log logger logger-backend logger-interface logger-middleware logging logs

Last synced: 9 days ago
JSON representation

LogIt++ is a flexible and versatile C++ logging library with support for various backends and stream-based output.

Awesome Lists containing this project

README

        

# LogIt++ Library
![LogIt++ Logo](docs/logo-640x320.png)

## Введение

**LogIt++** — это гибкая и универсальная библиотека логирования на C++, которая поддерживает различные бэкенды и потоковый вывод. Она предоставляет простой в использовании интерфейс для логирования сообщений с разными уровнями важности и позволяет настраивать форматы и назначения логов.

Библиотека сочетает простоту макросов для логирования, аналогичную **IceCream-Cpp**, и возможности настройки бэкендов и форматов логов, как в **spdlog**. LogIt++ полностью совместим с `C++11`.

## Возможности

- **Гибкое форматирование логов**: Настраивайте форматы сообщений логов с помощью шаблонов.
- **Логирование с использованием макросов**: Легко логируйте переменные и сообщения с помощью макросов.
- **Поддержка нескольких бэкендов**: Настройка логгеров для вывода в консоль, файлы, серверы или базы данных.
- **Асинхронное логирование**: Повышение производительности за счет логирования в асинхронном режиме.
- **Потоковое логирование**: Используйте операторы потоков для сложных сообщений.
- **Потокобезопасность**: Разработана для многопоточных приложений.
- **Расширяемость**: Создавайте собственные логгеры и форматтеры для удовлетворения ваших потребностей.

## Использование

Ниже приведен простой пример использования LogIt++ в вашем приложении:

```cpp
#define LOGIT_SHORT_NAME
#include

int main() {
// Инициализация логгера с выводом в консоль по умолчанию
LOGIT_ADD_CONSOLE_DEFAULT();

float a = 123.456f;
int b = 789;
int c = 899;
const char* someStr = "Hello, World!";

// Базовое логирование с использованием макросов
LOG_INFO("Starting the application");
LOG_DEBUG("Variable values", a, b);
LOG_WARN("This is a warning message");

// Логирование с форматированием
LOG_PRINTF_INFO("Formatted log: value of a = %.2f", a);
LOG_FORMAT_WARN("%.4d", b, c);

// Логирование ошибок и фатальных ошибок
LOG_ERROR("An error occurred", b);
LOG_FATAL("Fatal error. Terminating application.");

// Условное логирование
LOG_ERROR_IF(b < 0, "Value of b is negative");
LOG_WARN_IF(a > 100, "Value of a exceeds 100");

// Потоковое логирование с использованием коротких и длинных макросов
LOG_S_INFO() << "Logging a float: " << a << ", and an int: " << b;
LOG_S_ERROR() << "Error occurred in the system";
LOGIT_STREAM_WARN() << "Warning: potential issue detected with value: " << someStr;

// Использование LOGIT_TRACE для трассировки выполнения функций
LOGIT_TRACE0(); // Trace without arguments
LOG_PRINT_TRACE("Entering main function with variable a =", a);

// Ожидание завершения всех асинхронных операций логирования
LOGIT_WAIT();

return 0;
}
```

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

## Флаги форматирования сообщений

`LogIt++` поддерживает настраиваемое форматирование сообщений лога с использованием флагов форматирования. Вы можете задать, как должно выглядеть каждое сообщение лога, используя заполнители для различных данных, таких как временная метка, уровень лога, имя файла, имя функции и сообщение.

Ниже приведен список поддерживаемых флагов форматирования:

- *Флаги форматирования даты и времени*:

- `%Y`: Год (например, 2024)
- `%m`: Месяц (01-12)
- `%d`: День месяца (01-31)
- `%H`: Час (00-23)
- `%M`: Минута (00-59)
- `%S`: Секунда (00-59)
- `%e`: Миллисекунда (000-999)
- `%C`: Двузначный год (например, 24 для 2024 года)
- `%c`: Полная дата и время (например, Пн Окт 4 12:45:30 2024)
- `%D`: Короткая дата (например, 04/10/24)
- `%T`, `%X`: Время в формате ISO 8601 (например, 12:45:30)
- `%F`: Дата в формате ISO 8601 (например, 2024-10-04)
- `%s`, `%E`: Unix-временная метка в секундах
- `%ms`: Unix-временная метка в миллисекундах
- `%b`: Сокращенное название месяца (например, Янв)
- `%B`: Полное название месяца (например, Январь)
- `%a`: Сокращенное название дня недели (например, Пн)
- `%A`: Полное название дня недели (например, Понедельник)

- *Флаги уровня логирования*:

- `%l`: Полный уровень лога (например, INFO, ERROR)
- `%L`: Сокращенный уровень лога (например, I для INFO, E для ERROR)

- *Флаги для файла и функции*:

- `%f`: Имя исходного файла
- `%g`: Полный путь к файлу
- `%#`: Номер строки
- `%!`: Имя функции

- *Флаги потоков*:

- `%t`: Идентификатор потока

- *Флаги цвета*:

- `%^`: Начало цветового форматирования
- `%$`: Конец цветового форматирования
- `%SC`: Начало удаления цветовых кодов (Strip Color)
- `%EC`: Конец удаления цветовых кодов (End Color)

- *Флаги сообщения*:

- `%v`: Содержимое сообщения лога

## Укороченные макросы для логирования

`LogIt++` предоставляет укороченные версии макросов для логирования, когда определён флаг `LOGIT_SHORT_NAME`. Эти макросы позволяют лаконично логировать сообщения на разных уровнях, включая стандартное и потоковое логирование.

### Доступные макросы для уровня TRACE:

- Основное логирование:

- `LOG_T(...)`: Регистрирует сообщение уровня TRACE.
- `LOG_T0()`: Регистрирует сообщение уровня TRACE без аргументов.
- `LOG_0T()`: Псевдоним для `LOG_T0()`.
- `LOG_0_T()`: Псевдоним для `LOG_T0()`.
- `LOG_T_NOARGS()`: Псевдоним для `LOG_T0()`.
- `LOG_NOARGS_T()`: Псевдоним для `LOG_T0()`.

- Логирование с форматированием:

- `LOG_TF(fmt, ...)`: Регистрирует отформатированное сообщение уровня TRACE с использованием строк формата.
- `LOG_FT(fmt, ...)``: Псевдоним для `LOG_TF(fmt, ...)`.
- `LOG_T_PRINT(...)`: Регистрирует сообщение уровня TRACE, печатая каждый аргумент.
- `LOG_PRINT_T(...)`: Псевдоним для `LOG_T_PRINT(...)`.
- `LOG_T_PRINTF(fmt, ...)`: Регистрирует отформатированное сообщение уровня TRACE с использованием форматирования в стиле printf.
- `LOG_PRINTF_T(fmt, ...)`: Псевдоним для `LOG_T_PRINTF(fmt, ...)`.
- `LOG_TP(...)`: Псевдоним для `LOG_T_PRINT(...)`.
- `LOG_PT(...)`: Псевдоним для `LOG_T_PRINT(...)`.
- `LOG_TPF(fmt, ...)`: Псевдоним для `LOG_T_PRINTF(fmt, ...)`.
- `LOG_PFT(fmt, ...)`: Псевдоним для `LOG_T_PRINTF(fmt, ...)`.

- Альтернативные макросы уровня `TRACE`:

- `LOG_TRACE(...)`: Регистрирует сообщение уровня TRACE (то же, что и `LOG_T(...)`).
- `LOG_TRACE0()`: Регистрирует сообщение уровня TRACE без аргументов (то же, что и `LOG_T0()`).
- `LOG_0TRACE()`: Псевдоним для `LOG_TRACE0()`.
- `LOG_0_TRACE()`: Псевдоним для `LOG_TRACE0()`.
- `LOG_TRACE_NOARGS()`: Регистрирует сообщение уровня TRACE без аргументов (то же, что и `LOG_T_NOARGS()`).
- `LOG_NOARGS_TRACE()`: Псевдоним для `LOG_TRACE_NOARGS()`.
- `LOG_TRACEF(fmt, ...)`: Регистрирует отформатированное сообщение уровня TRACE (то же, что и `LOG_TF(fmt, ...)`).
- `LOG_FTRACE(fmt, ...)`: Псевдоним для `LOG_TRACEF(fmt, ...)`.
- `LOG_TRACE_PRINT(...)`: Регистрирует сообщение уровня TRACE, печатая каждый аргумент (то же, что и `LOG_T_PRINT(...)`).
- `LOG_PRINT_TRACE(...)`: Псевдоним для `LOG_TRACE_PRINT(...)`.
- `LOG_TRACE_PRINTF(fmt, ...)`: Регистрирует отформатированное сообщение уровня TRACE с использованием форматирования в стиле printf (так же, как `LOG_T_PRINTF(fmt, ...)`).
- `LOG_PRINTF_TRACE(fmt, ...)`: Псевдоним для `LOG_TRACE_PRINTF(fmt, ...)`.

Эти макросы обеспечивают гибкость и удобство при регистрации сообщений на уровне TRACE. Они позволяют выбирать между различными стилями регистрации, такими как стандартная регистрация, форматированная регистрация и печать каждого аргумента отдельно.

**Примечание**: Аналогичные макросы доступны для других уровней журнала — **INFO** (`LOG_I`, `LOG_INFO`), **DEBUG** (`LOG_D`, `LOG_DEBUG`), **WARN** (`LOG_W`, `LOG_WARN`), **ERROR** (`LOG_E`, `LOG_ERROR`) и **FATAL** (`LOG_F`, `LOG_FATAL`). Соглашения об именовании одинаковы для всех уровней, вам нужно только заменить букву уровня или слово в имени макроса.

- Пример:

```cpp
LOG_T("Trace message using short macro");
LOG_TF("%.4d", 999);
LOG_T_PRINT("Printing trace message with multiple variables: ", var1, var2);
LOG_TRACE("Trace message (alias for LOG_T)");
LOG_TRACE_PRINTF("Formatted trace: value = %d", value);
```

## Конфигурационные макросы

LogIt++ предоставляет несколько макросов, которые позволяют настраивать библиотеку под ваши нужды. Ниже приведены доступные конфигурационные макросы:

- **LOGIT_BASE_PATH**: Определяет базовый путь, используемый для файлов логов. Если `LOGIT_BASE_PATH` не определен или пуст (`{}`), будет использоваться полный путь из переменной `__FILE__`. Вы можете переопределить это, указав собственный базовый путь для логов.

```cpp
#define LOGIT_BASE_PATH "/path/to/your/project"
```

- **LOGIT_DEFAULT_COLOR**: Определяет цвет консоли по умолчанию. Если `LOGIT_DEFAULT_COLOR` не определен, по умолчанию используется `TextColor::LightGray`. Вы можете установить собственный цвет текста для консоли, переопределив этот макрос.

```cpp
#define LOGIT_DEFAULT_COLOR TextColor::Green
```

- **LOGIT_CURRENT_TIMESTAMP_MS**: Макрос для получения текущей временной метки в миллисекундах. По умолчанию используется `std::chrono` для получения метки времени. Вы можете переопределить этот макрос, чтобы использовать собственную функцию получения времени.

```cpp
#define LOGIT_CURRENT_TIMESTAMP_MS() my_custom_timestamp_function()
```

- **LOGIT_CONSOLE_PATTERN**: Определяет шаблон лога для вывода в консоль. Этот шаблон контролирует формат сообщений, отправляемых в консоль, включая временную метку, сообщение и цвет. Если `LOGIT_CONSOLE_PATTERN` не определен, он по умолчанию установлен на `%H:%M:%S.%e | %^%v%$`.

```cpp
#define LOGIT_CONSOLE_PATTERN "%H:%M:%S.%e | %^%v%$"
```

- **LOGIT_FILE_LOGGER_PATH**: Определяет путь к каталогу для логов. Если `LOGIT_FILE_LOGGER_PATH` не определен, по умолчанию используется *"data/logs"*. Вы можете задать этот путь для управления тем, где будут храниться логи.

```cpp
#define LOGIT_FILE_LOGGER_PATH "/custom/log/directory"
```

- **LOGIT_FILE_LOGGER_AUTO_DELETE_DAYS**: Определяет количество дней, по истечении которых старые файлы логов будут удалены. Если `LOGIT_FILE_LOGGER_AUTO_DELETE_DAYS` не определен, по умолчанию используется `30` дней. Вы можете задать это значение для управления политикой хранения логов.

```cpp
#define LOGIT_FILE_LOGGER_AUTO_DELETE_DAYS 60 // Хранить логи 60 дней
```

- **LOGIT_FILE_LOGGER_PATTERN**: Определяет шаблон лога для файловых логгеров. Этот шаблон контролирует формат сообщений, записываемых в файлы логов, включая временную метку, имя файла, номер строки, имя функции и информацию о потоке. Если `LOGIT_FILE_LOGGER_PATTERN` не определен, используется по умолчанию `[%Y-%m-%d %H:%M:%S.%e] [%ffn:%#] [%!] [thread:%t] [%l] %SC%v`.

```cpp
#define LOGIT_FILE_LOGGER_PATTERN "[%Y-%m-%d %H:%M:%S.%e] [%l] %SC%v"
```

- **LOGIT_UNIQUE_FILE_LOGGER_PATH**: Определяет путь по умолчанию для уникальных файлов логов. Если `LOGIT_UNIQUE_FILE_LOGGER_PATH` не определен, используется *"data/logs/unique_logs"*. Вы можете указать собственный путь для уникальных файлов логов.

```cpp
#define LOGIT_UNIQUE_FILE_LOGGER_PATH "/custom/unique/log/directory"
```

- **LOGIT_UNIQUE_FILE_LOGGER_PATTERN**: Определяет шаблон лога для уникальных файлов логов. Если `LOGIT_UNIQUE_FILE_LOGGER_PATTERN` не определен, по умолчанию используется `"%v"`. Вы можете настроить этот шаблон для управления форматом сообщений в уникальных файлах.

```cpp
#define LOGIT_UNIQUE_FILE_LOGGER_PATTERN "%v"
```

- **LOGIT_UNIQUE_FILE_LOGGER_HASH_LENGTH**: Определяет длину хеша, используемого в уникальных именах файлов логов. Если `LOGIT_UNIQUE_FILE_LOGGER_HASH_LENGTH` не определен, по умолчанию используется `8` символов. Это обеспечивает уникальные имена файлов для каждого лога.

```cpp
#define LOGIT_UNIQUE_FILE_LOGGER_HASH_LENGTH 12 // Set hash length to 12 characters
```

- **LOGIT_SHORT_NAME**: Включает короткие имена для макросов логирования, таких как `LOG_T`, `LOG_D`, `LOG_E` и другие, для более лаконичных записей логов.

- **LOGIT_USE_FMT_LIB**: Включает использование библиотеки fmt для форматирования строк.

## Пример формата

Чтобы определить пользовательский формат для ваших сообщений лога, вы можете использовать следующий метод:

```cpp
LOGIT_ADD_LOGGER(
logit::ConsoleLogger, (),
logit::SimpleLogFormatter,
("[%Y-%m-%d %H:%M:%S.%e] [%ffn:%#] [%!] [thread:%t] [%l] %^%v%$"));

// или...

logit::Logger::get_instance().add_logger(
std::make_unique(),
std::make_unique("[%Y-%m-%d %H:%M:%S.%e] [%ffn:%#] [%!] [thread:%t] [%l] %^%v%$"));
```

## Пример пользовательского логгера и форматтера

Вы можете расширить возможности LogIt++ с помощью реализации собственных логгеров и форматтеров. Вот как это сделать:

### Пример пользовательского логгера

```cpp
#include
#include
#include

class FileLogger : public logit::ILogger {
public:
FileLogger(const std::string& file_name) : m_file_name(file_name) {
m_log_file.open(file_name, std::ios::out | std::ios::app);
}

~FileLogger() {
if (m_log_file.is_open()) {
m_log_file.close();
}
}

void log(const logit::LogRecord& record, const std::string& message) override {
std::lock_guard lock(m_mutex);
if (m_log_file.is_open()) {
m_log_file << message << std::endl;
}
}

void wait() override {}

private:
std::string m_file_name;
std::ofstream m_log_file;
std::mutex m_mutex;
};
```

### Пример пользовательского форматтера

```cpp
#include
#include

class JsonLogFormatter : public logit::ILogFormatter {
public:
std::string format(const logit::LogRecord& record) const override {
Json::Value log_entry;
log_entry["level"] = static_cast(record.log_level);
log_entry["timestamp_ms"] = record.timestamp_ms;
log_entry["file"] = record.file;
log_entry["line"] = record.line;
log_entry["function"] = record.function;
log_entry["message"] = record.format;

Json::StreamWriterBuilder writer;
return Json::writeString(writer, log_entry);
}
};
```

## Установка

LogIt++ — это библиотека, работающая только с заголовками. Чтобы интегрировать её в ваш проект, выполните следующие шаги:

1. Клонируйте репозиторий с его подмодулями:

```bash
git clone --recurse-submodules https://github.com/NewYaroslav/log-it-cpp.git
```
2. Включите заголовочные файлы LogIt++ в ваш проект:

```cpp
#include
```

3. Настройте пути к заголовочным файлам для зависимостей, таких как time-shield-cpp.

LogIt++ зависит от *time-shield-cpp*, который находится в папке `libs` как подмодуль. Убедитесь, что путь к `libs\time-shield-cpp\include` добавлен в каталоги заголовков вашего проекта. Если вы используете IDE, такие как *Visual Studio* или *CLion*, вы можете добавить этот путь в настройках проекта.

4. (Необязательно) Включите поддержку библиотеки fmt:

LogIt++ поддерживает библиотеку *fmt* для продвинутого форматирования строк, которая также включена как подмодуль. Чтобы включить *fmt* в LogIt++, определите макрос `LOGIT_USE_FMT_LIB` в вашем проекте:

```cpp
#define LOGIT_USE_FMT_LIB
```

## Документация

Подробную документацию для LogIt++, включая описание API и примеры использования, можно найти [здесь](https://newyaroslav.github.io/log-it-cpp/).

## Лицензия
Эта библиотека распространяется под лицензией MIT. Подробности смотрите в файле [LICENSE](https://github.com/NewYaroslav/log-it-cpp/blob/main/LICENSE) в репозитории.