Entity Events
Status: Development
Overview
Entity events provide a way to communicate entity information as structured log events. This approach is complementary to defining entities as part of Resource data (see Entity Data Model).
Entity events are represented as structured events using the OpenTelemetry Logs Data Model,
specifically as Events with a defined EventName and attribute structure.
When to Use Entity Events
Entity events are particularly useful when:
No Associated Telemetry: The entity has no telemetry signals associated with it, or the telemetry is less important than the entity data itself.
Complex Descriptive Information: Entity descriptive information is too complex for simple resource attribute values. The resource attribute values are expected to be simple strings, but entity descriptions can contain complex values like maps and arrays (e.g., Kubernetes ConfigMap content, complex cloud metadata, nested tags).
Entity Relationships: The entity information needs to include relationships to other entities. Resource data cannot contain relationship information.
Lifecycle Tracking: There is a need to explicitly track entity lifecycle events (creation, state changes, deletion) independently from telemetry signals.
Entity events can be used alongside telemetry signals associated with entities to provide additional context and relationship information.
Event Types
Entity information is communicated through the following event types:
Entity State Event (
entity.state): Emitted when an entity is created, when its attributes change, or periodically to indicate the entity still exists.Entity Delete Event (
entity.delete): Emitted when an entity is removed.
Entity State Event
The Entity State Event is emitted when an entity is created, when its descriptive attributes change, or periodically to indicate the entity still exists.
Event Name: entity.state
Required Attributes:
| Attribute | Type | Description |
|---|---|---|
entity.type | string | Defines the type of the entity. MUST not change during the lifetime of the entity. For example: “service”, “host”, “k8s.pod”. |
entity.id | map<string, string> | Attributes that identify the entity. MUST not change during the lifetime of the entity. The map MUST contain at least one attribute. Keys and values MUST be strings. SHOULD follow OpenTelemetry semantic conventions for attribute names. |
Optional Attributes:
| Attribute | Type | Description |
|---|---|---|
entity.description | map<string, AnyValue> | Descriptive (non-identifying) attributes of the entity. These attributes are not part of the entity’s identity. Each Entity State event contains the complete current state of the entity’s description. When absent, MUST be treated as an empty map. Follows AnyValue definition: can contain scalar values, arrays, or nested maps. SHOULD follow OpenTelemetry semantic conventions for attributes. |
entity.relationships | array of maps | Relationships to other entities. Each relationship is a map containing: type (string, describes the relationship), entity.type (string, the type of the related entity), and entity.id (map<string, string>, identifying attributes of the related entity). When absent, MUST be treated as an empty array. |
entity.report.interval | int64 (seconds) | The reporting period for this entity. MUST be a non-negative value when present. When absent, the reporting period is unknown. A value of 0 indicates that no periodic state events will be sent. A positive value indicates the interval at which periodic state events will be emitted. Can be used by receivers to determine when to expect the next event and infer that an entity is gone if events stop arriving. |
Timestamp Field:
The Timestamp field of the LogRecord represents the time when this event was generated and sent.
Event Emission:
Implementations SHOULD emit Entity State events whenever entity descriptive attributes change,
and periodically based on the entity.report.interval value to indicate the entity still exists.
Implementations SHOULD also emit Entity Delete events when entities are removed.
Future Considerations:
Each Entity State event contains the complete current state of the entity. If scalability issues arise in the future, the specification may introduce a “patch” event mechanism to communicate only the changes rather than the full state.
Entity Delete Event
The Entity Delete Event indicates that a particular entity is gone.
Event Name: entity.delete
Required Attributes:
| Attribute | Type | Description |
|---|---|---|
entity.type | string | The type of the entity being deleted. |
entity.id | map<string, string> | Attributes that identify the entity being deleted. |
Optional Attributes:
| Attribute | Type | Description |
|---|---|---|
entity.delete.reason | string | The reason for entity deletion. Examples: “terminated”, “expired”, “evicted”, “user_requested”, “scaled_down”. |
Timestamp Field:
The Timestamp field of the LogRecord represents the time when the entity was deleted.
Delivery Guarantees:
Transmitting Entity Delete events is not guaranteed when an entity is gone. Recipients of
entity signals MUST be prepared to handle this situation by expiring entities that are no
longer seeing Entity State events reported. The expiration mechanism is based on the
previously reported entity.report.interval field. Recipients can use this value to compute when
to expect the next Entity State event and, if the event does not arrive in a timely manner,
consider the entity to be gone even if the Entity Delete event was not observed.
Recipients MUST also be prepared to receive an Entity Delete event out of order, for example, before the last Entity State event. In this case, recipients SHOULD apply state updates regardless, as each Entity State event represents the full current state of the entity and can be used to update a previously deleted entity record.
Entity Relationships
Entity relationships describe how entities are connected to each other. Relationships are embedded within Entity State events as an array of relationship descriptors.
Relationship Structure
Each relationship in the entity.relationships array is a map containing:
Required Fields:
| Field | Type | Description |
|---|---|---|
relationship.type | string | The type of relationship. Describes the semantic meaning of the relationship (e.g., “scheduled_on”, “contains”, “depends_on”). See Standard Relationship Types. |
entity.type | string | The type of the target entity. |
entity.id | map<string, string> | The identifying attributes of the target entity. |
Relationship Direction:
Relationships have direction: source --[type]--> target, where:
- The source is the entity emitting the Entity State event
- The target is referenced in the relationship descriptor
Standard Relationship Types
Relationship types form an open enumeration. Standard relationship types SHOULD be defined in OpenTelemetry semantic conventions. Custom relationship types MAY be defined to represent domain-specific relationships.
For example, a scheduled_on relationship type could be used to express that a workload
is scheduled on infrastructure (e.g., a Kubernetes Pod scheduled on a Node).
Relationship Placement
When choosing which entity should contain a relationship in its entity.relationships array,
implementations SHOULD prefer placing relationships on the entity type with the shorter
lifespan or higher churn rate. This minimizes the total number of Entity State events
that need to be sent.
Rationale: Since relationships are embedded in Entity State events, every time an entity’s relationships change, a new state event must be emitted. Placing relationships on the more stable entity would require frequent state event emissions whenever the shorter-lived entities are created or destroyed.
Examples:
Prefer:
k8s.pod -> part_of -> k8s.replicaset(relationship on the pod)- Rather than:
k8s.replicaset -> contains -> k8s.pod(relationship on the replicaset) - Reason: Pods churn frequently. With relationships on pods, only new pod state events are sent when pods are created/destroyed. If relationships were on the replicaset, every pod creation/destruction would require a new replicaset state event with an updated list of all contained pods.
- Rather than:
Prefer:
container -> part_of -> k8s.pod(relationship on the container)- Rather than:
k8s.pod -> contains -> container(relationship on the pod) - Reason: Containers may restart independently, so placing the relationship on the container reduces the number of pod state events.
- Rather than:
Prefer:
process -> runs_on -> host(relationship on the process)- Rather than:
host -> hosts -> process(relationship on the host) - Reason: Processes start and stop frequently, while hosts are long-lived.
- Rather than:
When both entities have similar lifespans, either direction is acceptable. Semantic conventions SHOULD provide guidance on relationship placement for common entity types.
Relationship Lifecycle
Creating Relationships:
Emit an Entity State event with the new relationship included in the entity.relationships array.
Updating Relationships:
Emit a new Entity State event with the updated entity.relationships array reflecting the current state.
Deleting Relationships:
Emit a new Entity State event with the relationship removed from the entity.relationships array.
Implicit Deletion: When an entity is deleted (Entity Delete event is emitted), all relationships where that entity is involved are implicitly deleted. Backends SHOULD handle this accordingly.
Examples
The following examples show the logical representation of entity events. These are NOT actual OTLP wire format representations, but rather illustrate the semantic structure of the events.
Kubernetes Pod Entity State
When a Kubernetes Pod is created or its attributes change:
LogRecord:
Timestamp: 2026-01-12T10:30:00.000000000Z
EventName: entity.state
Resource:
k8s.cluster.name: prod-cluster
Attributes:
entity.type: k8s.pod
entity.id:
k8s.pod.uid: abc-123-def-456
entity.description:
k8s.pod.name: nginx-deployment-66b6c
k8s.pod.labels:
app: nginx
version: "1.21"
tier: frontend
k8s.pod.phase: Running
entity.report.interval: 60
entity.relationships:
- relationship.type: scheduled_on
entity.type: k8s.node
entity.id:
k8s.node.uid: node-001
- relationship.type: part_of
entity.type: k8s.replicaset
entity.id:
k8s.replicaset.uid: rs-456
Service and Process Relationship
A host-level OTel Collector with process scraping (e.g. hostmetricsreceiver) emits a
process entity state event. It reads process metadata from the OS (via /proc on Linux).
LogRecord:
Timestamp: 2026-01-12T11:00:00.000000000Z
EventName: entity.state
Resource:
host.id: host-abc-123
host.name: prod-host-01
Attributes:
entity.type: process
entity.id:
process.pid: 4821
process.start_time: 1736928900
entity.description:
process.executable.name: payment-service
process.executable.path: /usr/bin/payment-service
process.command_line: /usr/bin/payment-service --port 8080
entity.report.interval: 300
The service.instance entity is emitted by an OTel SDK, which is the authoritative source:
it knows both its own service identity and the process it runs in. service.instance owns
the runs_on relationship to process. It also owns the part_of relationship to service,
since service instances are shorter-lived than the logical service they belong to.
LogRecord:
Timestamp: 2026-01-12T11:00:00.000000000Z
EventName: entity.state
Resource:
host.id: host-abc-123
host.name: prod-host-01
Attributes:
entity.type: service.instance
entity.id:
service.name: payment-service
service.namespace: prod
service.instance.id: payment-service-prod-abc123
entity.description:
service.version: "2.3.1"
entity.report.interval: 300
entity.relationships:
- relationship.type: runs_on
entity.type: process
entity.id:
process.pid: 4821
process.start_time: 1736928900
- relationship.type: part_of
entity.type: service
entity.id:
service.name: payment-service
service.namespace: prod
The service entity represents the logical service. It is also emitted by the OTel SDK
alongside the service.instance entity event.
LogRecord:
Timestamp: 2026-01-12T11:00:00.000000000Z
EventName: entity.state
Resource:
host.id: host-abc-123
host.name: prod-host-01
Attributes:
entity.type: service
entity.id:
service.name: payment-service
service.namespace: prod
entity.report.interval: 300
Entity Delete
When the Pod is terminated:
LogRecord:
Timestamp: 2026-01-12T11:00:00.000000000Z
EventName: entity.delete
Resource:
k8s.cluster.name: prod-cluster
Attributes:
entity.type: k8s.pod
entity.id:
k8s.pod.uid: abc-123-def-456
entity.delete.reason: terminated
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!