weaver
OpenTelemetry Weaver
Use this skill when an organization wants to define its own semantic conventions on top of upstream OTel and generate language bindings from them.
Usage:
- pair with
semantic-conventionsto decide which attributes already exist upstream and should not be redeclared in the local registry - pair with
manual-instrumentationwhen wiring generated symbols into application code - use
sdk-versionsonly for SDK package selection; Weaver versions are tracked separately at https://github.com/open-telemetry/weaver/releases
If a companion skill is unavailable:
- do not stop
- do not rely on memory alone when the guidance can be checked from official sources
- consult the Weaver repo,
schemas/semconv-syntax.v2.md, anddocs/usage.md/docs/validate.md - state which fallback you used and leave any unverified item unresolved
Mental Model
Three moving parts:
- Registry — directory of YAML files.
manifest.yamlis required and names the registry, declaressemconv_versionandschema_url. The rest declareattributes,metrics,spans,events,entities. The local registry'ssemconv_versionis yours to manage; bump it on changes. - Templates — directory of Jinja2 files plus a
weaver.yamlper target language describing which templates to run, with what filter, in whatapplication_mode, and with what output filename. - Policies — Rego rules. Built-in OTel policies are the floor; custom policies layer on org rules.
These three replace a hand-rolled const.go (or equivalent): const blocks become the registry, the act of writing them becomes codegen, and tribal knowledge becomes policies.
Non-Negotiable Rules
- Install Weaver via one of the methods documented at https://github.com/open-telemetry/weaver#install (release binary,
otel/weaver:vX.Y.ZDocker image, or thesetup-weaverGitHub Action). Neverbrew install weaver— that resolves to an unrelated Scribd tool. - Reference upstream semconv attributes by
refrather than redeclaring them. Boundary domains (http,db,messaging,rpc,network,gen-ai, ...) belong in upstream OTel semconv, not in a local registry. Use the language SDK's semconv package for those at runtime. - Every entry needs
stability. Weaver refuses to generate without it. - Use a domain prefix (e.g.
ecommerce.,acme.) for org-local attributes, metrics, and spans. - Run the language formatter (
gofmt -w,prettier,ruff format, ...) on generated output. Jinja whitespace produces multiple blank lines; without formatting, the diff check in CI will fail spuriously. - Confirm the resolved schema shape before writing a template. Run
weaver registry resolve -r <reg> -f json -o /tmp/r.jsonand inspect — inputkey/name/typefields are renamed at resolve time (seereferences/template-authoring.md).
Workflow
- Install or locate Weaver. Follow the upstream install instructions at https://github.com/open-telemetry/weaver#install — pick a pinned release binary, the
otel/weaver:vX.Y.ZDocker image, or thesetup-weaverGitHub Action. Use Docker for CI and reproducible local runs. - Author the registry. Required:
manifest.yamlplus at least one ofattributes.yaml/metrics.yaml/spans.yaml/events.yaml. Seereferences/registry-authoring.md. - Author templates. One target dir per language under
templates/registry/<lang>/withweaver.yamlplus*.j2. Seereferences/template-authoring.md. - Validate and generate.
weaver registry check -r ./telemetry/registry/for fast feedback.weaver registry generate --registry ./telemetry/registry/ --templates ./telemetry/templates/ <lang> <output-dir>for codegen. Run the language formatter on the output. - Wire into CI. Three gates:
check(schema),generate+git diff --exit-code(checked-in code is current),diffagainst the base branch (surfaces breaking changes). Seereferences/ci-integration.md.
Gotchas
These cost time and are not obvious from the upstream docs:
brew install weaverinstalls the wrong tool. Use GitHub releases or Docker.- Generated output is not formatter-clean. Always run the language formatter after
weaver registry generate. - Resolved field names differ from input. Attribute input
key→ resolvedname. Metric inputname→ resolvedmetric_name. Span inputtype→ resolvedidof the formspan.<type>, with a flatnamestring equal to the inputname.note. Always resolve and inspect before writing a template. - The
commentJinja filter takes a keyword argument:attr.brief | comment(format="go"). It already emits the//prefix; do not add another. - There is no prebuilt jq filter for spans. Use:
It must be single-quoted insemconv_signal("span"; {}) | group_by(.root_namespace) | map({root_namespace: .[0].root_namespace, spans: . | sort_by(.id)})weaver.yaml; the colons in jq syntax collide with YAML mapping rules otherwise. weaver registry checkemits "File formatdefinition/2is not yet stable" on every run as of 0.22.1. This is normal; do not treat it as a failure.--futureis opt-in but breaks today ondefinition/2. Note this in CI guidance and re-enable once the format goes stable.- CLI argument ordering for
generate: target directory name is positional after--registryand--templates; the output directory follows.--templatespoints at the parent that contains target dirs, not at the language-specific subdir. - Span name in registry vs. runtime: required schema fields are
type,kind(client/server/producer/consumer/internal),brief,stability, and a structuredname: { note: "..." }. For internal business spans, putting the dotted type identifier inname.noteand using the resolvedspan.namestring at runtime is clean. - What does NOT belong in your local registry. DB, HTTP, messaging, RPC, network, GenAI, and similar boundary spans/attributes follow upstream OTel semconv. Until upstream is pulled in as a manifest dependency, instrumentation for those should reference the language SDK's semconv package directly. This is the most common modeling mistake.
- Drop the
.totalsuffix from counter names — OTel naming has moved away from it. - Use seconds (
s) for duration histograms, not milliseconds. Migrating frommsis a natural step when authoring the schema; flag it.
References To Load On Demand
- registry YAML field reference:
references/registry-authoring.md - Jinja2 patterns, jq filters, resolved-shape cheat sheet:
references/template-authoring.md - ready-to-lift GitHub Actions example:
references/ci-integration.md - hand-maintained-constants → registry walkthrough:
references/migration-playbook.md - semantic conventions skill:
semantic-conventions - manual instrumentation skill:
manual-instrumentation
Out Of Scope
These are natural follow-ups but not part of this skill:
- publishing the registry as a versioned artifact for downstream consumers
- declaring upstream semantic-conventions as a manifest dependency
weaver registry live-checkagainst a local collector- custom Rego policies beyond the built-ins
- helper-function codegen (
MyMetricName(meter)wrappers)
Verification Contract
If you authored or modified a Weaver registry, templates, or CI integration:
- re-open the changed files before finishing
- run
weaver registry checkagainst the registry and capture the result - run
weaver registry generateand the language formatter, then verifygit diff --exit-codeis clean - confirm each applicable item with codebase evidence
Report the final check with:
[x]completed[~]not applicable, with a reason[ ]unresolved
Use these items:
- registry has
manifest.yamlwithname,semconv_version,schema_url - every entry has
stability - org-local attributes/metrics/spans use a domain prefix
- no boundary-domain (http/db/messaging/rpc/network/gen-ai) entries duplicated locally
- counter names have no
.totalsuffix - duration histograms use
s(seconds) - templates use jq filters that match the resolved schema, with the spans filter single-quoted
- generated output is formatter-clean
- CI runs
check,generate+git diff --exit-code, anddiffagainst the base branch - changed files were re-read
- remaining risks or gaps are stated
More from ollygarden/opentelemetry-agent-skills
sdk-setup
OpenTelemetry SDK initialization and configuration. Use when setting up or reviewing TracerProvider, MeterProvider, or LoggerProvider; choosing exporters, processors, or propagators; configuring OTLP transport; or extending an existing SDK setup for new signals. Use this skill whenever the task involves wiring up the OpenTelemetry SDK, even if the user only mentions "add tracing" or "set up metrics" without saying "SDK.
8telemetrygen
Construct telemetrygen commands for generating synthetic OpenTelemetry traces, metrics, and logs via OTLP. Use this skill whenever the user wants to generate test telemetry, load test a collector or backend, create synthetic OTLP data, send sample traces/metrics/logs to an endpoint, test collector pipelines or processors, validate OTTL transforms, test tail sampling, or mentions telemetrygen in any context. Also trigger when the user asks how to simulate telemetry traffic, stress test an observability stack, or produce sample data for dashboards.
8sdk-versions
OpenTelemetry SDK and package version lookup across languages. Use when choosing the latest compatible released OpenTelemetry SDK or package version and locating setup docs or examples.
8semantic-conventions
OpenTelemetry semantic convention lookup and naming guidance. Use when selecting released semantic convention groups, attributes, or span naming rules, or when checking semantic convention compliance.
8manual-instrumentation
OpenTelemetry best practices for manual instrumentation. Use when adding, changing, or reviewing OpenTelemetry instrumentation in code. Guidance to choose runtime boundaries, choose signals, apply semantic conventions, handle propagation, control cardinality, and verify the result.
8span-events-to-logs-migration
Migrate OpenTelemetry Span Events (AddEvent, RecordException) to the Logs API following the OTEP 4430 deprecation plan. Use when migrating instrumentation from span events to log-based events, reviewing code that still uses AddEvent or RecordException, or planning a migration across a codebase.
8