Converge auto-instrumentation for 8.0 - #38
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis release updates the repository to version 8.0.0, narrows generated and public instrumentation surfaces, adds version-pinned AI/MCP/CoreWCF contracts and demos, changes telemetry ownership and timing, and expands generator, package, managed, and NativeAOT verification. Changes8.0 architecture and release
Runtime instrumentation changes
Generator and contract model
Demos and verification
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Demo
participant QylSdk as QylSdk.AddQyl
participant OpenTelemetry
participant ActivitySource
Demo->>QylSdk: configure enabled sources and meters
QylSdk->>OpenTelemetry: register sources, meters, and Azure processor
Demo->>ActivitySource: execute instrumented operation
ActivitySource->>OpenTelemetry: export activity and normalized tags
OpenTelemetry-->>Demo: provide captured telemetry for report validation
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cs`:
- Around line 25-37: The HttpRequestIn.Start branch in the ASP.NET Core
diagnostic listener forces sampling even when middleware owns instrumentation.
Gate the ActivityTraceFlags.Recorded assignment on
!QylAspNetCoreOwnership.MiddlewareRegistered, or remove that flag update from
this listener, while preserving the existing event handling and return flow.
In
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs`:
- Around line 39-41: Add an immediate null check after
QylActivitySource.StartAtAmbientStart in the diagnostic listener, returning
before tag evaluation or DatabaseSemantics.ShouldWriteQueryText when no Activity
is created. Preserve the existing instrumentation flow for observed activities.
In `@src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cs`:
- Around line 91-99: Thread the already-normalized method from
StartRequestActivity through InvokeAsync and ObserveAsync into RecordResponse,
then pass it to BackfillServerRoute. Remove the per-response
QylHttpMethod.Normalize call in RecordResponse while preserving the existing
response status and header handling.
In `@src/Qyl.Sdk/QylAzureSpanProcessor.cs`:
- Around line 27-39: Update FindExceptionType to traverse events with
activity.EnumerateEvents() instead of activity.Events, avoiding heap enumerator
allocation, and only enumerate an event’s tags when it is an exception event;
preserve returning the exception.type string when present and null otherwise.
🪄 Autofix (Beta)
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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5f2b841b-3ac4-4568-9bde-97eeb3b87f8d
⛔ Files ignored due to path filters (4)
docs/generated/qyl-aot-contract.resolved.yamlis excluded by!**/generated/**,!**/Generated/**,!**/generated/**docs/generated/qyl-aot-contract.schema.jsonis excluded by!**/generated/**,!**/Generated/**,!**/generated/**src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/buildTransitive/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore.Bootstrap.g.csis excluded by!**/*.g.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/buildTransitive/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.Bootstrap.g.csis excluded by!**/*.g.cs
📒 Files selected for processing (114)
AGENTS.mdCHANGELOG.mdDirectory.Build.propsDirectory.Packages.propsQyl.OpenTelemetry.AutoInstrumentation.Demos.slnxREADME.mdbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.csdemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.csdemos/Qyl.RealAzureDemo/Qyl.RealAzureDemo.csprojdemos/Qyl.RealCoreWcfDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Qyl.RealCoreWcfDemo.csprojdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealGenAiDemo/Qyl.RealGenAiDemo.csprojdemos/Qyl.RealGrpcClientDemo/LiveProbeClient.csdemos/Qyl.RealGrpcClientDemo/Program.csdemos/Qyl.RealGrpcClientDemo/Qyl.RealGrpcClientDemo.csprojdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.csdemos/Qyl.RealMcpDemo/Qyl.RealMcpDemo.csprojdemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealNetRuntimeMetricsDemo/Program.csdemos/Qyl.RealNpgsqlDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.csdemos/Qyl.RealSqlClientDemo/Qyl.RealSqlClientDemo.csprojdocs/contracts/qyl-aot-ownership.yamldocs/contracts/qyl-native-instrumentations.yamldocs/coverage-matrix.mddocs/qyl-aot-autoinstrumentation.conformance-plan.jsonsrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/ModuleInitializerBoot.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/PublicAPI.Unshipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/Qyl.OpenTelemetry.AutoInstrumentation.Hosting.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDurationMetrics.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation/Qyl.OpenTelemetry.AutoInstrumentation.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivityNames.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylHttpClientMetrics.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentationDomains.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedAspNetCore.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedAzure.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedEntityFrameworkCore.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedGrpcNetClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpWebRequest.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfCore.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricNames.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylNServiceBusMetrics.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylRuntimeProcessMetrics.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSignalOwnership.cssrc/Qyl.Sdk/Qyl.Sdk.csprojsrc/Qyl.Sdk/QylAzureSpanProcessor.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonltests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/verified/report.jsontools/generate-contract-artifacts.pytools/generator_manifest_coverage.pytools/smoketest.shtools/verify-aot-autoinstrumentation-goal.pytools/verify-aot-publish-gate.pytools/verify-aspnetcore-middleware-delegate.pytools/verify-contract-coverage-report.pytools/verify-contract-invariants.pytools/verify-environment-options-behavior.pytools/verify-generator-snapshots.pytools/verify-instrumentation-disabled-behavior.pytools/verify-otlp-receiver.pytools/verify-real-aspnetcore-demo.pytools/verify-real-azure-demo.pytools/verify-real-corewcf-demo.pytools/verify-real-genai-demo.pytools/verify-real-grpc-client-demo.pytools/verify-real-mcp-demo.pytools/verify-real-sqlclient-demo.pytools/verify-source-interceptor-consumer.pytools/verify-version-sync.py
💤 Files with no reviewable changes (28)
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedAzure.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylNServiceBusMetrics.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfCore.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/ModuleInitializerBoot.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylRuntimeProcessMetrics.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/PublicAPI.Unshipped.txt
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedAspNetCore.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylHttpClientMetrics.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedEntityFrameworkCore.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cs
- demos/Qyl.RealGrpcClientDemo/LiveProbeClient.cs
- demos/Qyl.RealGrpcClientDemo/Qyl.RealGrpcClientDemo.csproj
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedGrpcNetClient.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricNames.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/Qyl.OpenTelemetry.AutoInstrumentation.csproj
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpWebRequest.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDurationMetrics.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/SqlClient/SqlClientDiagnosticListener.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylSignalOwnership.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylActivityNames.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.cs
- tools/verify-real-grpc-client-demo.py
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentationDomains.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cs
- src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: verify (macos-latest)
- GitHub Check: verify (ubuntu-24.04-arm)
- GitHub Check: webapi-aot-demo (ubuntu-24.04-arm)
🧰 Additional context used
📓 Path-based instructions (21)
**/*.{cs,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,csproj,props,targets}: Preserve the supported public API surface and keep internal implementation types internal; use IVT for cross-assembly access rather than widening types to public.
UseSemanticModel.GetInterceptableLocation(...)and ordinary generated C# for Roslyn interception; do not use CLR profilers, startup hooks, ReJIT, runtime IL rewriting, dynamic plugin loading, or reflection-based instrumentation dispatch.
Prefer a first-class runtime or DI hook when it owns the behavior; intercept source-visible calls only when required, and never let two generators own the same call site.
Use official OTLP protobuf types and a real loopback receiver for runtime and protocol evidence; do not use hand-shaped OTLP JSON, fabricated identifiers or timestamps, protobuf substring searches, or echoing mocks as interoperability proof.
Keep Core limited to shared runtime and compiler-facing ABI; keep Hosting generic bootstrap/DI, DiagnosticListeners diagnostic-payload consumption,Qyl.Sdkonboarding/export concerns without interceptors, and dependency-heavy integrations isolated in their respective packages.
Synthetic verifier consumers must compile against the public surface only; fix consumers when types become internal, and grant narrowly named IVT access only to probers that genuinely require internals.
Update analyzer-managed shipped/unshipped API baselines for public API changes.
Files:
Directory.Build.propssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/Qyl.OpenTelemetry.AutoInstrumentation.Hosting.csprojsrc/Qyl.Sdk/Qyl.Sdk.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.csdemos/Qyl.RealCoreWcfDemo/Qyl.RealCoreWcfDemo.csprojdemos/Qyl.RealGenAiDemo/Qyl.RealGenAiDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.csdemos/Qyl.RealMcpDemo/Qyl.RealMcpDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.csDirectory.Packages.propssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.csdemos/Qyl.RealNetRuntimeMetricsDemo/Program.csdemos/Qyl.RealSqlClientDemo/Qyl.RealSqlClientDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.csdemos/Qyl.RealAzureDemo/Qyl.RealAzureDemo.csprojdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.csdemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.csdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.csdemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.csdemos/Qyl.RealGrpcClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.csdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.csbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs
**/*.{cs,csproj,props,targets,yml,yaml,py}
📄 CodeRabbit inference engine (AGENTS.md)
Every capability must have an executable owner, such as a product call path, owned consumer, or conformance application exercising the complete contract.
Files:
Directory.Build.propssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/Qyl.OpenTelemetry.AutoInstrumentation.Hosting.csprojsrc/Qyl.Sdk/Qyl.Sdk.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.csdemos/Qyl.RealCoreWcfDemo/Qyl.RealCoreWcfDemo.csprojdemos/Qyl.RealGenAiDemo/Qyl.RealGenAiDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.csdemos/Qyl.RealMcpDemo/Qyl.RealMcpDemo.csprojtools/verify-real-genai-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cstools/verify-aot-publish-gate.pytools/verify-real-azure-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cstools/verify-contract-coverage-report.pyDirectory.Packages.propssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cstools/verify-aot-autoinstrumentation-goal.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.csdemos/Qyl.RealNetRuntimeMetricsDemo/Program.csdemos/Qyl.RealSqlClientDemo/Qyl.RealSqlClientDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cstools/verify-aspnetcore-middleware-delegate.pytools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.csdemos/Qyl.RealAzureDemo/Qyl.RealAzureDemo.csprojdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cstools/verify-real-corewcf-demo.pydocs/contracts/qyl-native-instrumentations.yamlsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.cstools/verify-otlp-receiver.pydemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.csdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.cstools/verify-generator-snapshots.pydemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.cstools/verify-real-aspnetcore-demo.pytools/verify-version-sync.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cstools/verify-real-mcp-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cstools/verify-source-interceptor-consumer.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.csdemos/Qyl.RealGrpcClientDemo/Program.cstools/verify-instrumentation-disabled-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.csdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.csdocs/contracts/qyl-aot-ownership.yamltools/generator_manifest_coverage.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.csbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cstools/verify-real-sqlclient-demo.pytools/verify-environment-options-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cstools/generate-contract-artifacts.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/verify-contract-invariants.py
**
⚙️ CodeRabbit configuration file
**: Operating principles (solo-dev, agentic SDLC — reviews are advisory, agents act on them):
- LAZY: one self-contained, correct review beats ten partial ones. Every finding is
definitive — concrete evidence with file:line, a concrete fix, no "consider maybe",
no open or ambiguous questions back to the author. If you cannot decide a point
from the diff plus repo context, stay silent on it. Never cite a source, API, or
version you have not verified; an unverifiable claim is a dropped claim.- IMPATIENT: never stall a PR. Internal and dogfooding-only surfaces converge directly;
removing shims, breaking internal signatures, and deleting dead paths are normal.
Published NuGet APIs follow SemVer: breaking changes require a deliberate new major
and migration of known consumers. Do not request compatibility layers without a
proven consumer.- EGO: hold the bar of the best reviewer on the market — flag real correctness,
security, data-loss, and structural problems precisely; produce zero noise.
Files:
Directory.Build.propssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/Qyl.OpenTelemetry.AutoInstrumentation.Hosting.csprojsrc/Qyl.Sdk/Qyl.Sdk.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.csdemos/Qyl.RealCoreWcfDemo/Qyl.RealCoreWcfDemo.csprojtests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonldemos/Qyl.RealGenAiDemo/Qyl.RealGenAiDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.csdemos/Qyl.RealMcpDemo/Qyl.RealMcpDemo.csprojtools/verify-real-genai-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/PublicAPI.Shipped.txttools/verify-aot-publish-gate.pyCHANGELOG.mdtools/verify-real-azure-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cstools/verify-contract-coverage-report.pydocs/qyl-aot-autoinstrumentation.conformance-plan.jsonDirectory.Packages.propssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cstools/verify-aot-autoinstrumentation-goal.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.csAGENTS.mddemos/Qyl.RealNetRuntimeMetricsDemo/Program.csdemos/Qyl.RealSqlClientDemo/Qyl.RealSqlClientDemo.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cstools/verify-aspnetcore-middleware-delegate.pytools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.csdemos/Qyl.RealAzureDemo/Qyl.RealAzureDemo.csprojdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cstools/verify-real-corewcf-demo.pydocs/contracts/qyl-native-instrumentations.yamlsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.cstools/verify-otlp-receiver.pydemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Program.csdocs/coverage-matrix.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.csdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.cstools/verify-generator-snapshots.pydemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.cstools/verify-real-aspnetcore-demo.pytools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/verified/report.jsontools/verify-version-sync.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cstools/verify-real-mcp-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.csQyl.OpenTelemetry.AutoInstrumentation.Demos.slnxtools/verify-source-interceptor-consumer.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.csdemos/Qyl.RealGrpcClientDemo/Program.csREADME.mdtools/verify-instrumentation-disabled-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.csdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.csdocs/contracts/qyl-aot-ownership.yamltools/generator_manifest_coverage.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.csbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cstools/verify-real-sqlclient-demo.pytools/smoketest.shsrc/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txttools/verify-environment-options-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cstools/generate-contract-artifacts.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/verify-contract-invariants.py
src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/**
📄 CodeRabbit inference engine (CLAUDE.md)
Keep Microsoft.Data.SqlClient code isolated in
Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.csprojsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cs
src/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/**
📄 CodeRabbit inference engine (CLAUDE.md)
Keep generic hosting/bootstrap code isolated in
Qyl.OpenTelemetry.AutoInstrumentation.Hosting.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation.Hosting/Qyl.OpenTelemetry.AutoInstrumentation.Hosting.csproj
src/Qyl.OpenTelemetry.AutoInstrumentation/**/*.{cs,props,targets}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not leak EFCore or SqlClient dependencies, warnings, or NativeAOT constraints into the core runtime package or Hosting package.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cs
**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.cs: Keep generated interceptor methods inQyl.OpenTelemetry.AutoInstrumentation.Generatedand runtime ABI helpers inQyl.OpenTelemetry.AutoInstrumentation.GeneratedCode; do not rename or conflate the namespaces.
Generated interceptor files must referenceQylGeneratedCodeAbi.V8; breaking ABI changes must bump theV<major>anchor.
Generated code must not referenceQylAutoInstrumentationOptionsorQylInstrumentationDomains; gate opt-ins at the policy type and emit domain names as literals.
All members of the generated-code ABI and bootstrap ABI must use[EditorBrowsable(EditorBrowsableState.Never)].
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.csdemos/Qyl.RealNetRuntimeMetricsDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.csdemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.csdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.csdemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.csdemos/Qyl.RealGrpcClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.csdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.csbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs
**/*.{cs,md,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
Keep missing runtime values missing, bound span names and metric dimensions, and apply the repository's explicit sensitive-value redaction and opt-in controls.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.csCHANGELOG.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.csAGENTS.mddemos/Qyl.RealNetRuntimeMetricsDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.csdocs/contracts/qyl-native-instrumentations.yamlsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.csdemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Program.csdocs/coverage-matrix.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.csdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.csdemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.csdemos/Qyl.RealGrpcClientDemo/Program.csREADME.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.csdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.csdocs/contracts/qyl-aot-ownership.yamlsrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.csbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs
**/*.{md,py,cs}
📄 CodeRabbit inference engine (AGENTS.md)
Before judging, planning, or implementing an external library or framework integration, verify its current package registry and upstream repository status, explicitly check for successors, and record what was checked and the date.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.cstools/verify-real-genai-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cstools/verify-aot-publish-gate.pyCHANGELOG.mdtools/verify-real-azure-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cstools/verify-contract-coverage-report.pysrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cstools/verify-aot-autoinstrumentation-goal.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.csAGENTS.mddemos/Qyl.RealNetRuntimeMetricsDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cstools/verify-aspnetcore-middleware-delegate.pytools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cstools/verify-real-corewcf-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.cstools/verify-otlp-receiver.pydemos/Qyl.RealNServiceBusDemo/Program.csdemos/Qyl.RealCoreWcfDemo/Program.csdocs/coverage-matrix.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.csdemos/Qyl.RealHttpClientDemo/Program.csdemos/Qyl.RealMcpDemo/Program.cstools/verify-generator-snapshots.pydemos/Qyl.RealAspNetCoreMetricsDemo/Program.csdemos/Qyl.RealAzureDemo/Program.cstools/verify-real-aspnetcore-demo.pytools/verify-version-sync.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cstools/verify-real-mcp-demo.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cstools/verify-source-interceptor-consumer.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.csdemos/Qyl.RealGrpcClientDemo/Program.csREADME.mdtools/verify-instrumentation-disabled-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.csdemos/Qyl.RealGenAiDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.cstools/generator_manifest_coverage.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.csbenchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cstools/verify-real-sqlclient-demo.pytools/verify-environment-options-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cstools/generate-contract-artifacts.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/verify-contract-invariants.py
src/**/*.cs
⚙️ CodeRabbit configuration file
src/**/*.cs: Zero-code instrumentation runtime: this code runs inside EVERY request of host
applications. Top priorities, in order: (1) allocations and boxing on hot paths —
flag closures, LINQ, params arrays, string concat in listener/semantic-tag code;
(2) tag cardinality — any attribute value that is unbounded (raw URLs, user input,
exception messages) explodes at scale; (3) Activity/Meter lifecycle — undisposed
listeners, leaked subscriptions, double-Start/Stop; (4) thread safety of shared
listener state. PublicAPI.Shipped/Unshipped.txt are analyzer-managed: edits must
come from the analyzer flow. These packages are public; breaking changes require
a deliberate new major and migration of known consumers.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreOwnership.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInstrumentation.cssrc/Qyl.Sdk/QylAzureSpanProcessor.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreInstrumentationServiceCollectionExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedWcfClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylGeneratedCodeAbi.cssrc/Qyl.Sdk/QylSdkOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientAutoInstrumentationBootstrap.cssrc/Qyl.Sdk/QylTelemetrySources.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedNServiceBus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCapturedNameMap.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.Sdk/QylSdkHostApplicationBuilderExtensions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedDbCommand.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationIds.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/**
📄 CodeRabbit inference engine (CLAUDE.md)
Source-generator verified snapshots are generated/evidence files and must be updated only through regeneration, not manual edits.
Files:
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonltests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cs
**/verified/**
📄 CodeRabbit inference engine (CLAUDE.md)
Snapshot/OTLP verified fixture files are generated/evidence files and must not be hand-edited.
Files:
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonltests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/verified/report.json
tests/**
⚙️ CodeRabbit configuration file
tests/**: Deterministic synchronization and assertions only. Container-backed integration
tests may use real external services; unit and snapshot tests must not depend on
ambient services. Assert observable telemetry output, not implementation internals.
Files:
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonltests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.Interceptors.g.verified.cs
**/PublicAPI.Shipped.txt
📄 CodeRabbit inference engine (CLAUDE.md)
Public API additions and changes must be reflected in
PublicAPI.Shipped.txt/PublicAPI.Unshipped.txtbaselines next to each packaged project.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txt
**/*.{sh,py}
📄 CodeRabbit inference engine (AGENTS.md)
Read verification gate exit codes directly; do not mask failures with
tail,head, orteewithout checking the underlying status or enablingpipefail.
Files:
tools/verify-real-genai-demo.pytools/verify-aot-publish-gate.pytools/verify-real-azure-demo.pytools/verify-contract-coverage-report.pytools/verify-aot-autoinstrumentation-goal.pytools/verify-aspnetcore-middleware-delegate.pytools/verify-real-corewcf-demo.pytools/verify-otlp-receiver.pytools/verify-generator-snapshots.pytools/verify-real-aspnetcore-demo.pytools/verify-version-sync.pytools/verify-real-mcp-demo.pytools/verify-source-interceptor-consumer.pytools/verify-instrumentation-disabled-behavior.pytools/generator_manifest_coverage.pytools/verify-real-sqlclient-demo.pytools/smoketest.shtools/verify-environment-options-behavior.pytools/generate-contract-artifacts.pytools/verify-contract-invariants.py
src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/**
📄 CodeRabbit inference engine (CLAUDE.md)
Keep EFCore code isolated in
Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreAutoInstrumentationBootstrap.cs
CHANGELOG*
📄 CodeRabbit inference engine (CLAUDE.md)
Keep the changelog synthetic and useful for continuation, not a raw commit dump.
Files:
CHANGELOG.md
docs/coverage-matrix.md
📄 CodeRabbit inference engine (COVERAGE_LEDGER.md)
Keep the coverage matrix aligned with the current contract classification and implemented coverage state.
Do not manually edit the generated coverage matrix or misrepresent unsupported, configuration-only, runtime, or NativeAOT rows as universally implemented or verified.
Files:
docs/coverage-matrix.md
README*
📄 CodeRabbit inference engine (CLAUDE.md)
Keep the README user-facing and operational.
Files:
README.md
benchmarks/**
⚙️ CodeRabbit configuration file
benchmarks/**: BenchmarkDotNet projects. Flag benchmarks that measure nothing (dead code paths,
constant-folded bodies) and setup work leaking into the measured body.
Files:
benchmarks/Qyl.OpenTelemetry.AutoInstrumentation.Benchmarks/Program.cs
tools/generate-contract-artifacts.py
📄 CodeRabbit inference engine (AGENTS.md)
Treat the YAML ownership contract and
tools/generate-contract-artifacts.pyas authoritative for generated coverage and conformance artifacts; regenerate and commit outputs together with input or generator changes.
Files:
tools/generate-contract-artifacts.py
🪛 ast-grep (0.44.1)
tools/verify-real-genai-demo.py
[info] 61-61: use jsonify instead of json.dumps for JSON output
Context: json.dumps(report, indent=2, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[error] 95-103: Command coming from incoming request
Context: subprocess.run(
["dotnet", str(artifacts_bin_assembly(PROJECT))],
cwd=PROJECT.parent,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
tools/verify-real-corewcf-demo.py
[error] 35-43: Command coming from incoming request
Context: subprocess.run(
["dotnet", str(artifacts_bin_assembly(PROJECT))],
cwd=PROJECT.parent,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[info] 57-57: use jsonify instead of json.dumps for JSON output
Context: json.dumps(report, indent=2, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
tools/verify-version-sync.py
[warning] 135-135: XPath query is request-/variable-derived; use parameterized XPath to prevent injection.
Context: reference_pattern.findall(path.read_text(encoding="utf-8"))
Note: [CWE-643] Improper Neutralization of Data within XPath Expressions ('XPath Injection').
(xpath-injection-python)
tools/verify-real-mcp-demo.py
[error] 198-206: Command coming from incoming request
Context: subprocess.run(
[str(executable)],
cwd=executable.parent,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[error] 226-234: Command coming from incoming request
Context: subprocess.run(
["dotnet", str(artifacts_bin_assembly(PROJECT))],
cwd=PROJECT.parent,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[error] 239-247: Command coming from incoming request
Context: subprocess.run(
["dotnet", str(artifacts_bin_assembly(PROJECT))],
cwd=PROJECT.parent,
env=disabled_env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[info] 94-94: use jsonify instead of json.dumps for JSON output
Context: json.dumps(report, indent=2, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
tools/generator_manifest_coverage.py
[error] 231-239: Use of unsanitized data to create processes
Context: subprocess.run(
command,
cwd=ROOT,
env=environment,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(os-system-unsanitized-data)
[info] 106-106: use jsonify instead of json.dumps for JSON output
Context: json.dumps(ordered, ensure_ascii=False, separators=(",", ":"))
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[error] 231-239: Command coming from incoming request
Context: subprocess.run(
command,
cwd=ROOT,
env=environment,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
tools/verify-real-sqlclient-demo.py
[info] 75-75: use jsonify instead of json.dumps for JSON output
Context: json.dumps(report, indent=2, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
| using var activity = QylActivitySource.StartAtAmbientStart( | ||
| QylActivityNames.SqlClientCommand(command.Operation), | ||
| ActivityKind.Client); |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
Missing null check for unobserved Activity on the hot path.
QylActivitySource.StartAtAmbientStart returns null when there are no listeners. Without an early return, the listener proceeds to evaluate tags and DatabaseSemantics.ShouldWriteQueryText, burning CPU on the hot path for unobserved telemetry. As per path instructions, preventing overhead on hot paths is a top priority.
⚡ Proposed fix
using var activity = QylActivitySource.StartAtAmbientStart(
QylActivityNames.SqlClientCommand(command.Operation),
ActivityKind.Client);
+
+ if (activity is null)
+ return;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| using var activity = QylActivitySource.StartAtAmbientStart( | |
| QylActivityNames.SqlClientCommand(command.Operation), | |
| ActivityKind.Client); | |
| using var activity = QylActivitySource.StartAtAmbientStart( | |
| QylActivityNames.SqlClientCommand(command.Operation), | |
| ActivityKind.Client); | |
| if (activity is null) | |
| return; |
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs`
around lines 39 - 41, Add an immediate null check after
QylActivitySource.StartAtAmbientStart in the diagnostic listener, returning
before tag evaluation or DatabaseSemantics.ShouldWriteQueryText when no Activity
is created. Preserve the existing instrumentation flow for observed activities.
Source: Path instructions
| private static void RecordResponse(Activity activity, HttpContext context) | ||
| { | ||
| QylHttpActivityPolicy.BackfillServerRoute(activity, QylHttpMethod.Normalize(context.Request.Method), GetRoute(context)); | ||
| QylHttpActivityPolicy.SetResponseStatus(activity, context.Response.StatusCode, 500); | ||
| QylCaptureHelpers.SetRequestHeaders( | ||
| activity, | ||
| QylAutoInstrumentationOptions.Current.AspNetCoreCapturedResponseHeaderMap, | ||
| context.Response.Headers); | ||
| } |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
Redundant Normalize call on every request.
RecordResponse re-normalizes context.Request.Method (Line 93) even though StartRequestActivity already computed it (Line 52, discarding methodOriginal). Thread the already-computed value through instead of recomputing it per response on this hot path.
♻️ Proposed fix
- private static async Task ObserveAsync(Task originalTask, HttpContext context, Activity? activity)
+ private static async Task ObserveAsync(Task originalTask, HttpContext context, Activity? activity, string method)
{
if (activity is null)
{
await originalTask.ConfigureAwait(false);
return;
}
try
{
await originalTask.ConfigureAwait(false);
- RecordResponse(activity, context);
+ RecordResponse(activity, context, method);
}(and pass method from StartRequestActivity's already-normalized value through InvokeAsync → ObserveAsync → RecordResponse, removing the second Normalize call.)
🤖 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 `@src/Qyl.OpenTelemetry.AutoInstrumentation/QylAspNetCoreStartupFilter.cs`
around lines 91 - 99, Thread the already-normalized method from
StartRequestActivity through InvokeAsync and ObserveAsync into RecordResponse,
then pass it to BackfillServerRoute. Remove the per-response
QylHttpMethod.Normalize call in RecordResponse while preserving the existing
response status and header handling.
| private static string? FindExceptionType(Activity activity) | ||
| { | ||
| foreach (var activityEvent in activity.Events) | ||
| { | ||
| foreach (var tag in activityEvent.Tags) | ||
| { | ||
| if (StringComparer.Ordinal.Equals(tag.Key, "exception.type") && tag.Value is string exceptionType) | ||
| return exceptionType; | ||
| } | ||
| } | ||
|
|
||
| return null; | ||
| } |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
Optimize event traversal on the hot path.
Iterating activity.Events allocates an IEnumerator on the heap for every ended Azure error span. Additionally, scanning tags for every event allocates an enumerator per event. Use activity.EnumerateEvents() to traverse events without allocation, and skip the tag enumeration for non-exception events to eliminate unnecessary allocations.
⚡ Proposed fix
- private static string? FindExceptionType(Activity activity)
- {
- foreach (var activityEvent in activity.Events)
- {
- foreach (var tag in activityEvent.Tags)
- {
- if (StringComparer.Ordinal.Equals(tag.Key, "exception.type") && tag.Value is string exceptionType)
- return exceptionType;
- }
- }
-
- return null;
- }
+ private static string? FindExceptionType(Activity activity)
+ {
+ foreach (var activityEvent in activity.EnumerateEvents())
+ {
+ if (activityEvent.Name != "exception")
+ continue;
+
+ foreach (var tag in activityEvent.Tags)
+ {
+ if (StringComparer.Ordinal.Equals(tag.Key, "exception.type") && tag.Value is string exceptionType)
+ return exceptionType;
+ }
+ }
+
+ return null;
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private static string? FindExceptionType(Activity activity) | |
| { | |
| foreach (var activityEvent in activity.Events) | |
| { | |
| foreach (var tag in activityEvent.Tags) | |
| { | |
| if (StringComparer.Ordinal.Equals(tag.Key, "exception.type") && tag.Value is string exceptionType) | |
| return exceptionType; | |
| } | |
| } | |
| return null; | |
| } | |
| private static string? FindExceptionType(Activity activity) | |
| { | |
| foreach (var activityEvent in activity.EnumerateEvents()) | |
| { | |
| if (activityEvent.Name != "exception") | |
| continue; | |
| foreach (var tag in activityEvent.Tags) | |
| { | |
| if (StringComparer.Ordinal.Equals(tag.Key, "exception.type") && tag.Value is string exceptionType) | |
| return exceptionType; | |
| } | |
| } | |
| return null; | |
| } |
🤖 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 `@src/Qyl.Sdk/QylAzureSpanProcessor.cs` around lines 27 - 39, Update
FindExceptionType to traverse events with activity.EnumerateEvents() instead of
activity.Events, avoiding heap enumerator allocation, and only enumerate an
event’s tags when it is an exception event; preserve returning the
exception.type string when present and null otherwise.
Source: Path instructions
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a9af3f426
ℹ️ 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".
| var ambient = Activity.Current; | ||
| if (ambient is not null) | ||
| ambient.ActivityTraceFlags |= ActivityTraceFlags.Recorded; |
There was a problem hiding this comment.
Avoid forcing the ambient ASP.NET sampled bit
When the Hosting listener sees Microsoft.AspNetCore.Hosting.HttpRequestIn.Start, this mutates the framework-owned Activity.Current by setting ActivityTraceFlags.Recorded. For requests that arrive with an unsampled traceparent or where the app's own sampler would drop the ASP.NET Core span, this flips the sampled flag for the rest of the request and can make downstream propagation/parent-based samplers record child spans the application intended to suppress. The qyl span should be enabled without changing the ambient ASP.NET Core activity's trace flags.
Useful? React with 👍 / 👎.
…ixed Lands the 8.0 convergence (PRs #38/#39 content) plus the fixes from the adversarially verified 30-agent review — as one release state, not a delete-then-restore history: - EF Core + SqlClient listener spans carry the operation's REAL timing (CommandEndEventData StartTime/Duration; SqlClient Before/After OperationId timestamp pairing) instead of inheriting the enclosing request's start time. - AspNetCore listener no longer forces ActivityTraceFlags.Recorded; sampler decisions and upstream traceparent are honored. Root sampling works because Qyl.Sdk registers the Microsoft.AspNetCore and System.Net.Http ActivitySources (options-gated). - HttpClient + gRPC client interceptor lanes restored as call-site owners: header/metadata capture with redaction, signal-ownership deferral for the completion listeners, core-package consumers keep HTTP/gRPC emission. Capture proven again by the environment-options gate and the dual-lane gRPC demo (managed + NativeAOT). - DB dedupe via ConditionalWeakTable in-flight registry — exactly-once without pinning DbCommand graphs on exported activities. - error.type is the fully-qualified exception type on every qyl-authored lane (Azure keeps its first-party source's native value); all demo assertions updated. - Meter truth: MCP metrics + native Npgsql/NServiceBus meters are consumer-registered per the qyl-native contract; CHANGELOG states the ownership plainly. Full local handoff gate green end-to-end (verify-aot-autoinstrumentation-goal). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs (1)
133-136: 🚀 Performance & Scalability | 🔴 Critical | ⚡ Quick winEliminate LINQ on the listener hot path to avoid struct boxing and iterator allocations.
Calling
WhereandSelectonStringValuesboxes the struct intoIEnumerable<string>and allocates multiple iterators per header capture. As per path instructions, avoid LINQ and boxing allocations in listener/semantic-tag code.⚡ Proposed fix using a manual loop
- private static string[] ToTagValues(StringValues values) - => values.Count is 0 - ? [] - : values.Where(static value => value is not null).Select(static value => value!).ToArray(); + private static string[] ToTagValues(StringValues values) + { + if (values.Count == 0) + return []; + + var result = new List<string>(values.Count); + for (var i = 0; i < values.Count; i++) + { + var value = values[i]; + if (value is not null) + result.Add(value); + } + + return result.ToArray(); + }🤖 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 `@src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs` around lines 133 - 136, Replace the LINQ-based Where/Select pipeline in ToTagValues with an allocation-free manual loop over StringValues, filtering null entries and populating the returned string array directly. Preserve the empty result for values.Count == 0 and avoid boxing, iterator creation, and other LINQ allocations on this hot path.Source: Path instructions
src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cs (2)
39-44: 🚀 Performance & Scalability | 🔴 Critical | ⚡ Quick winString allocations on the hot path.
GetGrpcServiceNameperforms substring allocations (clientTypeName[(lastDot + 1)..]andservice[..^6]) every time an RPC activity starts. Cache the resolved service name perclientTypeNameto eliminate these allocations on the hot path. As per path instructions, preventing allocations on hot paths is a top priority.🤖 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 `@src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cs` around lines 39 - 44, Update GetGrpcServiceName to cache the resolved service name keyed by clientTypeName, returning the cached value on repeated calls and computing it only on a cache miss. Preserve the existing namespace stripping and trailing “Client” removal behavior while ensuring the RPC activity hot path avoids repeated substring allocations.Source: Path instructions
39-44: 🚀 Performance & Scalability | 🔴 Critical | ⚡ Quick winString allocations on the hot path.
GetGrpcServiceNameperforms substring allocations (clientTypeName[(lastDot + 1)..]andservice[..^6]) every time an RPC activity starts. Cache the resolved service name perclientTypeNameto eliminate these allocations on the hot path. As per path instructions, preventing allocations on hot paths is a top priority.🤖 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 `@src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cs` around lines 39 - 44, The GetGrpcServiceName hot path allocates substrings on every call. Cache the resolved service name keyed by clientTypeName, return cached values when available, and only perform the existing suffix and namespace resolution when populating a new entry.Source: Path instructions
src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs (1)
280-335: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winFix the
Grpc.Core.ClientBasetype parameter name for target detection.The
Grpc.Core.ClientBaseclass is declared with the type parameterTClient(ClientBase<TClient>). Roslyn'sFullyQualifiedFormatfor generic type definitions includes these exact parameter names. Checking against"global::Grpc.Core.ClientBase<T>"will always return false, silently breaking the gRPC client interception.Update the checks in both
TryGetGrpcNetClientAsyncUnaryInvocationandTryGetGrpcNetClientStreamingInvocationto useTClient.🐛 Proposed fixes
private static bool TryGetGrpcNetClientAsyncUnaryInvocation(IMethodSymbol symbol, out InterceptorTarget target) { target = default; if (!IsConstructedFrom(symbol.ReturnType, "global::Grpc.Core.AsyncUnaryCall<TResponse>") || - !InheritsFromConstructedGeneric(symbol.ContainingType, "global::Grpc.Core.ClientBase<T>")) + !InheritsFromConstructedGeneric(symbol.ContainingType, "global::Grpc.Core.ClientBase<TClient>")) { return false; }private static bool TryGetGrpcNetClientStreamingInvocation(IMethodSymbol symbol, out InterceptorTarget target) { target = default; - if (!InheritsFromConstructedGeneric(symbol.ContainingType, "global::Grpc.Core.ClientBase<T>")) + if (!InheritsFromConstructedGeneric(symbol.ContainingType, "global::Grpc.Core.ClientBase<TClient>")) return false; var kind = default(InterceptorKind);🤖 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 `@src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs` around lines 280 - 335, Update the ClientBase type checks in TryGetGrpcNetClientAsyncUnaryInvocation and TryGetGrpcNetClientStreamingInvocation to match the declared generic parameter name, using global::Grpc.Core.ClientBase<TClient> instead of global::Grpc.Core.ClientBase<T>. Preserve the existing return-type detection and target construction logic.
🤖 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 `@demos/Qyl.RealQuartzDemo/Program.cs`:
- Around line 124-126: The failure diagnostic in the error-type validation
branch should report the fully qualified expected value,
“System.InvalidOperationException,” to match the predicate. Update the
failures.Add message in the surrounding error span check without changing the
validation logic.
In
`@src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cs`:
- Around line 34-38: Add an immediate null guard after QylActivitySource.StartAt
in EntityFrameworkCoreDiagnosticListener.cs (lines 34-38) and
SqlClientDiagnosticListener.cs (lines 68-72), returning before SetEndTime or any
tag/string evaluation when the activity is unobserved.
In
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs`:
- Around line 24-44: Replace the per-event PendingOperations.Count check in
OnEvent with a lightweight atomic bounding mechanism, such as an
Interlocked-maintained counter, so WriteCommandBefore avoids scanning dictionary
buckets. Increment only when an operation is successfully added and decrement
when its matching completion entry is removed, enforcing PendingOperationsCap
without introducing count drift or exceeding the cap under concurrency.
- Around line 24-44: The WriteCommandBefore hot path must not call
PendingOperations.Count for capacity checks. Update the PendingOperations
bookkeeping in SqlClientDiagnosticListener to use a lightweight Interlocked
count or equivalent bounded insertion mechanism, incrementing only for
successfully tracked operations and decrementing when entries are removed on
matching completion events, while preserving the 10,000-entry cap.
In
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cs`:
- Around line 44-49: Update TryReadOperationStart to enumerate the payload only
once, extracting both OperationIdKey and TimestampKey during that pass without
calling TryGetPayloadStruct twice. Preserve the existing out-parameter defaults
and return true only when both values are found.
- Around line 44-49: Update TryReadOperationStart to enumerate the payload once,
extracting both OperationIdKey and TimestampKey during that single pass.
Preserve the existing out-parameter defaults and return true only when both
values are found, avoiding the two TryGetPayloadStruct calls and their separate
enumerators.
---
Outside diff comments:
In
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cs`:
- Around line 280-335: Update the ClientBase type checks in
TryGetGrpcNetClientAsyncUnaryInvocation and
TryGetGrpcNetClientStreamingInvocation to match the declared generic parameter
name, using global::Grpc.Core.ClientBase<TClient> instead of
global::Grpc.Core.ClientBase<T>. Preserve the existing return-type detection and
target construction logic.
In `@src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs`:
- Around line 133-136: Replace the LINQ-based Where/Select pipeline in
ToTagValues with an allocation-free manual loop over StringValues, filtering
null entries and populating the returned string array directly. Preserve the
empty result for values.Count == 0 and avoid boxing, iterator creation, and
other LINQ allocations on this hot path.
In `@src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cs`:
- Around line 39-44: Update GetGrpcServiceName to cache the resolved service
name keyed by clientTypeName, returning the cached value on repeated calls and
computing it only on a cache miss. Preserve the existing namespace stripping and
trailing “Client” removal behavior while ensuring the RPC activity hot path
avoids repeated substring allocations.
- Around line 39-44: The GetGrpcServiceName hot path allocates substrings on
every call. Cache the resolved service name keyed by clientTypeName, return
cached values when available, and only perform the existing suffix and namespace
resolution when populating a new entry.
🪄 Autofix (Beta)
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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 87893845-8aef-4088-bfbb-bc0e3d3d16cd
⛔ Files ignored due to path filters (1)
docs/generated/qyl-aot-contract.resolved.yamlis excluded by!**/generated/**,!**/Generated/**,!**/generated/**
📒 Files selected for processing (50)
CHANGELOG.mddemos/Qyl.RealAdoNetDemo/Program.csdemos/Qyl.RealElasticTransportDemo/Program.csdemos/Qyl.RealElasticsearchDemo/Program.csdemos/Qyl.RealGraphQlDemo/Program.csdemos/Qyl.RealGrpcClientDemo/LiveProbeClient.csdemos/Qyl.RealGrpcClientDemo/Program.csdemos/Qyl.RealILoggerDemo/Program.csdemos/Qyl.RealMassTransitDemo/Program.csdemos/Qyl.RealMongoDbDemo/Program.csdemos/Qyl.RealMySqlConnectorDemo/Program.csdemos/Qyl.RealMySqlDataDemo/Program.csdemos/Qyl.RealNpgsqlDemo/Program.csdemos/Qyl.RealOracleMdaDemo/Program.csdemos/Qyl.RealQuartzDemo/Program.csdemos/Qyl.RealRabbitMqDemo/Program.csdemos/Qyl.RealRedisDemo/Program.csdemos/Qyl.RealSqlClientDemo/Program.csdemos/Qyl.RealSqliteDemo/Program.csdemos/Qyl.RealWcfClientDemo/Program.csdocs/contracts/qyl-aot-ownership.yamldocs/coverage-matrix.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.Sdk/QylTelemetrySources.cstests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonltools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cstools/generate-contract-artifacts.pytools/verify-environment-options-behavior.py
💤 Files with no reviewable changes (1)
- src/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/AspNetCore/AspNetCoreDiagnosticListener.cs
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
- GitHub Check: webapi-aot-demo (ubuntu-24.04-arm)
- GitHub Check: webapi-aot-demo (macos-latest)
- GitHub Check: verify (macos-latest)
- GitHub Check: verify (ubuntu-24.04-arm)
⚠️ CI failures not shown inline (4)
GitHub Actions: qyl-smoketest / smoke (ubuntu-24.04-arm): Converge auto-instrumentation for 8.0
Conclusion: failure
##[group]Run bash tools/smoketest.sh
�[36;1mbash tools/smoketest.sh�[0m
shell: /usr/bin/bash -e {0}
env:
DOTNET_ROOT: /usr/share/dotnet
##[endgroup]
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:07.20
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.94
Unhandled exception. System.InvalidOperationException: Unexpected Qyl.Sdk telemetry composition: qylHttpClientSpans=1, nativeHttpClientSpans=1, rawHttpClientDurationMeasurements=1, exportedHttpClientDurationMetrics=1, exportedHttpClientDurationSeries=1, exportedHttpClientDurationMeasurements=1.
at Program.<Main>$(String[] args) in /tmp/qyl-smoke/pkg-consumer/Program.cs:line 150
at Program.<Main>$(String[] args) in /tmp/qyl-smoke/pkg-consumer/Program.cs:line 183
at Program.<Main>(String[] args)
tools/smoketest.sh: line 518: 3612 Aborted (core dumped) dotnet "$dir/bin/Release/net10.0/Consumer.dll" > "$managed_out"
##[error]Process completed with exit code 134.
GitHub Actions: qyl-smoketest / smoke (macos-latest): Converge auto-instrumentation for 8.0
Conclusion: failure
##[group]Run bash tools/smoketest.sh
�[36;1mbash tools/smoketest.sh�[0m
shell: /bin/bash -e {0}
env:
DOTNET_ROOT: /Users/runner/.dotnet
##[endgroup]
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:07.25
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.80
Unhandled exception. System.InvalidOperationException: Unexpected Qyl.Sdk telemetry composition: qylHttpClientSpans=1, nativeHttpClientSpans=1, rawHttpClientDurationMeasurements=1, exportedHttpClientDurationMetrics=1, exportedHttpClientDurationSeries=1, exportedHttpClientDurationMeasurements=1.
at Program.<Main>$(String[] args) in /private/var/folders/8j/sfr9qqcj73j4p6nhwcfpr0th0000gn/T/qyl-smoke/pkg-consumer/Program.cs:line 150
at Program.<Main>$(String[] args) in /private/var/folders/8j/sfr9qqcj73j4p6nhwcfpr0th0000gn/T/qyl-smoke/pkg-consumer/Program.cs:line 183
at Program.<Main>(String[] args)
tools/smoketest.sh: line 518: 30425 Abort trap: 6 dotnet "$dir/bin/Release/net10.0/Consumer.dll" > "$managed_out"
##[error]Process completed with exit code 134.
GitHub Actions: qyl-smoketest / 0_smoke (macos-latest).txt: Converge auto-instrumentation for 8.0
Conclusion: failure
##[group]Run bash tools/smoketest.sh
�[36;1mbash tools/smoketest.sh�[0m
shell: /bin/bash -e {0}
env:
DOTNET_ROOT: /Users/runner/.dotnet
##[endgroup]
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:07.25
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.80
Unhandled exception. System.InvalidOperationException: Unexpected Qyl.Sdk telemetry composition: qylHttpClientSpans=1, nativeHttpClientSpans=1, rawHttpClientDurationMeasurements=1, exportedHttpClientDurationMetrics=1, exportedHttpClientDurationSeries=1, exportedHttpClientDurationMeasurements=1.
at Program.<Main>$(String[] args) in /private/var/folders/8j/sfr9qqcj73j4p6nhwcfpr0th0000gn/T/qyl-smoke/pkg-consumer/Program.cs:line 150
at Program.<Main>$(String[] args) in /private/var/folders/8j/sfr9qqcj73j4p6nhwcfpr0th0000gn/T/qyl-smoke/pkg-consumer/Program.cs:line 183
at Program.<Main>(String[] args)
tools/smoketest.sh: line 518: 30425 Abort trap: 6 dotnet "$dir/bin/Release/net10.0/Consumer.dll" > "$managed_out"
##[error]Process completed with exit code 134.
GitHub Actions: qyl-smoketest / 1_smoke (ubuntu-24.04-arm).txt: Converge auto-instrumentation for 8.0
Conclusion: failure
##[group]Run bash tools/smoketest.sh
�[36;1mbash tools/smoketest.sh�[0m
shell: /usr/bin/bash -e {0}
env:
DOTNET_ROOT: /usr/share/dotnet
##[endgroup]
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:07.20
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.94
Unhandled exception. System.InvalidOperationException: Unexpected Qyl.Sdk telemetry composition: qylHttpClientSpans=1, nativeHttpClientSpans=1, rawHttpClientDurationMeasurements=1, exportedHttpClientDurationMetrics=1, exportedHttpClientDurationSeries=1, exportedHttpClientDurationMeasurements=1.
at Program.<Main>$(String[] args) in /tmp/qyl-smoke/pkg-consumer/Program.cs:line 150
at Program.<Main>$(String[] args) in /tmp/qyl-smoke/pkg-consumer/Program.cs:line 183
at Program.<Main>(String[] args)
tools/smoketest.sh: line 518: 3612 Aborted (core dumped) dotnet "$dir/bin/Release/net10.0/Consumer.dll" > "$managed_out"
##[error]Process completed with exit code 134.
🧰 Additional context used
📓 Path-based instructions (16)
**/*.{cs,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,csproj,props,targets}: Preserve the supported public API surface, including HostingBoot()/AddQylAutoInstrumentation(...),Qyl.SdkAddQyl(...)/QylSdkOptions, coreAddQylAspNetCoreInstrumentation(), and the DiagnosticListeners subscriber surface.
Keep the interceptor namespaces distinct: emitted interceptor methods belong toQyl.OpenTelemetry.AutoInstrumentation.Generated, while runtime ABI helpers belong toQyl.OpenTelemetry.AutoInstrumentation.GeneratedCode.
Do not rename either generated namespace or alter thebuildTransitiveInterceptorsNamespaceswiring.
Prefer a first-class runtime or DI hook when it owns the behavior; intercept a source-visible call only when that is the required substrate, and do not let two generators own the same call site.
Keep the SDK pin at .NET10.0.302withlatestFeature, and updateglobal.json, the corresponding documentation, and the stated pinning guidance together when bumping it.
Generated source must be owned by source-generator snapshots; runtime and protocol claims require real execution with structural assertions over emitted telemetry.
Do not use hand-shaped OTLP JSON, fabricated identifiers or timestamps, protobuf-byte substring searches, or echo-input mocks as interoperability proof; use official OTLP protobuf types and a real loopback receiver.
Files:
demos/Qyl.RealGraphQlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.csdemos/Qyl.RealAdoNetDemo/Program.csdemos/Qyl.RealSqliteDemo/Program.csdemos/Qyl.RealMySqlConnectorDemo/Program.csdemos/Qyl.RealElasticTransportDemo/Program.csdemos/Qyl.RealMySqlDataDemo/Program.csdemos/Qyl.RealILoggerDemo/Program.csdemos/Qyl.RealRedisDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.csdemos/Qyl.RealMassTransitDemo/Program.csdemos/Qyl.RealElasticsearchDemo/Program.csdemos/Qyl.RealQuartzDemo/Program.csdemos/Qyl.RealOracleMdaDemo/Program.csdemos/Qyl.RealRabbitMqDemo/Program.csdemos/Qyl.RealMongoDbDemo/Program.csdemos/Qyl.RealWcfClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.csdemos/Qyl.RealGrpcClientDemo/LiveProbeClient.cssrc/Qyl.Sdk/QylTelemetrySources.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.csdemos/Qyl.RealGrpcClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.csdemos/Qyl.RealSqlClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.cs: Keep generated ABI helpers inQyl.OpenTelemetry.AutoInstrumentation.GeneratedCode; mark every member[EditorBrowsable(EditorBrowsableState.Never)], preserveQylGeneratedCodeAbi.V8, and bump theV<major>anchor on breaking ABI changes.
Generated interceptors must reference the generated-code ABI anchor and must not referenceQylAutoInstrumentationOptionsorQylInstrumentationDomains; gate opt-ins at policy types and emit domain names as literals.
KeepEntityFrameworkCoreAutoInstrumentationBootstrapandSqlClientAutoInstrumentationBootstrapunderQyl.OpenTelemetry.AutoInstrumentation.GeneratedCodeand hidden with[EditorBrowsable(EditorBrowsableState.Never)].
Keep implementation types, semantic helpers, listeners, meter inventory, and runtime state internal; use IVT for cross-assembly access rather than widening types to public.
UseSemanticModel.GetInterceptableLocation(...)and ordinary generated C# for Roslyn interceptor implementation.
Files:
demos/Qyl.RealGraphQlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.csdemos/Qyl.RealAdoNetDemo/Program.csdemos/Qyl.RealSqliteDemo/Program.csdemos/Qyl.RealMySqlConnectorDemo/Program.csdemos/Qyl.RealElasticTransportDemo/Program.csdemos/Qyl.RealMySqlDataDemo/Program.csdemos/Qyl.RealILoggerDemo/Program.csdemos/Qyl.RealRedisDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.csdemos/Qyl.RealMassTransitDemo/Program.csdemos/Qyl.RealElasticsearchDemo/Program.csdemos/Qyl.RealQuartzDemo/Program.csdemos/Qyl.RealOracleMdaDemo/Program.csdemos/Qyl.RealRabbitMqDemo/Program.csdemos/Qyl.RealMongoDbDemo/Program.csdemos/Qyl.RealWcfClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.csdemos/Qyl.RealGrpcClientDemo/LiveProbeClient.cssrc/Qyl.Sdk/QylTelemetrySources.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.csdemos/Qyl.RealGrpcClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.csdemos/Qyl.RealSqlClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
**/*.{cs,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,csproj}: Keep missing runtime values missing, bound span names and metric dimensions, and apply the repository's explicit sensitive-value redaction and opt-in controls.
Update analyzer-managed shipped/unshipped API baselines for public API changes; release work must pack, restore into a clean consumer, run managed and NativeAOT smoke tests, and validate published artifacts.
Files:
demos/Qyl.RealGraphQlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.csdemos/Qyl.RealAdoNetDemo/Program.csdemos/Qyl.RealSqliteDemo/Program.csdemos/Qyl.RealMySqlConnectorDemo/Program.csdemos/Qyl.RealElasticTransportDemo/Program.csdemos/Qyl.RealMySqlDataDemo/Program.csdemos/Qyl.RealILoggerDemo/Program.csdemos/Qyl.RealRedisDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.csdemos/Qyl.RealMassTransitDemo/Program.csdemos/Qyl.RealElasticsearchDemo/Program.csdemos/Qyl.RealQuartzDemo/Program.csdemos/Qyl.RealOracleMdaDemo/Program.csdemos/Qyl.RealRabbitMqDemo/Program.csdemos/Qyl.RealMongoDbDemo/Program.csdemos/Qyl.RealWcfClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.csdemos/Qyl.RealGrpcClientDemo/LiveProbeClient.cssrc/Qyl.Sdk/QylTelemetrySources.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.csdemos/Qyl.RealGrpcClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.csdemos/Qyl.RealSqlClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
**
⚙️ CodeRabbit configuration file
**: Operating principles (solo-dev, agentic SDLC — reviews are advisory, agents act on them):
- LAZY: one self-contained, correct review beats ten partial ones. Every finding is
definitive — concrete evidence with file:line, a concrete fix, no "consider maybe",
no open or ambiguous questions back to the author. If you cannot decide a point
from the diff plus repo context, stay silent on it. Never cite a source, API, or
version you have not verified; an unverifiable claim is a dropped claim.- IMPATIENT: never stall a PR. Internal and dogfooding-only surfaces converge directly;
removing shims, breaking internal signatures, and deleting dead paths are normal.
Published NuGet APIs follow SemVer: breaking changes require a deliberate new major
and migration of known consumers. Do not request compatibility layers without a
proven consumer.- EGO: hold the bar of the best reviewer on the market — flag real correctness,
security, data-loss, and structural problems precisely; produce zero noise.
Files:
demos/Qyl.RealGraphQlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.csdemos/Qyl.RealAdoNetDemo/Program.csdemos/Qyl.RealSqliteDemo/Program.csdemos/Qyl.RealMySqlConnectorDemo/Program.csdemos/Qyl.RealElasticTransportDemo/Program.csdemos/Qyl.RealMySqlDataDemo/Program.csdemos/Qyl.RealILoggerDemo/Program.csdemos/Qyl.RealRedisDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.csdemos/Qyl.RealMassTransitDemo/Program.csdemos/Qyl.RealElasticsearchDemo/Program.csdemos/Qyl.RealQuartzDemo/Program.csdemos/Qyl.RealOracleMdaDemo/Program.csdemos/Qyl.RealRabbitMqDemo/Program.csdemos/Qyl.RealMongoDbDemo/Program.csdemos/Qyl.RealWcfClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.csCHANGELOG.mdtests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonlsrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.csdemos/Qyl.RealGrpcClientDemo/LiveProbeClient.cssrc/Qyl.Sdk/QylTelemetrySources.csdemos/Qyl.RealNpgsqlDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.csdemos/Qyl.RealGrpcClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.csdocs/contracts/qyl-aot-ownership.yamldemos/Qyl.RealSqlClientDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cstools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.csdocs/coverage-matrix.mdsrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cstools/verify-environment-options-behavior.pysrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cstools/generate-contract-artifacts.pysrc/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txtsrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
src/Qyl.OpenTelemetry.AutoInstrumentation/**/*.{cs,props,targets}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not leak EFCore or SqlClient dependencies, warnings, or NativeAOT constraints into the core runtime package or Hosting package.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
src/**/*.cs
⚙️ CodeRabbit configuration file
src/**/*.cs: Zero-code instrumentation runtime: this code runs inside EVERY request of host
applications. Top priorities, in order: (1) allocations and boxing on hot paths —
flag closures, LINQ, params arrays, string concat in listener/semantic-tag code;
(2) tag cardinality — any attribute value that is unbounded (raw URLs, user input,
exception messages) explodes at scale; (3) Activity/Meter lifecycle — undisposed
listeners, leaked subscriptions, double-Start/Stop; (4) thread safety of shared
listener state. PublicAPI.Shipped/Unshipped.txt are analyzer-managed: edits must
come from the analyzer flow. These packages are public; breaking changes require
a deliberate new major and migration of known consumers.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylActivityStatus.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylHttpActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylSemanticAttributes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.cssrc/Qyl.Sdk/QylTelemetrySources.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylSensitiveCapturePolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Detection.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylRpcActivityPolicy.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylMetricMeters.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylInterceptedHttpClient.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/QylAutoInstrumentationOptions.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cssrc/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylCaptureHelpers.cs
src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/**
📄 CodeRabbit inference engine (CLAUDE.md)
Keep EFCore code isolated in
Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.cs
CHANGELOG*
📄 CodeRabbit inference engine (CLAUDE.md)
Keep the changelog synthetic and useful for continuation, not a raw commit dump.
Files:
CHANGELOG.md
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/**
📄 CodeRabbit inference engine (CLAUDE.md)
Source-generator verified snapshots are generated/evidence files and must be updated only through regeneration, not manual edits.
Files:
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonl
**/verified/**
📄 CodeRabbit inference engine (CLAUDE.md)
Snapshot/OTLP verified fixture files are generated/evidence files and must not be hand-edited.
Files:
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonl
tests/**
⚙️ CodeRabbit configuration file
tests/**: Deterministic synchronization and assertions only. Container-backed integration
tests may use real external services; unit and snapshot tests must not depend on
ambient services. Assert observable telemetry output, not implementation internals.
Files:
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonl
src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/**
📄 CodeRabbit inference engine (CLAUDE.md)
Keep Microsoft.Data.SqlClient code isolated in
Qyl.OpenTelemetry.AutoInstrumentation.SqlClient.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cssrc/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cs
**/*.{yml,yaml,py}
📄 CodeRabbit inference engine (AGENTS.md)
The YAML ownership contract and
tools/generate-contract-artifacts.pyown generated coverage and conformance artifacts; change inputs or generators, regenerate, and commit outputs together.
Files:
docs/contracts/qyl-aot-ownership.yamltools/verify-environment-options-behavior.pytools/generate-contract-artifacts.py
docs/coverage-matrix.md
📄 CodeRabbit inference engine (COVERAGE_LEDGER.md)
Keep the coverage matrix aligned with the current contract classification and implemented coverage state.
Files:
docs/coverage-matrix.md
**/*.{sh,py,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
Run the complete local handoff gate with
python3 tools/verify-aot-autoinstrumentation-goal.py, inspect its full exit status, and do not mask failures throughtail,head, orteewithoutpipefail.
Files:
tools/verify-environment-options-behavior.pytools/generate-contract-artifacts.py
**/PublicAPI.Shipped.txt
📄 CodeRabbit inference engine (CLAUDE.md)
Public API additions and changes must be reflected in
PublicAPI.Shipped.txt/PublicAPI.Unshipped.txtbaselines next to each packaged project.
Files:
src/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txt
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ANcpLua/Qyl.OpenTelemetry.AutoInstrumentation
Timestamp: 2026-07-19T10:31:40.228Z
Learning: Before judging, planning, or implementing an external library or framework integration, verify the live package registry and upstream repository, explicitly check for successors, and record what was checked and the date.
Learnt from: CR
Repo: ANcpLua/Qyl.OpenTelemetry.AutoInstrumentation
Timestamp: 2026-07-19T10:31:40.228Z
Learning: When comparing against `qyl-references/` clones, pull them first; correct upstream drift in existing source, meter names, identifiers, and documented claims before adding new integrations.
Learnt from: CR
Repo: ANcpLua/Qyl.OpenTelemetry.AutoInstrumentation
Timestamp: 2026-07-19T10:31:40.228Z
Learning: Synthetic verifier consumers must compile against the public surface only; fix consumers when types become internal, and grant narrowly named IVT access only to probers that genuinely require internals.
🔇 Additional comments (39)
demos/Qyl.RealNpgsqlDemo/Program.cs (1)
8-8: LGTM!Also applies to: 24-24, 130-130, 162-166
demos/Qyl.RealSqlClientDemo/Program.cs (1)
2-2: LGTM!Also applies to: 27-49, 65-68, 98-104, 123-193, 203-208, 220-240, 295-299
demos/Qyl.RealElasticTransportDemo/Program.cs (1)
107-107: LGTM!demos/Qyl.RealElasticsearchDemo/Program.cs (1)
98-99: LGTM!demos/Qyl.RealRabbitMqDemo/Program.cs (1)
139-139: LGTM!demos/Qyl.RealRedisDemo/Program.cs (1)
123-123: LGTM!demos/Qyl.RealSqliteDemo/Program.cs (1)
105-105: LGTM!demos/Qyl.RealWcfClientDemo/Program.cs (1)
100-126: LGTM!tools/Qyl.OpenTelemetry.AutoInstrumentation.WebApiAotDemo/Program.cs (1)
195-196: LGTM!Also applies to: 219-221
demos/Qyl.RealGraphQlDemo/Program.cs (1)
133-133: LGTM!demos/Qyl.RealILoggerDemo/Program.cs (1)
113-113: LGTM!demos/Qyl.RealMassTransitDemo/Program.cs (1)
139-139: LGTM!demos/Qyl.RealMongoDbDemo/Program.cs (1)
131-131: LGTM!demos/Qyl.RealMySqlConnectorDemo/Program.cs (1)
88-88: LGTM!demos/Qyl.RealMySqlDataDemo/Program.cs (1)
88-88: LGTM!demos/Qyl.RealOracleMdaDemo/Program.cs (1)
95-95: LGTM!CHANGELOG.md (1)
8-83: LGTM!demos/Qyl.RealAdoNetDemo/Program.cs (1)
111-111: LGTM!src/Qyl.Sdk/QylTelemetrySources.cs (1)
13-75: LGTM!demos/Qyl.RealGrpcClientDemo/LiveProbeClient.cs (1)
1-44: LGTM!demos/Qyl.RealGrpcClientDemo/Program.cs (1)
74-85: LGTM!Also applies to: 183-204
src/Qyl.OpenTelemetry.AutoInstrumentation.DiagnosticListeners/QylDiagnosticListenerSubscriber.cs (1)
34-37: LGTM!Also applies to: 46-48
tools/verify-environment-options-behavior.py (1)
253-258: LGTM!Also applies to: 440-451
src/Qyl.OpenTelemetry.AutoInstrumentation/PublicAPI.Shipped.txt (2)
7-8: LGTM!Also applies to: 39-89
7-8: LGTM!Also applies to: 39-89
src/Qyl.OpenTelemetry.AutoInstrumentation/QylActivitySource.cs (2)
45-59: LGTM!
45-59: LGTM!src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCorePayloadReader.cs (2)
28-30: LGTM!Also applies to: 58-60
28-30: LGTM!Also applies to: 58-60
src/Qyl.OpenTelemetry.AutoInstrumentation/Internal/QylDbActivityPolicy.cs (2)
4-13: LGTM!Also applies to: 26-27, 42-55
4-13: LGTM!Also applies to: 26-27, 42-55
src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Descriptors.cs (1)
10-151: LGTM!src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.Shapes.cs (1)
58-177: LGTM!Also applies to: 360-381, 786-851
src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylAutoInstrumentationGenerator.cs (1)
45-47: LGTM!Also applies to: 157-219, 255-290, 556-743
src/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators/QylGeneratedSourceInterceptorCatalog.cs (1)
9-13: LGTM!Also applies to: 30-37
tests/Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators.Snapshots/verified/QylAutoInstrumentation.ContractManifests.verified.jsonl (1)
11-15: LGTM!tools/generate-contract-artifacts.py (1)
19-19: LGTM!Also applies to: 102-111, 142-142, 173-266, 297-297, 374-510, 547-552, 566-610, 643-646, 738-738, 889-889, 916-943, 995-1001, 1090-1099, 1122-1157, 1182-1182, 1262-1264
docs/contracts/qyl-aot-ownership.yaml (1)
979-1026: LGTM!docs/coverage-matrix.md (1)
27-48: LGTM!Also applies to: 106-109
| else if (!error.Tags.TryGetValue(Qyl.OpenTelemetry.SemanticConventions.Attributes.Error.ErrorAttributes.Type, out var errorType) || | ||
| !StringComparer.Ordinal.Equals(errorType, "InvalidOperationException")) | ||
| !StringComparer.Ordinal.Equals(errorType, "System.InvalidOperationException")) | ||
| failures.Add("expected error.type=InvalidOperationException on error span"); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Update the stale failure diagnostic.
The predicate now requires System.InvalidOperationException, but Line 126 still reports InvalidOperationException. A failing probe will therefore give the wrong expected value.
Proposed fix
- failures.Add("expected error.type=InvalidOperationException on error span");
+ failures.Add("expected error.type=System.InvalidOperationException on error span");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| else if (!error.Tags.TryGetValue(Qyl.OpenTelemetry.SemanticConventions.Attributes.Error.ErrorAttributes.Type, out var errorType) || | |
| !StringComparer.Ordinal.Equals(errorType, "InvalidOperationException")) | |
| !StringComparer.Ordinal.Equals(errorType, "System.InvalidOperationException")) | |
| failures.Add("expected error.type=InvalidOperationException on error span"); | |
| else if (!error.Tags.TryGetValue(Qyl.OpenTelemetry.SemanticConventions.Attributes.Error.ErrorAttributes.Type, out var errorType) || | |
| !StringComparer.Ordinal.Equals(errorType, "System.InvalidOperationException")) | |
| failures.Add("expected error.type=System.InvalidOperationException on error span"); |
🤖 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 `@demos/Qyl.RealQuartzDemo/Program.cs` around lines 124 - 126, The failure
diagnostic in the error-type validation branch should report the fully qualified
expected value, “System.InvalidOperationException,” to match the predicate.
Update the failures.Add message in the surrounding error span check without
changing the validation logic.
| using var activity = QylActivitySource.StartAt( | ||
| QylActivityNames.DbCommand(command.Operation), | ||
| ActivityKind.Client, | ||
| command.StartTime); | ||
| activity?.SetEndTime((command.StartTime + command.Duration).UtcDateTime); |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔴 Critical | ⚡ Quick win
Missing early return for unobserved Activity on the hot path. QylActivitySource.StartAt returns null when there are no listeners. Failing to check for null causes the listener to needlessly evaluate tags and string allocations for unobserved telemetry. As per path instructions, preventing overhead on hot paths is a top priority.
src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cs#L34-L38: Addif (activity is null) return;immediately afterStartAt.src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs#L68-L72: Add the same early return guard here.
📍 Affects 2 files
src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cs#L34-L38(this comment)src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs#L68-L72
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.EntityFrameworkCore/EntityFrameworkCoreDiagnosticListener.cs`
around lines 34 - 38, Add an immediate null guard after
QylActivitySource.StartAt in EntityFrameworkCoreDiagnosticListener.cs (lines
34-38) and SqlClientDiagnosticListener.cs (lines 68-72), returning before
SetEndTime or any tag/string evaluation when the activity is unobserved.
Source: Path instructions
| /// <summary>In-flight command start timestamps, keyed by the diagnostic OperationId. Entries are | ||
| /// removed on the matching After/Error event; the size cap guards against events whose completion | ||
| /// never fires (killed connections) from accumulating forever.</summary> | ||
| private static readonly System.Collections.Concurrent.ConcurrentDictionary<Guid, long> PendingOperations = new(); | ||
|
|
||
| private const int PendingOperationsCap = 10_000; | ||
|
|
||
| /// <inheritdoc/> | ||
| protected override void OnEvent(string name, object? payload) | ||
| { | ||
| if (StringComparer.Ordinal.Equals(name, "Microsoft.Data.SqlClient.WriteCommandBefore")) | ||
| { | ||
| if (SqlClientPayloadReader.TryReadOperationStart(payload, out var operationId, out var startTimestamp) && | ||
| PendingOperations.Count < PendingOperationsCap) | ||
| { | ||
| PendingOperations[operationId] = startTimestamp; | ||
| } | ||
|
|
||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔴 Critical | 🏗️ Heavy lift
High overhead on hot path from ConcurrentDictionary.Count.
Evaluating PendingOperations.Count on every WriteCommandBefore event forces the dictionary to sum the counts across all its internal buckets, which scales poorly under concurrent load. Track the count with a separate Interlocked field or use a lightweight bounding mechanism. As per path instructions, preventing overhead on hot paths is a top priority.
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs`
around lines 24 - 44, Replace the per-event PendingOperations.Count check in
OnEvent with a lightweight atomic bounding mechanism, such as an
Interlocked-maintained counter, so WriteCommandBefore avoids scanning dictionary
buckets. Increment only when an operation is successfully added and decrement
when its matching completion entry is removed, enforcing PendingOperationsCap
without introducing count drift or exceeding the cap under concurrency.
Source: Path instructions
🚀 Performance & Scalability | 🔴 Critical | 🏗️ Heavy lift
High overhead on hot path from ConcurrentDictionary.Count.
Evaluating PendingOperations.Count on every WriteCommandBefore event forces the dictionary to sum the counts across all its internal buckets, which scales poorly under concurrent load. Track the count with a separate Interlocked field or use a lightweight bounding mechanism. As per path instructions, preventing overhead on hot paths is a top priority.
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientDiagnosticListener.cs`
around lines 24 - 44, The WriteCommandBefore hot path must not call
PendingOperations.Count for capacity checks. Update the PendingOperations
bookkeeping in SqlClientDiagnosticListener to use a lightweight Interlocked
count or equivalent bounded insertion mechanism, incrementing only for
successfully tracked operations and decrementing when entries are removed on
matching completion events, while preserving the 10,000-entry cap.
Source: Path instructions
| public static bool TryReadOperationStart(object? payload, out Guid operationId, out long timestamp) | ||
| { | ||
| timestamp = 0; | ||
| return TryGetPayloadStruct(payload, OperationIdKey, out operationId) && | ||
| TryGetPayloadStruct(payload, TimestampKey, out timestamp); | ||
| } |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔴 Critical | ⚡ Quick win
Multiple allocations and redundant iterations on hot path.
TryReadOperationStart calls TryGetPayloadStruct twice, resulting in two full iterations over the payload IEnumerable and allocating two enumerators on the hot path. Extract both keys in a single pass to eliminate the redundant iteration and allocation.
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cs`
around lines 44 - 49, Update TryReadOperationStart to enumerate the payload only
once, extracting both OperationIdKey and TimestampKey during that pass without
calling TryGetPayloadStruct twice. Preserve the existing out-parameter defaults
and return true only when both values are found.
🚀 Performance & Scalability | 🔴 Critical | ⚡ Quick win
Multiple allocations and redundant iterations on hot path.
TryReadOperationStart calls TryGetPayloadStruct twice, resulting in two full iterations over the payload IEnumerable and allocating two enumerators on the hot path. Extract both keys in a single pass to eliminate the redundant iteration and allocation.
🤖 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
`@src/Qyl.OpenTelemetry.AutoInstrumentation.SqlClient/SqlClientPayloadReader.cs`
around lines 44 - 49, Update TryReadOperationStart to enumerate the payload
once, extracting both OperationIdKey and TimestampKey during that single pass.
Preserve the existing out-parameter defaults and return true only when both
values are found, avoiding the two TryGetPayloadStruct calls and their separate
enumerators.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 299b7bcb54
ℹ️ 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".
| if (QylDbActivityPolicy.HasCurrentActivityFor(command.Command)) | ||
| return; |
There was a problem hiding this comment.
Suppress SqlClient fallback only for SqlClient-owned spans
When a SQL command is invoked through a DbCommand-typed variable or factory result, the source generator emits the generic ADONET interceptor, which records an in-flight activity for the same command. This new guard then drops the SqlClient diagnostic completion, so the operation is reported as generic other_sql/ADONET and the SQLCLIENT span attributes/metrics are lost in the default configuration; the fallback should only be suppressed when the in-flight interceptor activity was actually emitted for SQLCLIENT.
Useful? React with 👍 / 👎.
| // create their activities through the sampler (proper root sampling decisions, honored | ||
| // upstream traceparent) instead of the legacy unsampled DiagnosticListener fallback. | ||
| AddIfEnabled(names, options, QylAutoInstrumentationIds.AspNetCore, AspNetCore); | ||
| AddIfEnabled(names, options, QylAutoInstrumentationIds.HttpClient, HttpClient); |
There was a problem hiding this comment.
Avoid exporting native HttpClient spans alongside qyl spans
With AddQyl() and HTTPCLIENT traces enabled, source-generated QylInterceptedHttpClient already emits the qyl client span and only coordinates with the DiagnosticListener lane. Adding System.Net.Http to the OpenTelemetry sources also exports the BCL ActivitySource span for the same request on runtimes where that source fires, because QylSignalOwnership is not consulted by OpenTelemetry's native source subscription; this produces duplicate client spans instead of the intended single qyl-owned operation.
Useful? React with 👍 / 👎.
| if (SqlClientPayloadReader.TryReadOperationStart(payload, out var operationId, out var startTimestamp) && | ||
| PendingOperations.Count < PendingOperationsCap) |
There was a problem hiding this comment.
Evict stale SqlClient starts before hitting the cap
When a long-running process sees WriteCommandBefore events whose matching completion never arrives, this cap fills with stale operation IDs and then permanently stops recording new start timestamps. From that point every SqlClient fallback span uses a zero duration (endTime - TimeSpan.Zero), so all subsequent SQL spans in that process are exported with near-zero durations until restart; the cap needs eviction or cleanup rather than only refusing new inserts.
Useful? React with 👍 / 👎.
What changed
Why
This completes the feasibility run by turning its verified outcomes into one coherent breaking release design. Each supported capability now has an executable owner and evidence, while impossible or redundant designs are removed instead of preserved behind compatibility layers.
Impact
This is intentionally breaking. Consumers must use the 8.0 package set and V8 generated-code ABI. Removed options and helper surfaces have no compatibility shims.
Validation
env DOTNET_CLI_USE_MSBUILD_SERVER=0 python3 tools/verify-aot-autoinstrumentation-goal.pyaot-autoinstrumentation-goal-ok.