Logs custom events to Application Insights using Feature Telemetry or Session.LogMessage, tracks feature adoption with LogUptake, and queries telemetry data with KQL. Use when instrumenting BC extensions, debugging production issues, monitoring API integrations, or tracking feature usage.
72
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
OnRegisterTelemetryLogger fires)EventId prefix: Platform adds AL automatically → Code: APP-0001 → App Insights: ALAPP-0001
In app.json:
{
"applicationInsightsConnectionString": "InstrumentationKey=xxx;IngestionEndpoint=https://xxx.applicationinsights.azure.com/;..."
}Get connection string from: Azure Portal → Application Insights → Overview → Connection String
| Method | When to Use |
|---|---|
| Feature Telemetry (Recommended) | Standard logging with auto dimensions, uptake tracking |
| Session.LogMessage | Direct control, no duplicates, simple scenarios |
CRITICAL: Exactly ONE per publisher!
codeunit <ID> "<PREFIX> 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 "<PREFIX> Telemetry Logger";
begin
Sender.Register(TelemetryLogger);
end;
}Format: <PREFIX>-<NNNN> (with hyphen to distinguish from BC standard)
Organization by Range:
| Range | Area | Convention |
|---|---|---|
| 00xx | Area 1 (e.g., API to System A) | Even = success, Odd = error |
| 01xx | Area 2 (e.g., API to System B) | Even = success, Odd = error |
| 02xx | Authentication | Even = success, Odd = error |
| 09xx | Fallback/Generic | For unmapped operations |
Example Registry:
| EventId | Operation | Result |
|---|---|---|
APP-0001 | SendOrder | Success |
APP-0002 | SendOrder | Error |
APP-0003 | SendLine | Success |
APP-0004 | SendLine | Error |
var
FeatureTelemetry: Codeunit "Feature Telemetry";
CustomDimensions: Dictionary of [Text, Text];
begin
// Replace <Record> and field names with your source record
CustomDimensions.Add('<KeyFieldName>', <Record>."<KeyField>");
CustomDimensions.Add('<RelatedFieldName>', <Record>."<RelatedField>");
FeatureTelemetry.LogUsage('<PREFIX>-0001', '<FeatureName>', '<OperationDescription>', CustomDimensions);
FeatureTelemetry.LogError('<PREFIX>-0002', '<FeatureName>', '<OperationDescription>',
GetLastErrorText(), GetLastErrorCallStack(), CustomDimensions);
FeatureTelemetry.LogUptake('<PREFIX>-0010', '<FeatureName>',
Enum::"Feature Uptake Status"::Used);
end;var
CustomDimensions: Dictionary of [Text, Text];
begin
// Replace <Record> and field names with your source record
CustomDimensions.Add('<KeyFieldName>', <Record>."<KeyField>");
CustomDimensions.Add('Operation', '<OperationName>');
Session.LogMessage('<PREFIX>-0001', '<LogMessage>', Verbosity::Normal,
DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions);
end;For API integrations, use both:
See BC-Telemetry-Guide.md Section 14 for complete implementation.
Basic KQL Query:
traces
| where timestamp > ago(24h)
| where customDimensions.eventId startswith "AL<PREFIX>-"
| project
timestamp,
eventId = tostring(customDimensions.eventId),
message,
customDimensions
| order by timestamp descNote: Remember the AL prefix rule from Key Concept when searching in App Insights.
DataClassification: ALWAYS use SystemMetadata - other values won't be sent!
TelemetryScope: ExtensionPublisher = only your App Insights | All = yours AND customer's
Multi-App: ONE Telemetry Logger per publisher. Distinguish apps via alCallerAppName dimension.
Job Queue entries trigger Scheduled Tasks at platform level. Key event IDs:
AL0000E24 (Enqueued), AL0000E25 (Started), AL0000E26 (Success), AL0000HE7 (Failure)LC0040-LC0045, LC0057 (Created → Failed → Timeout)Correlate via alScheduledTaskId dimension in AL0000E24.
See references/job-queue-telemetry.md for complete event tables and KQL queries.
| Issue | Fix |
|---|---|
| Events not appearing | Check applicationInsightsConnectionString in app.json |
| Wrong eventId in App Insights | Remember: platform adds AL prefix automatically |
| DataClassification error | MUST use SystemMetadata - other values won't send |
| Duplicate events | Feature Telemetry creates 2 by design - de-duplicate in KQL |
Feedback loop: Fix configuration → Re-deploy → Wait 5 minutes → Re-check in App Insights.
See references/ folder for:
kql-queries.md - Common KQL queriesjob-queue-telemetry.md - Job Queue and Scheduled Task monitoringBC Telemetry:
KQL Learning:
52f8705
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.