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:

  1. No Associated Telemetry: The entity has no telemetry signals associated with it, or the telemetry is less important than the entity data itself.

  2. 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).

  3. Entity Relationships: The entity information needs to include relationships to other entities. Resource data cannot contain relationship information.

  4. 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:

  1. Entity State Event (entity.state): Emitted when an entity is created, when its attributes change, or periodically to indicate the entity still exists.

  2. 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:

AttributeTypeDescription
entity.typestringDefines the type of the entity. MUST not change during the lifetime of the entity. For example: “service”, “host”, “k8s.pod”.
entity.idmap<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:

AttributeTypeDescription
entity.descriptionmap<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.relationshipsarray of mapsRelationships 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.intervalint64 (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:

AttributeTypeDescription
entity.typestringThe type of the entity being deleted.
entity.idmap<string, string>Attributes that identify the entity being deleted.

Optional Attributes:

AttributeTypeDescription
entity.delete.reasonstringThe 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:

FieldTypeDescription
relationship.typestringThe type of relationship. Describes the semantic meaning of the relationship (e.g., “scheduled_on”, “contains”, “depends_on”). See Standard Relationship Types.
entity.typestringThe type of the target entity.
entity.idmap<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.
  • 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.
  • 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.

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