---
sidebar_label: "Часто задаваемые вопросы"
title: "FAQ - CyberGo DD | Часто задаваемые вопросы"
description: "Сборник частых вопросов и подробных ответов по библиотеке логирования CyberGo DD, охватывающий приёмы настройки, рекомендации по оптимизации производительности, правила фильтрации конфиденциальных данных, методы настройки аудитных логов и соответствия, выбор и оптимизацию стратегий ротации файлов, лучшие практики обработки ошибок и примеры использования системы хуков и другие темы, помогая разработчикам быстро решать различные проблемы, возникающие в реальных проектах."
sidebar_position: 1
---

# Часто задаваемые вопросы

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

### В чём разница между глобальным логгером и пользовательским логгером?

**Глобальный логгер** используется через пакетные функции `dd.Info()` и т.д., подходит для простых сценариев. **Пользовательский логгер** создаётся через `dd.New()`, поддерживает независимую конфигурацию и управление жизненным циклом.

```go
// Глобальный логгер
dd.Info("Глобальный лог")

// Пользовательский логгер
logger, _ := dd.New(dd.JSONConfig())
logger.Info("Независимый лог")
```

### Как инициализировать глобальный логгер при запуске программы?

```go
func init() {
    err := dd.InitDefault(dd.JSONConfig())
    if err != nil {
        log.Fatal(err)
    }
}
```

Или через `SetDefault`:

```go
logger, _ := dd.New(dd.Config{
    Format: dd.FormatJSON,
    Targets: []dd.OutputTarget{
        dd.ConsoleOutput(),
        dd.FileOutput("logs/app.json"),
    },
})
dd.SetDefault(logger)
```

### Что происходит при уровне Fatal?

`Fatal` / `Fatalf` / `FatalWith` вызывают `os.Exit(1)` после вывода лога (**defer-выражения не выполняются**; внутренне сначала попытается `Close()` сбросить отложенные логи, ожидая максимум 5 секунд). Поведение выхода можно настроить через `FatalHandler`; если требуется очистка ресурсов, используйте `ErrorWith` + явный `Shutdown(ctx)`.

## Конфигурация

### Как одновременно выводить в консоль и файл?

```go
logger, _ := dd.New(dd.Config{
    Targets: []dd.OutputTarget{
        dd.ConsoleOutput(),
        dd.FileOutput("logs/app.log"),
    },
})
// Или в формате JSON
logger, _ := dd.New(dd.Config{
    Format: dd.FormatJSON,
    Targets: []dd.OutputTarget{
        dd.ConsoleOutput(),
        dd.FileOutput("logs/app.json"),
    },
})
```

### Как динамически изменить уровень логирования?

```go
_ = logger.SetLevel(dd.LevelDebug)  // Изменение во время выполнения (возвращает error)
_ = dd.SetLevel(dd.LevelDebug)      // Изменение уровня глобального логгера
```

### Как настроить стратегию ротации файлов?

Через конфигурацию `FileWriter`:

```go
fw, _ := dd.NewFileWriter("logs/app.log",
    dd.DefaultFileWriterConfig(),  // 100МБ, 30 дней, 10 резервных копий
)
```

## Производительность

### Влияет ли логирование на производительность программы?

DD разработан для высокой производительности:
- Низкоаллокационная оптимизация на горячих путях
- Атомарная проверка уровня, без блокировок
- Фильтрация конфиденциальных данных для больших входных данных (≥10КБ) выполняется в отдельной goroutine с защитой по таймауту; малые входные данные обрабатываются синхронно
- Опциональная буферизованная запись для уменьшения I/O

### Как оптимизировать в сценариях с высокой пропускной способностью?

1. Используйте `BufferedWriter` для уменьшения I/O
2. Проверяйте уровень перед конструированием полей
3. Рассмотрите возможность включения сэмплирования логов
4. Избегайте использования поля `Any` на высокочастотных путях

Подробнее в [Оптимизация производительности](../advanced/performance).

## Безопасность

### Как работает фильтрация конфиденциальных данных?

`SensitiveDataFilter` использует regex-сопоставление шаблонов для автоматической замены конфиденциальных значений на `[REDACTED]` перед записью лога. Малые входные данные обрабатываются синхронно, большие — в отдельной goroutine с защитой по таймауту, не блокируя запись логов.

### Как добавить пользовательские шаблоны конфиденциальных данных?

```go
filter, _ := dd.NewCustomSensitiveDataFilter(
    `(?i)my_secret_field\s*[:=]\s*\S+`,
)
```

### Как убедиться, что логи не были подделаны?

Используйте `IntegritySigner` для HMAC-подписи логов:

```go
cfg, _ := dd.DefaultIntegrityConfigSafe()
signer, _ := dd.NewIntegritySigner(cfg)
sig := signer.Sign(logMessage)
// Проверка: signer.Verify(signedEntry)
```

## Обработка ошибок

### Почему AddWriter возвращает ошибку?

Возможные причины:
- `ErrNilWriter` -- передан nil Writer
- `ErrLoggerClosed` -- логгер закрыт
- `ErrMaxWritersExceeded` -- превышено количество Writer

### Как обработать ошибку записи?

```go
logger.SetWriteErrorHandler(func(w io.Writer, err error) {
    // Пользовательская обработка
    metrics.WriteErrors.Inc()
})
```

## Тестирование

### Как перехватить логи в тестах?

Используйте `LoggerRecorder`:

```go
rec := dd.NewLoggerRecorder()
logger, _ := rec.NewLogger()

logger.Info("test")

if !rec.ContainsMessage("test") {
    t.Error("Ожидаемый лог не найден")
}
```

Подробнее в [Тестовые утилиты](../api-reference/dev-tools/recorder).

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

- [Быстрый старт](../getting-started/) -- руководство для начала работы
- [Справочник API](../api-reference/) -- полный API
- [Контрольный список для продакшена](../security/production-checklist) -- проверка перед развёртыванием
