---
sidebar_label: "Основные концепции"
title: "Основные концепции - CyberGo DD | Архитектура и дизайн"
description: "Глубокое понимание основной архитектуры и принципов дизайна библиотеки логирования CyberGo DD, включая взаимосвязь и жизненный цикл Logger и LoggerEntry, типобезопасные шаблоны использования структурированных полей Field, полный процесс обработки конвейера логирования, четырёхуровневую прогрессивную архитектуру интерфейсов и потокобезопасную модель конкурентности, помогая разработчикам сформировать системное понимание библиотеки DD."
sidebar_position: 1
---

# Основные концепции

Понимание основных концепций DD — это основа для эффективного использования библиотеки. В этой главе описаны архитектура Logger, система полей, конвейер обработки и иерархия интерфейсов.

## Архитектура Logger

Логирование в DD строится вокруг трёх основных типов:

```text
Logger (логгер)
  │
  ├── Прямое использование → logger.Info("message")
  │
  └── WithFields() → LoggerEntry (Entry с предустановленными полями)
                        │
                        └── entry.Info("message")  // Автоматически несёт предустановленные поля
```

### Logger

`Logger` — основной логгер, создаваемый через `dd.New()`:

```go
logger, err := dd.New(dd.DefaultConfig())
if err != nil {
    log.Fatal(err)
}
defer logger.Close()

logger.Info("Сервис запущен")
logger.InfoWith("Обработка запроса",
    dd.String("method", "GET"),
    dd.Int("status", 200),
)
```

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

### LoggerEntry

`LoggerEntry` создаётся через `WithFields()`, представляет собой неизменяемый контейнер предустановленных полей:

```go
// Создание Entry с предустановленными полями
requestLog := logger.WithFields(
    dd.String("service", "user-api"),
    dd.String("version", "2.1.0"),
)

// Каждый вызов автоматически несёт предустановленные поля
requestLog.Info("Сервис запущен")
// Вывод: ... Сервис запущен service=user-api version=2.1.0

requestLog.InfoWith("Пользователь вошёл",
    dd.String("user", "alice"),
)
// Вывод: ... Пользователь вошёл service=user-api version=2.1.0 user=alice
```

:::tip Неизменяемая конструкция
Каждый вызов `WithFields()` создаёт новый `LoggerEntry`, оригинальный Entry не затрагивается. Это означает, что вы можете безопасно повторно использовать один и тот же Entry в разных goroutine.
:::

### Глобальный логгер

DD предоставляет глобальный логгер, подходящий для простых сценариев или быстрого прототипирования:

```go
// Прямое использование пакетных функций (через глобальный Logger)
dd.Info("Глобальный лог")

// Эквивалентно
dd.Default().Info("Глобальный лог")
```

## Система полей

### Тип Field

`Field` — базовая единица структурированного лога, состоящая из пары ключ-значение:

```go
// Конструкторы полей покрывают все распространённые типы
dd.String("method", "GET")           // Строка
dd.Int("status", 200)                // Целое число
dd.Float64("latency", 0.123)         // Число с плавающей точкой
dd.Bool("success", true)             // Логическое значение
dd.Duration("elapsed", 150*time.Millisecond) // Временной интервал
dd.Time("timestamp", time.Now())     // Временная метка
dd.Err(err)                          // Ошибка (ключ фиксирован как "error")
dd.ErrWithKey("db_error", err)       // Ошибка (пользовательский ключ)
dd.Any("data", payload)              // Любой тип
```

### Цепочная передача полей

Поля могут передаваться между Logger и Entry по цепочке:

```go
// Первый уровень: поля уровня сервиса
serviceLog := logger.WithFields(
    dd.String("service", "api-gateway"),
)

// Второй уровень: поля уровня запроса (добавляются к сервисным)
requestLog := serviceLog.WithFields(
    dd.String("request_id", "req-001"),
    dd.String("path", "/api/users"),
)

// Третий уровень: фактический лог (добавляются ещё поля)
requestLog.InfoWith("Обработка завершена",
    dd.Int("status", 200),
    dd.Duration("elapsed", 50*time.Millisecond),
)
// Вывод содержит: service=api-gateway request_id=req-001 path=/api/users status=200 elapsed=50ms
```

## Конвейер обработки логов

Каждый лог проходит следующий процесс обработки:

```text
Вызов logger.InfoWith("msg", fields...)
       │
       ▼
  ① Проверка уровня ─── Уровень не включён → немедленный возврат (нулевые накладные расходы)
       │
       ▼
  ② Фильтрация безопасности ─── Конфиденциальные данные в сообщении и полях → [REDACTED]
       │
       ▼
  ③ Извлечение контекста ── Вызов зарегистрированных экстракторов для добавления статических/глобальных полей (вызывается с context.Background(), не может прочитать request-scoped TraceID)
       │
       ▼
  ④ Хук BeforeLog
       │
       ▼
  ⑤ Форматирование ──── Текстовый формат или формат JSON
       │
       ▼
  ⑥ Ограничение размера безопасности ─── Превышение Security.MaxMessageSize → усечение (0 = без ограничения)
       │
       ▼
  ⑦ Запись ────── Вывод в один или несколько Writer
       │
       ▼
  ⑧ Хук AfterLog
       │
       ▼
  ⑨ Обработка Fatal ── Только LevelFatal: сначала асинхронно закрывает Logger (макс. ожидание 5с, вызывает хук OnClose и сбрасывает writer), затем вызывает os.Exit(1) или пользовательский FatalHandler
```

:::info Проектирование производительности
Проверка уровня (шаг ①) использует атомарные операции, без блокировок, практически нулевые накладные расходы. Фильтрация безопасности (шаг ②) имеет защиту по таймауту, предотвращающую длительную блокировку основного потока (большой ввод через goroutine + таймаут обеспечивает возврат в худшем случае примерно за 50мс). Обработка Fatal (шаг ⑨) асинхронно запускает Close логгера (со сбросом и хуком OnClose), ожидая максимум 5с; defer в пользовательском main при этом не выполняется, но собственный Close логгера будет вызван.
:::

## Иерархия интерфейсов

DD определяет четыре интерфейса, поддерживающих точное внедрение зависимостей:

```text
CoreLogger                    ← Базовое логирование: Debug/Info/Warn/Error/Fatal + WithFields
    │
    ├── LevelLogger           ← Управление уровнями: GetLevel/SetLevel/IsLevelEnabled (встраивает CoreLogger)
    │
    └── ConfigurableLogger    ← Управление конфигурацией: Writer/безопасность/контекст/хуки (встраивает CoreLogger)

LogProvider                   ← Полный функционал: независимый плоский интерфейс, содержащий все методы
```

```go
// Нужен только базовый логгер? Внедрите CoreLogger
type Service struct {
    log dd.CoreLogger
}

// Нужно динамически регулировать уровень? Внедрите LevelLogger
type Handler struct {
    log dd.LevelLogger
}
```

:::tip Лучшие практики
В конструкторах принимайте минимально необходимый интерфейс, а не конкретный тип. Это делает код более тестируемым и гибким.
:::

## Потокобезопасная модель

Основной принцип проектирования DD: **безопасное использование из нескольких goroutine без дополнительной синхронизации**.

| Компонент | Механизм безопасности |
|-----------|----------------------|
| Logger | Все методы безопасны для конкурентного вызова |
| LoggerEntry | Неизменяемый, только для чтения после создания |
| Config | Метод Clone() для безопасного копирования |
| Writers | Атомарные указатели, чтение без блокировок |
| SensitiveDataFilter | Разделение чтения и записи, отдельная goroutine |
| HookRegistry | RWMutex защищает регистрацию и чтение (Logger удерживает его указатель через `atomic.Value`) |

```go
// Безопасно: несколько goroutine разделяют один Logger
var logger *dd.Logger  // Инициализируется один раз

func handleRequest(w http.ResponseWriter, r *http.Request) {
    // Безопасно: конкурентный вызов
    logger.InfoWith("Запрос получен",
        dd.String("path", r.URL.Path),
        dd.String("method", r.Method),
    )
}
```

## Система целей вывода

DD поддерживает три цели вывода, которые можно свободно комбинировать:

```go
logger, err := dd.New(dd.Config{
    Targets: []dd.OutputTarget{
        dd.ConsoleOutput(),                    // Консоль
        dd.FileOutput("logs/app.log"),         // Файл (автоматическая ротация)
        dd.CustomOutput(customWriter),         // Пользовательский io.Writer
    },
})
if err != nil {
    log.Fatal(err)
}
defer logger.Close()
```

Встроенные компоненты Writer:

| Компонент | Назначение |
|-----------|------------|
| `FileWriter` | Запись в файл + ротация по размеру/времени + сжатие |
| `BufferedWriter` | Буферизованная запись, уменьшение количества I/O |
| `MultiWriter` | Многоцелевая доставка, запись в несколько Writer |

## Следующие шаги

- [Структурированное логирование](./structured-logging) -- подробное описание использования полей
- [Вывод в файл и ротация](./file-output) -- конфигурация файловых логов
- [Фильтрация конфиденциальных данных](./sensitive-filtering) -- практика фильтрации безопасности
- [Справочник API](../api-reference/) -- полная документация API
