Telemetry requires a Telemetry Logger implementation

Properties
AC0034 Warning Design Code Fix Ignore Obsolete

Codeunit Telemetry and Codeunit "Feature Telemetry" do not call Session.LogMessage for the calling app. They look up the "Telemetry Logger" registered for the calling app’s publisher and hand the message to it. A logger is registered by a subscriber to the OnRegisterTelemetryLogger event of Codeunit "Telemetry Loggers".

Every publisher needs to have an implementation of the “Telemetry Logger” interface and a subscriber to “Telemetry Loggers”.OnRegisterTelemetryLogger event in one of their apps in order for this codeunit to work as expected

— Codeunit Telemetry on Microsoft Learn

When no logger is registered for the publisher, "Telemetry Loggers Impl." logs warning 0000G7K and discards the message. The publisher’s Application Insights resource never receives the event:

An app from publisher %1 is sending telemetry, but there is no registered telemetry logger for this publisher.

— NoPublisherErr label in "Telemetry Loggers Impl." in the System Application

Implement "Telemetry Logger" in the app and register it in an OnRegisterTelemetryLogger subscriber.

Example

codeunit 50101 "Sales Order Telemetry" // Telemetry requires a Telemetry Logger implementation [AC0034]
{
    procedure LogOrderReleased()
    var
        FeatureTelemetry: Codeunit "Feature Telemetry";
    begin
        FeatureTelemetry.LogUsage('0000ABC', 'Sales Order Release', 'Sales order released');
    end;
}

"Sales Order Telemetry" stays as it is. Add a codeunit that implements "Telemetry Logger" and registers itself:

codeunit 50111 "App Telemetry Logger" implements "Telemetry Logger"
{
    Access = Internal;

    procedure LogMessage(EventId: Text; Message: Text; Verbosity: Verbosity; DataClassification: DataClassification; TelemetryScope: TelemetryScope; CustomDimensions: Dictionary of [Text, Text])
    begin
        Session.LogMessage(EventId, Message, Verbosity, DataClassification, TelemetryScope, CustomDimensions);
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Telemetry Loggers", 'OnRegisterTelemetryLogger', '', true, true)]
    local procedure OnRegisterTelemetryLogger(var Sender: Codeunit "Telemetry Loggers")
    var
        TelemetryLogger: Codeunit "App Telemetry Logger";
    begin
        Sender.Register(TelemetryLogger);
    end;
}

The registration is per publisher, not per app: the System Application expects exactly one "Telemetry Logger" implementation registered per app publisher. AC0034 only checks that the app contains an implementation. It does not check that the implementation is registered.

When the diagnostic is reported

  • An object declares a global variable, local variable, parameter or return value of type Codeunit Telemetry or Codeunit "Feature Telemetry". Locals in triggers of fields, actions, controls, report data items and XMLport elements count.
  • No codeunit in the same app implements "Telemetry Logger".
  • The telemetry codeunits are matched on both their ID (8711 for Telemetry, 8703 for "Feature Telemetry") and their name.
  • One diagnostic is reported per object, on the object name, regardless of how many telemetry variables the object declares.

Exception

Test codeunits (Subtype = Test or TestRunner) and obsolete objects are not reported.

Only codeunits in the app being compiled count as an implementation. Because the logger is registered per publisher, a logger in a dependency app from the same publisher, such as a shared foundation app, serves every app of that publisher, but AC0034 does not see it. Suppress the diagnostic on the object:

// The "Telemetry Logger" for this publisher is implemented and registered in the
// foundation app, a dependency from the same publisher: one logger per publisher.
#pragma warning disable AC0034
codeunit 50101 "Sales Order Telemetry"
#pragma warning restore AC0034
{
    procedure LogOrderReleased()
    var
        FeatureTelemetry: Codeunit "Feature Telemetry";
    begin
        FeatureTelemetry.LogUsage('0000ABC', 'Sales Order Release', 'Sales order released');
    end;
}

For an app that relies on a shared logger throughout, disable the rule in the ruleset instead.

AC0033 applies the same check to Codeunit "Rest Client" and "Http Client Handler".

See also