-
Notifications
You must be signed in to change notification settings - Fork 366
Add configuring-opentelemetry-dotnet skill (+8.1% eval, near-miss) #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,264 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ```skill | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name: configuring-opentelemetry-dotnet | ||||||||||||||||||||||||||||||||||||||||||||||||||
| description: Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up OTLP exporters, creating custom metrics/spans, or troubleshooting distributed trace correlation. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Configuring OpenTelemetry in .NET | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ## When to Use | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| - Adding distributed tracing to an ASP.NET Core application | ||||||||||||||||||||||||||||||||||||||||||||||||||
| - Setting up OpenTelemetry exporters (OTLP, Jaeger, Prometheus) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| - Creating custom metrics or trace spans for business operations | ||||||||||||||||||||||||||||||||||||||||||||||||||
| - Troubleshooting distributed trace context propagation across services | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ## When Not to Use | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| - The user wants application-level logging only (use ILogger, Serilog) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| - The user is using Application Insights SDK directly (different API) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| - The user needs APM with a commercial vendor's proprietary SDK | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Inputs | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| | Input | Required | Description | | ||||||||||||||||||||||||||||||||||||||||||||||||||
| |-------|----------|-------------| | ||||||||||||||||||||||||||||||||||||||||||||||||||
| | ASP.NET Core project | Yes | The application to instrument | | ||||||||||||||||||||||||||||||||||||||||||||||||||
| | Observability backend | No | Where to export: Jaeger, Prometheus, OTLP collector, Aspire | | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Step 1: Install the correct packages | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| **There are many OpenTelemetry NuGet packages. Install exactly these:** | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Core SDK + ASP.NET Core instrumentation | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Extensions.Hosting | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Instrumentation.AspNetCore | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Instrumentation.Http | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Exporter (pick one or more) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol # OTLP (recommended) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Exporter.Console # Dev/debugging | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Optional: additional auto-instrumentation | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Instrumentation.SqlClient # SQL Server | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Instrumentation.EntityFrameworkCore # EF Core | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package OpenTelemetry.Instrumentation.GrpcNetClient # gRPC | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| **Do NOT install `OpenTelemetry` alone** — you need `OpenTelemetry.Extensions.Hosting` for proper DI integration. | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Step 2: Configure tracing in Program.cs | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ```csharp | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using OpenTelemetry.Resources; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using OpenTelemetry.Trace; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using OpenTelemetry.Metrics; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using OpenTelemetry.Logs; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| var builder = WebApplication.CreateBuilder(args); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| // Define the service resource (appears in all telemetry) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| var serviceName = "MyOrderService"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| var serviceVersion = "1.0.0"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| builder.Services.AddOpenTelemetry() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .ConfigureResource(resource => resource | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddService(serviceName: serviceName, serviceVersion: serviceVersion)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .WithTracing(tracing => tracing | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Auto-instrumentation sources | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddAspNetCoreInstrumentation(options => | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Filter out health check endpoints from traces | ||||||||||||||||||||||||||||||||||||||||||||||||||
| options.Filter = httpContext => | ||||||||||||||||||||||||||||||||||||||||||||||||||
| !httpContext.Request.Path.StartsWithSegments("/healthz"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddHttpClientInstrumentation(options => | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Enrich outgoing HTTP spans with request/response details | ||||||||||||||||||||||||||||||||||||||||||||||||||
| options.RecordException = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddSqlClientInstrumentation(options => | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| options.SetDbStatementForText = true; // Capture SQL text | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does |
||||||||||||||||||||||||||||||||||||||||||||||||||
| options.RecordException = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Custom activity sources (for your own spans) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Many apps probably have no need to do this. You might want to segregate this into another step that is clearly optional. |
||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddSource("MyOrderService.Orders") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddSource("MyOrderService.Payments") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Exporter | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddOtlpExporter(options => | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| options.Endpoint = new Uri("http://localhost:4317"); // gRPC endpoint | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // For HTTP: options.Protocol = OtlpExportProtocol.HttpProtobuf; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // options.Endpoint = new Uri("http://localhost:4318/v1/traces"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .WithMetrics(metrics => metrics | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddAspNetCoreInstrumentation() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddHttpClientInstrumentation() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddRuntimeInstrumentation() // GC, thread pool metrics | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does it need to reference OpenTelemetry.Instrumentation.Runtime package? |
||||||||||||||||||||||||||||||||||||||||||||||||||
| // Custom meters | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddMeter("MyOrderService.Metrics") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .AddOtlpExporter()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these doesn't need to configure the endpoint as you did with metrics? |
||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Step 3: Add OpenTelemetry logging integration | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ```csharp | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Connect ILogger to OpenTelemetry | ||||||||||||||||||||||||||||||||||||||||||||||||||
| builder.Logging.AddOpenTelemetry(logging => | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| logging.IncludeScopes = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| logging.IncludeFormattedMessage = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| logging.AddOtlpExporter(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| **This correlates logs with traces automatically** — each log entry gets the current TraceId and SpanId. | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Step 4: Create custom spans (Activities) for business operations | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd recommend marking this optional. I suspect many customers don't need this. |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| ```csharp | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using System.Diagnostics; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| public class OrderService | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create an ActivitySource matching what you registered in Step 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| private static readonly ActivitySource ActivitySource = new("MyOrderService.Orders"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| public async Task<Order> ProcessOrderAsync(CreateOrderRequest request) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Start a new span | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using var activity = ActivitySource.StartActivity("ProcessOrder"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| // Add attributes (tags) to the span | ||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.SetTag("order.customer_id", request.CustomerId); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.SetTag("order.item_count", request.Items.Count); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| try | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Child span for validation | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using (var validationActivity = ActivitySource.StartActivity("ValidateOrder")) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| await ValidateOrderAsync(request); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| validationActivity?.SetTag("validation.result", "passed"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| // Child span for payment | ||||||||||||||||||||||||||||||||||||||||||||||||||
| using (var paymentActivity = ActivitySource.StartActivity("ProcessPayment", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ActivityKind.Client)) // Client = outgoing call | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| paymentActivity?.SetTag("payment.method", request.PaymentMethod); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| await ProcessPaymentAsync(request); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.SetTag("order.status", "completed"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.SetStatus(ActivityStatusCode.Ok); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return order; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+157
to
+161
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| catch (Exception ex) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Record the exception on the span | ||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.SetStatus(ActivityStatusCode.Error, ex.Message); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.RecordException(ex); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+158
to
+166
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| activity?.SetStatus(ActivityStatusCode.Ok); | |
| return order; | |
| } | |
| catch (Exception ex) | |
| { | |
| // Record the exception on the span | |
| activity?.SetStatus(ActivityStatusCode.Error, ex.Message); | |
| activity?.RecordException(ex); | |
| if (activity != null) | |
| { | |
| OpenTelemetry.Trace.ActivityExtensions.SetStatus(activity, ActivityStatusCode.Ok); | |
| } | |
| return order; | |
| } | |
| catch (Exception ex) | |
| { | |
| // Record the exception on the span | |
| if (activity != null) | |
| { | |
| OpenTelemetry.Trace.ActivityExtensions.SetStatus(activity, ActivityStatusCode.Error, ex.Message); | |
| OpenTelemetry.Trace.ActivityExtensions.RecordException(activity, ex); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also be optional, though probably more apps would benefit from it than customer tracing spans.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The official guidance is for apps using DI to use IMeterFactory rather than creating a static Meter:
https://learn.microsoft.com/en-us/aspnet/core/log-mon/metrics/metrics?view=aspnetcore-10.0#creating-metrics-in-aspnet-core-apps-with-imeterfactory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume GetQueueDepth just demonstrating the idea and doesn't have to exist in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need using directives here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And logs/metrics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this accurate? wouldn't the instrumentation still work with the spans created from clients not created from IHttpClientFactory?
@rajkumar-rangaraj may help confirming or correcting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMeterFactory again :)
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| scenarios: | ||
| - name: "Add OpenTelemetry tracing and metrics to an ASP.NET Core API" | ||
| prompt: | | ||
| I need to add distributed tracing and custom metrics to my ASP.NET Core 8 API. We use an OTLP-compatible collector (Jaeger). I want to: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd recommend either adding more eval prompts, or if we will only have a limited number of prompts focus on prompts that are simpler and more generalized. I'd guess prompts like these are going to be more common: Regardless of whether those imprecise prompts are best-practice, its what I would expect real users will frequently do. |
||
| 1. Auto-instrument incoming HTTP requests and outgoing HttpClient calls | ||
| 2. Create custom spans for my order processing business logic using ActivitySource | ||
| 3. Add a custom counter metric for orders processed using System.Diagnostics.Metrics.Meter | ||
|
|
||
| Show me the full setup including package installation, Program.cs configuration, and how to create the custom spans and metrics in my service class. I want to make sure my custom traces and metrics actually show up in Jaeger — last time I tried, the auto-instrumentation worked but my custom spans were invisible. | ||
| assertions: | ||
| - type: "output_matches" | ||
| pattern: "(OpenTelemetry\\.Extensions\\.Hosting|AddOpenTelemetry)" | ||
| - type: "output_matches" | ||
| pattern: "(ActivitySource|StartActivity)" | ||
| - type: "output_matches" | ||
| pattern: "(AddSource|AddMeter)" | ||
| - type: "output_matches" | ||
| pattern: "(Counter|Histogram|CreateCounter|CreateHistogram)" | ||
| rubric: | ||
| - "Installed the correct packages: OpenTelemetry.Extensions.Hosting, OpenTelemetry.Instrumentation.AspNetCore, OpenTelemetry.Exporter.OpenTelemetryProtocol" | ||
| - "Configured AddOpenTelemetry() with .WithTracing() and .WithMetrics() in Program.cs" | ||
| - "Added AddAspNetCoreInstrumentation() and AddHttpClientInstrumentation() for auto-instrumentation" | ||
| - "Registered custom ActivitySource names via AddSource() matching the source name used in the service class" | ||
| - "Created custom spans using ActivitySource.StartActivity() with proper using/dispose pattern" | ||
| - "Created custom metrics using Meter.CreateCounter() or similar, with the Meter name matching AddMeter()" | ||
| - "Explicitly warned that ActivitySource/Meter names must match AddSource/AddMeter registrations exactly or custom telemetry will be silently dropped" | ||
| expect_tools: ["bash"] | ||
| timeout: 120 | ||
|
|
||
| - name: "OpenTelemetry skill should not activate for simple logging question" | ||
| prompt: "How do I configure Serilog structured logging in my ASP.NET Core app to write to a file and console?" | ||
| assertions: | ||
| - type: "output_not_contains" | ||
| value: "OpenTelemetry" | ||
| - type: "output_not_matches" | ||
| pattern: "(ActivitySource|StartActivity|AddOpenTelemetry|OTLP)" | ||
| rubric: | ||
| - "Did NOT suggest OpenTelemetry for a Serilog logging question" | ||
| - "Provided Serilog-specific configuration guidance" | ||
| timeout: 60 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SKILL.md is wrapped in a fenced ```skill code block, but the skill validator only parses YAML frontmatter when the file starts with
---. As written, metadata (especially `description`) won’t be detected and the whole document will be treated as code fencing. Remove the outer code fence and use normal top-of-file YAML frontmatter like the other skills.