Пример
go.opentelemetry.io/otel/trace v1.37.0: NewSpanStartConfig
Проверенный пример — golang go.opentelemetry.io/otel/trace v1.37.0: NewSpanStartConfig. Контракт выполнен на go 1.26 · linux debian/x64 · docker и пройден.
sha256:30f878c311a2b744fa1b30cb8cb96a857f038719c0965ebf4f14f0b598aff3b0
Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла.
Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди.
MIT-0
Свидетельства выполнения
Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.
- Основа свидетельства
- Подписанный контракт пройден
- Квитанции проверки
- 2
- Ключи подписи, собравшие его
- 1
Заявленная среда
go 1.26 linux 24 · ubuntu · glibc 2.39 x64 go 1.26 go go 1
Среды запусков проверки
| Окружение | Контракт | Этапы | Запуск |
|---|---|---|---|
| go 1.26 · linux debian/x64 · docker ed25519:c1973797be207ac4 | SKIPPED | compile:SKIPPED · contract:SKIPPED · load:SKIPPED · resolve:FAIL CONTAINER_RUN · golang@1golang:1.26@sha256:e30143be198a… |
2026-09-19 |
| go 1.26 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1golang:1.26@sha256:e30143be198a… |
2026-09-19 |
Кейс
HOW- Цель
- verify go.opentelemetry.io/otel/trace.NewSpanStartConfig in pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0
- Символы
-
- go.opentelemetry.io/otel/trace.NewSpanStartConfig
- Окружение
- go 1.26.6
- Создан
- 2026-09-19T14:49:41Z
Контракт
- NewSpanStartConfig returns empty SpanConfig when no options are provided
- WithAttributes appends attribute key-values across multiple options preserving order and duplicates without deduplication
- WithTimestamp sets start timestamp on SpanConfig and successive WithTimestamp options overwrite earlier values with last-value-wins precedence
- WithSpanKind sets span kind on SpanConfig and successive WithSpanKind options overwrite earlier values with last-value-wins precedence
- NewSpanStartConfig composes WithAttributes, WithTimestamp, and WithSpanKind into a unified SpanConfig
Файлы
- NOTES.md
- PROMPT.md
- csx.json
- go.mod
- go.sum
- span_start_config_test.go
- spec.json
Исходный код
# OpenTelemetry Go SpanStartOption Configuration
## Context & Pitfall
- In OpenTelemetry Go (`trace@v1.37.0`), callers frequently assume that `trace.WithAttributes(...)` deduplicates keys or replaces earlier attributes similarly to `attribute.NewSet` or `trace.WithInstrumentationAttributes`.
- In reality, `NewSpanStartConfig` performs no deduplication or bounding on attributes: multiple `WithAttributes` calls sequentially append entries, preserving duplicates and call order.
- In contrast, scalar options such as `trace.WithTimestamp` and `trace.WithSpanKind` employ last-value-wins overwriting semantics.
## Proved Behaviour
1. `NewSpanStartConfig` returns an empty `SpanConfig` with zero timestamp, unspecified span kind, no root override, and empty attributes/links when called without options.
2. `WithAttributes` appends attribute key-values across multiple option invocations without deduplicating identical keys.
3. `WithTimestamp` sets start timestamp on `SpanConfig`, with successive invocations overwriting earlier timestamps using last-value-wins precedence.
4. `WithSpanKind` sets span kind on `SpanConfig`, with successive invocations overwriting earlier kinds using last-value-wins precedence.
5. `NewSpanStartConfig` composes `WithAttributes`, `WithTimestamp`, and `WithSpanKind` cleanly into a unified `SpanConfig`.
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify go.opentelemetry.io/otel/trace.NewSpanStartConfig in pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0
Demonstrate these symbols/APIs:
- go.opentelemetry.io/otel/trace.NewSpanStartConfig
Required runtime conditions:
- ecosystem: golang
- language: go
- packageManager: go@1.26.6
- runtime: go@1.26.6
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:f7ca48cb7620d83fb76cc3aeebf7a07bfc887c777bb448ea3429c22234ef1f80","contract":["NewSpanStartConfig returns empty SpanConfig when no options are provided","WithAttributes appends attribute key-values across multiple options preserving order and duplicates without deduplication","WithTimestamp sets start timestamp on SpanConfig and successive WithTimestamp options overwrite earlier values with last-value-wins precedence","WithSpanKind sets span kind on SpanConfig and successive WithSpanKind options overwrite earlier values with last-value-wins precedence","NewSpanStartConfig composes WithAttributes, WithTimestamp, and WithSpanKind into a unified SpanConfig"],"goal":"verify go.opentelemetry.io/otel/trace.NewSpanStartConfig in pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0","kind":"HOW","packages":["pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0"],"schemaVersion":1,"symbols":["go.opentelemetry.io/otel/trace.NewSpanStartConfig"]},"contractCommand":["go","test","./..."],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"golang","language":"go","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"go","packageManagerVersion":"1.26.6","runtime":"go","runtimeVersion":"1.26.6","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0"],"schemaVersion":1,"subject":"pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0","symbols":["go.opentelemetry.io/otel/trace.NewSpanStartConfig"],"verifierAdapter":"golang@1"}
module sample
go 1.23.0
require (
go.opentelemetry.io/otel v1.37.0
go.opentelemetry.io/otel/trace v1.37.0
)
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
package sample_test
import (
"testing"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
func TestNewSpanStartConfig(t *testing.T) {
t.Run("returns empty SpanConfig when no options are provided", func(t *testing.T) {
cfg := trace.NewSpanStartConfig()
if len(cfg.Attributes()) != 0 {
t.Fatalf("expected 0 attributes, got %d", len(cfg.Attributes()))
}
if !cfg.Timestamp().IsZero() {
t.Fatalf("expected zero timestamp, got %v", cfg.Timestamp())
}
if cfg.SpanKind() != trace.SpanKindUnspecified {
t.Fatalf("expected SpanKindUnspecified, got %v", cfg.SpanKind())
}
if cfg.NewRoot() {
t.Fatalf("expected NewRoot to be false, got true")
}
if len(cfg.Links()) != 0 {
t.Fatalf("expected 0 links, got %d", len(cfg.Links()))
}
})
t.Run("WithAttributes appends attribute key-values across multiple options preserving order and duplicates without deduplication", func(t *testing.T) {
attr1 := attribute.String("service.name", "billing")
attr2 := attribute.Int("retry.count", 3)
attr3 := attribute.String("env", "staging")
attrDuplicate := attribute.String("service.name", "billing-worker")
cfg := trace.NewSpanStartConfig(
trace.WithAttributes(attr1, attr2),
trace.WithAttributes(attr3, attrDuplicate),
)
attrs := cfg.Attributes()
if len(attrs) != 4 {
t.Fatalf("expected 4 attributes, got %d", len(attrs))
}
if attrs[0] != attr1 {
t.Errorf("expected attrs[0] to be %v, got %v", attr1, attrs[0])
}
if attrs[1] != attr2 {
t.Errorf("expected attrs[1] to be %v, got %v", attr2, attrs[1])
}
if attrs[2] != attr3 {
t.Errorf("expected attrs[2] to be %v, got %v", attr3, attrs[2])
}
if attrs[3] != attrDuplicate {
t.Errorf("expected attrs[3] to be %v, got %v", attrDuplicate, attrs[3])
}
})
t.Run("WithTimestamp sets start timestamp on SpanConfig and successive WithTimestamp options overwrite earlier values with last-value-wins precedence", func(t *testing.T) {
t1 := time.Date(2024, 1, 15, 10, 0, 0, 0, time.UTC)
t2 := time.Date(2024, 1, 15, 10, 5, 30, 500, time.UTC)
cfg := trace.NewSpanStartConfig(
trace.WithTimestamp(t1),
trace.WithTimestamp(t2),
)
if !cfg.Timestamp().Equal(t2) {
t.Fatalf("expected timestamp %v, got %v", t2, cfg.Timestamp())
}
})
t.Run("WithSpanKind sets span kind on SpanConfig and successive WithSpanKind options overwrite earlier values with last-value-wins precedence", func(t *testing.T) {
cfg := trace.NewSpanStartConfig(
trace.WithSpanKind(trace.SpanKindServer),
trace.WithSpanKind(trace.SpanKindProducer),
)
if cfg.SpanKind() != trace.SpanKindProducer {
t.Fatalf("expected SpanKindProducer, got %v", cfg.SpanKind())
}
})
t.Run("NewSpanStartConfig composes WithAttributes, WithTimestamp, and WithSpanKind into a unified SpanConfig", func(t *testing.T) {
ts := time.Date(2024, 2, 1, 8, 30, 0, 0, time.UTC)
attr := attribute.String("component", "gateway")
cfg := trace.NewSpanStartConfig(
trace.WithAttributes(attr),
trace.WithTimestamp(ts),
trace.WithSpanKind(trace.SpanKindClient),
)
if len(cfg.Attributes()) != 1 || cfg.Attributes()[0] != attr {
t.Fatalf("unexpected attributes: %v", cfg.Attributes())
}
if !cfg.Timestamp().Equal(ts) {
t.Fatalf("expected timestamp %v, got %v", ts, cfg.Timestamp())
}
if cfg.SpanKind() != trace.SpanKindClient {
t.Fatalf("expected SpanKindClient, got %v", cfg.SpanKind())
}
})
}
{
"schemaVersion": 1,
"goal": "verify go.opentelemetry.io/otel/trace.NewSpanStartConfig in pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0",
"kind": "HOW",
"packages": [
"pkg:golang/go.opentelemetry.io/otel/trace@v1.37.0"
],
"symbols": [
"go.opentelemetry.io/otel/trace.NewSpanStartConfig"
],
"runtimeConditions": {
"ecosystem": "golang",
"language": "go",
"packageManager": "go@1.26.6",
"runtime": "go@1.26.6"
}
}
Исходный сидер
аноним