По каким критериям оценивается качество кода, работающего в продакшене?

Ответ

Оценка качества кода в продакшене — это комплексный процесс, который включает анализ как метрик времени выполнения, так и качества самой кодовой базы.

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)
}

Ответ 18+ 🔞

А, вот ты про качество кода в продакшене спрашиваешь! Ну это, блядь, целая наука, ёпта. Не просто так — написал, запустил и пошёл пиво пить. Тут надо смотреть на две большие, сука, категории, которые друг без друга нихуя не стоят.

1. Метрики, пока сервис в бою (Runtime Metrics)

Это когда твой код уже работает, и на него наваливаются реальные пользователи. Тут главное — не обосраться.

  • Стабильность и надёжность (Stability & Reliability):

    • Error Rate: Сколько запросов кончились пиздецом. Если этот процент высокий — ты уже в жопе, чувак. Это ключевой показатель, чтобы не выглядеть мудаком.
    • SLA/SLO/SLI: Твои обещания, блядь. Сервис должен делать то, что ты пообещал, а не просто "ну вроде работает". Если не выполняешь — готовься к разборкам.
    • MTTR (Mean Time To Recover): Сколько времени ты тратишь, чтобы поднять упавшее. Чем быстрее — тем меньше тебя будут ненавидеть.
  • Скорость (Performance):

    • Latency: Сколько времени твой сервис думает, прежде чем ответить. Особенно смотри на p99 — это как раз те самые несчастные запросы, которые ебались дольше всех.
    • Throughput: Сколько запросов в секунду ты можешь проглотить. Если мало — сервис захлебнётся, как алкаш дешёвой водкой.
  • Жрёт ли он ресурсы (Resource Consumption):

    • CPU, память, диск. Если память растёт как сумасшедшая — у тебя утечка, дружок. Если CPU на 100% на ровном месте — алгоритм говно, переписывай.

2. Качество самого кода и как ты с ним работаешь (Codebase & Process Quality)

А вот это, блядь, про то, чтобы через полгода не захотеть выколоть себе глаза, глядя на свою же работу.

  • Наблюдаемость (Observability): Можешь ли ты понять, что болит, не вскрывая черепную коробку сервиса?

    • Логи: Чтобы они были не как поток сознания шизофреника, а структурированные и понятные.
    • Метрики: Всё должно считаться и быть на графиках. Без этого ты слепой.
    • Трейсы: Чтобы когда запрос пошёл по пяти микросервисам, ты мог проследить, в каком именно из них он сдох, блядь.
  • Поддерживаемость (Maintainability):

    • Технический долг: Если у тебя одни костыли и временные решения, которые стали вечными — это пиздец. Рано или поздно всё рухнет.
    • Читаемость кода: Если имена переменных a1, tmp и shit, а отступы как попало — ты пидор. И не спорь.
    • Сложность: Если в одной функции на 300 строк ещё и цикл в цикле в условии — это уже не код, а лапша, в которой все запутаются.
  • Безопасность (Security):

    • Не тащи в проект библиотеки с дырами, по которым уже все давно ездят. Регулярно проверяй зависимости, а то получишь инъекцию или утечку данных, и будешь потом охуевать.

Вот, например, как на 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)
}

Короче, суть в чём: хороший код в продакшене — это не только когда он работает. Это когда он работает предсказуемо, его можно понимать, а когда он сбоит — ты это видишь и можешь быстро починить. Всё остальное — путь в ад, блядь.