Subscribing to Telemetry Data Using gNMI
The gNMI protocol defines the Subscribe
RPC for subscribing to telemetry
data. The telemetry collector uses this RPC to request updates from the network device for
state and configuration data.
Requests for new subscriptions are encapsulated within
a SubscribeRequest
message containing one or more resource paths. The
subscribed paths relate to specific data instances on the target network device. The request
can contain paths based on the OpenConfig or native Junos schemas.
The subscription request must also include one of the following modes:
-
ONCE
- a one-time request for data. -
POLL
- for periodic, on-demand retrieval of data. -
STREAM
- a long-lived subscription that streams data according to specified triggers.
Subscriptions in STREAM
mode must specify one of the following
sub-modes:
-
ON_CHANGE
- data updates are only sent when the value of the data item changes. -
SAMPLE
- data updates are sent once per sample interval based on an interval period specified in the subscription request. The default sample interval is 30 seconds. -
TARGET_DEFINED
- the network device receiving the subscription request determines the best type of delivery for the data on a per-leaf basis. If the path specified within the message refers to event-driven data, then anON_CHANGE
subscription might be created. For data that represents counter values aSAMPLE
subscription might be created.Note:The
TARGET_DEFINED
subscription requests for configuration paths are treated asON_CHANGE
requests only.
For ONCE
, ON_CHANGE
and SAMPLE
subscriptions, the collector can request an initial update containing the current state of the
paths in the subscription. This update, also known as an initial sync, is valuable
because:
-
The collector has a complete view of the current state of every field on the device for that sensor path.
-
Event-driven data (
ON_CHANGE
) is received by the collector at least once before the next event is seen. In this way, the collector is aware of the data state before the next event happens. -
Packet Forwarding Engine sensors that contain zero counter values that normally do not show up in streamed data due to zero-suppression are sent. This ensures that all fields from each line card are known to the collector.
The target device responds to the subscription request with a
SubscribeResponse
message. If the subscription request calls for an initial
sync, the target sends the data followed by the response message with the
sync_response
flag set to true
. After the intial sync, the
target device proceeds with updates for the paths according to the subscription mode.
The SubscribeRequest
message includes a flag called
updates_only
. When this flag is set to true
, the target
device does not send an initial sync, only subsequent updates as follows:
-
For
STREAM
subscriptions inSAMPLE
mode, the update is sent at the next sample interval. -
For
STREAM
subscriptions inON_CHANGE
mode, the update is sent upon the next value change. -
For
ONCE
subscriptions, only theSubscribeResponse
is sent withsync_response
set tofalse
, and the subscription is closed. -
TARGET_DEFINED
subscriptions are treated asON_CHANGE
for configuration paths and the update is sent upon the next value change.
The contents of the SubscribeRequest
and SubscribeResponse
messages are defined in gnmi.proto file. For more information on the Subscribe RPC and
subscription modes, see the gNMI specification at: gNMI Specification: Subscribing to Telemetry
Updates.
The following limitations apply to configuration paths:
-
POLL
subscriptions are not supported. -
Prefix paths are not included in the update messages.
-
The gNMI response is not supported for Juniper-specific metadata operations, such as
active/inactive
,insert before/after
,comment/annotate
, andprotect/unprotect
. These might appear in the message but are not valid. -
Unsupported parameters in the
SubscribeRequest
includesuppress_redundant
,heartbeat_level
,allow_aggregation
, andqos
. -
Only PROTO encoding is supported.
-
Extensions in
SubscribeRequest
messages are not supported -
Filtering of the subscription paths is supported only at a key level.
The following commit variants are not supported for
ON_CHANGE
andTARGET_DEFINED
subscriptions:commit at
,commit prepare/activate
, and batch commits.Commits are not supported from the
edit dynamic
andedit private
edit or configure modes.-
Update messages are not sent for presence containers.
-
For subscription lists where the identifier or key is the only leaf configured, there might not be an update message.
Examples
The following examples show subscription requests and responses made by a gNMI client and target device in protobuf format.
Example: ONCE mode
The following example shows a subscription request sent from a gNMI client in protobuf
format. The subscription mode is ONCE
and the OpenConfig resource path is
/system/aaa/authentication/users:
root@controller:~# /usr/local/bin/gnmic sub -a 10.225.0.0:32767 --mode once --path /system/aaa/authentication/users -u <username> -p <password> --format prototext
The target responds with a one-time update:
update: { timestamp: 1676294840 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test2" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } }
Example: ON_CHANGE
The following example shows a subscription request in STREAM
mode with
ON_CHANGE
sub-mode. The OpenConfig resource path is
/system/aaa/authentication/users/user[username="test1"]:
root@controller:~# /usr/local/bin/gnmic sub -a 10.225.0.0:32767 --mode stream --stream-mode on-change --path /system/aaa/authentication/users -u <username> -p <password> --format prototext
The OpenConfig configuration at the time of the subscription request:
user@root> show configuration openconfig-system:system aaa authentication | display set set openconfig-system:system aaa authentication users user test1 config password $ABC123 set openconfig-system:system aaa authentication users user test1 config role superuser
The example response message shows the values for the configuration paths and the
sync_response
flag set to true
:
update: { timestamp: 1676311979 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } } sync_response: true
The following configuration changes are made to the subscribed paths:
-
Add username for
test1
. -
Delete password for
test1
.
The target device sends the following update in response:
update: { timestamp: 1676312428 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } delete: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } }
Example: SAMPLE
The following example shows a subscription request in STREAM
mode and
SAMPLE
sub-mode. The OpenConfig resource path is
/system/aaa/authentication/users/user[username="test1"]:
root@controller:~# /usr/local/bin/gnmic sub -a 10.225.0.0:32767 --mode stream --stream-mode sample --sample-interval 5s --path /system/aaa/authentication/users -u <username> -p <password> --format prototext
The OpenConfig configuration at the time of the subscription request:
user@root> show configuration openconfig-system:system aaa authentication | display set set openconfig-system:system aaa authentication users user test1 config username test1 set openconfig-system:system aaa authentication users user test1 config password "$ABC123" set openconfig-system:system aaa authentication users user test1 config role superuser
The example response messages show an initial update sent with the
sync_response
flag set to true
and subsequent updates
sent at 5 second intervals:
update: { timestamp: 1676295454 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } } sync_response: true update: { timestamp: 1676295459 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } } update: { timestamp: 1676295464 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } }