Skip to content

feat(otlp): add OTLP/JSON channel (@microsoft/applicationinsights-otlpchannel-js) - #2751

Draft
JacksonWeber wants to merge 1 commit into
microsoft:mainfrom
JacksonWeber:jacksonweber/otlp-json-channel
Draft

feat(otlp): add OTLP/JSON channel (@microsoft/applicationinsights-otlpchannel-js)#2751
JacksonWeber wants to merge 1 commit into
microsoft:mainfrom
JacksonWeber:jacksonweber/otlp-json-channel

Conversation

@JacksonWeber

Copy link
Copy Markdown
Contributor

Summary

Adds @microsoft/applicationinsights-otlpchannel-js (0.1.0), a new preview channel that converts Application Insights telemetry to OTLP/JSON in memory and exports it to an OpenTelemetry Protocol (OTLP) HTTP endpoint (/v1/traces and /v1/logs). It requires no @opentelemetry/* dependency and can be used on its own or alongside the existing sender, which forwards every item along the chain (the tee channel is only needed when the channels must be in separate queues).

Details

  • Conversion happens on the ingest path. Items are converted and serialized inside processTelemetry as they are received, and records are buffered pre-grouped by resource and signal with incremental byte accounting, so sending a batch performs no conversion work. This keeps the page unload path as fast as possible.
  • Mapping. RequestData / RemoteDependencyData / PageviewData are exported as spans, and MessageData / ExceptionData / EventData / PageviewPerformanceData as log records. Native Common Schema spans (OTelSpan) are exported as spans directly, preserving their kind, parent, trace state and status.
  • Attributes. Context tags are promoted onto the OTLP Resource; everything else becomes record attributes, with Application Insights specific values namespaced under microsoft..
  • Privacy. Values that the Common Schema marks as PII or customer content are dropped by default (configurable via piiMode), since OTLP has no equivalent marker.
  • Offline support. Implements getOfflineSupport() so it can be combined with @microsoft/applicationinsights-offlinechannel-js.

Example / validation

Adds examples/otlp, a multi page test site that runs two independent SDK instances per page against a local mock OTLP collector. It can be driven manually or run headlessly (npm test), and validates the OTLP envelope, resource attributes, span/log field validity, nanosecond timestamp precision, attribute well-formedness, and that the two instances stay fully isolated from each other. The collector config can optionally round-trip payloads through a real OpenTelemetry Collector so malformed data is rejected by the real protocol implementation rather than quietly accepted.

Repo wiring

Registers the package in rush.json, gruntfile.js, version.json, .aiAutoMinify.json and tools/release-tools/package_groups.json, and adds an RELEASES.md entry under Unreleased Changes.

Unit tests

New unit tests under channels/otlp-channel-js/Tests/Unit cover the channel lifecycle and config, channel chaining, item conversion, OTLP fidelity (including PII drop/hash modes) and nanosecond time utilities.

…pchannel-js)

Adds a new preview channel that converts Application Insights telemetry to
OTLP/JSON in memory and exports it to an OTLP HTTP endpoint (/v1/traces and
/v1/logs) with no @opentelemetry/* dependency.

- Conversion and serialization happen on the processTelemetry path, with
  records buffered pre-grouped by resource and signal and incremental byte
  accounting, so flushing a batch performs no conversion work
- RequestData / RemoteDependencyData / PageviewData export as spans;
  MessageData / ExceptionData / EventData / PageviewPerformanceData export as
  log records; native Common Schema OTelSpan items export as spans directly
- Context tags are promoted onto the OTLP Resource, other values become record
  attributes namespaced under microsoft.
- Values marked as PII or customer content are dropped by default (piiMode)
- Implements getOfflineSupport() for use with the offline channel
- Adds examples/otlp, a multi page test site running two isolated SDK
  instances per page against a local mock OTLP collector, runnable headlessly
- Registers the package in rush.json, gruntfile.js, version.json,
  .aiAutoMinify.json and package_groups.json

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
}

results.check(!seen[attr.key], path + " does not repeat the key '" + attr.key + "'");
seen[attr.key] = true;
seen[attr.key] = true;

validateAnyValue(results, attr.value, attrPath + "(" + attr.key + ").value");
map[attr.key] = attr.value;
const serviceName = resourceAttrs["service.name"] && resourceAttrs["service.name"].stringValue;
const marker = resourceAttrs["test.instance.marker"] && resourceAttrs["test.instance.marker"].stringValue;
if (serviceName) {
summary.services[serviceName] = (summary.services[serviceName] || 0) + 1;

if (isTrace) {
summary.spans++;
summary.spanNames[record.name] = (summary.spanNames[record.name] || 0) + 1;
const statusCode = record.status && typeof record.status.code !== "undefined"
? record.status.code : 0;

summary.spanKinds[kind] = (summary.spanKinds[kind] || 0) + 1;
? record.status.code : 0;

summary.spanKinds[kind] = (summary.spanKinds[kind] || 0) + 1;
summary.spanStatuses[statusCode] = (summary.spanStatuses[statusCode] || 0) + 1;
const telemetryType = attrs["microsoft.telemetry_type"] &&
attrs["microsoft.telemetry_type"].stringValue;
if (telemetryType) {
summary.telemetryTypes[telemetryType] = (summary.telemetryTypes[telemetryType] || 0) + 1;

if (serviceName && recordMarker) {
const bucket = summary.markersByService[serviceName] ||
(summary.markersByService[serviceName] = {});
if (serviceName && recordMarker) {
const bucket = summary.markersByService[serviceName] ||
(summary.markersByService[serviceName] = {});
bucket[recordMarker] = (bucket[recordMarker] || 0) + 1;
"Content-Length": Buffer.byteLength(payload),
"Access-Control-Allow-Origin": "*"
});
res.end(payload);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants