Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ Include a body that describes the change.
Keep diffs minimal and focused.
Do not refactor or apply style changes beyond the lines you directly touch.

## Include Policy
- Do not use `../` in `#include` directives.
- Within a module (`logit/utils/*`, `logit/formatter/*`, `logit/loggers/*`) only include headers located in the same sub-tree using forward paths (for example `#include "compiler/PatternCompiler.hpp"`).
- Cross-module dependencies must be provided by the nearest umbrella header: include the corresponding aggregator first instead of including a sibling module directly.
- Files under `logit/detail/` may include other detail headers, but must not include public `logit/...` headers. Their public prerequisites must be included by the parent header before they are pulled in.
- Preferred entry points are the self-contained umbrellas in `include/logit_cpp`: `<logit.hpp>`, `<logit/utils.hpp>`, `<logit/formatter.hpp>`, and `<logit/loggers.hpp>`.

## Header naming conventions
When adding or renaming headers, follow these rules:

Expand Down
20 changes: 20 additions & 0 deletions README-RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@
- **Гибкое форматирование и маршрутизация.** Настраивайте шаблоны формата, комбинируйте консольные/файловые/системные бэкенды или подключайте собственные реализации логгеров.
- **Асинхронность по умолчанию.** Каждый бэкенд обслуживается исполнителем задач с настраиваемыми размерами очереди и политиками переполнения, а макросы вроде `LOGIT_WARN_ONCE` или `LOGIT_ERROR_THROTTLE` помогают упорядочить повторяющиеся сообщения.

## Структура заголовков

Библиотека включает несколько самодостаточных «зонтичных» заголовков, которые подготавливают зависимости в правильном порядке:

| Точка входа | Назначение |
|-------------|------------|
| `<logit.hpp>` | Подключает конфигурацию, перечисления, утилиты, форматтеры, все логгеры, синглтон `Logger` и публичные макросы. |
| `<logit/utils.hpp>` | Собирает модуль `logit/utils/`, включая `LogRecord`, утилиты форматирования и работы с аргументами. |
| `<logit/formatter.hpp>` | Предоставляет интерфейсы форматтеров и стандартный компилятор паттернов. |
| `<logit/loggers.hpp>` | Экспортирует готовые бэкенды логгеров и подготавливает их внутренние зависимости. |

Листовые заголовки используют правило **NHR (Nearest Header Requirement)**: сначала подключите соответствующий зонтик, затем конкретный файл, например:

```cpp
#include <logit/utils.hpp>
#include <logit/utils/LogRecord.hpp>
```

Внутренние файлы из `logit/detail/` предназначены только для реализации и не должны подключаться напрямую пользователями.

Ниже приведены примеры макросов; также загляните в каталог `examples/` с отдельными сценариями, включая настройку очереди и обработку аварийного завершения.

## Примеры макросов
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@ Key characteristics:
- **Flexible formatting and routing.** Customize output patterns, mix console/file/system backends, or supply custom logger implementations.
- **Async by default.** Each backend is served by the task executor with configurable queue sizes and overflow policies, plus helpers such as `LOGIT_WARN_ONCE` or `LOGIT_ERROR_THROTTLE` to keep repeated messages under control.

## Header layout

The library ships with self-contained umbrella headers that provide a predictable include order:

| Entry point | Purpose |
|-------------|---------|
| `<logit.hpp>` | Brings in configuration macros, enums, utilities, formatters, loggers, the singleton `Logger` and public macros. |
| `<logit/utils.hpp>` | Aggregates everything in `logit/utils/`, including `LogRecord`, formatting helpers and argument utilities. |
| `<logit/formatter.hpp>` | Provides formatter interfaces and the default pattern compiler implementation. |
| `<logit/loggers.hpp>` | Exposes the logger backends and prepares their internal dependencies. |

Leaf headers follow the **Nearest Header Requirement (NHR)**: include the matching umbrella *first* and then the specific header you need, e.g.

```cpp
#include <logit/utils.hpp>
#include <logit/utils/LogRecord.hpp>
```

Internal headers under `logit/detail/` are private implementation details and should not be included directly by consumers.

See the macro examples below or browse the `examples/` folder for focused demonstrations, including queue tuning and crash handling.

## Macro Examples
Expand Down
12 changes: 7 additions & 5 deletions include/logit_cpp/logit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
#define LOGIT_CPP_LOGIT_HPP

/// \file logit.hpp
/// \brief Main header file for the LogIt++ library.
/// \brief Unified umbrella header for the LogIt++ library.
///
/// Including this header provides a fully self-contained entry point that
/// aggregates configuration, utilities, formatters, loggers and the logging
/// façade. No additional includes are required to start using the library.

#include "logit/config.hpp"
#include "logit/enums.hpp"
#include "logit/utils.hpp"
#include "logit/Logger.hpp"
#include "logit/detail/LogStream.hpp"
#include "logit/detail/ScopeTimer.hpp"
#include "logit/log_macros.hpp"
#include "logit/formatter.hpp"
#include "logit/loggers.hpp"
#include "logit/Logger.hpp"
#include "logit/log_macros.hpp"

/// \namespace logit
/// \brief The primary namespace for the LogIt++ library.
Expand Down
2 changes: 0 additions & 2 deletions include/logit_cpp/logit/detail/CompressionWorker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
# include <zstd.h>
#endif

#include "../enums.hpp"

namespace logit { namespace detail {

/// \brief Compress a file using the specified compression type.
Expand Down
2 changes: 0 additions & 2 deletions include/logit_cpp/logit/detail/LogStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
/// \brief Defines the LogStream class for stream-like logging functionality.

#include <sstream>
#include "../Logger.hpp"
#include "../utils/path_utils.hpp"

namespace logit {

Expand Down
4 changes: 0 additions & 4 deletions include/logit_cpp/logit/detail/ScopeTimer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
/// \file ScopeTimer.hpp
/// \brief RAII timer that logs the duration of a scope.

#include "../config.hpp"
#include "../utils.hpp"
#include "../Logger.hpp"

#include <chrono>
#include <string>

Expand Down
2 changes: 0 additions & 2 deletions include/logit_cpp/logit/detail/TaskExecutor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
/// \file TaskExecutor.hpp
/// \brief Defines the TaskExecutor class, which manages task execution in a separate thread.

#include "../config.hpp"

#include <functional>
#include <atomic>
#if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)
Expand Down
3 changes: 0 additions & 3 deletions include/logit_cpp/logit/detail/system_error_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
/// \file system_error_macros.hpp
/// \brief Internal helpers shared by the system error logging macros.

#include "../config.hpp"
#include "../utils/format.hpp"

#if defined(_WIN32)
#include <windows.h>
#endif
Expand Down
6 changes: 5 additions & 1 deletion include/logit_cpp/logit/formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
#define _LOGIT_FORMATTER_HPP_INCLUDED

/// \file formatter.hpp
/// \brief Aggregates all formatter components for convenient inclusion.
/// \brief Aggregates the formatter subsystem for convenient inclusion.
///
/// This header is self-contained and pulls in the generic formatter interface alongside the
/// default implementations and pattern compiler support utilities.

#include "utils.hpp"
#include "formatter/ILogFormatter.hpp"
#include "formatter/SimpleLogFormatter.hpp"
#include "formatter/compiler/PatternCompiler.hpp"
Expand Down
9 changes: 6 additions & 3 deletions include/logit_cpp/logit/log_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
#endif

#include "config.hpp"
#include "utils/format.hpp"
#include "utils.hpp"
#include "Logger.hpp"

#include "detail/LogStream.hpp"
#include "detail/ScopeTimer.hpp"
#include "detail/system_error_macros.hpp"

/// \file log_macros.hpp
/// \brief Provides various logging macros for different log levels and options.
Expand Down Expand Up @@ -71,8 +76,6 @@ static_assert(LOGIT_LEVEL_FATAL == static_cast<int>(logit::LogLevel::LOG_LVL_FAT
//------------------------------------------------------------------------------
// System error logging helpers

#include "detail/system_error_macros.hpp"

//------------------------------------------------------------------------------
// Platform-specific error logging macros

Expand Down
12 changes: 11 additions & 1 deletion include/logit_cpp/logit/loggers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@
#define _LOGIT_LOGGERS_HPP_INCLUDED

/// \file loggers.hpp
/// \brief Aggregates all logger implementations for convenient inclusion.
/// \brief Aggregates all public logger backends.
///
/// This header is self-contained: it prepares common configuration, utility and detail
/// dependencies before including each backend implementation. Include it prior to including
/// any header under `loggers/` to satisfy the nearest-header requirement.

#include "config.hpp"
#include "utils.hpp"
#include "detail/TaskExecutor.hpp"
#ifndef __EMSCRIPTEN__
#include "detail/CompressionWorker.hpp"
#endif

#include "loggers/ILogger.hpp"
#include "loggers/ConsoleLogger.hpp"
#include "loggers/FileLogger.hpp"
Expand Down
1 change: 0 additions & 1 deletion include/logit_cpp/logit/loggers/CrashPosixLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
/// \brief POSIX crash logger persisting the last messages to a file descriptor.

#include "ILogger.hpp"
#include "../utils.hpp"

#include <atomic>
#include <array>
Expand Down
1 change: 0 additions & 1 deletion include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
/// \\brief Windows crash logger persisting the last messages to a file handle.

#include "ILogger.hpp"
#include "../utils.hpp"

#include <array>
#include <atomic>
Expand Down
4 changes: 0 additions & 4 deletions include/logit_cpp/logit/loggers/FileLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
/// \brief File logger implementation that outputs logs to files with rotation and deletion of old logs.

#include "ILogger.hpp"
#include "../enums.hpp"
#ifndef __EMSCRIPTEN__
#include "../detail/CompressionWorker.hpp"
#endif
#include <iostream>
#include <fstream>
#include <mutex>
Expand Down
10 changes: 6 additions & 4 deletions include/logit_cpp/logit/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
#define _LOGIT_UTILS_HPP_INCLUDED

/// \file utils.hpp
/// \brief Aggregates various utility modules used throughout the project.
/// \brief Aggregates the public utilities module.
///
/// This header includes modules for formatting, handling variable values, argument parsing,
/// encoding utilities, path utilities, and log record management. Including this header
/// provides a single point of access to common utility functions and types.
/// This header is a self-contained entry point that exposes all utility components required
/// by the library: configuration macros, enums, formatting helpers, value wrappers and the
/// log record type. Include
/// it before any header inside `utils/` to satisfy the nearest-header requirement.

#include "config.hpp"
#include "enums.hpp"
#include "utils/format.hpp"
#include "utils/VariableValue.hpp"
Expand Down
18 changes: 18 additions & 0 deletions tests/include_formatter_nhr_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <logit/formatter.hpp>
#include <logit/formatter/SimpleLogFormatter.hpp>

int main() {
logit::SimpleLogFormatter formatter;
logit::LogRecord record(
logit::LogLevel::LOG_LVL_INFO,
123,
__FILE__,
__LINE__,
__func__,
"format",
"",
-1,
false);
const std::string formatted = formatter.format(record);
return formatted.empty() ? 1 : 0;
}
9 changes: 9 additions & 0 deletions tests/include_loggers_nhr_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <logit/loggers.hpp>
#include <logit/loggers/ConsoleLogger.hpp>

int main() {
logit::ConsoleLogger logger(false);
logger.set_log_level(logit::LogLevel::LOG_LVL_WARN);
logger.wait();
return 0;
}
79 changes: 79 additions & 0 deletions tests/include_only_ilogger_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <logit/loggers.hpp>
#include <logit/loggers/ILogger.hpp>

namespace {
class CountingLogger final : public logit::ILogger {
public:
void log(const logit::LogRecord& record, const std::string& message) override {
++m_count;
m_last_message = message;
m_last_timestamp = record.timestamp_ms;
m_last_file = record.file;
}

std::string get_string_param(const logit::LoggerParam& param) const override {
switch (param) {
case logit::LoggerParam::LastFileName:
return m_last_file;
case logit::LoggerParam::LastFilePath:
return m_last_file;
case logit::LoggerParam::LastLogTimestamp:
case logit::LoggerParam::TimeSinceLastLog:
return {};
}
return {};
}

int64_t get_int_param(const logit::LoggerParam& param) const override {
switch (param) {
case logit::LoggerParam::LastLogTimestamp:
return m_last_timestamp;
case logit::LoggerParam::TimeSinceLastLog:
return 0;
case logit::LoggerParam::LastFileName:
case logit::LoggerParam::LastFilePath:
return static_cast<int64_t>(m_count);
}
return 0;
}

double get_float_param(const logit::LoggerParam&) const override { return 0.0; }

void set_log_level(logit::LogLevel level) override { m_level = level; }

logit::LogLevel get_log_level() const override { return m_level; }

void wait() override {}

int count() const { return m_count; }
const std::string& last_message() const { return m_last_message; }

private:
logit::LogLevel m_level = logit::LogLevel::LOG_LVL_TRACE;
int m_count = 0;
std::string m_last_message;
std::string m_last_file;
int64_t m_last_timestamp = 0;
};
} // namespace

int main() {
CountingLogger logger;
logger.set_log_level(logit::LogLevel::LOG_LVL_INFO);

logit::LogRecord record(
logit::LogLevel::LOG_LVL_INFO,
42,
__FILE__,
__LINE__,
__func__,
"message",
"",
-1,
false);

logger.log(record, "from test");
logger.wait();

return (logger.count() > 0 && !logger.last_message().empty()) ? 0 : 1;
}
8 changes: 8 additions & 0 deletions tests/include_quickstart_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <logit.hpp>

int main() {
LOGIT_ADD_CONSOLE_DEFAULT();
LOGIT_INFO("quickstart include works");
LOGIT_WAIT();
return 0;
}
17 changes: 17 additions & 0 deletions tests/include_utils_nhr_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <logit/utils.hpp>
#include <logit/utils/LogRecord.hpp>

int main() {
logit::LogRecord record(
logit::LogLevel::LOG_LVL_DEBUG,
0,
__FILE__,
__LINE__,
__func__,
"%s",
"",
-1,
true);
record.args_array.emplace_back("answer", 42);
return record.logger_index == -1 ? 0 : 1;
}
Loading