Install
$ agentstack add skill-emgreppi-business-central-ai-skill-implementing-telemetry ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: AL Telemetry Implementation
Validation Gates
- After Step 3: Telemetry Logger registered (check
OnRegisterTelemetryLoggerfires) - After Step 5: Events appear in Application Insights within 5 minutes
- Final: KQL query returns your custom eventIds with correct dimensions
Key Concept
EventId prefix: Platform adds AL automatically → Code: APP-0001 → App Insights: ALAPP-0001
Procedure
Step 1: Configure Application Insights
In app.json:
{
"applicationInsightsConnectionString": "InstrumentationKey=xxx;IngestionEndpoint=https://xxx.applicationinsights.azure.com/;..."
}
Get connection string from: Azure Portal → Application Insights → Overview → Connection String
Step 2: Choose Telemetry Method
| Method | When to Use | |--------|-------------| | Feature Telemetry (Recommended) | Standard logging with auto dimensions, uptake tracking | | Session.LogMessage | Direct control, no duplicates, simple scenarios |
Step 3: Create Telemetry Logger (Required for Feature Telemetry)
CRITICAL: Exactly ONE per publisher!
codeunit " 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 " Telemetry Logger";
begin
Sender.Register(TelemetryLogger);
end;
}
Step 4: Define EventId Convention
Format: - (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 |
Step 5: Implement Logging
Using Feature Telemetry (Recommended)
var
FeatureTelemetry: Codeunit "Feature Telemetry";
CustomDimensions: Dictionary of [Text, Text];
begin
// Replace and field names with your source record
CustomDimensions.Add('', ."");
CustomDimensions.Add('', ."");
FeatureTelemetry.LogUsage('-0001', '', '', CustomDimensions);
FeatureTelemetry.LogError('-0002', '', '',
GetLastErrorText(), GetLastErrorCallStack(), CustomDimensions);
FeatureTelemetry.LogUptake('-0010', '',
Enum::"Feature Uptake Status"::Used);
end;
Using Session.LogMessage (Direct)
var
CustomDimensions: Dictionary of [Text, Text];
begin
// Replace and field names with your source record
CustomDimensions.Add('', ."");
CustomDimensions.Add('Operation', '');
Session.LogMessage('-0001', '', Verbosity::Normal,
DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions);
end;
Step 6: Hybrid Logging (Telemetry + Local Table)
For API integrations, use both:
- Telemetry: Synthetic data for monitoring/alerts
- Local Table: Complete JSON for debugging
See BC-Telemetry-Guide.md Section 14 for complete implementation.
Step 7: Query in Application Insights
Basic KQL Query:
traces
| where timestamp > ago(24h)
| where customDimensions.eventId startswith "AL-"
| project
timestamp,
eventId = tostring(customDimensions.eventId),
message,
customDimensions
| order by timestamp desc
Note: Remember the AL prefix rule from Key Concept when searching in App Insights.
Important Notes
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 and Scheduled Task Telemetry
Job Queue entries trigger Scheduled Tasks at platform level. Key event IDs:
- Job Queue (AL):
AL0000E24(Enqueued),AL0000E25(Started),AL0000E26(Success),AL0000HE7(Failure) - Scheduled Task (LC):
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.
Troubleshooting
| 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.
References
See references/ folder for:
kql-queries.md- Common KQL queriesjob-queue-telemetry.md- Job Queue and Scheduled Task monitoring
External Documentation
BC Telemetry:
- Microsoft: Telemetry Overview
- Microsoft: Telemetry Event IDs
- Microsoft: Feature Telemetry
- Microsoft: Custom Telemetry Events
- Microsoft: Task Scheduler
- BCTech Samples & KQL Queries
KQL Learning:
- MustLearnKQL - 21-part KQL tutorial series (Sentinel-focused but KQL syntax is universal)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: emgreppi
- Source: emgreppi/Business-Central-AI-Skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.