Skip to content

Allow customers to provide Telemetry properties at individual item level, and at global level. #820

@cijothomas

Description

@cijothomas

Present State
Currently ITelemetry has a TelemetryContext which can define the context of the ITelemetry item. This context holds information that are global than the individual item properties. Apart from well known fields like Cloud ("ai.cloud.roleinstnace"), Device("ai.user.devicetype") etc., TelemetryContext also contains a property bag collection to store any key,value (string,string) pair of information.

All concrete ITelemetry implementations defined in the base sdk (eg: RequestTelemetry, DependencyTelemetry) also implements ISupportProperties interface.
This gives them a 'Properties' bag which can store any key,value (string,string) pair of information applicable to the individual telemetry item.

TelemetryClient also contains a TelemetryContext and properties from it are automatically applied to all the telemetry items tracked using that instance of TelemetryClient.
In effect, there are 3 places to set properties about an item.

  1. Using Properties of ISupportProperties
  2. Using Properties of TelemetryContext of ITelemetry
  3. Using Properties of TelemetryContext of TelemetryClient (more like a helper method, as this property bag is simply copied to (2) in Track() method.

For the current json wire format, all the above properties are serialized into "properties" section inside the telemetry.

The present implementation internally uses same Dictionary to hold the properties of individual item, and that from TelemetryContext.
i.e
var req = RequestTelemetry()
req.Properties and req.Context.Properties are internally the same collection, each being affected by modification to the other.

Issues
Since all properties are serialized into same "properties" bag in json, AI back-end cannot distinguish whether any given property belongs to just individual item or it belongs to a more global context.
Withtout this information back-end or UI cannot make special provisions for the global properties.
For eg: UI could chose to index global properties for fast filtering.

As the current implementation internally uses the same object to hold both properties, users has no way of informing AI that some properties are meant to
be global and some are only applicable to telemetry item.

Proposal
We want to provide users with a way to specify properties for telemetry items in 2 levels - one is local to the individual item, and can be high cardinality.
Other is more of a 'global' property, which AI back-end could chose to treat special. (For eg: by providing UI filters for global propps)

By splitting the Properties of ISupportProperties and Properties of TelemetryContext into separate collection, user can achieve this.
But this might be breaking change for customers who counted on these two property bags being the same.

So we'd like to provide a new field in TelemetryContext, called GlobalProperties (making it obvious to users that these are global level properties, and to avoid confusion with Properties on ISupportProperties). Users wishing to supply global properties could use GlobalProperties on TelemetryContext to do so.
For properties limited to individual item, Properties on ISupportProperties could be used. The Properties on TelemetryContext would be marked obsolete.

Note: For initial implementation, the GlobalProperties will be serialized into same "properties" bag in wire format (only in wire format). This is temporary until back-ends are changed. Also there are few internal users who would be using this SDK with custom channel+serialization, to send data to different back-ends (which support global vs local). They can take advantage of this right away.

Eg:

var tc = new TelemetryClient();
var req = new RequestTelemetry()
// User can continue to use old way of populating properties as shown below.
// These properties however will not be distinguished by AI back-end.
req.Context.Properties.Add("ObsoleteProp", "Value");  // Still works but obsolete

// Setting properties like the following make it obvious that this property is applied to the Context, rather than individual item. Once backend changes are in, these items would be serialized separately
req.Context.GlobalProperties.Add("GlobalProp", "TrueValue");

// Following works as before. Distinct collection from the Context.GlobalProperties, but same collection as deprecated Context.Properties
req.Properties.Add("LoalPropKey", "Value"); 

Since no breaking change, we will ship this in 2.7 itself. And use 3.0 to remove the obsolete fields.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions