
Otel Name Metric
- 20 installs
- 10 repo stars
- Updated July 21, 2026
- trogonstack/agentskills
Helps with ai & agent building tasks.
About
otel-name-metric is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- otel-name-metric
- AI & Agent Building
- AI-coding skill
Otel Name Metric by the numbers
- 20 all-time installs (skills.sh)
- Ranked #10,459 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/trogonstack/agentskills --skill otel-name-metricAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 20 |
|---|---|
| repo stars | ★ 10 |
| Last updated | July 21, 2026 |
| Repository | trogonstack/agentskills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Review or Create OpenTelemetry Metric Names
Review or create metric names that follow OTel Semantic Conventions, ensuring correct naming format, instrument selection, unit placement, and attribute separation.
Before applying any rule below, fetch the latest naming guidance to check for updates:
- https://opentelemetry.io/docs/specs/semconv/general/naming/
- https://opentelemetry.io/docs/specs/semconv/general/metrics/
- https://opentelemetry.io/blog/2025/how-to-name-your-metrics/
If the fetched content contradicts any rule in this skill, follow the fetched content and flag the discrepancy.
Core Principle
The metric name identifies what you are measuring. Everything else — who is measuring, where it runs, which version — belongs in attributes or resource attributes.
Metric Name Patterns
The OTel spec defines these patterns for metric names:
Default Pattern: {area}.{metric_name}
Use when the area or metric name already implies the communication side.
Examples: system.memory.usage, kestrel.connection.duration, messaging.process.duration
Client/Server Pattern: {area}.{client|server}.{metric_name}
Use when the communication side is ambiguous for a given {area} and {metric_name}.
- Include
clientorserverwhen both perspectives exist (e.g.,http.server.*vshttp.client.*) - Omit when the system name implies the side (e.g.,
kestrelis always a server) - Omit when the metric name implies the side (e.g.,
messaging.processis always consumer)
Examples: http.server.request.duration, db.client.operation.duration
System-Specific Pattern: {system_name}.*.{metric_name}
Use when a metric is specific to a system, project, or provider.
Examples: azure.cosmosdb.client.operation.request_charge, jvm.gc.duration
How Segments Work
Metric names use dot-delimited namespaces where each dot adds specificity. Namespaces can be nested — there is no fixed number of segments. Real metrics range from 2 segments (system.uptime) to 6 segments (azure.cosmosdb.client.operation.request_charge).
Follow the {object}.{property} principle: be precise. Use system.network.packet.dropped instead of system.network.dropped.
Name vs Attributes
If a dimension changes what is being measured → put it in the metric name. If it changes who/where/when → put it in attributes.
| Dimension | Goes in... | Why |
|---|---|---|
Protocol domain (http, db) | Name | Changes what you're measuring |
Communication side (client, server) | Name (when ambiguous) | Changes the perspective |
Entity and property (request.duration) | Name | Changes what is captured |
| Service name | Resource attribute | Same metric across services |
| Environment | Resource attribute | Same metric across envs |
| Version | Resource attribute | Same metric across versions |
| HTTP method, route | Metric attribute | Filters within the same metric |
| Technology stack | Nowhere in name | Won't survive language migrations |
Unit (ms, bytes) | Unit metadata field | UCUM standard, not in name |
Naming Format
- Lowercase with dot-delimited namespaces
- snake_case within segments:
http.response.status_code - Must start with a letter, end with alphanumeric
- No consecutive delimiters (
..,__,._) - Printable Basic Latin only (U+0021–U+007E)
Measurement Suffixes
| Suffix | Meaning | Example |
|---|---|---|
entity.limit | Known total amount | system.memory.limit |
entity.usage | Amount used from known total | system.memory.usage |
entity.utilization | Fraction of usage/limit (0–1) | system.memory.utilization |
entity.time | Passage of time | system.cpu.time |
entity.io | Bidirectional data flow | system.network.io |
Pluralization Rules
- Pluralize Counters for discrete countable instances:
system.paging.faults,system.disk.operations - Do NOT pluralize utilization, duration, time:
system.filesystem.utilization - UpDownCounter names SHOULD NOT be pluralized:
system.process.countnotsystem.processes - Never append `_total` — confuses meaning in delta backends
Unit Conventions (UCUM)
- Units go in metadata, NOT in metric names
- Use non-prefixed units:
BynotMiBy - Durations: use seconds (
s) - Utilization: dimensionless, unit
1 - Curly brace annotations match grammatical number:
{request}not{requests} - Case-sensitive:
Celfor degree Celsius
Attribute Naming
- Pattern:
{object}.{property}with dot separators - Lowercase, snake_case within segments
- Namespace related attributes together:
order.id,order.total,order.status - Keep names stable; let values carry dynamic data
- Do NOT put user IDs, request IDs, or IP addresses as metric attributes — cardinality explosion
Reference Material
Detailed guidance on specific topics is in the references/ directory. Read these when the task requires deeper context:
- namespaces.md — Full catalog of official namespace roots, worked examples showing which pattern each metric uses, custom namespace guidelines
- instruments.md — Instrument selection decision tree, additivity rules, sync vs async, UpDownCounter consistency
- anti-patterns.md — Bad→good naming examples, attribute anti-patterns, cardinality traps
Review Checklist
When reviewing metric definitions, verify:
1. Name uses dot-delimited lowercase snake_case 2. No unit, service name, environment, or version in the metric name 3. Correct instrument type for the measurement 4. Unit in metadata field, following UCUM 5. Pluralization matches the instrument type 6. No _total suffix 7. Custom names don't collide with otel.* or existing semantic convention namespaces 8. Attributes follow {object}.{property} format 9. No high-cardinality values in metric attributes 10. UpDownCounter increments/decrements use matching attribute values
Output
Provide:
- List of metrics reviewed with pass/fail per checklist item
- Suggested corrections for any violations
- Instrument type recommendation if missing or incorrect
- Attribute placement corrections (name → resource → metric attribute)
Metric Naming Anti-Patterns
Spec sources:
- https://opentelemetry.io/docs/specs/semconv/general/naming/
- https://opentelemetry.io/blog/2025/how-to-name-your-metrics/
Bad Metric Names
| Bad Name | Correct | Why |
|---|---|---|
payment_transaction_total | transaction.count + service.name=payment | Service name → resource attribute |
user_service_auth_latency_ms | auth.duration + unit ms | No service name or unit in name |
inventory_db_query_seconds | db.client.operation.duration + unit s | Use semantic conventions |
api_gateway_requests_per_second | http.server.request.rate + unit {request}/s | Clean name, rate in unit |
redis_cache_hit_ratio_percent | cache.hit_ratio + unit 1 | Ratios are unitless |
prod_payment_errors | error.count + deployment.environment.name=prod | Environment → resource attribute |
user_service_v2_latency | request.duration + service.version=2.0 | Version → resource attribute |
nodejs_payment_memory | process.runtime.memory | Tech stack irrelevant to name |
latency_ms | request.duration + unit ms | Unit in metadata |
count_total | request.count | Never append _total |
ecommerce_cpu_usage | system.cpu.utilization | Business domain doesn't belong |
node_42_memory_usage | system.memory.usage + instance attribute | Instance in resource |
Attribute Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
product.id vs product.uuid vs product.unique_identifier | Same concept, different names | Pick one and standardize |
service.env vs service.environment vs env | Inconsistent naming | Use deployment.environment.name |
userId vs user_id vs user.id | Mixed formats | Use dot-delimited snake_case: user.id |
Cardinality Traps
High-cardinality metric attributes explode time series and cost. Never use as metric attributes:
- User IDs
- Request IDs
- IP addresses
- Full URL paths
- Session tokens
- Trace/span IDs
These belong in span attributes or log fields, not metric dimensions.
Cross-Cutting Mistakes
1. Units in metric names — use unit metadata field 2. Service/team names in metric names — use service.name resource attribute 3. Environment/version in names — use resource attributes 4. Appending `_total` to counters — confuses delta backends 5. Technology stack in names (nodejs_payment_memory) — won't survive language migrations 6. *Using `otel.` namespace for custom names — reserved, risks future conflicts 7. UpDownCounter attribute mismatch** — different attributes on increment vs decrement creates separate time series
Instrument Selection
Spec sources:
- https://opentelemetry.io/docs/specs/semconv/general/metrics/
- https://opentelemetry.io/docs/specs/otel/metrics/supplementary-guidelines/
Decision Tree
1. Counting something (delta values)?
- Monotonically increasing → Counter (total bytes received, requests completed)
- Can increase or decrease → UpDownCounter (active connections, queue depth)
2. Need distributions/percentiles? → Histogram (request latency, response sizes) 3. Absolute point-in-time value?
- Non-additive (summing meaningless) → Gauge (temperature, CPU %)
- Additive + monotonic → Asynchronous Counter (page faults since boot)
- Additive + non-monotonic → Asynchronous UpDownCounter
Additivity
| Instrument | Additive? | Sum Meaningful? |
|---|---|---|
| Counter | Yes | Total across instances |
| UpDownCounter | Yes | Combined value meaningful |
| Histogram | Mixed | Bucket counts yes; min/max no |
| Gauge | No | Summing meaningless |
Synchronous vs Asynchronous
- Synchronous: recorded when events occur (event-driven, lower latency)
- Asynchronous: pulled/observed at collection time (reduces unnecessary polling, e.g., reading a sensor only at scrape time)
- Spec uses synchronous names but implementations MAY use async equivalents
UpDownCounter Consistency
The same attribute values used to record an increment MUST be used for the associated decrement. Mismatched attributes create separate time series.
If an attribute is not available at increment time, do not add it at decrement time.
OTel Metric Namespace Reference
Spec source: https://opentelemetry.io/docs/specs/semconv/general/naming/
Worked Examples
| Metric | Pattern Used | Why |
|---|---|---|
http.server.request.duration | {area}.{server}.{metric_name} | Both client and server HTTP metrics exist — need server |
http.client.request.body.size | {area}.{client}.{metric_name} | Same area, client perspective |
db.client.operation.duration | {area}.{client}.{metric_name} | DB is always measured from client side, but convention uses client |
system.memory.usage | {area}.{metric_name} | No client/server ambiguity |
system.network.packet.dropped | {area}.{metric_name} | Precise: includes packet rather than just network.dropped |
kestrel.connection.duration | {system_name}.{metric_name} | Kestrel-specific, always server — no server needed |
messaging.process.duration | {area}.{metric_name} | "process" implies consumer side |
messaging.client.sent.messages | {area}.{client}.{metric_name} | Ambiguous side — needs client |
jvm.gc.duration | {system_name}.{metric_name} | JVM-specific runtime metric |
system.linux.cpu.load_1m | system.{os}.{metric_name} | OS-specific — different meaning across operating systems |
Root Namespace Catalog
Protocol Namespaces
| Root | Description | Example Metrics |
|---|---|---|
http | HTTP client/server metrics | http.server.request.duration, http.client.request.body.size |
rpc | Remote procedure calls (gRPC, etc.) | rpc.server.duration, rpc.client.duration |
messaging | Message brokers (Kafka, RabbitMQ, NATS) | messaging.client.sent.messages, messaging.process.duration |
dns | DNS resolution | dns.lookup.duration |
Database Namespaces
| Root | Description | Example Metrics |
|---|---|---|
db | Database operations | db.client.operation.duration, db.client.connection.count |
Infrastructure Namespaces
| Root | Description | Example Metrics |
|---|---|---|
system | Host-level metrics | system.cpu.utilization, system.memory.usage, system.disk.io |
process | Process-level metrics | process.cpu.time, process.memory.usage |
container | Container metrics | container.cpu.usage, container.memory.usage |
k8s | Kubernetes metrics | k8s.pod.cpu.utilization, k8s.node.memory.usage |
Runtime Namespaces
| Root | Description | Example Metrics |
|---|---|---|
jvm | Java Virtual Machine | jvm.memory.used, jvm.gc.duration, jvm.thread.count |
dotnet | .NET runtime | dotnet.gc.collections, dotnet.thread_pool.queue.length |
nodejs | Node.js runtime | nodejs.eventloop.delay, nodejs.active_handles.total |
go | Go runtime | go.goroutine.count, go.memory.used |
v8js | V8 JavaScript engine | v8js.heap.space.used_size |
Cloud Namespaces
| Root | Description | Example Metrics |
|---|---|---|
aws.* | AWS services | aws.dynamodb.consumed_capacity, aws.s3.request.duration |
azure.* | Azure services | azure.cosmosdb.request.duration |
gcp.* | Google Cloud services | gcp.pubsub.publish.duration |
Application Namespaces
| Root | Description | Example Metrics |
|---|---|---|
faas | Function-as-a-Service | faas.invoke_duration, faas.init_duration |
gen_ai | Generative AI / LLM | gen_ai.client.token.usage, gen_ai.client.operation.duration |
cicd | CI/CD pipelines | cicd.pipeline.run.duration |
System-Specific Namespaces
Some systems define their own root namespace when they don't fit into the generic categories above:
| Root | Description | Example Metrics |
|---|---|---|
kestrel | ASP.NET Kestrel server | kestrel.connection.duration, kestrel.active_connections |
signalr | ASP.NET SignalR | signalr.server.connection.duration |
aspnetcore | ASP.NET Core | aspnetcore.routing.match_attempts |
Sub-namespace Patterns
Communication Side: {client|server}
Used to disambiguate perspective when both sides exist:
http.server.request.duration ← measured at the server receiving requests
http.client.request.duration ← measured at the client sending requests
db.client.operation.duration ← always client-side (no db.server in OTel)When to omit: if the root namespace or metric name already implies the side:
kestrel.*— always server-sidemessaging.process.*— always consumer-sidejvm.*— always local runtime
Runtime Context: {runtime}
Used within process-level metrics:
process.runtime.jvm.memory.usage
process.runtime.dotnet.gc.collectionsCustom Namespace Guidelines
Company-Specific
Use reverse domain notation to avoid collisions:
com.acme.checkout.cart.items ← company metric
com.acme.payment.transaction.count ← company metricApplication-Specific
Use a unique application name as root:
myapp.queue.depth
myapp.cache.hit_ratio
myapp.job.processing.durationWhen to Propose a New OTel Namespace
If your metric could apply across the industry (not just your company), consider proposing it to the OTel specification. Examples of metrics that became standard:
gen_ai.*— started as custom, became official for LLM observabilitycicd.*— CI/CD pipeline metrics