Special Attributes

Modality's flexible data model lets you put any number of key-value pairs, called attributes, on timelines and events. In this way you can collect runtime data and annotate your events with metadata about what part of the system they are from, which run they belong to, and much more.

There are a set of known attribute names which, if present, will contribute to enhanced Modality functionality. This document describes these special attributes and their functions.

# Namespaces

Attribute naming is done with a namespacing convention to group related attributes. Modality's well-known namespaces are:

  • source, for information about where an event came from, like source.line, source.module, etc...
  • internal, for information specific to the underlying plugin or tracing technology.
  • interaction, for information indicating to Modality that a timeline communicated with another timeline.

# Interaction Attributes

Interactions between timelines are a key concept in Modality, since a timeline receiving a message can change its behavior. Thus, when investigating problematic behavior, we must look at other timelines that have affected the timeline on which the bad behavior was observed. The following attributes, in the interaction namespace, are for recording communication between timelines.

# Example

For the purposes of illustration, let us imagine that a timeline named sender is sending a message to a timeline named receiver.

The general idea is that, when sender is going to send a message, it should record an event with one of the logical_time, timestamp, or nonce attributes described below. Then, when receiver gets the message, it should immediately record an event with interaction.remote_timeline_id and whichever of the remote_logical_time, remote_timestamp, or remote_nonce attributes corresponds to the event on sender.

With this information Modality can create a causal link, describing exactly which part of receiver's history has been affected by which part of sender's history.

       ─╮             [Interaction i0000] sending @ main   [3ab0c3184c604bcbb385882b6b6bdf1b:e5]
                 logical_time = 0:0:0:229
                 module_path = simple_multi
                 name = sending
nonce = 0
╰─────▶ [Interaction i0000] received @ worker01 [471ad6be22134524af15de8877b0c161:044f]
interaction.remote_nonce = 0
interaction.remote_timeline_id = 3ab0c318-4c60-4bcb-b385-882b6b6bdf1b
logical_time = 0:0:0:1103 module_path = simple_multi name = received

There are a few things to notice here:

  • The sending event records a nonce, generated by the system to uniquely identify this event at runtime.
  • The receiving event records the corresponding remote_nonce and remote_timeline_id.
  • Modality uses these attributes to create the causal link, as demonstrated by the arrow between the two timelines.
  • Both events record a logical_time, but this is not what is being used to record the interaction.

# Attribute Details

event.logical_time - Logical time for this event. Modality will match this to the interaction.remote_logical_time on an event on a different timeline to record an interaction between timelines. Most plugins record logical time automatically.

event.timestamp - Wall-clock time for this event. Modality will match this to the interaction.remote_timestamp on an event on a different timeline to record an interaction between timelines. In addition, recording wall clock time enables you to write time-based queries. (opens new window)

event.nonce - A cryptographic nonce (opens new window) to uniquely identify this event. Modality will match this to the interaction.remote_nonce on an event on a different timeline to record an interaction between timelines.

event.interaction.remote_timeline_id - This attribute is used to identify the timeline that has sent a message. When a timeline receives a communication from another timeline, it should record an event with remote_timeline_id to identify the timeline that sent the communication. This event must also have one of the three attributes below to identify when the communication was sent from the other timeline.

event.interaction.remote_logical_time - This attribute is used to identify the point in another timeline's history when it sent a message to this timeline. It will match the logical_time attribute on an event on that timeline. When a timeline receives a communication from another timeline, it should record an event with exactly one of remote_logical_time, remote_timestamp, or remote_nonce, along with remote_timeline_id, to identify where the communication came from.

event.interaction.remote_timestamp - This attribute is used to identify the point in another timeline's history when it sent a message to this timeline. It will match the timestamp attribute on an event on that timeline. When a timeline receives a communication from another timeline, it should record an event with exactly one of remote_logical_time, remote_timestamp, or remote_nonce, along with remote_timeline_id, to identify where the communication came from.

event.interaction.remote_nonce - This attribute is used to identify the point in another timeline's history when it sent a message to this timeline. It will match the nonce attribute on an event on that timeline. When a timeline receives a communication from another timeline, it should record an event with exactly one of remote_logical_time, remote_timestamp, or remote_nonce, along with remote_timeline_id, to identify where the communication came from.

event.interaction.remote_timeline., event.interaction.remote_event. - Attributes with these special prefixes may be used on the receive side of an interaction, and can be used to help Modality identify the send point of the interaction. For example, if an event has event.interaction.remote_timeline.name = "sender" and event.interaction.remote_event.sequence_id = 12, Modality will attempt to find an event which matches both those criteria and construct an interaction.

event.interaction.reverse - This attribute is used on the receive side of an explicit iteraction (one with event.interaction.remote_event.*). When it is set to true, the send and receive side of any constructed interaction from that event are reversed.

# Source Attributes

Information about the source of an event is often crucial, since once you have identified a problem you need to know where to go to fix it. As such, the source namespace is meant to collect all information about where an event came from, whatever that means. The attributes below are generally useful, but depending on your system you may wish to put further custom information in the source namespace.

event.source.file - The source file where this event is recorded.

event.source.line - The source line where this event is recorded.

# Other Attributes

event.name - Name for this event. This is commonly used to refer to this event in queries and various command output. As such, it is good for the name to be short but descriptive and unique.

event.payload - We recommend following the convention that an event which reports a single scalar value should put it in an attribute named event.payload. An example of this could be an event reporting a sensor reading, where the name indicates which sensor and the value of the reading is put in the event.payload attribute.

timeline.name - Name for this timeline. This is commonly used to refer to this timeline in queries and various command output. As such, it is good for the name to be short but descriptive and unique.

timeline.ingest_edge_id - Unique identifier for the operation that resulted in this timeline being included in Modality's database. Used by the modality delete command to select data for deletion.

timeline.run_id - Identifier for the system run that this timeline belongs to. Depending on the platform you are using this value may be set automatically. The default workspace automatically segments by run_id so that you can easily analyze individual runs.