Skip to content

Integration Npgsql Extension

aryehcitron@gmail.com edited this page May 24, 2026 · 6 revisions

The Kronikol.Extensions.Npgsql package adds PostgreSQL operation tracking to your test diagrams via Npgsql's built-in DiagnosticSource instrumentation. No code changes required in production — just install and configure in your test project.

Zero production changes. Npgsql emits diagnostic events automatically. This extension subscribes to them globally, so every NpgsqlConnection in the process is tracked without any wrapping or decoration.


How It Works

Npgsql publishes DiagnosticSource events under the listener name "Npgsql". The NpgsqlDiagnosticTracker subscribes to these events and correlates BeforeExecuteCommand / AfterExecuteCommand pairs using ExecutionId (a GUID extracted via reflection). Each pair is classified by UnifiedSqlClassifier and logged to RequestResponseLogger.

Because it logs to the same RequestResponseLogger as the standard TestTrackingMessageHandler, SQL operations appear alongside your HTTP API calls in the same sequence diagram.


Install

dotnet add package Kronikol.Extensions.Npgsql

Setup

Option A — Dependency Injection

// In your test WebApplicationFactory ConfigureTestServices:
services.AddPostgreSqlTestTracking(options =>
{
    options.Verbosity = SqlTrackingVerbosityLevel.Detailed;
    // options.LogSqlText = true;
    // options.LogParameters = true;
});

Option B — Static (No DI)

// In your test setup (e.g. constructor or OneTimeSetUp):
NpgsqlTestTracking.EnsureTracking(new NpgsqlTrackingOptions
{
    Verbosity = SqlTrackingVerbosityLevel.Detailed
});

// In teardown:
NpgsqlTestTracking.Reset();

Configuration

Property Default Description
ServiceName "PostgreSQL" The participant name shown in diagrams
CallerName "Caller" The caller participant name
Verbosity Detailed Raw, Detailed, or Summarised
LogSqlText true Include full SQL text in Detailed mode
LogParameters false Include parameter values
DependencyCategory "PostgreSQL" Controls participant shape/colour
UriScheme "postgresql" URI scheme in diagram URIs
CurrentTestInfoFetcher null Returns the current test's name and ID. Required for wrapping approach
HttpContextAccessor null Optional — enables dual-resolution of test identity from HTTP headers
ExcludedOperations [] Operations to exclude from tracking
SetupVerbosity null Verbosity override for the Setup phase. See Phase-Aware Tracking
ActionVerbosity null Verbosity override for the Action phase. See Phase-Aware Tracking
TrackDuringSetup true Track during test setup phase
TrackDuringAction true Track during test action phase
LogResponseContent true Include response data in diagram arrows at all verbosity levels (v2.37.0+)
MaxResponseRows 10 Maximum rows to capture in response content
MaxValueDisplayLength 500 Truncate individual cell values beyond this length
ResponseDetail RowCountAndColumns RowCountOnly, RowCountAndColumns, or FullRows

All options inherit from SqlTrackingOptionsBase in the core package.


Verbosity Levels

Level Arrow label URI
Raw Full SQL text postgresql://host/database
Detailed SELECT FROM Users postgresql://host/database/Users
Summarised SELECT postgresql:///database/Users

Classified Operations

Uses UnifiedSqlClassifier — supports SELECT, INSERT, UPDATE, DELETE, MERGE, UPSERT (ON CONFLICT DO UPDATE), stored procedures (EXEC/CALL), DDL (CREATE/ALTER/DROP TABLE), TRUNCATE, and transactions. Multi-dialect: handles PostgreSQL double-quotes, brackets, backticks, CTEs, SET prefix stripping, and Spanner hints.


Response Payload Capture (v2.37.0+)

Response arrows in diagrams now show actual data instead of being empty. The ResponseDetail option controls the level of detail:

ResponseDetail Example output
RowCountOnly 3 rows
RowCountAndColumns (default) 3 rows [Name, Preference, CreatedAt]
FullRows JSON row preview (up to MaxResponseRows)

Set LogResponseContent = false to restore previous empty-arrow behaviour.


Wrapping Alternative (v2.37.0+)

In addition to the zero-change DiagnosticSource approach above, the Npgsql extension also provides a connection-wrapping approach. This is useful when DiagnosticSource instrumentation is unavailable, disabled, or when you need response payload capture from ExecuteReader/ExecuteScalar.

Classes

Class Wraps Purpose
TrackingNpgsqlConnection NpgsqlConnection Intercepts command creation and transaction begin
TrackingNpgsqlCommand NpgsqlCommand Intercepts ExecuteReader, ExecuteNonQuery, ExecuteScalar (sync + async)
TrackingNpgsqlTransaction NpgsqlTransaction Logs BEGIN, COMMIT, ROLLBACK

Extension Method

using Npgsql;
using Kronikol.Extensions.Npgsql;

var connection = new NpgsqlConnection(connectionString)
    .WithTestTracking(new NpgsqlTrackingOptions
    {
        ServiceName = "PostgreSQL",
        Verbosity = SqlTrackingVerbosityLevel.Detailed,
        CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
    });

NpgsqlConnection.WithTestTracking() returns a TrackingNpgsqlConnection (which extends DbConnection), so it works transparently with any code that accepts DbConnection — including Dapper, raw ADO.NET, and DI registrations.

DI Registration

builder.ConfigureTestServices(services =>
{
    services.AddScoped<DbConnection>(sp =>
    {
        var inner = new NpgsqlConnection(connectionString);
        return inner.WithTestTracking(new NpgsqlTrackingOptions
        {
            ServiceName = "PostgreSQL",
            Verbosity = SqlTrackingVerbosityLevel.Detailed,
            CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
        });
    });
});

DiagnosticSource vs Wrapping: The DiagnosticSource approach (Option A/B above) requires zero production code changes but cannot capture response payloads. The wrapping approach captures response data from ExecuteReader and ExecuteScalar, but requires the connection to be wrapped. Choose based on your needs — you can use both in the same project for different connections.

Home


Demo


Getting Started

Common Tasks

Integration Guides

Extensions

Configuration

Features

Reference

Clone this wiki locally