샘플
go.opentelemetry.io/otel/trace v1.24.0: SpanStartOption configures span start options including NewSpanStartConfig WithSpanKind WithAttributes and WithTimestamp
검증된 샘플 — golang go.opentelemetry.io/otel/trace v1.24.0: SpanStartOption configures span start options including NewSpanStartConfig WithSpanKind…
sha256:9a9fb56f57403994083d45f5c9335552516916328107c0b6c591dc57cba734ad
이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다.
통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다.
MIT-0
실행 증거
선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.
- 증거 기준
- 서명된 컨트랙트 통과
- 검증 영수증
- 1
- 빌드한 서명 키
- 1
선언된 환경
linux 24 · ubuntu · glibc 2.39 x64 go
검증 실행 환경
| 환경 | 컨트랙트 | 단계 | 실행일 |
|---|---|---|---|
| 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-02 |
케이스
HOW- 목표
- SpanStartOption configures span start options including NewSpanStartConfig WithSpanKind WithAttributes and WithTimestamp
- 심벌
-
- go.opentelemetry.io/otel/trace.NewSpanStartConfig
- go.opentelemetry.io/otel/trace.WithAttributes
- go.opentelemetry.io/otel/trace.WithSpanKind
- go.opentelemetry.io/otel/trace.WithTimestamp
- 생성일
- 2026-09-02T22:48:46Z
컨트랙트
- 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
## Search Known Solution Result
- `search_known_solution` returned `NO_SAFE_MATCH` for `NewSpanStartConfig`, `WithAttributes`, `WithSpanKind`, and `WithTimestamp` in `go.opentelemetry.io/otel/trace@v1.24.0`.
- Existing samples focus on `ContextWithSpanContext`, `LinkFromContext`, `ValidateSpanKind`, and `TraceState` limits.
## Context & Pitfall
- In OpenTelemetry Go (`trace@v1.24.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: SpanStartOption configures span start options including NewSpanStartConfig WithSpanKind WithAttributes and WithTimestamp
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0
Demonstrate these symbols/APIs:
- go.opentelemetry.io/otel/trace.NewSpanStartConfig
- go.opentelemetry.io/otel/trace.WithAttributes
- go.opentelemetry.io/otel/trace.WithSpanKind
- go.opentelemetry.io/otel/trace.WithTimestamp
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:d21c35df75fffe03dc6f9d97fee415f4f345dc3fbbb3092f0cce96380c50026d","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":"SpanStartOption configures span start options including NewSpanStartConfig WithSpanKind WithAttributes and WithTimestamp","kind":"HOW","packages":["pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0"],"schemaVersion":1,"symbols":["go.opentelemetry.io/otel/trace.NewSpanStartConfig","go.opentelemetry.io/otel/trace.WithAttributes","go.opentelemetry.io/otel/trace.WithSpanKind","go.opentelemetry.io/otel/trace.WithTimestamp"]},"contractCommand":["go","test","./..."],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"golang","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0"],"schemaVersion":1,"subject":"pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0","symbols":["go.opentelemetry.io/otel/trace.NewSpanStartConfig","go.opentelemetry.io/otel/trace.WithAttributes","go.opentelemetry.io/otel/trace.WithSpanKind","go.opentelemetry.io/otel/trace.WithTimestamp"],"verifierAdapter":"golang@1"}
module sample
go 1.22
require (
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
)
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
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": "SpanStartOption configures span start options including NewSpanStartConfig WithSpanKind WithAttributes and WithTimestamp",
"kind": "HOW",
"packages": [
"pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0"
],
"symbols": [
"go.opentelemetry.io/otel/trace.NewSpanStartConfig",
"go.opentelemetry.io/otel/trace.WithAttributes",
"go.opentelemetry.io/otel/trace.WithSpanKind",
"go.opentelemetry.io/otel/trace.WithTimestamp"
]
}
오리진 시더
익명