Install
$ agentstack add skill-fernandoartalf-al-copilot-skills-collection-bc-telemetry-generator ✓ 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
BC Telemetry Generator
Instruments Business Central AL codeunits with Application Insights telemetry. Analyzes a target codeunit, creates or extends a dedicated telemetry helper codeunit, and adds Telemetry.LogMessage calls following Microsoft best practices.
Reference: alguidelines.dev — Adding Telemetry
Prerequisites
- Target codeunit to instrument (user provides the codeunit)
- Available object ID for telemetry helper codeunit
- Extension prefix established (e.g., BCS)
- Application Insights configured in extension (or environment)
Workflow
Step 1: Read the Target Codeunit
Ask the user which codeunit to instrument. Read the file and identify:
- Public procedures — entry points needing start/end tracking
- Validation procedures — needing warning-level telemetry on failure
- Error-prone operations — posting, external calls, database writes
- Performance-sensitive paths — loops, bulk operations, external HTTP calls
- Feature decision points — discount type selection, payment method, routing logic
Step 2: Plan Telemetry Strategy
For each identified procedure, determine:
| Category | Verbosity | When to Log | |----------|-----------|-------------| | Lifecycle (start/end) | Normal | Entry points, key milestones | | Error | Error | Catch blocks, posting failures, validation errors | | Warning | Warning | Validation failures, degraded paths | | Performance | Warning | Operations exceeding threshold | | Feature usage | Normal | Business decisions, option selections |
Event ID scheme: [PREFIX]-[AREA][NNN] for info, [PREFIX]-[AREA]E[NNN] for errors, [PREFIX]-[AREA]W[NNN] for warnings, [PREFIX]-[AREA]P[NNN] for performance.
Example: BCS-SALES001, BCS-SALESE001, BCS-SALESW001, BCS-SALESP001
Step 3: Create or Extend Telemetry Helper Codeunit
Check if a telemetry helper already exists in the workspace. If so, add new procedures to it. If not, create one.
File location: Same feature folder as the target codeunit, or Codeunit/ folder.
Naming: [Prefix] [Feature] Telemetry (e.g., BCS Sales Telemetry)
Telemetry Helper Structure
codeunit [ID] "[Prefix] [Feature] Telemetry"
{
Access = Internal;
SingleInstance = true;
var
Telemetry: Codeunit Telemetry;
procedure LogOperationStarted(EventId: Text; Message: Text; CustomDimensions: Dictionary of [Text, Text])
begin
Telemetry.LogMessage(
EventId, Message,
Verbosity::Normal, DataClassification::SystemMetadata,
TelemetryScope::ExtensionPublisher, CustomDimensions);
end;
procedure LogOperationCompleted(EventId: Text; Message: Text; StartTime: DateTime; CustomDimensions: Dictionary of [Text, Text])
var
DurationMs: Duration;
begin
DurationMs := CurrentDateTime - StartTime;
CustomDimensions.Set('DurationMs', Format(DurationMs));
Telemetry.LogMessage(
EventId, Message,
Verbosity::Normal, DataClassification::SystemMetadata,
TelemetryScope::ExtensionPublisher, CustomDimensions);
end;
procedure LogError(EventId: Text; Message: Text; CustomDimensions: Dictionary of [Text, Text])
begin
CustomDimensions.Set('ErrorMessage', GetLastErrorText());
CustomDimensions.Set('ErrorCallStack', GetLastErrorCallStack());
Telemetry.LogMessage(
EventId, Message,
Verbosity::Error, DataClassification::SystemMetadata,
TelemetryScope::ExtensionPublisher, CustomDimensions);
end;
procedure LogWarning(EventId: Text; Message: Text; CustomDimensions: Dictionary of [Text, Text])
begin
Telemetry.LogMessage(
EventId, Message,
Verbosity::Warning, DataClassification::SystemMetadata,
TelemetryScope::ExtensionPublisher, CustomDimensions);
end;
procedure LogFeatureUsage(EventId: Text; FeatureArea: Text; FeatureAction: Text; CustomDimensions: Dictionary of [Text, Text])
begin
CustomDimensions.Set('FeatureArea', FeatureArea);
CustomDimensions.Set('FeatureAction', FeatureAction);
Telemetry.LogMessage(
EventId, FeatureArea + ' - ' + FeatureAction,
Verbosity::Normal, DataClassification::SystemMetadata,
TelemetryScope::ExtensionPublisher, CustomDimensions);
end;
procedure LogPerformanceWarning(EventId: Text; OperationName: Text; DurationMs: Duration; ThresholdMs: Integer; CustomDimensions: Dictionary of [Text, Text])
begin
if DurationMs Customer.Blocked::" " then begin
Clear(CustomDimensions);
CustomDimensions.Add('CustomerNo', SalesHeader."Sell-to Customer No.");
CustomDimensions.Add('BlockedReason', Format(Customer.Blocked));
BCStelemetry.LogWarning('BCS-SALESW001', 'Order validation failed: Customer blocked', CustomDimensions);
Error('Customer %1 is blocked.', Customer."No.");
end;
Performance Monitoring
StartTime := CurrentDateTime;
ValidateOrder(SalesHeader);
Duration := CurrentDateTime - StartTime;
BCStelemetry.LogPerformanceWarning(
'BCS-SALESP001', 'ValidateOrder', Duration, 1000, CustomDimensions);
Feature Usage
BCStelemetry.LogFeatureUsage(
'BCS-FEAT001', 'Discounts', 'Line Discount Applied', CustomDimensions);
Step 6: Build and Validate
- Run
al_buildto verify compilation - Check
@problemsfor errors - Verify no sensitive data is logged
Event ID Convention
| Pattern | Meaning | Example | |---------|---------|---------| | PREFIX-AREA### | Informational | BCS-SALES001 | | PREFIX-AREAE### | Error | BCS-SALESE001 | | PREFIX-AREAW### | Warning | BCS-SALESW001 | | PREFIX-AREAP### | Performance | BCS-SALESP001 | | PREFIX-FEAT### | Feature usage | BCS-FEAT001 |
- Keep the AREA tag short (4-8 chars)
- Number sequentially within a category
- Maintain an event ID registry comment at the top of the telemetry codeunit
DataClassification Rules
| Data Type | Classification | Examples | |-----------|---------------|----------| | Technical metrics | SystemMetadata | Duration, counts, operation name | | Business identifiers | CustomerContent | Order No., Customer No., amounts | | User references | EndUserIdentifiableInformation | User ID (anonymize!) | | Sensitive data | NEVER LOG | Passwords, API keys, credit cards |
Best Practices
- Don't over-log — log entry/exit of key operations, not every line
- Use consistent event IDs — prefix + area + sequential number
- Include helpful dimensions — enough to diagnose issues, not everything
- Clear dimensions before reuse — call
Clear(CustomDimensions)between events - Log at appropriate verbosity — Normal for info, Warning for degraded paths, Error for failures
- Always use TelemetryScope::ExtensionPublisher — routes to your Application Insights
- Keep dimension values short — Application Insights truncates at ~8 KB per event
- Never log PII — anonymize user IDs, never log passwords or tokens
- Add duration to completion events — essential for performance analysis
- Leave telemetry helper body empty for feature usage — just add dimensions and call helper
Advanced Patterns
- Telemetry wrapper codeunit: See [references/telemetry-reference.md](references/telemetry-reference.md#telemetry-wrapper-pattern)
- Contextual telemetry (environment, version): See [references/telemetry-reference.md](references/telemetry-reference.md#contextual-telemetry)
- KQL queries for Application Insights: See [references/kql-queries.md](references/kql-queries.md)
External References
- alguidelines.dev — Adding Telemetry
- Microsoft Docs — Telemetry Codeunit
- Microsoft Docs — Custom Telemetry Signals
- Microsoft Docs — Application Insights for Extensions
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: fernandoartalf
- Source: fernandoartalf/AL-Copilot-Skills-Collection
- License: MIT
- Homepage: https://alcopilotskills.com/
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.