Observables
How we model observables in our systems shapes how we understand, monitor, and reason about their behavior. In observability, the subject is the thing or part of the system that has structure and behavior. Like the main subject in a sentence, the subject in an observability toolkit is the center of attention for monitoring and analyzing. People and languages often use the subject to represent groups and nested structures. This collective way of thinking makes things easier to track and understand because it lets us group related things together, simplifying the monitoring of complex interactions and dependencies. Subjects can also represent abstract concepts, like situations, scenes, or scenarios, which our brains understand as a whole but can be tricky to model as a resource.
Subjects
At its core, a subject represents an entity that maintains a persistent identity as it evolves. Unlike resources, which primarily focus on static and manageable assets, subjects encompass structure, state, and behavior as integral components of their temporal existence. A subject can manifest as a concrete system component, such as a service or database, an abstract concept, like a user session or business transaction, or even a complex situation or scenario. The temporal continuity of a subject is fundamental to its nature. It exists beyond any single point in time, preserving its identity through state changes while providing essential context for understanding its behavioral evolution. This continuity enables us to track and comprehend changes over time in a manner that point-in-time resource snapshots cannot capture.
Emissions
In the subject-based model, all changes are simply emissions from a subject, eliminating the artificial distinction between states and signals that plague many current observability systems. Properties, a set of named states within the extent of a subject, can evolve in various patterns: some remain relatively stable, others exhibit cyclic patterns, and others change dynamically and unpredictably. There are threshold-based transitions where states abruptly transition between distinct values, event-driven changes triggered by external stimuli, and accumulative patterns indicating gradual evolution over time. Some states emerge from complex system interactions, while others are compositional, derived from the combination of other states.
Structures
Subjects naturally form hierarchical relationships that reflect both the system’s structure and behavioral patterns. These hierarchies emerge organically from the way systems are constructed and operate. A user session, for instance, consists of multiple transactions, each transaction comprising multiple steps, and each step involving multiple system components. These are not merely structural relationships; they represent genuine patterns of behavior and interaction that we must comprehend. The significance of this hierarchical model becomes clear when we consider how it effectively handles both concrete and abstract relationships. A database cluster, for example, is not merely a collection of nodes; it is a subject in its own right, possessing emergent properties and behaviors that arise from the interaction of its components. Similarly, a distributed transaction is not just a sequence of operations but a subject that encapsulates a complex pattern of interaction and state change.
Reframing
A resource-based model can make it hard to understand how systems work. It separates state changes from signals, making it confusing to see how systems behave. A service entity is not just a resource with some attributes that occasionally send signals; it is a real thing that changes in different ways, like its behavior.
A subject-based approach gets rid of these artificial boundaries. Every part of a system component, whether we usually think of it as a state or a signal, becomes another type of emission from that subject. This makes it easier to track and understand how systems work over time, and it is more like how we naturally think about systems.
The new approach to observability modeling is a significant advancement over traditional resource-based models. It aligns more closely with how systems behave and how humans reason about them, enabling more effective system understanding and analysis. While it differs from current practices, its benefits include model clarity, flexibility, and power. Framing observable entities as subjects rather than resources creates a more natural and powerful framework for understanding system behavior and handling modern system complexity while remaining intuitive and approachable for human operators.
The shift from “Resource” to “Subject” represents a fundamental change in how we understand system behavior. This terminological change significantly impacts our comprehension because the term “Resource” inherently frames our perspective around management, allocation, and consumption. Resources are viewed as assets to be used, tracked, and controlled, a perspective useful for infrastructure management but limiting to a comprehensive understanding of system behavior. This approach promotes a static, snapshot view, favoring property-based descriptions rather than dynamic interactions.
In contrast, the term “Subject” expands our conceptual framework. A subject is an entity with agency, identity, and temporal continuity. It exists, evolves, and interacts. When we model something as a subject, we naturally consider its behavior over time, interactions with other subjects, and its role within larger patterns of system behavior. This conceptual shift transforms our approach to system observation. Instead of asking “What resources does this system possess?” we inquire “What subjects are participating in this behavior?” Instead of tracking resource usage, we follow subject evolution. The change in terminology guides us toward more sophisticated and natural models of system behavior. Consider how this affects our understanding of the state. With resources, the state feels like a set of properties to be checked and updated. With subjects, the state becomes part of a continuous narrative of system evolution. We cease thinking about snapshots and instead think about trajectories.
Abstractions
The terminology also influences how we handle abstraction. Resources resist abstracting beyond tangible system components. Subjects naturally encompass situations, patterns, and emergent behaviors. This expansion of our conceptual vocabulary enables us to model and reason about higher-level system behaviors that resource-based thinking struggles to capture. What makes this distinction so potent is precisely its subtlety. By altering merely this one term in our mental model, we transform our perception of system behavior, observation, and analysis. It serves as a reminder that the languages and metaphors we employ profoundly shape our understanding.
The subject model bridges the philosophical divide between object-oriented and process-oriented ontologies. Objects are discrete entities with properties, while processes are continuous change flows. This dichotomy challenges reality. The subject model maintains object identity while embodying process change. It is neither static nor dynamic but a persistent evolving entity. Subjects handle state by recognizing different change patterns, from near-static to highly dynamic, as aspects of the subject’s existence. This bridge allows both object- and process-oriented thinking without forcing a choice. The subject connects structure, state, and behavior, tracking object-like and process-like aspects of the same fundamental entity for a more complete system model.
Efficiencies
The subject model is a fundamentally efficient approach for tracking system states. It requires only two types of emissions: initial state registration and later emissions for actual state changes. In contrast, OpenTelemetry’s implementation involves sending a comprehensive payload of resource attributes with each span or metric emission. This repetitive transmission of static data generates unnecessary network traffic and processing overhead. Consider a service emitting thousands of spans per second with identical resource attributes that rarely change. In hierarchical contexts, a single trace may contain redundant copies of resource attributes at multiple levels, which are repeatedly transmitted despite constant values.
A subject-based model maintains state efficiency by being temporally aware. All emissions reference the subject’s identity, implicitly understanding its current state from the last known state plus changes. This reduces network traffic and storage, providing a clearer semantic model of system behavior. Instead of treating each observation as an isolated event, we continuously monitor the subject’s state, only updating it when changes occur.
This efficiency is especially pronounced in large-scale systems with many identical contexts. It extends beyond performance, enhancing system modeling accuracy. Real systems maintain identity and signal changes, not repeatedly redefining their static properties. The subject model accurately reflects this reality, offering practical benefits in capacity and scalability.
Substrates
The Substrates API introduces a hierarchical model for managing distributed communication and state management. Circuits represent active processing units with associated communications or state changes. Conduits group and organize Channels based on signal type or semantic meaning, creating named channels for signal transmission. This three-level hierarchy enables precise control over signal flow and state management. The model is used to define the essence of systems in specific forms, functions, and flows. It facilitates the monitoring and management of distributed service-to-service communication and forms the basis for event sourcing, business analytics, process intelligence, situational awareness, cybernetic semiotics, and digital twins.
Let us start with the Subject interface definition within the Substrates API. Note the extension of the Extent interface, which is how structural hierarchies are abstractly defined across types in Substrates.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Identity @Provided interface Subject extends Extent < Subject >, Substrate { String id (); Name name (); Name type (); } |
We will cover the Extent interface in a future post, but another interface that extends it is Name.
1 2 3 4 5 6 |
@Identity @Provided interface Name extends Extent < Name >, Substrate { } |
We have seen in previous posts that a Name is used to create a Channel, but a Circuit and Conduit can be given a Name. The code below shows how the traditional resource can still be modeled as a Circuit and with it a Subject.
1 2 3 4 5 6 7 8 9 10 11 |
var resource = cortex.circuit ( cortex.name ( "Redis" ) ); out.println ( resource .subject () .part () ); |
Running the above code will print out the following:
1 2 3 |
Subject[name=Redis,type=Circuit,id=0cb1dac7-fc84-45c4-a982-bdeb2db6f623] |
A Circuit allows for the creation of multiple named Conduits. In the code below, a Conduit is used to represent integer counters emitted by the resource. The Source is then used to subscribe to emissions and print out the Subject of the Channels and the emission value. The part method is used to print only the immediate Extent.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var counters = resource.conduit ( cortex.name ( "Counters" ), Integer.class, Inlet::pipe ); var source = counters.source (); var subscription = source.subscribe ( ( subject, registrar ) -> registrar.register ( emission -> out.printf ( "%s -> %d%n", subject.part (), emission ) ) ); var hits = counters.compose ( cortex.name ( "cache.hit" ) ); var misses = counters.compose ( cortex.name ( "cache.miss" ) ); hits.emit ( 1 ); misses.emit ( 1 ); |
Here is the output:
1 2 3 4 |
Subject[name=cache.hit,type=Channel,id=b2ac1a2b-ab5f-47c7-b62a-4ff2ee4c9c9d] -> 1 Subject[name=cache.miss,type=Channel,id=138182c0-db44-494c-81df-7d8189ca842e] -> 1 |
The Subject structure can be seen using the path method in the Extent interface.
1 2 3 4 5 6 7 |
out.printf ( "%s -> %d%n", subject.path ("\n\t"), emission ) |
With the above code change, the printout from Channel interception reveals the three-level nesting.
1 2 3 4 5 6 7 8 |
Subject[name=Redis,type=Circuit,id=e41bfccf-dc78-4423-ab78-657a321a5e1b] Subject[name=Counters,type=Conduit,id=3dbee192-962d-40f9-aa57-404c0e3b6427] Subject[name=cache.hit,type=Channel,id=4fdbf813-2be8-4905-af70-5406d3e35612] -> 1 Subject[name=Redis,type=Circuit,id=e41bfccf-dc78-4423-ab78-657a321a5e1b] Subject[name=Counters,type=Conduit,id=3dbee192-962d-40f9-aa57-404c0e3b6427] Subject[name=cache.miss,type=Channel,id=7aa565ba-9a26-4207-a0c1-7bbcd531a72d] -> 1 |
In a future post, we will delve deeper into the Extent and State interfaces.