Логирование и Алертинг
Обзор системы мониторинга
Система мониторинга использует Unified Trace ID для отслеживания запросов через все сервисы:
// Gateway пробрасывает trace_id
app.use("*", async (c, next) => {
const traceId = c.req.header("x-trace-id") || crypto.randomUUID();
c.header("x-trace-id", traceId);
await next();
});
// Service Binding получает trace_id из headers
const request = new Request(c.req.raw);
request.headers.set("x-trace-id", traceId);
const response = await sofa.fetch(request);Это позволяет отследить запрос от Gateway через все интеграции и сервисы.
Просмотр логов в Cloudflare Dashboard
Открытие логов
- Перейти в Cloudflare Dashboard
- Выбрать Workers and Pages (слева в меню)
- Выбрать интеграцию (например,
integ-sofa-dev) - Нажать вкладку Logs (справа)
Должны увидеть список логов в реальном времени.
Фильтрация логов
Все логи выводятся в JSON формате, что позволяет их искать и фильтровать:
Поиск по уровню ошибки:
"level":"error"Поиск по контексту:
"context":"webhook"Поиск по Trace ID:
"traceId":"550e8400-e29b-41d4-a716-446655440000"Поиск по сообщению об ошибке:
"message":"Rate limit exceeded"Поиск по действию:
"action":"init"Поиск HTTP ошибок:
"httpStatus":400Поиск ошибок конкретного внешнего API:
"httpUrl":"api.nethunt.com"Примеры поиска в логах
Найти все ошибки в интеграции:
"level":"error"Найти все ошибки конкретного обработчика:
"level":"error" "context":"webhook"Найти все события по одному трассе (для дебага):
"traceId":"550e8400-e29b-41d4-a716-446655440000"Найти все события по одному действию:
"action":"init"Найти HTTP ошибки по статус коду:
"httpStatus":400Найти ошибки при запросах к внешнему API:
"httpStatus":500 "httpUrl":"api.nethunt.com"Структура логов
LOG_LEVEL
Уровень логирования настраивается через переменную LOG_LEVEL в wrangler.toml ([vars]):
| LOG_LEVEL | Видимые уровни | Когда |
|---|---|---|
debug | debug, info, warn, error | pnpm debug <target> — локальная отладка |
info | info, warn, error | pnpm start <target> (по умолчанию), CF prod |
warn | warn, error | Минимальный вывод |
error | error | Только ошибки |
Два источника логов
1. Trace-система (@happ-integ/trace) — для handlers:
- Используется через
ctx.log,step.run(),ctx - Автоматически добавляет traceId, handler name, span timing
LOG_LEVELфильтрует step :input/:output (debug) и другие события
2. Logger (@happ-integ/logger) — для packages и gateway:
- Используется через
new Logger("service-name") - Формат зависит от режима: JSON (prod) или pretty console (local)
Формат логов (prod / CF Observability)
Все логи в production выводятся в JSON формате:
{
"level": "debug|info|warn|error",
"handler": "handler_name",
"message": "описание события",
"traceId": "tr_m1abc123_xyz789",
"timestamp": "2024-01-01T00:00:00.000Z",
"durationMs": 145,
"error": "error message (только для ошибок)",
"stack": "stack trace (только для ошибок)",
"httpStatus": 400,
"httpUrl": "https://api.example.com/endpoint",
"httpMethod": "POST",
"httpResponseBody": "{\"error\":\"Invalid request\"}",
"httpRequestBody": {"field": "value"},
"...additional_data": "любые дополнительные поля"
}Логи из Logger (packages) имеют поле service вместо handler:
{
"level": "error",
"service": "redis",
"message": "get: Failed to get key \"user:123\"",
"timestamp": "2024-01-01T00:00:00.000Z",
"error": "Connection refused",
"stack": "Error: Connection refused..."
}Ключевые поля:
| Поле | Описание |
|---|---|
level | Уровень: debug, info, warn, error |
handler / service | Имя обработчика (trace) или сервиса (Logger) |
message | Описание события |
traceId | Уникальный идентификатор запроса для корреляции |
timestamp | ISO время события |
durationMs | Время выполнения (для timing логов) |
error | Текст ошибки (только для ошибок) |
stack | Stack trace ошибки (только для ошибок) |
httpStatus | HTTP статус код (только для HTTP ошибок) |
httpUrl | URL запроса (только для HTTP ошибок) |
httpMethod | HTTP метод: GET, POST, PUT, DELETE (только для HTTP ошибок) |
httpResponseBody | Тело ответа от сервера (только для HTTP ошибок, до 1000 символов) |
httpRequestBody | Тело запроса (только для HTTP ошибок) |
Используемые функции логирования
В обработчиках используйте ctx.log из контекста (автоматически включает traceId):
// В handler доступен ctx.log с автоматическим traceId
export const myHandler = defineHandler<IMyPayload, IMyResponse>({
name: "my-handler",
endpoint: "POST /my-endpoint",
handler: async (ctx) => {
// Информационное сообщение
ctx.log.info("Starting processing", { userId: ctx.payload.userId });
// Ошибки
ctx.log.error("Something failed", error, { additionalData: "value" });
// Измерение времени выполнения
const operationStart = Date.now();
await someOperation();
ctx.log.duration("operation_completed", operationStart, { operationType: "db_query" });
return { success: true };
},
});Структура логов:
{
"level": "info",
"handler": "my-handler",
"message": "Starting processing",
"traceId": "tr_m1abc123_xyz789",
"timestamp": "2024-01-01T12:00:00.000Z",
"userId": "123"
}Формат traceId: tr_{timestamp_base36}_{random_8chars} — генерируется автоматически если не передан в заголовке x-trace-id.
Примеры использования логирования
В обработчике (рекомендуемый способ):
export const initHandler = defineHandler<IInitPayload, IInitResponse>({
name: "init",
endpoint: "POST /init",
handler: async (ctx) => {
// ctx.log автоматически содержит traceId и имя handler
ctx.log.info("Starting initialization", { companyId: ctx.payload.companyId });
if (!ctx.payload.companyId) {
throw new Error("companyId is required");
}
// Измерение времени операций
const dbStart = Date.now();
await ctx.db.init();
ctx.log.duration("db_init_completed", dbStart);
ctx.log.info("Initialization completed successfully", {
companyId: ctx.payload.companyId,
});
return { success: true };
},
});Автоматические логи:
Фреймворк автоматически логирует:
webhook_received— при получении webhookwebhook_accepted— после успешной обработки webhook (с durationMs)handler_completed— после выполнения handler (с durationMs и status)
Пример автоматического лога:
{
"level": "info",
"handler": "init",
"message": "handler_completed",
"durationMs": 145,
"traceId": "tr_m1abc123_xyz789",
"timestamp": "2024-01-01T12:00:00.145Z",
"status": "success"
}Алерты и уведомления
Какие алерты настроены
В текущей настройке активен Workers Error Alert:
- Тип: Workers Error
- Триггер: Любая необработанная ошибка в Worker
- Назначение: Slack канал
#alerts-integ - Формат сообщения: Автоматически от Cloudflare
Пример сообщения в Slack:
⚠️ Workers Error Alert
━━━━━━━━━━━━━━━━━━━━━━━━━
Worker: integ-sofa-dev
Error: phone_number is required
Stack: Error: phone_number is required
at handler (integrations/sofa/src/handlers/webinar-call-originate.ts:41:10)
at processRequest (integrations/sofa/src/index.ts:12:15)
Timestamp: 2024-01-01 12:00:00 UTCКак реагировать на алерты
Когда приходит алерт в Slack:
Прочитать сообщение об ошибке — обычно оно содержит:
- Название Worker (например,
integ-sofa-dev) - Текст ошибки
- Stack trace
- Время ошибки
- Название Worker (например,
Открыть логи в Cloudflare Dashboard:
- Перейти в Workers and Pages →
integ-sofa-dev→ Logs - Поискать по времени из алерта или по тексту ошибки
- Перейти в Workers and Pages →
Найти полный контекст:
- В логах найти JSON логи с более подробной информацией
- Использовать
traceIdесли есть для отслеживания всего запроса
Проверить код обработчика:
- Проверить handler, который упоминается в ошибке
- Убедиться что все входные параметры валидны
Отправить фикс:
- Исправить код
- Задеплоить интеграцию
- Убедиться что ошибка больше не появляется
Дополнительные алерты (опционально)
Можно добавить алерты на другие события:
- Rate Limiting — часто превышается лимит запросов
- High Error Rate — > 5% ошибок за 5 минут
- Slow Requests — > 3 сек за 5 минут
Смотрите раздел Настройка алертов в SETUP.md
Дебаг по Trace ID
Как работает Trace ID
Каждый запрос получает уникальный Trace ID:
1. Запрос → Gateway (генерирует traceId или берет из x-trace-id header)
2. Gateway пробрасывает traceId через x-trace-id header в Service Bindings
3. Интеграция извлекает traceId из header или генерирует новый
4. Интеграция логирует traceId со всеми событиями
5. Handler execution содержит traceId для продолжения трассировки
6. Результат: все логи одного запроса имеют один traceIdФормат traceId: tr_{timestamp_base36}_{random_8chars}
Пример: tr_m1abc123_xyz789
Поиск запроса по Trace ID
В Cloudflare Dashboard:
- Открыть логи интеграции: Workers →
integ-sofa-dev→ Logs - В поле поиска ввести:
"traceId":"tr_m1abc123_xyz789" - Должны увидеть все логи этого запроса
Пример JSON лога с traceId:
{
"level": "error",
"handler": "init",
"traceId": "tr_m1abc123_xyz789",
"message": "handler_failed",
"error": "companyId is required",
"timestamp": "2024-01-01T12:00:00.000Z",
"stack": "Error: companyId is required..."
}Пример лога HTTP ошибки (при обращении к внешнему API):
{
"level": "error",
"handler": "sync-contacts",
"traceId": "tr_m1abc123_xyz789",
"message": "nethunt.updateRecord:end",
"error": "HTTP 400: {\"error\":\"Field not found\"}",
"timestamp": "2024-01-01T12:00:00.000Z",
"httpStatus": 400,
"httpUrl": "https://nethunt.com/api/v1/zapier/record/123",
"httpMethod": "POST",
"httpResponseBody": "{\"error\":\"Field not found\"}",
"httpRequestBody": {"fieldActions": {"Комментарій": {"add": "..."}}}
}Это позволяет видеть полный контекст HTTP ошибки: какой URL, какой метод, что отправляли и что получили в ответ.
Связь логов Gateway и интеграций
Когда вы видите ошибку в интеграции, её traceId позволяет найти соответствующие логи в Gateway:
Запрос поступает:
POST /sofa/webhook/webinar-call-originate
↓
Gateway логирует с traceId="xyz"
↓
Gateway вызывает интеграцию через Service Binding
↓
Интеграция логирует с тем же traceId="xyz"
↓
Результат: оба сервиса имеют логи с одинаковым traceIdДля отслеживания полной цепочки:
- Найти логи в интеграции с нужным
traceId - Пойти в Gateway логи
- Искать там тот же
traceId - Видеть полный путь запроса
Logpush - архивирование логов
Настройте Logpush для отправки логов в R2 bucket или другое хранилище:
# Создать R2 bucket
wrangler r2 bucket create integ-logs-archive
# Настроить Logpush через Cloudflare API
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/logpush/jobs" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
-d '{
"account_id": "{account_id}",
"enabled": true,
"frequency": "low",
"dataset": "workers_trace_events",
"destination_conf": "s3://r2-bucket-endpoint/integ-logs",
"ownership_challenge": "challenge"
}'Логи архивируются ежедневно в R2 для долгосрочного хранения.
Метрики для отслеживания
Error Rate
Alert: > 5% за 5 минут → Slack
Query: (count(errors) / count(total_requests)) * 100
Как проверить вручную:
- Cloudflare Dashboard → Workers → Logs
- Посчитать количество логов с
"level":"error" - Поделить на общее количество логов
Latency P99
Alert: > 3 сек за 5 минут → Slack
Target: < 1 сек для обычных запросов
Отслеживание: Смотреть duration в логах интеграции
Integration Health
Alert: Service Down → Slack
Check: /health endpoint каждые 30 сек
# Проверить здоровье Gateway
curl https://integ.happ.tools/health
# Проверить здоровье интеграции через Gateway
curl -H "x-access-token: TOKEN" https://integ.happ.tools/sofa/healthGrafana Dashboards (опционально)
Dashboard 1: Overview
- Total requests per integration
- Error rate trend
- Average latency
- Integration health status
Dashboard 2: Per-Integration Details
- Sofa-specific metrics
- Request breakdown by handler
- Error distribution
Dashboard 3: Errors & Alerts
- Error log viewer (searchable by traceId)
- Error rate timeline
- Top error types
- Failed requests with stack traces
Быстрый старт мониторинга
1. Первое деплоение
cd integrations/sofa
pnpm build
pnpm deploy:dev2. Проверить логи
- Dashboard → Workers →
integ-sofa-dev→ Logs - Должны видеть JSON логи в реальном времени
3. Проверить алерты
- Отправить запрос с ошибкой
- Должно придти уведомление в Slack
4. Регулярный мониторинг
- Ежедневно: проверять наличие ошибок в логах
- По алертам: реагировать на сообщения в Slack
- Еженедельно: смотреть тренд ошибок и latency
Полезные ссылки
- SETUP.md - Logging и Alerting Setup — как настроить систему
- Cloudflare Workers Logs — официальная документация
- Cloudflare Notifications — документация по алертам