Skip to content

Commit

Permalink
[Instrumentation.MysqlData] Compatibility with Mysql.Data 8.0.32. (#902)
Browse files Browse the repository at this point in the history
  • Loading branch information
moonheart authored Jan 18, 2023
1 parent 7d62f10 commit 49bcb44
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Compatibility with Mysql.Data 8.0.32 or later.
([#901](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/901))

## 1.0.0-beta.4

Released 2022-Oct-17
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using MySql.Data.MySqlClient;
using OpenTelemetry.Trace;
Expand All @@ -28,10 +29,12 @@ namespace OpenTelemetry.Instrumentation.MySqlData;
/// </summary>
internal class MySqlDataInstrumentation : DefaultTraceListener
{
private readonly ConcurrentDictionary<long, MySqlConnectionStringBuilder> dbConn = new ConcurrentDictionary<long, MySqlConnectionStringBuilder>();
private readonly ConcurrentDictionary<long, MySqlConnectionStringBuilder> dbConn = new();

private readonly MySqlDataInstrumentationOptions options;

private readonly Func<string, MySqlConnectionStringBuilder> builderFactory;

public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null)
{
this.options = options ?? new MySqlDataInstrumentationOptions();
Expand All @@ -40,25 +43,63 @@ public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null)
MySqlTrace.Switch.Level = SourceLevels.Information;

// Mysql.Data removed `MySql.Data.MySqlClient.MySqlTrace.QueryAnalysisEnabled` since 8.0.31 so we need to set this using reflection.
var queryAnalysisEnabled = typeof(MySqlTrace).GetProperty("QueryAnalysisEnabled", BindingFlags.Public | BindingFlags.Static);
var queryAnalysisEnabled =
typeof(MySqlTrace).GetProperty("QueryAnalysisEnabled", BindingFlags.Public | BindingFlags.Static);
if (queryAnalysisEnabled != null)
{
queryAnalysisEnabled.SetValue(null, true);
}

// Mysql.Data add optional param `isAnalyzed` to MySqlConnectionStringBuilder constructor since 8.0.32
var ctor = typeof(MySqlConnectionStringBuilder).GetConstructor(new[] { typeof(string), typeof(bool) });
if (ctor == null)
{
ctor = typeof(MySqlConnectionStringBuilder).GetConstructor(new[] { typeof(string) });
if (ctor == null)
{
MySqlDataInstrumentationEventSource.Log.ErrorInitialize(
"Failed to get proper MySqlConnectionStringBuilder constructor, maybe unsupported Mysql.Data version. Connection Level Details will not be available.",
string.Empty);
return;
}

var p1 = Expression.Parameter(typeof(string), "connectionString");
var newExpression = Expression.New(ctor, p1);
var func = Expression.Lambda<Func<string, MySqlConnectionStringBuilder>>(newExpression, p1).Compile();
this.builderFactory = s => func(s);
}
else
{
var p1 = Expression.Parameter(typeof(string));
var p2 = Expression.Parameter(typeof(bool));
var newExpression = Expression.New(ctor, p1, p2);
var func = Expression.Lambda<Func<string, bool, MySqlConnectionStringBuilder>>(newExpression, p1, p2).Compile();
this.builderFactory = s => func(s, false);
}
}

/// <inheritdoc />
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
public override void TraceEvent(
TraceEventCache eventCache,
string source,
TraceEventType eventType,
int id,
string format,
params object[] args)
{
try
{
switch ((MySqlTraceEventType)id)
{
case MySqlTraceEventType.ConnectionOpened:
// args: [driverId, connStr, threadId]
var driverId = (long)args[0];
var connStr = args[1].ToString();
this.dbConn[driverId] = new MySqlConnectionStringBuilder(connStr);
if (this.builderFactory != null)
{
var driverId = (long)args[0];
var connStr = args[1].ToString();
this.dbConn[driverId] = this.builderFactory(connStr);
}

break;
case MySqlTraceEventType.ConnectionClosed:
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ public void ErrorTraceEvent(int mysqlEventId, string message, string exception)
{
this.WriteEvent(1, mysqlEventId, message, exception);
}

[Event(2, Message = "Error accured while initializing MySqlDataInstrumentation, Message {0}, Exception: {1}", Level = EventLevel.Warning)]
public void ErrorInitialize(string message, string exception)
{
this.WriteEvent(1, message, exception);
}
}

0 comments on commit 49bcb44

Please sign in to comment.