opentelemetry-go #8397 — генерация x-пакета из общего шаблона
Диаграмма: от бага до PR (archify) →
Смерженный PR: open-telemetry/opentelemetry-go #8397, "sdk/metric/internal/x: generate x package from x component template". Мерж 2026-06-03, +110/-92, файлы sdk/metric/internal/x/{features.go,features_test.go,x.go,x_test.go}.
Что за x-пакет и зачем его шаблонизировать
В opentelemetry-go у каждого SDK-модуля (sdk/internal/x, sdk/log/internal/x, sdk/metric/internal/x, exporters/prometheus/internal/x) есть свой пакет x — единая точка объявления экспериментальных feature-флагов, включаемых через переменные окружения OTEL_GO_X_*. До этого PR каждый такой пакет писался вручную и постепенно расходился в деталях.
PR приводит sdk/metric/internal/x к общему шаблону internal/shared/x/x.go.tmpl, из которого уже сгенерированы остальные три пакета. Итоговый файл x.go начинается с комментария // Code generated by gotmpl. DO NOT MODIFY. — это сигнал инструментам и людям, что правки нужно вносить в шаблон, а не в этот файл, иначе следующая генерация их сотрёт.
Главное изменение: один ключ → список ключей
До PR Feature[T] хранил один key string и отдавал его через Key() string. После — хранит keys []string и отдаёт через Keys() []string, а Lookup() проверяет ключи по очереди и возвращает значение первого непустого:
func (f Feature[T]) Lookup() (v T, ok bool) {
for _, key := range f.keys {
vRaw := os.Getenv(key)
if vRaw != "" {
return f.parse(vRaw)
}
}
return v, ok
}Это открывает практическую возможность: одна и та же экспериментальная фича может в будущем поддерживать несколько имён переменной окружения (например старое имя для обратной совместимости и новое — более удачное), без изменения сигнатуры Feature[T] ещё раз.
Проверено вживую на упрощённой копии этого же кода: если фича регистрируется с двумя ключами-алиасами и установлен только "старый" (второй по счёту) — Lookup() всё равно находит значение, перебирая ключи по порядку:
Вывод подтверждает: keys: [OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE OTEL_GO_X_METRIC_BATCH_SIZE], нашли через второй ключ: 200 true — значение находится, даже если установлен не первый по счёту алиас.
PR также добавляет новую фичу MetricExportBatchSize (файл features.go) как первое практическое применение шаблона — с полным набором тестов на пустое/невалидное/нулевое/отрицательное/валидное значение переменной окружения.
Почему это ценно на собесе
Здесь ценность не в сложности diff'а (он небольшой и в основном механический), а в самой сути изменения: следование существующей конвенции репозитория вместо изобретения своей. Три других пакета уже были сгенерированы из этого шаблона — задача PR не "придумать, как лучше", а "привести четвёртый пакет к тому же виду, что и первые три", не внося отсебятины. На реальном код-ревью это то же самое умение: сначала понять, как уже принято делать в конкретной кодовой базе, и только потом писать код, а не сразу навязывать свой стиль.