mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-19 18:07:05 +01:00
143 lines
5.9 KiB
C#
143 lines
5.9 KiB
C#
// Copyright © WireMock.Net
|
|
// OpenTelemetry Tracing Demo for WireMock.Net
|
|
// This demo uses the Console Exporter to visualize traces in the terminal.
|
|
|
|
using OpenTelemetry;
|
|
using OpenTelemetry.Trace;
|
|
using WireMock.OpenTelemetry;
|
|
using WireMock.Server;
|
|
using WireMock.Settings;
|
|
using WireMock.RequestBuilders;
|
|
using WireMock.ResponseBuilders;
|
|
|
|
Console.WriteLine("=== WireMock.Net OpenTelemetry Tracing Demo ===\n");
|
|
|
|
// WireMock.Net creates Activity objects using System.Diagnostics.Activity (built into .NET).
|
|
// These activities are automatically created when ActivityTracingEnabled is set to true.
|
|
//
|
|
// To export these traces, you have two options:
|
|
//
|
|
// Option 1: Configure your own TracerProvider (shown below)
|
|
// - Full control over exporters (Console, OTLP, Jaeger, etc.)
|
|
// - Add additional instrumentation (HttpClient, database, etc.)
|
|
// - Recommended for most applications
|
|
//
|
|
// Option 2: Use WireMock.Net.OpenTelemetry package
|
|
// - Reference the WireMock.Net.OpenTelemetry NuGet package
|
|
// - Use services.AddWireMockOpenTelemetry(openTelemetryOptions)
|
|
// - Adds WireMock + ASP.NET Core instrumentation and OTLP exporter
|
|
// - Good for quick setup with all-in-one configuration
|
|
|
|
// Option 1: Custom TracerProvider with Console exporter for this demo
|
|
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
|
|
.AddWireMockInstrumentation(new OpenTelemetryOptions() { ExcludeAdminRequests = true })
|
|
.AddHttpClientInstrumentation() // HTTP client traces (for our test requests)
|
|
.AddConsoleExporter() // Export traces to console for demo purposes
|
|
.AddOtlpExporter() // Export to real OTLP collector (e.g. Jaeger, Tempo, etc.)
|
|
.Build();
|
|
|
|
Console.WriteLine("Console Exporter configured to visualize:");
|
|
Console.WriteLine(" - WireMock.Net traces (wiremock.* tags)");
|
|
Console.WriteLine(" - ASP.NET Core server traces");
|
|
Console.WriteLine(" - HTTP client traces\n");
|
|
|
|
// Start WireMock server with OpenTelemetry enabled (ActivityTracingOptions != null enables tracing)
|
|
var server = WireMockServer.Start(new WireMockServerSettings
|
|
{
|
|
StartAdminInterface = true,
|
|
ActivityTracingOptions = new ActivityTracingOptions
|
|
{
|
|
ExcludeAdminRequests = true
|
|
}
|
|
});
|
|
|
|
Console.WriteLine($"WireMock server started at: {string.Join(", ", server.Urls)}\n");
|
|
|
|
// Configure some mock mappings
|
|
server
|
|
.Given(Request.Create()
|
|
.WithPath("/api/hello")
|
|
.UsingGet())
|
|
.RespondWith(Response.Create()
|
|
.WithStatusCode(200)
|
|
.WithBody("Hello from WireMock!"));
|
|
|
|
server
|
|
.Given(Request.Create()
|
|
.WithPath("/api/user/*")
|
|
.UsingGet())
|
|
.RespondWith(Response.Create()
|
|
.WithStatusCode(200)
|
|
.WithHeader("Content-Type", "application/json")
|
|
.WithBody(@"{""name"": ""John Doe"", ""email"": ""john@example.com""}"));
|
|
|
|
server
|
|
.Given(Request.Create()
|
|
.WithPath("/api/error")
|
|
.UsingGet())
|
|
.RespondWith(Response.Create()
|
|
.WithStatusCode(500)
|
|
.WithBody("Internal Server Error"));
|
|
|
|
Console.WriteLine("Mock mappings configured:");
|
|
Console.WriteLine(" GET /api/hello -> 200 OK");
|
|
Console.WriteLine(" GET /api/user/* -> 200 OK (JSON)");
|
|
Console.WriteLine(" GET /api/error -> 500 Error");
|
|
Console.WriteLine();
|
|
|
|
// Make some test requests to generate traces
|
|
using var httpClient = server.CreateClient();
|
|
|
|
Console.WriteLine("Making test requests to generate traces...\n");
|
|
Console.WriteLine("─────────────────────────────────────────────────────────────────");
|
|
|
|
// Request 1: Successful request
|
|
Console.WriteLine("\n>>> Request 1: GET /api/hello");
|
|
var response1 = await httpClient.GetAsync("/api/hello");
|
|
Console.WriteLine($"<<< Response: {(int)response1.StatusCode} {response1.StatusCode}");
|
|
Console.WriteLine($" Body: {await response1.Content.ReadAsStringAsync()}");
|
|
|
|
await Task.Delay(500); // Small delay to let trace export complete
|
|
|
|
// Request 2: Another successful request with path parameter
|
|
Console.WriteLine("\n>>> Request 2: GET /api/user/123");
|
|
var response2 = await httpClient.GetAsync("/api/user/123");
|
|
Console.WriteLine($"<<< Response: {(int)response2.StatusCode} {response2.StatusCode}");
|
|
Console.WriteLine($" Body: {await response2.Content.ReadAsStringAsync()}");
|
|
|
|
await Task.Delay(500);
|
|
|
|
// Request 3: Error response
|
|
Console.WriteLine("\n>>> Request 3: GET /api/error");
|
|
var response3 = await httpClient.GetAsync("/api/error");
|
|
Console.WriteLine($"<<< Response: {(int)response3.StatusCode} {response3.StatusCode}");
|
|
Console.WriteLine($" Body: {await response3.Content.ReadAsStringAsync()}");
|
|
|
|
await Task.Delay(500);
|
|
|
|
// Request 4: No matching mapping (404)
|
|
Console.WriteLine("\n>>> Request 4: GET /api/notfound");
|
|
var response4 = await httpClient.GetAsync("/api/notfound");
|
|
Console.WriteLine($"<<< Response: {(int)response4.StatusCode} {response4.StatusCode}");
|
|
|
|
await Task.Delay(500);
|
|
|
|
// Request 5: Admin API request (should be excluded from tracing)
|
|
Console.WriteLine("\n>>> Request 5: GET /__admin/health");
|
|
var response5 = await httpClient.GetAsync("/__admin/health");
|
|
Console.WriteLine($"<<< Admin Health Status: {response5.StatusCode}");
|
|
|
|
Console.WriteLine("\n─────────────────────────────────────────────────────────────────");
|
|
Console.WriteLine("\nTraces above show OpenTelemetry activities from WireMock.Net!");
|
|
Console.WriteLine("Look for 'Activity.TraceId', 'Activity.SpanId', and custom tags like:");
|
|
Console.WriteLine(" - http.request.method");
|
|
Console.WriteLine(" - url.path");
|
|
Console.WriteLine(" - http.response.status_code");
|
|
Console.WriteLine(" - wiremock.mapping.matched");
|
|
Console.WriteLine(" - wiremock.mapping.guid");
|
|
Console.WriteLine();
|
|
|
|
// Cleanup
|
|
server.Stop();
|
|
Console.WriteLine("WireMock server stopped. Demo complete!");
|