Skip to content

Commit

Permalink
Add tracing support for EntityFramework 6 (.NET Framework) (#171)
Browse files Browse the repository at this point in the history
* Added support for EntityFramework 6 for .NET framework.
  • Loading branch information
lupengamzn authored Jan 27, 2021
1 parent ff3648d commit 2a1891a
Show file tree
Hide file tree
Showing 12 changed files with 620 additions and 193 deletions.
67 changes: 62 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Following API reference documentation provides guidance for using the SDK and mo
4. [Trace AWS SDK request](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-aws-sdk-request-net-and-net-core--nuget)
5. [Trace out-going HTTP requests](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-out-going-http-requests-net-and-net-core--nuget)
6. [Trace Query to SQL Server](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-query-to-sql-server-net-and-net-core--nuget)
7. [Trace SQL Query through Entity Framework Core 3.0 and above](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-core-30-and-above-net-core--nuget)
7. [Trace SQL Query through Entity Framework](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-net-and-net-core--nuget)
8. [Multithreaded Execution](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#multithreaded-execution-net-and-net-core--nuget)
9. [Trace custom methods ](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-custom-methods-net-and-net-core)
10. [Creating custom Segment/Subsegment](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#creating-custom-segmentsubsegment-net-and-net-core)
Expand Down Expand Up @@ -384,7 +384,11 @@ using (var command = new TraceableSqlCommand("SELECT * FROM products", connectio
2. Parameterized values will appear in their tokenized form and will not be expanded.
3. The value of `collectSqlQueries` in the `TraceableSqlCommand` instance overrides the value set in the global configuration using the `CollectSqlQueries` property.

### Trace SQL Query through Entity Framework Core 3.0 and above (.NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Handlers.EntityFramework/)
### Trace SQL Query through Entity Framework (.NET and .NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Handlers.EntityFramework/)

#### Setup

##### .NET Core

AWS XRay SDK for .NET Core provides interceptor for tracing SQL query through Entity Framework Core (>=3.0).

Expand All @@ -397,8 +401,6 @@ For how to start with Entity Framework Core in an ASP.NET Core web app, please t

*Known Limitation (as of 12-03-2020):* If you're using another `DbCommandInterceptor` implementation along with the `AddXRayInterceptor` in the `DbContext`, it may not work as expected and you may see a "EntityNotAvailableException" from the XRay EFCore interceptor. This is due to [`AsyncLocal`](https://docs.microsoft.com/en-us/dotnet/api/system.threading.asynclocal-1?view=netcore-2.0) not being able to maintain context across the `ReaderExecutingAsync` and `ReaderExecutedAsync` methods. Ref [here](https://github.com/dotnet/efcore/issues/22766) for more details on the issue.

#### Setup

In order to trace SQL query, you can register your `DbContext` with `AddXRayInterceptor()` accordingly in the `ConfigureServices` method in `startup.cs` file.

For instance, when dealing with MySql server using Nuget: [Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql) (V 3.1.1).
Expand Down Expand Up @@ -426,10 +428,45 @@ public class your_DbContext : DbContext

The connection string can be either hard coded or configured from `appsettings.json` file.

##### .NET

AWS XRay SDK for .NET provides interceptor for tracing SQL query through Entity Framework 6 (>= 6.2.0).

For how to start with Entity Framework 6 in an ASP.NET web app, please take reference to [link](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application).

For instrumentation, you will need to install `AWSXRayRecorder.Handlers.EntityFramework` nuget package and call `AWSXRayEntityFramework6.AddXRayInterceptor()` in your code. Make sure to call it **only once** to avoid duplicate tracing.

For instance, you can call `AddXRayInterceptor()` in the `Application_Start` method of **Global.asax** file.

```
using Amazon.XRay.Recorder.Handlers.EntityFramework;
protected void Application_Start()
{
AWSXRayEntityFramework6.AddXRayInterceptor();
}
```

Or you can call it in the `DbConfiguration` class if there is one in your application to configure execution policy.

```
using Amazon.XRay.Recorder.Handlers.EntityFramework;
public class YourDbConfiguration : DbConfiguration
{
public YourDbConfiguration()
{
AWSXRayEntityFramework6.AddXRayInterceptor();
}
}
```

#### Capture SQL Query text in the traced SQL calls to SQL Server

You can also opt in to capture the `DbCommand.CommandText` as part of the subsegment created for your SQL query. The collected `DbCommand.CommandText` will appear as `sanitized_query` in the subsegment JSON. By default, this feature is disabled due to security reasons.

##### .NET Core

If you want to enable this feature, it can be done in two ways. First, by setting the `CollectSqlQueries` to **true** in the `appsettings.json` file as follows:

```json
Expand All @@ -440,7 +477,7 @@ If you want to enable this feature, it can be done in two ways. First, by settin
}
```

Secondly, you can set the `collectSqlQueries` parameter in the `AddXRayInterceptor()` as **true** to collect the SQL query text. If you set this parameter as **false**, it will disable the `collectSqlQueries` feature for this `AddXRayInterceptor()`.
Secondly, you can set the `collectSqlQueries` parameter in the `AddXRayInterceptor()` as **true** to collect the SQL query text. If you set this parameter as **false**, it will disable the `collectSqlQueries` feature for this `AddXRayInterceptor()`. Opting in `AddXRayInterceptor()` has the highest execution priority, which will override the configuration item in `appsettings.json` mentioned above.

```csharp
using Microsoft.EntityFrameworkCore;
Expand All @@ -463,6 +500,26 @@ public class your_DbContext : DbContext
}
```

##### .NET

You can enable tracing SQL query text for EF 6 interceptor in the `Web.config` file.

```xml
<configuration>
<appSettings>
<add key="CollectSqlQueries" value="true"/>
</appSettings>
</configuration>
```

You can also pass **true** to `AddXRayInterceptor()` to collect SQL query text, otherwise pass **false** to disable. Opting in `AddXRayInterceptor()` has the highest execution priority, which will override the configuration item in `Web.config` mentioned above.

```
using Amazon.XRay.Recorder.Handlers.EntityFramework;
AWSXRayEntityFramework6.AddXRayInterceptor(true);
```

### Multithreaded Execution (.NET and .NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Core/)

In multithreaded execution, X-Ray context from current to its child thread is automatically set.
Expand Down
38 changes: 38 additions & 0 deletions sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// <copyright file="AWSXRayEntityFramework6.cs" company="Amazon.com">
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// A copy of the License is located at
//
// http://aws.amazon.com/apache2.0
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
// </copyright>
//-----------------------------------------------------------------------------

using System.Data.Entity.Infrastructure.Interception;

namespace Amazon.XRay.Recorder.Handlers.EntityFramework
{
/// <summary>
/// Class for <see cref="DbInterception"/> to add <see cref="EFInterceptor"/>.
/// User can pass collectSqlQueries to AddXRayInterceptor() to decide if sanitized_query should be included in the trace
/// context or not.
/// </summary>
public static class AWSXRayEntityFramework6
{
/// <summary>
/// Enable tracing SQL queries through EntityFramework 6 for .NET framework by calling AWSXRayEntityFramework6.AddXRayInterceptor() to add <see cref="EFInterceptor"/> into <see cref="DbInterception"/> to register X-Ray tracing interceptor.
/// </summary>
/// <param name="collectSqlQueries">Set this parameter to true to capture sql query text. The value set here overrides the value of CollectSqlQueries in Web.config if present. The default value of this parameter is null.</param>
public static void AddXRayInterceptor(bool? collectSqlQueries = null)
{
DbInterception.Add(new EFInterceptor(collectSqlQueries));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static class AWSXRayInterceptorExtensions
/// Add <see cref="EFInterceptor"/> to <see cref="DbContextOptionsBuilder"/>.
/// </summary>
/// <param name="dbContextOptionsBuilder">Instance of <see cref="DbContextOptionsBuilder"/>.</param>
/// <param name="collectSqlQueries"></param>
/// <param name="collectSqlQueries">Set this parameter to true to capture sql query text. The value set here overrides the value of CollectSqlQueries in appsettings.json if present. The default value of this parameter is null.</param>
/// <returns>Instance of <see cref="DbContextOptionsBuilder"/>.</returns>
public static DbContextOptionsBuilder AddXRayInterceptor(this DbContextOptionsBuilder dbContextOptionsBuilder, bool? collectSqlQueries = null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<Company>Amazon.com, Inc</Company>
<Product>Amazon Web Service X-Ray Recorder</Product>
<Copyright>Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.</Copyright>
Expand All @@ -11,7 +11,7 @@
<AssemblyName>AWSXRayRecorder.Handlers.EntityFramework</AssemblyName>
<RootNamespace>Amazon.XRay.Recorder.Handlers.EntityFramework</RootNamespace>
<Authors>Amazon Web Services</Authors>
<Description>This package contains libraries to trace SQL queries through Entity Framework Core.</Description>
<Description>This package contains libraries to trace SQL queries through Entity Framework.</Description>
<PackageLicenseUrl>http://aws.amazon.com/apache2.0/</PackageLicenseUrl>
<PackageProjectUrl>https://aws.amazon.com/documentation/xray/</PackageProjectUrl>
<RepositoryUrl>https://github.com/aws/aws-xray-sdk-dotnet</RepositoryUrl>
Expand All @@ -30,8 +30,16 @@
<NoWarn>1701;1702;1591;</NoWarn>
</PropertyGroup>

<ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.0" />
<Compile Remove="AWSXRayEntityFramework6.cs" />
<Compile Remove="EFInterceptor.net45.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="EntityFramework" Version="6.2.0" />
<Compile Remove="AWSXRayInterceptorExtensions.cs" />
<Compile Remove="EFInterceptor.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 2a1891a

Please sign in to comment.