EasyProfiler

This repo, provides query profiler for EF Core

View project on GitHub

CodeFactor Gitmoji .NET Core Nuget Nuget Nuget Nuget Nuget Nuget Nuget Nuget License: MIT

Give a Star 🌟

If you liked the project or if EasyProfiler helped you, please give a star.

Easy Profiler

Welcome EasyProfiler documentation.

Purpose

This repo, provides query profiler for EF Core.

Getting started with EasyProfiler

Easy Profiler uses Interceptor to measure the performance of your queries.

It uses the ProfilerDbContext object to store the results.

Supported Databases

  • SQL Server
  • PostgreSQL
  • MariaDb
  • MySQL
  • MongoDB
  • SQLite
  • Firebird

Sample for SQL Server

Install EasyProfiler.SQLServer from Nuget Package

Initilaze EasyProfilerDbContext in Startup.cs to save the results.

Sample

services.AddEasyProfilerDbContext(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});

and EasyProfilerInterceptor extensions add for own DbContext.

Sample

services.AddDbContext<SampleDbContext>(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
    .AddEasyProfiler(services);
});

Migrations

Use the ApplyEasyProfilerSQLServer extension method for pending migrations.

Sample

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ProfilerDbContext profilerDbContext)
{
    app.ApplyEasyProfilerSQLServer(profilerDbContext);
}

Run your application and check your db. Must be created Profiler entity.

Sample for MariaDb and MySQL

Install EasyProfiler.MariaDb from Nuget Package

Initilaze EasyProfilerDbContext in Startup.cs to save the results.

Sample

services.AddEasyProfilerDbContext(options =>
{
    options.UseMySql(Configuration.GetConnectionString("DefaultConnection"));
});

and EasyProfilerInterceptor extensions add for own DbContext.

Sample

services.AddDbContext<SampleDbContext>(options =>
{
    options.UseMySql(Configuration.GetConnectionString("DefaultConnection"))
    .AddEasyProfiler(services);
});

Migrations

Use the ApplyEasyProfilerMariaDb extension method for pending migrations.

Sample

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ProfilerDbContext profilerDbContext)
{
    app.ApplyEasyProfilerMariaDb(profilerDbContext);
}

Run your application and check your db. Must be created Profiler entity.

Sample for PostgreSQL

Install EasyProfiler.PostgreSQL from Nuget Package

Initilaze EasyProfilerDbContext in Startup.cs to save the results.

Sample

services.AddEasyProfilerDbContext(options =>
{
    options.UseNpsql(Configuration.GetConnectionString("DefaultConnection"));
});

and EasyProfilerInterceptor extensions add for own DbContext.

Sample

services.AddDbContext<SampleDbContext>(options =>
{
    options.UseNpsql(Configuration.GetConnectionString("DefaultConnection"))
    .AddEasyProfiler(services);
});

Migrations

Use the ApplyEasyProfilerPostgreSQL extension method for pending migrations.

Sample

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ProfilerDbContext profilerDbContext)
{
    app.ApplyEasyProfilerPostgreSQL(profilerDbContext);
}

Run your application and check your db. Must be created Profiler entity.

Sample for MongoDb

Install EasyProfiler.Mongo from Nuget Package

Initilaze EasyProfilerDbContext in Startup.cs to save the results.

Sample

services.AddEasyProfilerDbContext(options =>
{
    options.ConnectionString = "mongodb://localhost:27017";
    options.Database = "EasyProfiler";
});

and EasyProfilerInterceptor extensions add for own MongoContext.

Sample

public MongoContext(IServiceProvider serviceProvider)
{
    var client = new MongoClient(new MongoClientSettings()
    {
        Server = new MongoServerAddress("localhost"),
        ClusterConfigurator = cb =>
        {
            cb.Subscribe<CommandStartedEvent>(e =>
            {
                e.InitilazeStartedEvent(serviceProvider);
        
            cb.Subscribe<CommandSucceededEvent>(e =>
            {
                e.InitilazeSucceededEvent(serviceProvider);
            });
        }
    });
}

Run your application and check your db. Must be created Profiler entity.

Watch Queries with AdvancedFilter

Usage

Get IEasyProfilerBaseService<ProfilerDbContext> From Dependency Injection.

var queryProfilers = await easyProfilerService.AdvancedFilterAsync(new AdvancedFilterModel()
{
    CombineWith = CombineType.Or,
    Duration = new Range<TimeSpan> { Max = TimeSpan.MaxValue, Min = TimeSpan.MinValue},
    Page = 1,
    PerPage = 15,
    Query = "Select", // <---- Contains
    SortBy = Sorting.Descending, // <---  Default value Sorting.Descending,
    Sort = "Duration" // <--- Default value "Duration",
    QueryType = QueryType.SELECT
});

Response

[
  {
    "query": "SELECT [c].[CustomerId], [c].[CreateDate], [c].[Name], [c].[Surname]\r\nFROM [Customers] AS [c]",
    "duration": {
      "ticks": 8737783,
      "days": 0,
      "hours": 0,
      "milliseconds": 873,
      "minutes": 0,
      "seconds": 0,
      "totalDays": 0.000010113174768518518,
      "totalHours": 0.00024271619444444446,
      "totalMilliseconds": 873.7783,
      "totalMinutes": 0.014562971666666667,
      "totalSeconds": 0.8737783
    },
    "id": "c06cae66-3dd1-4e34-810c-498c979a5c6a"
  }
]

Find slowest endpoint with EasyProfiler

Get IEasyProfilerBaseService<ProfilerDbContext> From Dependency Injection.

var slowetEndpoints = await easyProfilerService.GetSlowestEndpointsAsync();

Response

[
  {
    "requestUrl": "/Default/GetAllCustomers",
    "count": 25,
    "avarageDurationTime": {
      "ticks": 664882,
      "days": 0,
      "hours": 0,
      "milliseconds": 66,
      "minutes": 0,
      "seconds": 0,
      "totalDays": 7.695393518518518e-7,
      "totalHours": 0.000018468944444444444,
      "totalMilliseconds": 66.4882,
      "totalMinutes": 0.0011081366666666668,
      "totalSeconds": 0.0664882
    }
  },
  {
    "requestUrl": "/Default/InsertCustomers",
    "count": 6,
    "avarageDurationTime": {
      "ticks": 44127,
      "days": 0,
      "hours": 0,
      "milliseconds": 4,
      "minutes": 0,
      "seconds": 0,
      "totalDays": 5.107291666666667e-8,
      "totalHours": 0.00000122575,
      "totalMilliseconds": 4.4127,
      "totalMinutes": 0.000073545,
      "totalSeconds": 0.0044127
    }
  }
]

You can try it !! Sample Project

README-Mozilla-Firefox-2020-11-0

RoadMap

  • PostgreSQL support.
  • MySQL support.
  • MariaDB support.
  • SQLServer support.
  • MongoDB support.
  • QueryType. (For Example : Select,Insert,Update,Delete)
  • Request Path. (For Example : “customer/getCustomer?fullname=sample”)
  • Dashboard UI Support.