8000 Instrument with DiagnosticSource · Issue #471 · mysql-net/MySqlConnector · GitHub
[go: up one dir, main page]

Skip to content

Instrument with DiagnosticSource #471

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

Closed
yang-xiaodong opened this issue Apr 4, 2018 · 9 comments
Closed

Instrument with DiagnosticSource #471

yang-xiaodong opened this issue Apr 4, 2018 · 9 comments

Comments

@yang-xiaodong
Copy link
yang-xiaodong commented Apr 4, 2018

Hello , Thanks for the great work.

I'm working on APM-related work. Using diagnostics allows users to get more runtime event data, which is helpful for distributed tracking systems.

EntityFramewokCore has provided support for diagnostics, but if users do not use EF, it is difficult for them to obtain these event data, so is there any plan to provide some diagnostic event data at the driver level?

Diagnositics doc :
https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md

@bgrainger
Copy link
Member

Do you know if there's a "standard" or documentation for typical ADO.NET diagnostic events? Or is each provider supposed to implement it in an idiosyncratic way?

I found this example for SqlClient; didn't find any usage within Npgsql or Microsoft.Data.Sqlite.

@bgrainger bgrainger changed the title Is there any plan to support Diagnostics ? Instrument with DiagnosticSource Apr 4, 2018
@yang-xiaodong
Copy link
Author

@bgrainger
I did not find some ADO.NET related "standard", I think maybe we can refer to the SqlClient implementation to do it.

@jiangjinnan
Copy link
jiangjinnan commented Jun 27, 2018

There is not such a diagnostic "standard", you just need to name your diagnostic source and event following your naming convention, and specify the event specific payload.

In general, you can provide the following instrumentation activities:

  • Open-Connection
  • Close-Connection
  • Commit-Transaction
  • Rollback-Transaction
  • Command-Execution

For each instrumentation activity, it's better define the following events:

  • Start: Diagnostic event fired when starting instrumentation activity
  • Stop: Diagnostic event fired when stopping instrumentation activity
  • Error: Diagnostic event fired when throwing exception.

The following is a demo:

{
    private static readonly DiagnosticSource _source = new DiagnosticListener("MySql.Data.MySqlClient");

    public static void OnCommandExecuting(MySqlCommand command, long timestamp)
    {
        if (_source.IsEnabled("MySql.Data.MySqlClient.CommandExecution.Start"))
        {
            _source.Write("MySql.Data.MySqlClient.CommandExecution.Start", new { Command = command, Timestamp = timestamp });
        }
    }

    public static void OnCommandExecuted(MySqlCommand command, TimeSpan slaped)
    {
        if (_source.IsEnabled("MySql.Data.MySqlClient.CommandExecution.Stop"))
        {
            _source.Write("MySql.Data.MySqlClient.CommandExecution.Stop", new { Command = command, Slaped = slaped });
        }
    }

    public static void OnCommandError(MySqlCommand command, Exception exception)
    {
        if (_source.IsEnabled("MySql.Data.MySqlClient.CommandExecution.Error"))
        {
            _source.Write("MySql.Data.MySqlClient.CommandExecution.Error", new { Command = command, Exception = exception });
        }
    }
}

internal class TextCommandExecutor : ICommandExecutor
{
    public Task<int> ExecuteNonQueryAsync(string commandText, MySqlParameterCollection parameterCollection, IOBehavior ioBehavior, CancellationToken cancellationToken)
    {
        var command = new MySqlCommand(commandText);
        DiagnosticLogger.OnCommandExecuting(command);
        var sw = Stopwatch.StartNew();
        try
        {
            //...
            DiagnosticLogger.OnCommandExecuted(command, sw.Elapsed);
        }
        catch (Exception ex)
        {
            DiagnosticLogger.OnCommandError(command, ex);
        }
    }
}

You can also provide more antagonistic payload like System.Data.SqlClient.

@holyslon
Copy link

Hello folks. We really need this functionality. We need it for integration with OpenTracing. May be is there any way we can help you do this?

@bgrainger
Copy link
Member 8000

I haven't looked into OpenTracing much yet. Would it be possible to integrate with OpenTracing by writing a wrapper DbDataReader that delegates to an underlying database provider, but sends spans to an OpenTracing collector? I've written something similar before: https://github.com/Faithlife/FaithlifeTracing/tree/master/src/Faithlife.Tracing.Data (and it's vendor-neutral).

@martinjt
Copy link
martinjt commented Oct 7, 2020

Is/has anyone picking/picked this up?

@bgrainger
Copy link
Member

Just answered here: #493 (comment)

@bgrainger
Copy link
Member
909F

Superseded by #1036.

@bgrainger
Copy link
Member

Available in 2.0.0-beta.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants
0