AgentStack
SKILL verified MIT Self-run

Bc Telemetry Generator

skill-fernandoartalf-al-copilot-skills-collection-bc-telemetry-generator · by fernandoartalf

Instruments Business Central AL codeunits with Application Insights telemetry using the System Application Telemetry codeunit. Analyzes an existing codeunit supplied by the user, generates a dedicated Feature Usage Telemetry codeunit (or extends an existing one) with helper procedures for LogStart/LogEnd with automatic duration, LogError with call stack, LogFeatureUsage, and LogPerformanceWarning…

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-fernandoartalf-al-copilot-skills-collection-bc-telemetry-generator

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Bc Telemetry Generator? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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_build to verify compilation
  • Check @problems for 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

  1. Don't over-log — log entry/exit of key operations, not every line
  2. Use consistent event IDs — prefix + area + sequential number
  3. Include helpful dimensions — enough to diagnose issues, not everything
  4. Clear dimensions before reuse — call Clear(CustomDimensions) between events
  5. Log at appropriate verbosity — Normal for info, Warning for degraded paths, Error for failures
  6. Always use TelemetryScope::ExtensionPublisher — routes to your Application Insights
  7. Keep dimension values short — Application Insights truncates at ~8 KB per event
  8. Never log PII — anonymize user IDs, never log passwords or tokens
  9. Add duration to completion events — essential for performance analysis
  10. 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

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.