Unverified Commit c2f591a8 authored by Lemon's avatar Lemon Committed by GitHub

Add supports for some EntityFrameworkCore Providers (#41)

* Add EntityFrameworkCore component define

* Add EntityFrameworkCore component define

* Refactor Diagnostics.EntityFrameworkCore

* Remove DefaultEFCoreComponentProvider

* Support EntityFrameworkCore.Sqlite

* Update Sample.Backend

* Support Pomelo_EntityFrameworkCore_MySql provider for EntityFrameworkCore

*  Fix Parent Application Instance Id is 0

* Support Npgsql.EntityFramework
parent e328c61a
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using SkyWalking.Sample.Backend.Models;
namespace SkyWalking.Sample.Backend.Controllers
{
[Route("api/[controller]")]
public class AppsController: Controller
{
private readonly SampleDbContext _dbContext;
public AppsController(SampleDbContext sampleDbContext)
{
_dbContext = sampleDbContext;
}
[HttpGet]
public IEnumerable<Application> Get()
{
return _dbContext.Applications.ToList();
}
[HttpGet("{id}")]
public Application Get(int id)
{
return _dbContext.Applications.Find(id);
}
[HttpPut]
public void Put([FromBody]Application application)
{
_dbContext.Applications.Add(application);
_dbContext.SaveChanges();
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using SkyWalking.Sample.Backend.Models;
namespace SkyWalking.Sample.Backend.Controllers
{
......@@ -12,15 +14,14 @@ namespace SkyWalking.Sample.Backend.Controllers
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
return new List<string> {"value1", "value2"};
}
// GET api/values/5
[HttpGet("{id}")]
public async Task<string> Get(int id)
public string Get(int id)
{
var httpClient = new HttpClient();
return await httpClient.GetStringAsync("http://www.baidu.com");
return "value";
}
}
}
\ No newline at end of file
namespace SkyWalking.Sample.Backend.Models
{
public class Application
{
public int Id { get; set; }
public string Name { get; set; }
}
}
\ No newline at end of file
using Microsoft.EntityFrameworkCore;
namespace SkyWalking.Sample.Backend.Models
{
public class SampleDbContext :DbContext
{
public DbSet<Application> Applications { get; set; }
public SampleDbContext(DbContextOptions options):base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Application>().HasKey(x => x.Id);
modelBuilder.Entity<Application>().Property(x => x.Name);
base.OnModelCreating(modelBuilder);
}
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\SkyWalking.AspNetCore\SkyWalking.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite\SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
......
using Microsoft.AspNetCore.Builder;
using System.Data.SqlClient;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SkyWalking.AspNetCore;
using SkyWalking.Diagnostics.EntityFrameworkCore;
using SkyWalking.Sample.Backend.Models;
namespace SkyWalking.Sample.Backend
{
......@@ -24,7 +29,13 @@ namespace SkyWalking.Sample.Backend
{
option.DirectServers = "localhost:11800";
option.ApplicationCode = "asp-net-core-backend";
});
}).
AddEntityFrameworkCore(c => { c.AddSqlite(); });
var sqliteConnection = new SqliteConnection("DataSource=:memory:");
sqliteConnection.Open();
services.AddEntityFrameworkSqlite().AddDbContext<SampleDbContext>(c => c.UseSqlite(sqliteConnection));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
......@@ -35,6 +46,14 @@ namespace SkyWalking.Sample.Backend
app.UseDeveloperExceptionPage();
}
using (var scope = app.ApplicationServices.CreateScope())
{
using (var sampleDbContext = scope.ServiceProvider.GetService<SampleDbContext>())
{
sampleDbContext.Database.EnsureCreated();
}
}
app.UseMvc();
}
}
......
......@@ -50,6 +50,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkyWalking.Diagnostics.Enti
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkyWalking.Diagnostics.SqlClient", "src\SkyWalking.Diagnostics.SqlClient\SkyWalking.Diagnostics.SqlClient.csproj", "{44DFFDF7-5935-475A-825F-2C0298464117}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFrameworkCore", "EntityFrameworkCore", "{A4E67E09-3156-4D30-B451-F24F706E96C4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite", "src\SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite\SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite.csproj", "{F5C529C9-23C4-46B7-84FF-E86C6D17EB3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql", "src\SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql\SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql.csproj", "{7BD880F3-2886-4EE6-9569-114613AFFCBC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql", "src\SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql\SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql.csproj", "{F8D96C30-369C-4FCB-B5B2-02EAA74199C9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -116,6 +124,18 @@ Global
{44DFFDF7-5935-475A-825F-2C0298464117}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44DFFDF7-5935-475A-825F-2C0298464117}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44DFFDF7-5935-475A-825F-2C0298464117}.Release|Any CPU.Build.0 = Release|Any CPU
{F5C529C9-23C4-46B7-84FF-E86C6D17EB3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5C529C9-23C4-46B7-84FF-E86C6D17EB3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5C529C9-23C4-46B7-84FF-E86C6D17EB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5C529C9-23C4-46B7-84FF-E86C6D17EB3E}.Release|Any CPU.Build.0 = Release|Any CPU
{7BD880F3-2886-4EE6-9569-114613AFFCBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BD880F3-2886-4EE6-9569-114613AFFCBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BD880F3-2886-4EE6-9569-114613AFFCBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BD880F3-2886-4EE6-9569-114613AFFCBC}.Release|Any CPU.Build.0 = Release|Any CPU
{F8D96C30-369C-4FCB-B5B2-02EAA74199C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8D96C30-369C-4FCB-B5B2-02EAA74199C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8D96C30-369C-4FCB-B5B2-02EAA74199C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8D96C30-369C-4FCB-B5B2-02EAA74199C9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -135,9 +155,13 @@ Global
{BF5579ED-113C-4EE6-AE03-9A9CA590C924} = {79ED86A5-E9B9-49B2-9354-C911C079D03E}
{55621423-19C3-4928-8B45-666FA87BF6A2} = {79ED86A5-E9B9-49B2-9354-C911C079D03E}
{05E533B1-473F-48C0-95F7-B87061BE9834} = {613F0980-91ED-4064-8E8C-168582EF4AD7}
{CD334460-8E61-41EB-9762-62C6A342CACB} = {79ED86A5-E9B9-49B2-9354-C911C079D03E}
{4CF91A8C-25C8-4BD8-A93D-3183AF0FE2E2} = {613F0980-91ED-4064-8E8C-168582EF4AD7}
{44DFFDF7-5935-475A-825F-2C0298464117} = {79ED86A5-E9B9-49B2-9354-C911C079D03E}
{A4E67E09-3156-4D30-B451-F24F706E96C4} = {79ED86A5-E9B9-49B2-9354-C911C079D03E}
{CD334460-8E61-41EB-9762-62C6A342CACB} = {A4E67E09-3156-4D30-B451-F24F706E96C4}
{F5C529C9-23C4-46B7-84FF-E86C6D17EB3E} = {A4E67E09-3156-4D30-B451-F24F706E96C4}
{7BD880F3-2886-4EE6-9569-114613AFFCBC} = {A4E67E09-3156-4D30-B451-F24F706E96C4}
{F8D96C30-369C-4FCB-B5B2-02EAA74199C9} = {A4E67E09-3156-4D30-B451-F24F706E96C4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {94C0DA2C-CCCB-4314-93A2-9809B5DD0583}
......
......@@ -154,7 +154,6 @@ namespace SkyWalking.Context.Trace
if (_type == SegmentRefType.CrossProcess)
{
traceSegmentReference.RefType = RefType.CrossProcess;
traceSegmentReference.ParentApplicationInstanceId = _parentApplicationInstanceId;
if (_peerId == DictionaryUtil.NullValue)
{
traceSegmentReference.NetworkAddress = _peerHost;
......@@ -168,7 +167,7 @@ namespace SkyWalking.Context.Trace
{
traceSegmentReference.RefType = RefType.CrossThread;
}
traceSegmentReference.ParentApplicationInstanceId = _parentApplicationInstanceId;
traceSegmentReference.EntryApplicationInstanceId = _entryApplicationInstanceId;
traceSegmentReference.ParentTraceSegmentId = _traceSegmentId.Transform();
traceSegmentReference.ParentSpanId = _spanId;
......
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
*/
using Microsoft.Extensions.DependencyInjection;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public static class DatabaseProviderBuilderExtensions
{
public static DatabaseProviderBuilder AddNpgsql(this DatabaseProviderBuilder builder)
{
builder.Services.AddSingleton<IEfCoreSpanMetadataProvider, NpgsqlEFCoreSpanMetadataProvider>();
return builder;
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
*/
using System.Data.Common;
using Npgsql;
using SkyWalking.NetworkProtocol.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public class NpgsqlEFCoreSpanMetadataProvider : IEfCoreSpanMetadataProvider
{
public IComponent Component { get; } = ComponentsDefine.Npgsql_EntityFrameworkCore_PostgreSQL;
public bool Match(DbConnection connection)
{
return connection is NpgsqlConnection;
}
public string GetPeer(DbConnection connection)
{
return connection.DataSource;
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<AssemblyName>SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql</AssemblyName>
<AssemblyTitle>SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql</AssemblyTitle>
<PackageId>SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql</PackageId>
<PackageTags>SkyWalking;APM;EntityFrameworkCore;EF</PackageTags>
<Description>SkyWalking.Diagnostics.EntityFrameworkCore.Npgsql notifies of EF requests.</Description>
<RootNamespace>SkyWalking.Diagnostics.EntityFrameworkCore</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SkyWalking.Abstractions\SkyWalking.Abstractions.csproj" />
<ProjectReference Include="..\SkyWalking.Core\SkyWalking.Core.csproj" />
<ProjectReference Include="..\SkyWalking.Diagnostics.EntityFrameworkCore\SkyWalking.Diagnostics.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\SkyWalking.Extensions.DependencyInjection\SkyWalking.Extensions.DependencyInjection.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.0" />
</ItemGroup>
</Project>
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
*/
using Microsoft.Extensions.DependencyInjection;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public static class DatabaseProviderBuilderExtensions
{
public static DatabaseProviderBuilder AddPomeloMysql(this DatabaseProviderBuilder builder)
{
builder.Services.AddSingleton<IEfCoreSpanMetadataProvider, MySqlEFCoreSpanMetadataProvider>();
return builder;
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
*/
using System.Data.Common;
using MySql.Data.MySqlClient;
using SkyWalking.NetworkProtocol.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public class MySqlEFCoreSpanMetadataProvider : IEfCoreSpanMetadataProvider
{
public IComponent Component { get; } = ComponentsDefine.Pomelo_EntityFrameworkCore_MySql;
public bool Match(DbConnection connection)
{
return connection is MySqlConnection;
}
public string GetPeer(DbConnection connection)
{
return connection.DataSource;
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<AssemblyName>SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql</AssemblyName>
<AssemblyTitle>SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql</AssemblyTitle>
<PackageId>SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql</PackageId>
<PackageTags>SkyWalking;APM;EntityFrameworkCore;EF</PackageTags>
<Description>SkyWalking.Diagnostics.EntityFrameworkCore.Pomelo.MySql notifies of EF requests.</Description>
<RootNamespace>SkyWalking.Diagnostics.EntityFrameworkCore</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SkyWalking.Abstractions\SkyWalking.Abstractions.csproj" />
<ProjectReference Include="..\SkyWalking.Core\SkyWalking.Core.csproj" />
<ProjectReference Include="..\SkyWalking.Diagnostics.EntityFrameworkCore\SkyWalking.Diagnostics.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\SkyWalking.Extensions.DependencyInjection\SkyWalking.Extensions.DependencyInjection.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.0.1" />
</ItemGroup>
</Project>
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
*/
using Microsoft.Extensions.DependencyInjection;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public static class DatabaseProviderBuilderExtensions
{
public static DatabaseProviderBuilder AddSqlite(this DatabaseProviderBuilder builder)
{
builder.Services.AddSingleton<IEfCoreSpanMetadataProvider, SqliteEFCoreSpanMetadataProvider>();
return builder;
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<AssemblyName>SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite</AssemblyName>
<AssemblyTitle>SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite</AssemblyTitle>
<PackageId>SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite</PackageId>
<PackageTags>SkyWalking;APM;EntityFrameworkCore;EF</PackageTags>
<Description>SkyWalking.Diagnostics.EntityFrameworkCore.Sqlite notifies of EF requests.</Description>
<RootNamespace>SkyWalking.Diagnostics.EntityFrameworkCore</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SkyWalking.Abstractions\SkyWalking.Abstractions.csproj" />
<ProjectReference Include="..\SkyWalking.Core\SkyWalking.Core.csproj" />
<ProjectReference Include="..\SkyWalking.Diagnostics.EntityFrameworkCore\SkyWalking.Diagnostics.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\SkyWalking.Extensions.DependencyInjection\SkyWalking.Extensions.DependencyInjection.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" />
</ItemGroup>
</Project>
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
*/
using System.Data.Common;
using Microsoft.Data.Sqlite;
using SkyWalking.NetworkProtocol.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public class SqliteEFCoreSpanMetadataProvider : IEfCoreSpanMetadataProvider
{
public IComponent Component { get; } = ComponentsDefine.EntityFrameworkCore_Sqlite;
public bool Match(DbConnection connection)
{
return connection is SqliteConnection;
}
public string GetPeer(DbConnection connection)
{
string dataSource;
switch (connection.DataSource)
{
case "":
dataSource = "localhost";
break;
default:
dataSource = connection.DataSource;
break;
}
return $"{dataSource}";
}
}
}
\ No newline at end of file
using Microsoft.Extensions.DependencyInjection;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public class DatabaseProviderBuilder
{
public IServiceCollection Services { get; }
public DatabaseProviderBuilder(IServiceCollection services)
{
Services = services;
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Diagnostics;
using SkyWalking.Context;
using SkyWalking.Context.Trace;
using SkyWalking.NetworkProtocol.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public class EfCoreSpanFactory : IEfCoreSpanFactory
{
private readonly IEnumerable<IEfCoreSpanMetadataProvider> _spanMetadataProviders;
public EfCoreSpanFactory(IEnumerable<IEfCoreSpanMetadataProvider> spanMetadataProviders)
{
_spanMetadataProviders = spanMetadataProviders;
}
public ISpan Create(string operationName, CommandEventData eventData)
{
foreach (var provider in _spanMetadataProviders)
if (provider.Match(eventData.Command.Connection)) return CreateSpan(operationName, eventData, provider);
return CreateDefaultSpan(operationName, eventData);
}
protected virtual ISpan CreateSpan(string operationName, CommandEventData eventData, IEfCoreSpanMetadataProvider metadataProvider)
{
var span = ContextManager.CreateExitSpan(operationName, metadataProvider.GetPeer(eventData.Command.Connection));
span.SetComponent(metadataProvider.Component);
return span;
}
private ISpan CreateDefaultSpan(string operationName, CommandEventData eventData)
{
var span = ContextManager.CreateLocalSpan(operationName);
span.SetComponent(ComponentsDefine.EntityFrameworkCore);
return span;
}
}
}
\ No newline at end of file
......@@ -18,19 +18,22 @@
using System;
using System.Data.Common;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using SkyWalking.Config;
using SkyWalking.Context;
using SkyWalking.Context.Tag;
using SkyWalking.Context.Trace;
using SkyWalking.NetworkProtocol.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public class EntityFrameworkCoreDiagnosticProcessor : ITracingDiagnosticProcessor
{
private Func<CommandEventData, string> _operationNameResolver;
private readonly IEfCoreSpanFactory _efCoreSpanFactory;
public string ListenerName => DbLoggerCategory.Name;
......@@ -42,17 +45,25 @@ namespace SkyWalking.Diagnostics.EntityFrameworkCore
get
{
return _operationNameResolver ??
(_operationNameResolver = (data) => "DB " + data.ExecuteMethod.ToString());
(_operationNameResolver = (data) =>
{
var commandType = data.Command.CommandText?.Split(' ');
return "DB " + (commandType.FirstOrDefault() ?? data.ExecuteMethod.ToString());
});
}
set => _operationNameResolver = value ?? throw new ArgumentNullException(nameof(OperationNameResolver));
}
public EntityFrameworkCoreDiagnosticProcessor(IEfCoreSpanFactory spanFactory)
{
_efCoreSpanFactory = spanFactory;
}
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting")]
public void CommandExecuting([Object]CommandEventData eventData)
public void CommandExecuting([Object] CommandEventData eventData)
{
var operationName = OperationNameResolver(eventData);
var span = ContextManager.CreateLocalSpan(operationName);
span.SetComponent(ComponentsDefine.EntityFrameworkCore);
var span = _efCoreSpanFactory.Create(operationName, eventData);
span.SetLayer(SpanLayer.DB);
Tags.DbType.Set(span, "Sql");
Tags.DbInstance.Set(span, eventData.Command.Connection.Database);
......
using Microsoft.EntityFrameworkCore.Diagnostics;
using SkyWalking.Context.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public interface IEfCoreSpanFactory
{
ISpan Create(string operationName, CommandEventData eventData);
}
}
\ No newline at end of file
using System;
using System.Data.Common;
using SkyWalking.NetworkProtocol.Trace;
namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public interface IEfCoreSpanMetadataProvider
{
IComponent Component { get; }
bool Match(DbConnection connection);
string GetPeer(DbConnection connection);
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<AssemblyName>SkyWalking.Diagnostics.EntityFrameworkCore</AssemblyName>
<AssemblyTitle>SkyWalking.Diagnostics.EntityFrameworkCore</AssemblyTitle>
<PackageId>SkyWalking.Diagnostics.EntityFrameworkCore</PackageId>
<PackageTags>SkyWalking;APM;EntityFrameworkCore;EF</PackageTags>
<Description>SkyWalking.Diagnostics.EntityFrameworkCore notifies of EF requests.</Description>
<RootNamespace>SkyWalking.Diagnostics.HttpClient</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SkyWalking.Abstractions\SkyWalking.Abstractions.csproj" />
<ProjectReference Include="..\SkyWalking.Core\SkyWalking.Core.csproj" />
<ProjectReference Include="..\SkyWalking.Extensions.DependencyInjection\SkyWalking.Extensions.DependencyInjection.csproj" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<AssemblyName>SkyWalking.Diagnostics.EntityFrameworkCore</AssemblyName>
<AssemblyTitle>SkyWalking.Diagnostics.EntityFrameworkCore</AssemblyTitle>
<PackageId>SkyWalking.Diagnostics.EntityFrameworkCore</PackageId>
<PackageTags>SkyWalking;APM;EntityFrameworkCore;EF</PackageTags>
<Description>SkyWalking.Diagnostics.EntityFrameworkCore notifies of EF requests.</Description>
<RootNamespace>SkyWalking.Diagnostics.EntityFrameworkCore</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SkyWalking.Abstractions\SkyWalking.Abstractions.csproj" />
<ProjectReference Include="..\SkyWalking.Core\SkyWalking.Core.csproj" />
<ProjectReference Include="..\SkyWalking.Extensions.DependencyInjection\SkyWalking.Extensions.DependencyInjection.csproj" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -24,7 +24,7 @@ namespace SkyWalking.Diagnostics.EntityFrameworkCore
{
public static class SkyWalkingBuilderExtensions
{
public static SkyWalkingBuilder AddEntityFrameworkCore(this SkyWalkingBuilder builder)
public static SkyWalkingBuilder AddEntityFrameworkCore(this SkyWalkingBuilder builder, Action<DatabaseProviderBuilder> optionAction)
{
if (builder == null)
{
......@@ -32,7 +32,14 @@ namespace SkyWalking.Diagnostics.EntityFrameworkCore
}
builder.Services.AddSingleton<ITracingDiagnosticProcessor, EntityFrameworkCoreDiagnosticProcessor>();
builder.Services.AddSingleton<IEfCoreSpanFactory, EfCoreSpanFactory>();
if (optionAction != null)
{
var databaseProviderBuilder = new DatabaseProviderBuilder(builder.Services);
optionAction(databaseProviderBuilder);
}
return builder;
}
}
......
......@@ -37,17 +37,27 @@ namespace SkyWalking.NetworkProtocol.Trace
public static readonly OfficialComponent SqlServer = new OfficialComponent(3006, "SqlServer");
public static readonly OfficialComponent Npgsql = new OfficialComponent(3007, "Npgsql");
public static readonly OfficialComponent MySqlConnector = new OfficialComponent(3008, "MySqlConnector");
public static readonly OfficialComponent EntityFrameworkCore_InMemory = new OfficialComponent(3009, "EntityFrameworkCore.InMemory");
public static readonly OfficialComponent EntityFrameworkCore_SqlServer = new OfficialComponent(3010, "EntityFrameworkCore.SqlServer");
public static readonly OfficialComponent EntityFrameworkCore_Sqlite = new OfficialComponent(3011, "EntityFrameworkCore.Sqlite");
public static readonly OfficialComponent Pomelo_EntityFrameworkCore_MySql = new OfficialComponent(3012, "Pomelo.EntityFrameworkCore.MySql");
public static readonly OfficialComponent Npgsql_EntityFrameworkCore_PostgreSQL = new OfficialComponent(3013, "Npgsql.EntityFrameworkCore.PostgreSQL");
public static readonly OfficialComponent InMemoryDatabase = new OfficialComponent(3014, "InMemoryDatabase");
private static readonly ComponentsDefine _instance = new ComponentsDefine();
public ComponentsDefine Instance
{
get
{
return _instance;
}
}
public ComponentsDefine Instance => _instance;
private Dictionary<int, string> _components;
private readonly Dictionary<int, string> _components;
private ComponentsDefine()
{
......@@ -58,6 +68,14 @@ namespace SkyWalking.NetworkProtocol.Trace
AddComponent(CAP);
AddComponent(StackExchange_Redis);
AddComponent(SqlServer);
AddComponent(Npgsql);
AddComponent(MySqlConnector);
AddComponent(EntityFrameworkCore_InMemory);
AddComponent(EntityFrameworkCore_SqlServer);
AddComponent(EntityFrameworkCore_Sqlite);
AddComponent(Pomelo_EntityFrameworkCore_MySql);
AddComponent(Npgsql_EntityFrameworkCore_PostgreSQL);
AddComponent(InMemoryDatabase);
}
private void AddComponent(OfficialComponent component)
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
......@@ -57,7 +58,7 @@ namespace SkyWalking.Diagnostics.EntityFrameworkCore.Tests
{
var processorObserver = new TracingDiagnosticProcessorObserver(new[]
{
new EntityFrameworkCoreDiagnosticProcessor()
new EntityFrameworkCoreDiagnosticProcessor(new EfCoreSpanFactory(new List<IEfCoreSpanMetadataProvider>()))
});
DiagnosticListener.AllListeners.Subscribe(processorObserver);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment