Skip to content

Add configurable business tracing profile - #90

Merged
yilmaztayfun merged 2 commits into
masterfrom
feature/business-tracing-profile
Aug 10, 2026
Merged

Add configurable business tracing profile#90
yilmaztayfun merged 2 commits into
masterfrom
feature/business-tracing-profile

Conversation

@brnskn

@brnskn brnskn commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Introduces a configurable tracing detail level for Aether telemetry. The new Business profile becomes the default and keeps service boundaries and [Trace] application spans while suppressing low-level diagnostic noise. Applications that require the previous full-detail behavior can explicitly select the Verbose profile through configuration.

Key Changes

  • Added AetherTracingDetailLevel: Introduces Business and Verbose tracing profiles with a process-wide AetherTracingRuntime.
  • Changed the default profile to Business: Both AetherTracingOptions and the tracing runtime now default to the business-focused profile when no configuration is provided.
  • Preserved [Trace] spans: Application and business spans created through [Trace] remain available in both profiles.
  • Reduced diagnostic noise in Business: Suppresses EF Core instrumentation, distributed cache/lock diagnostic spans, low-level Dapr state/secret/configuration/lock requests, and ordered pipeline-step spans whose final display name starts with [.
  • Retained full diagnostics through Verbose: Explicitly selecting Verbose restores all configured diagnostic instrumentation.
  • Improved Dapr invocation spans: Remaining Dapr service invocation spans use clearer display names and include rpc.system, rpc.service, rpc.method, and dapr.app_id attributes.
  • Updated documentation and tests: Documents profile behavior and configuration while adding coverage for default selection, [Trace] behavior, infrastructure diagnostics, and business span filtering.

Implementation Details

The tracing profile can be configured globally through appsettings.json:

{
  "Telemetry": {
    "Tracing": {
      "DetailLevel": "Business"
    }
  }
}

To enable the complete diagnostic waterfall:

{
  "Telemetry": {
    "Tracing": {
      "DetailLevel": "Verbose"
    }
  }
}

If Telemetry:Tracing:DetailLevel is omitted, Aether now uses Business.

AddAetherTelemetry initializes the process-wide tracing profile from the bound options. Static infrastructure instrumentation uses AetherTracingRuntime.IsVerbose, while the BusinessSpanFilterProcessor removes ordered pipeline-step spans after their final display names are known.

This is a behavioral default change: applications that previously relied on the implicit verbose behavior should explicitly configure DetailLevel as Verbose.

Validation completed:

  • TraceDetailLevelTests: 4 passed
  • BusinessSpanFilterTests: 3 passed
  • git diff --check: clean

Summary by Sourcery

Introduce a configurable tracing detail level with a new default business-focused profile while keeping full diagnostics available via an explicit verbose profile.

New Features:

  • Add a process-wide Aether tracing detail level with Business and Verbose profiles configurable via options and runtime.
  • Add a BusinessSpanFilterProcessor to drop pipeline-detail spans while preserving business/application spans.
  • Enhance Dapr HTTP client invocation spans with clearer display names and standard RPC attributes.

Enhancements:

  • Gate infrastructure diagnostic spans, EF Core instrumentation, and various distributed cache/lock and Dapr diagnostics on the global tracing detail level.
  • Default Aether tracing options and runtime to the Business profile to reduce production trace noise.
  • Document tracing profiles, configuration, and guidance for using the global tracing runtime in custom instrumentation.

Tests:

  • Add TraceDetailLevelTests to verify global profile behavior, [Trace] span emission, and infrastructure diagnostics adherence to the detail level.
  • Add BusinessSpanFilterTests to validate default profile selection and business-span filtering behavior.

Summary by CodeRabbit

  • New Features

    • Added Business and Verbose tracing profiles, with Business as the default.
    • Added configurable diagnostic span collection, including infrastructure and Entity Framework Core tracing in Verbose mode.
    • Improved distributed cache and lock operation tracing.
    • Added filtering to omit detailed pipeline spans from exported telemetry in Business mode.
    • Enhanced Dapr invocation telemetry with additional metadata.
  • Documentation

    • Expanded tracing guidance with diagnostic examples and profile-specific behavior.

@brnskn
brnskn requested review from a team and yilmaztayfun and a lite review from Copilot August 10, 2026 09:36
@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a global tracing detail level with a new Business default profile, wires it into telemetry configuration/runtime, gates infrastructure diagnostics and HTTP/Dapr spans on this profile, adds a business-span filter processor, and updates docs/tests accordingly.

Flow diagram for configurable tracing detail level and Business profile

flowchart LR
    subgraph Config
        A[appsettings.json
Telemetry:Tracing:DetailLevel]
    end

    subgraph AspNetCore
        B[TelemetryOptions
AetherTracingOptions.DetailLevel]
        C[AddAetherTelemetry]
        D[AetherTracingRuntime.Configure]
        E[BusinessSpanFilterProcessor]
    end

    subgraph Infrastructure
        F[InfrastructureActivitySource
StartDiagnosticActivity]
        G[EF Core instrumentation
AddEntityFrameworkCoreInstrumentation]
        H[HTTP client instrumentation
FilterHttpRequestMessage
EnrichHttpClientActivity]
    end

    A --> B
    B --> C
    C --> D
    D --> F
    D --> G
    D --> H
    C --> E

    D -. IsVerbose false .- E
    D -. IsVerbose true .- G
    D -. IsVerbose true .- F
    D -. IsVerbose true .- H

    H -. suppress Dapr diagnostics when Business .- A2[Filtered Dapr diagnostic requests]
    E --> A3["Filter spans with DisplayName starting with [ ] (pipeline detail)"]
Loading

File-Level Changes

Change Details Files
Wire global tracing detail level into telemetry options and runtime, and use it to control OpenTelemetry setup.
  • Bind Telemetry:Tracing:DetailLevel into AetherTracingOptions with default Business profile.
  • Configure AetherTracingRuntime from AddAetherTelemetry using the bound detail level.
  • Gate EF Core instrumentation and a new BusinessSpanFilterProcessor on AetherTracingRuntime.IsVerbose.
framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherTelemetryServiceCollectionExtensions.cs
framework/src/BBT.Aether.AspNetCore/BBT/Aether/AspNetCore/Telemetry/TelemetryOptions.cs
framework/src/BBT.Aether.Core/BBT/Aether/Telemetry/AetherTracingProfile.cs
Introduce BusinessSpanFilterProcessor and pipeline-step filtering behavior for business profile.
  • Add BusinessSpanFilterProcessor that clears Recorded flag for spans whose final DisplayName starts with '['.
  • Register the processor only when the active profile is Business.
  • Cover behavior with BusinessSpanFilterTests exporting activities from a test ActivitySource.
framework/src/BBT.Aether.AspNetCore/BBT/Aether/AspNetCore/Telemetry/BusinessSpanFilterProcessor.cs
framework/test/BBT.Aether.Postgres.Tests/BusinessSpanFilterTests.cs
Gate infrastructure diagnostic spans on the verbose profile and expose helper for starting diagnostic activities.
  • Add InfrastructureActivitySource.StartDiagnosticActivity that returns null unless IsVerbose.
  • Switch distributed cache and distributed lock implementations to use StartDiagnosticActivity instead of Source.StartActivity.
  • Verify infrastructure diagnostics follow global detail level in tests.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/Telemetry/InfrastructureActivitySource.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Dapr/DaprDistributedLockService.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Redis/RedisDistributedLockHandle.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Redis/RedisDistributedLockService.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Dapr/DaprDistributedCacheService.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Dapr/DaprDistributedLockHandle.cs
framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs
Reduce Dapr and HTTP client diagnostic noise in Business profile while enriching remaining invocation spans.
  • Replace inline HTTP filter with ShouldTraceHttpRequest to respect exclusion patterns and suppress Dapr diagnostic calls when not verbose.
  • Introduce IsDaprDiagnosticRequest to identify low-level Dapr state/secret/config/lock endpoints.
  • Add EnrichHttpClientActivity to rename Dapr invoke spans and tag them with rpc.* and dapr.app_id attributes.
framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherTelemetryServiceCollectionExtensions.cs
Update documentation to describe tracing detail profiles and usage of [Trace] aspects under Business vs Verbose.
  • Clarify that [Trace] spans represent application/business spans and are emitted in both profiles, with bracket-prefixed pipeline detail filtered in Business.
  • Document Telemetry:Tracing:DetailLevel configuration, defaults, and its effect on diagnostic instrumentation.
  • Mention AetherTracingRuntime.IsVerbose as the hook for custom static instrumentation.
framework/docs/aspects/README.md
framework/docs/telemetry/README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds Business and Verbose tracing profiles. It configures OpenTelemetry instrumentation and filtering by profile, gates infrastructure diagnostic activities, enriches Dapr spans, and adds tests and documentation for the new behavior.

Changes

Tracing detail profiles

Layer / File(s) Summary
Tracing runtime contract
framework/src/BBT.Aether.Core/..., framework/src/BBT.Aether.AspNetCore/...
Adds AetherTracingDetailLevel, AetherTracingRuntime, and AetherTracingOptions.DetailLevel, which defaults to Business.
Profile-aware telemetry wiring
framework/src/BBT.Aether.AspNetCore/..., framework/docs/aspects/README.md, framework/docs/telemetry/README.md
Configures instrumentation by profile, filters Dapr traffic, enriches Dapr invocation spans, and filters bracket-prefixed spans in Business mode.
Diagnostic activity gating
framework/src/BBT.Aether.Infrastructure/...
Adds conditional diagnostic activity creation and routes distributed cache and lock activities through it.
Tracing profile validation
framework/test/BBT.Aether.Infrastructure.Tests/..., framework/test/BBT.Aether.Postgres.Tests/...
Tests runtime configuration, trace span behavior, infrastructure activity suppression, and exported span filtering.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Configuration
  participant AetherTelemetryServiceCollectionExtensions
  participant AetherTracingRuntime
  participant OpenTelemetry
  participant BusinessSpanFilterProcessor
  participant InfrastructureActivitySource

  Configuration->>AetherTelemetryServiceCollectionExtensions: register tracing options
  AetherTelemetryServiceCollectionExtensions->>AetherTracingRuntime: Configure(DetailLevel)
  AetherTelemetryServiceCollectionExtensions->>OpenTelemetry: configure profile-specific instrumentation
  OpenTelemetry->>BusinessSpanFilterProcessor: process completed activities
  BusinessSpanFilterProcessor-->>OpenTelemetry: clear Recorded for bracket-prefixed spans
  InfrastructureActivitySource->>AetherTracingRuntime: read IsVerbose
  InfrastructureActivitySource-->>OpenTelemetry: create diagnostic activity only in Verbose mode
Loading

Possibly related PRs

  • burgan-tech/aether#61: Shares changes to telemetry registration, infrastructure activity sources, and distributed cache and lock instrumentation.
  • burgan-tech/aether#63: Shares telemetry registration, distributed-lock tracing, and Entity Framework Core instrumentation changes.

Suggested reviewers: yilmaztayfun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding configurable business tracing profiles.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/business-tracing-profile

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In AetherTracingRuntime.Configure, the Enum.IsDefined call is using the wrong overload; it should pass the enum type (e.g., Enum.IsDefined(typeof(AetherTracingDetailLevel), detailLevel) or the generic Enum.IsDefined(detailLevel) overload if available in your target framework) to avoid a compile error.
  • Consider tightening the Dapr-path detection in IsDaprDiagnosticRequest by centralizing the path constants or patterns (e.g., precomputed HashSet of suffixes) to make it easier to maintain when new Dapr APIs are added and to avoid missing cases due to manual string lists.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AetherTracingRuntime.Configure`, the `Enum.IsDefined` call is using the wrong overload; it should pass the enum type (e.g., `Enum.IsDefined(typeof(AetherTracingDetailLevel), detailLevel)` or the generic `Enum.IsDefined(detailLevel)` overload if available in your target framework) to avoid a compile error.
- Consider tightening the Dapr-path detection in `IsDaprDiagnosticRequest` by centralizing the path constants or patterns (e.g., precomputed `HashSet` of suffixes) to make it easier to maintain when new Dapr APIs are added and to avoid missing cases due to manual string lists.

## Individual Comments

### Comment 1
<location path="framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherTelemetryServiceCollectionExtensions.cs" line_range="42" />
<code_context>
         }

         section.Bind(opts);
+        AetherTracingRuntime.Configure(opts.Tracing.DetailLevel);

         // Apply defaults and environment variables
</code_context>
<issue_to_address>
**issue (bug_risk):** Configure tracing detail level after all configuration sources (including environment) are applied.

Currently `AetherTracingRuntime.Configure` is called before defaults and environment-variable overrides are applied, so `AetherTracingRuntime.DetailLevel` may not match the final `opts.Tracing.DetailLevel`. Please move this call to after all configuration sources are applied so the runtime state reflects the effective tracing configuration.
</issue_to_address>

### Comment 2
<location path="framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherTelemetryServiceCollectionExtensions.cs" line_range="336-338" />
<code_context>
+               || path.StartsWith("/v1.0/configuration/", StringComparison.OrdinalIgnoreCase);
+    }
+
+    private static void EnrichHttpClientActivity(Activity activity, HttpRequestMessage request)
+    {
+        var segments = request.RequestUri?.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
+        if (segments is not { Length: >= 5 }
+            || !string.Equals(segments[0], "v1.0", StringComparison.OrdinalIgnoreCase)
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against null RequestUri to avoid a potential NullReferenceException in the enricher.

Because the null-conditional applies only to `AbsolutePath`, `Split` is still invoked on a null string, which will throw. Please add an explicit guard (e.g., early return when `request.RequestUri` is null or assign `AbsolutePath` to a local variable and null-check before calling `Split`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

}

section.Bind(opts);
AetherTracingRuntime.Configure(opts.Tracing.DetailLevel);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Configure tracing detail level after all configuration sources (including environment) are applied.

Currently AetherTracingRuntime.Configure is called before defaults and environment-variable overrides are applied, so AetherTracingRuntime.DetailLevel may not match the final opts.Tracing.DetailLevel. Please move this call to after all configuration sources are applied so the runtime state reflects the effective tracing configuration.

Comment on lines +336 to +338
private static void EnrichHttpClientActivity(Activity activity, HttpRequestMessage request)
{
var segments = request.RequestUri?.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Guard against null RequestUri to avoid a potential NullReferenceException in the enricher.

Because the null-conditional applies only to AbsolutePath, Split is still invoked on a null string, which will throw. Please add an explicit guard (e.g., early return when request.RequestUri is null or assign AbsolutePath to a local variable and null-check before calling Split).

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 41 complexity · 0 duplication

Metric Results
Complexity 41
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs`:
- Around line 19-29: Reset process-wide tracing state safely in both affected
tests: in TraceDetailLevelTests.cs lines 19-29, save the initial
AetherTracingRuntime.DetailLevel on entry and restore it in finally; in
BusinessSpanFilterTests.cs lines 57-83, save and restore the tracing profile
around AddAetherTelemetry, or prevent that call from mutating the static. If
these mutating tests may run concurrently, place them in a non-parallel test
collection.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ec4d859a-7f11-4b4d-ba0a-f6496afe24cf

📥 Commits

Reviewing files that changed from the base of the PR and between bdcaba6 and c8e1517.

📒 Files selected for processing (15)
  • framework/docs/aspects/README.md
  • framework/docs/telemetry/README.md
  • framework/src/BBT.Aether.AspNetCore/BBT/Aether/AspNetCore/Telemetry/BusinessSpanFilterProcessor.cs
  • framework/src/BBT.Aether.AspNetCore/BBT/Aether/AspNetCore/Telemetry/TelemetryOptions.cs
  • framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherTelemetryServiceCollectionExtensions.cs
  • framework/src/BBT.Aether.Core/BBT/Aether/Telemetry/AetherTracingProfile.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Dapr/DaprDistributedCacheService.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Dapr/DaprDistributedLockHandle.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Dapr/DaprDistributedLockService.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Redis/RedisDistributedLockHandle.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Redis/RedisDistributedLockService.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/Telemetry/InfrastructureActivitySource.cs
  • framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs
  • framework/test/BBT.Aether.Postgres.Tests/BusinessSpanFilterTests.cs

Comment on lines +19 to +29
AetherTracingRuntime.Configure(AetherTracingDetailLevel.Business);

Assert.False(AetherTracingRuntime.IsVerbose);

AetherTracingRuntime.Configure(AetherTracingDetailLevel.Verbose);

Assert.True(AetherTracingRuntime.IsVerbose);
}
finally
{
AetherTracingRuntime.Configure(AetherTracingDetailLevel.Business);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether xUnit parallel execution is disabled or scoped by collections.
rg -n -C 3 'CollectionBehavior|DisableTestParallelization|parallelizeTestCollections|parallelizeAssembly' framework

# Find every process-wide tracing runtime mutation in tests.
rg -n -C 3 'AetherTracingRuntime\.Configure|AddAetherTelemetry\s*\(' framework/test

Repository: burgan-tech/aether

Length of output: 156


🏁 Script executed:

#!/bin/bash
set -u

echo "== tracked test files matching targets =="
git ls-files 'framework/test/**/TraceDetailLevelTests.cs' 'framework/test/**/BusinessSpanFilterTests.cs' || true

echo "== all AetherTracingRuntime.Configure occurrences =="
rg -n -C 3 'AetherTracingRuntime\.Configure|AddAetherTelemetry\s*\(' framework/test || true

echo "== xUnit parallelization/collection attributes =="
rg -n -C 3 'CollectionBehavior|DisableTestParallelization|parallelizeTestCollections|parallelizeAssembly|Collection\s*\(' framework || true

Repository: burgan-tech/aether

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -u

echo "== AetherTracingRuntime definitions/usages =="
rg -n -C 3 'class AetherTracingRuntime|AetherTracingRuntime|AetherTracingDetailLevel|DetailLevel' framework/src framework/test || true

echo "== specific relevant files first 120 lines =="
for f in \
  framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs \
  framework/test/BBT.Aether.Postgres.Tests/BusinessSpanFilterTests.cs \
  framework/src/BBT.Aether.TestBase/BBT/Aether/Testing/TestBase.cs
do
  echo "--- $f"
  wc -l "$f"
  sed -n '1,140p' "$f"
done

echo "== xUnit disabling settings in project files =="
rg -n -C 3 'DisableTestParallelization|CollectionBehavior|ParallelizeTestCollections|xunit.runner|ParallelizeAssembly' -g '*.csproj' -g 'Directory.*Props' -g '*.targets' framework || true

Repository: burgan-tech/aether

Length of output: 35911


Reset tracing state on entry and wrap telemetry configuration.

AetherTracingRuntime.Configure(...) changes a process-wide static and can affect later tests. Save the initial AetherTracingRuntime.DetailLevel and restore it in finally, including at framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs#L19-L29. In framework/test/BBT.Aether.Postgres.Tests/BusinessSpanFilterTests.cs#L57-L83, save and restore the tracing profile around AddAetherTelemetry, or make that call not mutate the static. If tests can run in parallel, put mutators in a non-parallel collection.

📍 Affects 2 files
  • framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs#L19-L29 (this comment)
  • framework/test/BBT.Aether.Postgres.Tests/BusinessSpanFilterTests.cs#L57-L83
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs`
around lines 19 - 29, Reset process-wide tracing state safely in both affected
tests: in TraceDetailLevelTests.cs lines 19-29, save the initial
AetherTracingRuntime.DetailLevel on entry and restore it in finally; in
BusinessSpanFilterTests.cs lines 57-83, save and restore the tracing profile
around AddAetherTelemetry, or prevent that call from mutating the static. If
these mutating tests may run concurrently, place them in a non-parallel test
collection.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)
B Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8e151778f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +329 to +333
return path.StartsWith("/v1.0/state/", StringComparison.OrdinalIgnoreCase)
|| path.StartsWith("/v1.0-alpha1/state/", StringComparison.OrdinalIgnoreCase)
|| path.StartsWith("/v1.0-alpha1/lock/", StringComparison.OrdinalIgnoreCase)
|| path.StartsWith("/v1.0/secrets/", StringComparison.OrdinalIgnoreCase)
|| path.StartsWith("/v1.0/configuration/", StringComparison.OrdinalIgnoreCase);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict Dapr route matching to the sidecar

In the Business profile, every outgoing HTTP request whose path starts with one of these prefixes is suppressed, regardless of its host. Consequently, a normal dependency request such as https://api.example.com/v1.0/state/orders/123 is mistaken for Dapr traffic and loses its service-boundary span. Check that the destination is the configured Dapr sidecar before applying these path-based exclusions.

Useful? React with 👍 / 👎.

Comment on lines +339 to +342
if (segments is not { Length: >= 5 }
|| !string.Equals(segments[0], "v1.0", StringComparison.OrdinalIgnoreCase)
|| !string.Equals(segments[1], "invoke", StringComparison.OrdinalIgnoreCase)
|| !string.Equals(segments[3], "method", StringComparison.OrdinalIgnoreCase))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enrich Dapr invocations made over gRPC

This recognizes only the Dapr HTTP invocation route, but the framework's DaprExternalService.InvokeAsync calls DaprClient.InvokeMethodAsync (DaprExternalService.cs:25-29), whose sidecar request uses the gRPC path /dapr.proto.runtime.v1.Dapr/InvokeService. Those are the invocation spans produced by the repository's normal Dapr flow, so they pass through without the new display name or rpc.*/dapr.app_id attributes.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a configurable tracing “detail level” so Aether telemetry can default to a quieter, business-focused span set while still allowing full diagnostic output when explicitly enabled. This fits the telemetry stack by centralizing the decision in a process-wide runtime (AetherTracingRuntime) and using it to gate/export instrumentation and diagnostic spans.

Changes:

  • Introduces AetherTracingDetailLevel (Business default, Verbose opt-in) and a process-wide AetherTracingRuntime.
  • Gates infrastructure diagnostics (cache/lock) and EF Core instrumentation behind the Verbose profile, and filters bracket-prefixed pipeline-step spans in Business.
  • Improves Dapr invocation span naming/attributes and adds docs + tests covering the new behavior.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
framework/test/BBT.Aether.Postgres.Tests/BusinessSpanFilterTests.cs Adds tests verifying the business-span filter behavior across profiles.
framework/test/BBT.Aether.Infrastructure.Tests/BBT/Aether/Tracing/TraceDetailLevelTests.cs Adds tests for global runtime behavior, [Trace] spans, and infra diagnostics gating.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/Telemetry/InfrastructureActivitySource.cs Adds helper to start infra diagnostic spans only in Verbose.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Redis/RedisDistributedLockService.cs Routes lock diagnostic spans through the new StartDiagnosticActivity gate.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Redis/RedisDistributedLockHandle.cs Routes lock diagnostic spans through the new StartDiagnosticActivity gate.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Dapr/DaprDistributedLockService.cs Routes lock diagnostic spans through the new StartDiagnosticActivity gate.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedLock/Dapr/DaprDistributedLockHandle.cs Routes lock diagnostic spans through the new StartDiagnosticActivity gate.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs Routes cache diagnostic spans through the new StartDiagnosticActivity gate.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Dapr/DaprDistributedCacheService.cs Routes cache diagnostic spans through the new StartDiagnosticActivity gate.
framework/src/BBT.Aether.Core/BBT/Aether/Telemetry/AetherTracingProfile.cs Introduces detail-level enum and process-wide runtime state.
framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherTelemetryServiceCollectionExtensions.cs Applies runtime config, gates EF Core instrumentation, adds business filter processor, and improves Dapr HTTP client span enrichment/filtering.
framework/src/BBT.Aether.AspNetCore/BBT/Aether/AspNetCore/Telemetry/TelemetryOptions.cs Adds Tracing.DetailLevel option with Business default.
framework/src/BBT.Aether.AspNetCore/BBT/Aether/AspNetCore/Telemetry/BusinessSpanFilterProcessor.cs Adds export-time filter for bracket-prefixed pipeline-step spans in Business.
framework/docs/telemetry/README.md Documents the new tracing detail level and defaults/behavior.
framework/docs/aspects/README.md Documents [Trace] span behavior across profiles and interaction with detail level.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +306 to +312
private static bool IsDaprDiagnosticRequest(Uri? uri)
{
var path = uri?.AbsolutePath;
if (string.IsNullOrEmpty(path))
{
return false;
}
Comment on lines +336 to +339
private static void EnrichHttpClientActivity(Activity activity, HttpRequestMessage request)
{
var segments = request.RequestUri?.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (segments is not { Length: >= 5 }
Comment on lines +1 to +27
using System;
using System.Diagnostics;
using OpenTelemetry;

namespace BBT.Aether.AspNetCore.Telemetry;

/// <summary>
/// Removes pipeline-detail spans from the export path when the Business tracing profile is active.
/// </summary>
/// <remarks>
/// Pipeline steps assign their final display names while the activity is running, so this filter
/// must run on completion rather than at sampling time. Clearing the recorded flag allows the
/// standard OpenTelemetry activity export processors to skip the span while preserving its
/// in-process activity context for any child operations created during execution.
/// </remarks>
internal sealed class BusinessSpanFilterProcessor : BaseProcessor<Activity>
{
public override void OnEnd(Activity activity)
{
ArgumentNullException.ThrowIfNull(activity);

if (activity.DisplayName.StartsWith("[", StringComparison.Ordinal))
{
activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded;
}
}
}
Comment on lines +39 to +84
private static List<string> ExportTwoActivities(AetherTracingDetailLevel detailLevel)
{
var exportedNames = new List<string>();
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Telemetry:ServiceName"] = "business-span-filter-tests",
["Telemetry:MetricsEnabled"] = "false",
["Telemetry:LoggingEnabled"] = "false",
["Telemetry:Tracing:DetailLevel"] = detailLevel.ToString(),
["Telemetry:Tracing:EnableAspNetCore"] = "false",
["Telemetry:Tracing:EnableHttpClient"] = "false",
["Telemetry:Tracing:EnableEntityFrameworkCore"] = "false",
["Telemetry:Tracing:EnableConsoleExporter"] = "false",
["Telemetry:Tracing:EnableOtlpExporter"] = "false",
})
.Build();

var services = new ServiceCollection();
services.AddAetherTelemetry(
configuration,
configure: builder => builder.ConfigureTracing((_, tracing) =>
{
tracing.AddSource(ActivitySourceName);
tracing.AddProcessor(
new SimpleActivityExportProcessor(new CapturingActivityExporter(exportedNames)));
}));

using var serviceProvider = services.BuildServiceProvider();
using var tracerProvider = serviceProvider.GetRequiredService<TracerProvider>();
using var source = new ActivitySource(ActivitySourceName);

using (var pipelineStep = source.StartActivity("PipelineStep.ExecuteAsync"))
{
Assert.NotNull(pipelineStep);
pipelineStep.DisplayName = "[20] CreateTransitionRecordStep";
}

using (var transition = source.StartActivity("TransitionExecutor.ExecuteOneAsync"))
{
Assert.NotNull(transition);
transition.DisplayName = "transition/start";
}

return exportedNames;
}
@yilmaztayfun
yilmaztayfun merged commit c642763 into master Aug 10, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants