Ответ
Оценка качества кода в продакшене — это комплексный процесс, который включает анализ как метрик времени выполнения, так и качества самой кодовой базы.
1. Метрики времени выполнения (Runtime Metrics)
Это показатели работы сервиса под реальной нагрузкой.
Стабильность и надежность (Stability & Reliability):
- Error Rate: Процент запросов, завершившихся ошибкой. Низкий показатель — ключевой признак качества.
- SLA/SLO/SLI: Соответствие соглашениям об уровне обслуживания. Показывает, выполняет ли сервис свои обязательства.
- MTTR (Mean Time To Recover): Среднее время восстановления после сбоя. Чем оно меньше, тем лучше.
Производительность (Performance):
- Latency: Время ответа на запрос (часто измеряется в перцентилях: p50, p90, p99).
- Throughput: Количество запросов, обрабатываемых в единицу времени (RPS - requests per second).
Потребление ресурсов (Resource Consumption):
- Эффективное использование CPU, Memory, Disk I/O. Аномальные всплески могут указывать на утечки памяти или неэффективные алгоритмы.
2. Качество кодовой базы и процессов (Codebase & Process Quality)
Эти аспекты влияют на долгосрочную поддержку и развитие продукта.
Наблюдаемость (Observability): Насколько легко понять внутреннее состояние системы по внешним данным.
- Логи: Информативные и структурированные логи (например, в формате JSON).
- Метрики: Сбор ключевых показателей с помощью инструментов вроде Prometheus.
- Трейсы: Возможность отследить путь запроса через несколько микросервисов (Jaeger, OpenTelemetry).
Поддерживаемость (Maintainability):
- Технический долг: Минимум "костылей" и временных решений.
- Читаемость кода: Соответствие код-стайлу (
gofmt
,go vet
), понятные имена переменных и функций. - Низкая сложность: Оценка цикломатической сложности кода.
Безопасность (Security):
- Отсутствие известных уязвимостей (проверка по базам OWASP Top 10).
- Регулярное сканирование зависимостей.
Пример сбора метрик в Go с помощью Prometheus:
import "github.com/prometheus/client_golang/prometheus"
var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests.",
},
[]string{"method", "code", "path"},
)
httpRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests.",
Buckets: prometheus.DefBuckets,
},
[]string{"path"},
)
)
func init() {
prometheus.MustRegister(httpRequestsTotal)
prometheus.MustRegister(httpRequestDuration)
}