MetricsHub
MetricsHub Community Connectors 1.0.22
-
Home
- Connector Developer Guide Connector Structure 6
Metric and Attribute Naming
MetricsHub is not a raw metric exporter: it is a semantic normalization layer aligned with OpenTelemetry. Connectors normalize vendor-specific data into a consistent model. These rules are mandatory for every connector.
All connectors:
- MUST use OpenTelemetry semantic conventions[1] whenever they exist.
- MUST reuse existing MetricsHub metric names before introducing new ones.
- MUST extend conventions in a consistent, structured, attribute-driven way.
- MUST NOT invent metric names directly from SNMP MIBs, REST payloads, or vendor documentation.
Where to check what already exists:
- The semconv dictionaries in this repository:
src/main/connector/semconv/(Hardware,System,Storage,Database) — see Reuse and Configuration[2]. - The metrics emitted by existing connectors (search
src/main/connector/for the measurement you need). - The OpenTelemetry semantic conventions[1].
Core Principles
Metrics Are Domain-Oriented
Metric names follow a structured namespace: <domain>.<subsystem>.<measurement> — for example hw.temperature, system.cpu.utilization, db.server.connections, storage.io. The first segment defines the domain:
| Domain | Scope |
|---|---|
hw |
Physical hardware components |
system |
OS-level metrics |
process |
Process-level metrics |
db |
Database server metrics |
storage |
Storage systems and arrays |
http |
HTTP services |
tcp / udp |
Network protocol metrics |
firewall |
Firewall appliances |
ssl |
SSL/TLS components |
service |
Logical services (load balancers, app services) |
Never mix domains: process metrics do not belong in system, hardware metrics do not belong in storage.
Attributes Over Metric Explosion
If you are about to create hw.disk.read.bytes and hw.disk.write.bytes — stop. Model the variant as an attribute:
system.disk.io{disk.io.direction="read"}
system.disk.io{disk.io.direction="write"}
Attributes represent dimensions:
- Direction:
read,write,receive,transmit - State:
used,free,idle - Type:
physical_disk,gpu,controller - Protocol:
tcp,udp,nfs_v4 - Limit type:
high.critical,low.degraded - Cache state:
hit,miss
Metric names represent what is measured, not its variants.
Reuse Before Extending
Before creating a new metric:
- Search the semconv dictionaries and existing connectors.
- Check OpenTelemetry semantic conventions.
- Check whether an attribute can model your case.
Reusable measurement patterns: *.limit, *.usage, *.utilization, *.operations, *.operation_time, *.io, *.errors, *.status, *.size, *.connections, *.sessions.
Domain Guidelines
hw — Hardware
Physical components: CPU, GPU, memory modules, physical disks, fans, power supplies, batteries, enclosures, network interfaces, tape drives.
| Pattern | Meaning |
|---|---|
hw.status |
Component health (stateSet: ok, degraded, failed) |
hw.temperature / hw.temperature.limit |
Temperature and thresholds |
hw.power / hw.power.limit |
Power consumption and thresholds |
hw.errors |
Hardware error count |
hw.network.io |
Interface traffic |
Wrong: dellFanCriticalTemperature. Correct:
hw.temperature{hw.type="fan"}
hw.temperature.limit{limit_type="high.critical", hw.type="fan"}
Vendor detail goes in attributes (hw.status{hw.type="controller", netapp.storage.type="node"}) — never in the metric name.
system — Operating System
Use state/direction attributes, never name variants:
system.cpu.time{system.cpu.state="user"}
system.memory.usage{system.memory.state="used"}
system.disk.io{disk.io.direction="read"}
system.filesystem.usage{system.filesystem.state="used"}
Do not create system.cpu.user_time or system.cpu.idle_percent.
process — Processes
process.cpu.time, process.memory.usage, process.disk.io{disk.io.direction="read"}, process.thread.count. Never mix process metrics into system.
db — Databases
Structured as db.server.* (models the database instance, not the host):
db.server.connections
db.server.current_connections{db.connection.state="active"}
db.server.cache.operations{db.cache.state="hit"}
db.server.queries{db.query.state="slow"}
db.server.storage.io{db.io.direction="read"}
Vendor-specific extensions are acceptable only for vendor-unique functionality, with the vendor after db.server.: db.server.mariadb.galera_replication.status, db.server.postgresql.replication.lag. Never mysql_connections_total.
storage — Storage Systems
SAN/NAS/arrays: storage.io{storage.type="volume"}, storage.operations{storage.io.direction="read"}, storage.usage{storage.provisioning.state="used"}, storage.status. Vendor variants via attributes: storage.io{netapp.storage.type="aggregate"}.
http, tcp, udp — Network Services
Follow OpenTelemetry network conventions: http.server.requests, http.server.errors, tcp.server.packets{tcp.method="SYN"}, udp.server.io. Use attributes (http.method.type, protocol.version, network.io.direction) — never http_get_requests.
firewall
firewall.sessions, firewall.connections, firewall.vpn.io, firewall.ssl.io, with protocol, direction, tunnel.phase attributes. Vendor between domain and measurement when structural: firewall.palo_alto.vsys.sessions.
Vendor-Specific Metrics
- Prefer attributes: if the vendor detail is a variant, model it as
storage.io{vendor.attribute="value"}. - Vendor namespace only for structural differences:
db.server.mariadb.galera_replication.status. - Never encode the vendor in the root metric name:
netapp_volume_read_latencyis wrong;storage.latency{netapp.storage.type="volume"}is right.
Limits, Usage, Utilization
Strict semantic meanings — do not mix them:
| Metric | Meaning |
|---|---|
*.limit |
Upper bound of the corresponding metric: a total capacity (system.memory.limit, system.filesystem.limit), a link/design speed (hw.network.bandwidth.limit), or an alerting threshold qualified by limit_type (hw.temperature.limit{limit_type="high.critical"}) |
*.usage |
Absolute used value |
*.utilization |
Ratio between 0 and 1 (unit 1) — always convert percentages, e.g. with percent2Ratio($n) |
*.size |
Total size |
*.operations |
Count of operations |
*.operation_time |
Time spent performing operations |
*.io |
Volume of data transferred |
Attribute Naming
Attributes follow OpenTelemetry-style dotted notation: system.cpu.state, db.cache.state, storage.io.direction, network.transport, limit_type, error.type. Use error.type in non-hardware domains and hw.error.type for hardware errors. Keep casing and naming consistent with existing connectors.
What NOT To Do
- Do not mirror SNMP OID or MIB entry names.
- Do not encode units in metric names (declare
unitin the metric metadata instead). - Do not create one metric per state — use a
stateSetor state attribute. - Do not duplicate direction in the metric name.
- Do not create vendor-prefixed root metrics.
Decision Tree
When implementing a connector:
- Identify the domain.
- Search existing metric names (semconv dictionaries, existing connectors, OTel).
- Reuse the measurement pattern.
- Use attributes for variants.
- Introduce a vendor namespace only if structurally required.
- Validate against OpenTelemetry semantics.
When unsure, default to: a generic metric, rich attributes, no vendor prefix.
If you find yourself copying a vendor metric name directly, you are almost certainly doing it wrong.
- [1] https://opentelemetry.io/docs/specs/semconv/
- [2] reuse-and-configuration.html
