/
SqlServer.cs
94 lines (84 loc) · 3.25 KB
/
SqlServer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System;
using System.Data;
using System.Data.Common;
namespace Datadog.Trace.ClrProfiler.Integrations
{
/// <summary>
/// SqlServer handles tracing System.Data.SqlClient
/// </summary>
public static class SqlServer
{
private const string OperationName = "sqlserver.query";
private static Func<object, CommandBehavior, object> _executeReader;
private static Func<object, CommandBehavior, string, object> _executeReaderWithMethod;
/// <summary>
/// ExecuteReader traces any SQL call.
/// </summary>
/// <param name="this">The "this" pointer for the method call.</param>
/// <param name="behavior">The behavior.</param>
/// <param name="method">The method.</param>
/// <returns>The original methods return.</returns>
public static object ExecuteReaderWithMethod(dynamic @this, int behavior, string method)
{
var command = (DbCommand)@this;
if (_executeReaderWithMethod == null)
{
_executeReaderWithMethod = DynamicMethodBuilder.CreateMethodCallDelegate<Func<object, CommandBehavior, string, object>>(
command.GetType(),
"ExecuteReader",
new Type[] { typeof(CommandBehavior), typeof(string) });
}
using (var scope = CreateScope(command))
{
try
{
return _executeReaderWithMethod(command, (CommandBehavior)behavior, method);
}
catch (Exception ex)
{
scope.Span.SetException(ex);
throw;
}
}
}
/// <summary>
/// ExecuteReader traces any SQL call.
/// </summary>
/// <param name="this">The "this" pointer for the method call.</param>
/// <param name="behavior">The behavior.</param>
/// <returns>The original methods return.</returns>
public static object ExecuteReader(dynamic @this, int behavior)
{
var command = (DbCommand)@this;
if (_executeReader == null)
{
_executeReader = DynamicMethodBuilder.CreateMethodCallDelegate<Func<object, CommandBehavior, object>>(
command.GetType(),
"ExecuteReader",
new Type[] { typeof(CommandBehavior) });
}
using (var scope = CreateScope(command))
{
try
{
return _executeReader(command, (CommandBehavior)behavior);
}
catch (Exception ex)
{
scope.Span.SetException(ex);
throw;
}
}
}
private static Scope CreateScope(DbCommand command)
{
var scope = Tracer.Instance.StartActive(OperationName);
// set the scope properties
// - row count is not supported so we don't set it
scope.Span.ResourceName = command.CommandText;
scope.Span.Type = SpanTypes.Sql;
scope.Span.SetTag(Tags.SqlDatabase, command.Connection?.ConnectionString);
return scope;
}
}
}