Recently I came upon a post from Rown Miller in which he created a simple interceptor to log poor performing queries or failing queries, which really seems promising to track down those queries. Although there is already an awesome well-known tool, Glimpse, this helps you track down the server processing time and other informational data with a quick setup. It also logs the queries if your ASP.NET application is using Entity Framework. But it’s limited to Web applications. So what about Windows, WPF, and other standalone apps?
I just extended the interceptor class as a library and included the support to introduce a custom logger to write queries on any target.
By introducing an Interface for logging:
- /// <summary>
- /// Implement this logger for any custom targets where queries should be logged.
- /// </summary>
- public interface IQueryLogger
- {
- void Write(params string[] content);
- }
- public class ExpensiveSqlLoggerInterceptor: DbCommandInterceptor {
- private readonly IQueryLogger _queryLogger;
- private readonly int _executionMillisecondThreshold;
- private readonly bool _includeStackTrace;
- public ExpensiveSqlLoggerInterceptor(IQueryLogger logger, int executionMillisecondThreshold, bool enableStackTrace = true) {
- _queryLogger = logger;
- _executionMillisecondThreshold = executionMillisecondThreshold;
- _includeStackTrace = enableStackTrace;
- }
- public override voidR eaderExecuting(DbCommand command, DbCommandInterceptionContext < DbDataReader > interceptionContext) {
- Executing(interceptionContext);
- base.ReaderExecuting(command, interceptionContext);
- }
- public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext < DbDataReader > interceptionContext) {
- Executed(command, interceptionContext);
- base.ReaderExecuted(command, interceptionContext);
- }
- public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext < int > interceptionContext) {
- Executing(interceptionContext);
- base.NonQueryExecuting(command, interceptionContext);
- }
- public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext < int > interceptionContext) {
- Executed(command, interceptionContext);
- base.NonQueryExecuted(command, interceptionContext);
- }
- public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext < object > interceptionContext) {
- Executing(interceptionContext);
- base.ScalarExecuting(command, interceptionContext);
- }
- public override void ScalarExecuted(DbCommand command, DbCommandInterceptionContext < object > interceptionContext) {
- Executed(command, interceptionContext);
- base.ScalarExecuted(command, interceptionContext);
- }
- private void Executing < T > (DbCommandInterceptionContext < T > interceptionContext) {
- var timer = new Stopwatch();
- interceptionContext.UserState = timer;
- timer.Start();
- }
- private void Executed < T > (DbCommand command, DbCommandInterceptionContext < T > interceptionContext) {
- var timer = (Stopwatch) interceptionContext.UserState;
- timer.Stop();
- if (interceptionContext.Exception != null) {
- _queryLogger.Write("FAILED COMMAND",
- interceptionContext.Exception.Message,
- command.CommandText,
- _includeStackTrace ? Environment.StackTrace : string.Empty,
- string.Empty,
- string.Empty);
- } else if (timer.ElapsedMilliseconds >= _executionMillisecondThreshold) {
- _queryLogger.Write(
- string.Format("SLOW COMMAND ({0} ms)", timer.ElapsedMilliseconds),
- command.CommandText,
- _includeStackTrace ? Environment.StackTrace : string.Empty,
- string.Empty,
- string.Empty
- );
- }
- }
- }
- /// <summary>
- /// Writes the output to the visual studio output window.
- /// </summary>
- public class OutputWindowLogger: IQueryLogger
- {
- public void Write(params string[] content)
- {
- content.ToList().ForEach(data => System.Diagnostics.Trace.WriteLine(data, "Expensive Query log =>"));
- }
- }
- public class CustomConfig: DbConfiguration
- {
- public CustomConfig()
- {
- this.AddInterceptor(new ExpensiveSqlLoggerInterceptor(new OutputWindowLogger(), 1, false));
- }
- }

Here’s the complete source code of the EF6Logger library on GitHub.
Read more articles on .NET Core:

Bhavik PatelPosted Apr 11, 2016, 10:58 PM
useful
Kashif SohailPosted Mar 24, 2016, 10:17 PM
Informative
Rajeev PunhaniPosted Feb 29, 2016, 12:51 AM
Really nice and helpfull post.
Sonu ChaudharyPosted Feb 25, 2016, 6:32 AM
good one!
Pramod ThakurPosted Feb 25, 2016, 2:59 AM
very informative...
Mohammed IbrahimPosted Feb 24, 2016, 7:14 PM
nice
Amit ChoudharyPosted Feb 24, 2016, 5:23 PM
Thanks guys!! :-)
Kumaresh RajalingamPosted Feb 23, 2016, 8:13 PM
Good one sir
Ehsan SajjadPosted Feb 23, 2016, 4:42 PM
Very good , I like it
Santhakumar MunuswamyPosted Feb 23, 2016, 2:05 PM
Thanks for nice article
Sibeesh VenuPosted Feb 23, 2016, 9:10 AM
Nice Share, Thanks for the information.
Raja TPosted Feb 23, 2016, 8:15 AM
Thanks for sharing
Humayun Kabir MamunPosted Feb 23, 2016, 7:01 AM
Nice...