diff --git a/CoreProfilerExample.Common/CoreProfilerExample.Common.csproj b/CoreProfilerExample.Common/CoreProfilerExample.Common.csproj
index fa71b7a..04296cf 100644
--- a/CoreProfilerExample.Common/CoreProfilerExample.Common.csproj
+++ b/CoreProfilerExample.Common/CoreProfilerExample.Common.csproj
@@ -6,4 +6,8 @@
enable
+
+
+
+
diff --git a/CoreProfilerExample.Common/Extensions/MethodBaseExtension.cs b/CoreProfilerExample.Common/Extensions/MethodBaseExtension.cs
new file mode 100644
index 0000000..6cc4101
--- /dev/null
+++ b/CoreProfilerExample.Common/Extensions/MethodBaseExtension.cs
@@ -0,0 +1,39 @@
+using CoreProfiler;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace CoreProfilerExample.Common.Extensions
+{
+ public static class MethodBaseExtension
+ {
+ public static IDisposable ProfilingStep(this MethodBase method, string? stepName = null)
+ {
+ if (stepName == null)
+ {
+ // 取得方法的類型物件
+ var methodType = method.ReflectedType;
+
+ // 取得類別的類型物件
+ var classType = methodType?.ReflectedType ?? methodType;
+
+ // 取出類別底下所有非同步類型的方法,比對出當前的方法類型
+ var classMethodType = classType?
+ .GetMethods()
+ .Select(x => new
+ {
+ Method = x,
+ Attribute = x.GetCustomAttribute(),
+ })
+ .FirstOrDefault(x => x.Attribute?.StateMachineType == methodType);
+
+ var className = classType?.Name ?? "無法取得類別名稱";
+
+ var methodName = classMethodType?.Method.Name ?? method.Name ?? "無法取得方法名稱";
+
+ stepName = $"{classType?.Name}.{methodName}";
+ }
+
+ return ProfilingSession.Current.Step(stepName);
+ }
+ }
+}
diff --git a/CoreProfilerExample.Common/Options/CoreProfilerOption.cs b/CoreProfilerExample.Common/Options/CoreProfilerOption.cs
new file mode 100644
index 0000000..8ad4cfd
--- /dev/null
+++ b/CoreProfilerExample.Common/Options/CoreProfilerOption.cs
@@ -0,0 +1,61 @@
+using Newtonsoft.Json;
+
+namespace CoreProfilerExample.Common.Options
+{
+ public class CoreProfilerOption
+ {
+ ///
+ /// 資料保存上限(Session)。
+ ///
+ [JsonProperty("circularBufferSize")]
+ public int CircularBufferSize { get; set; } = 200;
+ ///
+ /// 要過濾掉的項目。
+ ///
+ [JsonProperty("filters")]
+ public IEnumerable Filters { get; set; } = [
+ new CoreProfilerOptionFilter
+ {
+ Key = "/coreprofiler",
+ Value = "/coreprofiler",
+ Type = "CoreProfiler.ProfilingFilters.NameContainsProfilingFilter, CoreProfiler",
+ },
+ new CoreProfilerOptionFilter
+ {
+ Key = "static files",
+ Value = "ico,jpg,js,css,svg,json,ttf,woff,woff2,eot",
+ Type = "CoreProfiler.ProfilingFilters.FileExtensionProfilingFilter, CoreProfiler",
+ },
+ ];
+
+ public CoreProfilerOption Save(string filename)
+ {
+ var json = JsonConvert.SerializeObject(this, Formatting.Indented);
+
+ File.WriteAllText(filename, json);
+
+ return this;
+ }
+
+ public static CoreProfilerOption UseCoreProfilerSetting()
+ {
+ var filename = Path.Combine(AppContext.BaseDirectory, "coreprofiler.json");
+
+ if (File.Exists(filename))
+ {
+ try
+ {
+ var json = File.ReadAllText(filename);
+
+ return JsonConvert.DeserializeObject(json);
+ }
+ catch
+ {
+
+ }
+ }
+
+ return new CoreProfilerOption().Save(filename);
+ }
+ }
+}
diff --git a/CoreProfilerExample.Common/Options/CoreProfilerOptionFilter.cs b/CoreProfilerExample.Common/Options/CoreProfilerOptionFilter.cs
new file mode 100644
index 0000000..48b2bc4
--- /dev/null
+++ b/CoreProfilerExample.Common/Options/CoreProfilerOptionFilter.cs
@@ -0,0 +1,14 @@
+using Newtonsoft.Json;
+
+namespace CoreProfilerExample.Common.Options
+{
+ public class CoreProfilerOptionFilter
+ {
+ [JsonProperty("key")]
+ public string Key { get; set; } = null!;
+ [JsonProperty("value")]
+ public string Value { get; set; } = null!;
+ [JsonProperty("type")]
+ public string Type { get; set; } = null!;
+ }
+}
diff --git a/CoreProfilerExample.Repository/Implements/WeatherForecastRepository.cs b/CoreProfilerExample.Repository/Implements/WeatherForecastRepository.cs
index 65d929d..494fb17 100644
--- a/CoreProfilerExample.Repository/Implements/WeatherForecastRepository.cs
+++ b/CoreProfilerExample.Repository/Implements/WeatherForecastRepository.cs
@@ -1,5 +1,7 @@
-using CoreProfilerExample.Repository.Interfaces;
+using CoreProfilerExample.Common.Extensions;
+using CoreProfilerExample.Repository.Interfaces;
using CoreProfilerExample.Repository.Models.DataModels;
+using System.Reflection;
using static CoreProfilerExample.Common.Constants.WeatherConstant;
namespace CoreProfilerExample.Repository.Implements
@@ -8,12 +10,15 @@ namespace CoreProfilerExample.Repository.Implements
{
public Task> GetAsync(int days)
{
- return Task.Run(() => days > 0 ? Enumerable.Range(1, days).Select(index => new WeatherForecastDataModel
+ using (MethodBase.GetCurrentMethod()?.ProfilingStep())
{
- Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = WeatherSummaries[Random.Shared.Next(WeatherSummaries.Length)]
- }) : []);
+ return Task.Run(() => days > 0 ? Enumerable.Range(1, days).Select(index => new WeatherForecastDataModel
+ {
+ Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
+ TemperatureC = Random.Shared.Next(-20, 55),
+ Summary = WeatherSummaries[Random.Shared.Next(WeatherSummaries.Length)]
+ }) : []);
+ }
}
}
}
diff --git a/CoreProfilerExample.Service/Extensions/MapperExtension.cs b/CoreProfilerExample.Service/Extensions/MapperExtension.cs
index b597b76..9db7a1a 100644
--- a/CoreProfilerExample.Service/Extensions/MapperExtension.cs
+++ b/CoreProfilerExample.Service/Extensions/MapperExtension.cs
@@ -1,10 +1,5 @@
using CoreProfilerExample.Repository.Models.DataModels;
using CoreProfilerExample.Service.Models.Dtos;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace CoreProfilerExample.Service.Extensions
{
diff --git a/CoreProfilerExample.Service/Implements/WeatherService.cs b/CoreProfilerExample.Service/Implements/WeatherService.cs
index 46e5555..dc7d52c 100644
--- a/CoreProfilerExample.Service/Implements/WeatherService.cs
+++ b/CoreProfilerExample.Service/Implements/WeatherService.cs
@@ -1,21 +1,28 @@
-using CoreProfilerExample.Repository.Interfaces;
+using CoreProfilerExample.Common.Extensions;
+using CoreProfilerExample.Repository.Interfaces;
using CoreProfilerExample.Service.Extensions;
using CoreProfilerExample.Service.Interfaces;
using CoreProfilerExample.Service.Models.Dtos;
using CoreProfilerExample.Service.Models.ParameterDtos;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Reflection;
namespace CoreProfilerExample.Service.Implements
{
- public class WeatherService(IWeatherForecastRepository weatherForecast) : IWeatherService
+ public class WeatherService : IWeatherService
{
+ public WeatherService(IWeatherForecastRepository weatherForecast)
+ {
+ this.weatherForecast = weatherForecast;
+ }
+
+ private readonly IWeatherForecastRepository weatherForecast = null!;
+
public Task GetWeatherForecastAsync(GetWeatherForecastParameterDto parameterDto)
{
- return weatherForecast.GetAsync(parameterDto.ForecastDays).ToDtoAsync();
+ using (MethodBase.GetCurrentMethod()?.ProfilingStep())
+ {
+ return weatherForecast.GetAsync(parameterDto.ForecastDays).ToDtoAsync();
+ }
}
}
}
diff --git a/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastDto.cs b/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastDto.cs
index 1ed21fb..452b529 100644
--- a/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastDto.cs
+++ b/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastDto.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CoreProfilerExample.Service.Models.Dtos
+namespace CoreProfilerExample.Service.Models.Dtos
{
public class GetWeatherForecastDto
{
diff --git a/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastItemDto.cs b/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastItemDto.cs
index 79a36b7..0565875 100644
--- a/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastItemDto.cs
+++ b/CoreProfilerExample.Service/Models/Dtos/GetWeatherForecastItemDto.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CoreProfilerExample.Service.Models.Dtos
+namespace CoreProfilerExample.Service.Models.Dtos
{
public class GetWeatherForecastItemDto
{
diff --git a/CoreProfilerExample.Service/Models/ParameterDtos/GetWeatherForecastParameterDto.cs b/CoreProfilerExample.Service/Models/ParameterDtos/GetWeatherForecastParameterDto.cs
index 15e89b0..6a90bf2 100644
--- a/CoreProfilerExample.Service/Models/ParameterDtos/GetWeatherForecastParameterDto.cs
+++ b/CoreProfilerExample.Service/Models/ParameterDtos/GetWeatherForecastParameterDto.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CoreProfilerExample.Service.Models.ParameterDtos
+namespace CoreProfilerExample.Service.Models.ParameterDtos
{
public class GetWeatherForecastParameterDto
{
diff --git a/CoreProfilerExample.sln b/CoreProfilerExample.sln
index 75a48a1..96579f7 100644
--- a/CoreProfilerExample.sln
+++ b/CoreProfilerExample.sln
@@ -11,6 +11,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreProfilerExample.Service
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreProfilerExample.Common", "CoreProfilerExample.Common\CoreProfilerExample.Common.csproj", "{DDD6FCC3-454E-42CB-94D0-23A7EA57D039}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "方案項目", "方案項目", "{5C1FF8FA-0F30-4581-8173-320356AFD2CC}"
+ ProjectSection(SolutionItems) = preProject
+ README.md = README.md
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/CoreProfilerExample/Controllers/WeatherController.cs b/CoreProfilerExample/Controllers/WeatherController.cs
index db44914..8ad5c66 100644
--- a/CoreProfilerExample/Controllers/WeatherController.cs
+++ b/CoreProfilerExample/Controllers/WeatherController.cs
@@ -1,9 +1,11 @@
+using CoreProfilerExample.Common.Extensions;
using CoreProfilerExample.Infrastructure.Extensions;
using CoreProfilerExample.Models.Parameters;
using CoreProfilerExample.Models.ViewModels;
using CoreProfilerExample.Service.Interfaces;
using Microsoft.AspNetCore.Mvc;
using System.Net;
+using System.Reflection;
namespace CoreProfilerExample.Controllers
{
@@ -17,13 +19,16 @@ namespace CoreProfilerExample.Controllers
[ProducesResponseType(typeof(ExceptionViewModel), (int)HttpStatusCode.BadRequest)]
public async Task GetWeatherForecastAsync(GetWeatherForecastParameter parameter)
{
- try
+ using (MethodBase.GetCurrentMethod()?.ProfilingStep())
{
- return Ok(await weather.GetWeatherForecastAsync(parameter.ToDto()).ToViewModel());
- }
- catch (Exception ex)
- {
- return BadRequest(ex.ToViewModel());
+ try
+ {
+ return Ok(await weather.GetWeatherForecastAsync(parameter.ToDto()).ToViewModel());
+ }
+ catch (Exception ex)
+ {
+ return BadRequest(ex.ToViewModel());
+ }
}
}
}
diff --git a/CoreProfilerExample/CoreProfilerExample.csproj b/CoreProfilerExample/CoreProfilerExample.csproj
index 0b8764a..7118ec8 100644
--- a/CoreProfilerExample/CoreProfilerExample.csproj
+++ b/CoreProfilerExample/CoreProfilerExample.csproj
@@ -7,6 +7,7 @@
+
diff --git a/CoreProfilerExample/Infrastructure/Extensions/DependencyInjectionExtension.cs b/CoreProfilerExample/Infrastructure/Extensions/DependencyInjectionExtension.cs
index cf85aed..b8eda56 100644
--- a/CoreProfilerExample/Infrastructure/Extensions/DependencyInjectionExtension.cs
+++ b/CoreProfilerExample/Infrastructure/Extensions/DependencyInjectionExtension.cs
@@ -1,4 +1,6 @@
-using CoreProfilerExample.Repository.Implements;
+using CoreProfiler.Web;
+using CoreProfilerExample.Common.Options;
+using CoreProfilerExample.Repository.Implements;
using CoreProfilerExample.Repository.Interfaces;
using CoreProfilerExample.Service.Implements;
using CoreProfilerExample.Service.Interfaces;
@@ -18,5 +20,14 @@ namespace CoreProfilerExample.Infrastructure.Extensions
services.AddScoped();
return services;
}
+
+ public static IApplicationBuilder UseCoreProfiler(this IApplicationBuilder app)
+ {
+ CoreProfilerOption.UseCoreProfilerSetting();
+
+ app.UseCoreProfiler(true);
+
+ return app;
+ }
}
}
diff --git a/CoreProfilerExample/Program.cs b/CoreProfilerExample/Program.cs
index c03b524..f7e249a 100644
--- a/CoreProfilerExample/Program.cs
+++ b/CoreProfilerExample/Program.cs
@@ -22,4 +22,8 @@ app.UseAuthorization();
app.MapControllers();
+#region CoreProfilerExample
+app.UseCoreProfiler();
+#endregion
+
app.Run();
diff --git a/CoreProfilerExampleResource/LastestProfilingResult.JPG b/CoreProfilerExampleResource/LastestProfilingResult.JPG
new file mode 100644
index 0000000..6d5ccb8
Binary files /dev/null and b/CoreProfilerExampleResource/LastestProfilingResult.JPG differ
diff --git a/CoreProfilerExampleResource/LastestProfilingResultDetail.JPG b/CoreProfilerExampleResource/LastestProfilingResultDetail.JPG
new file mode 100644
index 0000000..a920d55
Binary files /dev/null and b/CoreProfilerExampleResource/LastestProfilingResultDetail.JPG differ
diff --git a/README.md b/README.md
index b9d1bd3..7de1725 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,119 @@
-# CoreProfilerExample
\ No newline at end of file
+## CoreProfiler
+
+```Shell
+NUGET INSTALL coreprofiler -Version 1.1.4
+```
+
+ΩSw϶ӮɡC
+
+kpU:
+
+```C#
+var stepName = $"{class_name}.{method_name}";
+
+using (ProfilingSession.Current.Step(stepName))
+{
+ // ݭnpɪ{Xq
+}
+```
+
+ѩjOϥάۦPҫA]dҤѤ@XRkAzLϮgoOPkW١C
+
+```C#
+// ./CoreProfilerExample.Common/Extensions/MethodBaseExtension.cs
+
+public static IDisposable ProfilingStep(this MethodBase method, string? stepName = null)
+{
+ if (stepName == null)
+ {
+ // ok
+ var methodType = method.ReflectedType;
+
+ // oO
+ var classType = methodType?.ReflectedType ?? methodType;
+
+ // XOUҦDPBkAXek
+ var classMethodType = classType?
+ .GetMethods()
+ .Select(x => new
+ {
+ Method = x,
+ Attribute = x.GetCustomAttribute(),
+ })
+ .FirstOrDefault(x => x.Attribute?.StateMachineType == methodType);
+
+ var className = classType?.Name ?? "LkoOW";
+
+ var methodName = classMethodType?.Method.Name ?? method.Name ?? "LkokW";
+
+ stepName = $"{classType?.Name}.{methodName}";
+ }
+
+ return ProfilingSession.Current.Step(stepName);
+}
+```
+
+XR MethodBase OA}o̥iHۦMwO_nJstepNameѼơAYSJh|zLϮgNoOPkW١A@Ӯɪ϶qW١C
+
+Ϯg: zLMethodBaseӨokTypeAAoOTypeA쥻o˴NiHϥNameӨoOPkW١AkYDPBAh|Xn\ŪW١A]ݭnAHUާ@Өo\ŪW:
+
+```C#
+var classMethodType = classType?
+ .GetMethods()
+ .Select(x => new
+ {
+ Method = x,
+ Attribute = x.GetCustomAttribute(),
+ })
+ .Where(x => x.Attribute?.StateMachineType == methodType)
+ .FirstOrDefault();
+```
+
+QOTypeo䩳UҦkAAzLkType覡okMethodInfoANiHϥNameӨoŪkW٤FC
+
+XRkϥΤkpU:
+
+```C#
+using (MethodBase.GetCurrentMethod()?.ProfilingStep())
+{
+ // ݭnpɪ{Xq
+}
+
+using (MethodBase.GetCurrentMethod()?.ProfilingStep("qW"))
+{
+ // ݭnpɪ{Xq
+}
+```
+
+## CoreProfiler.Web
+
+```Shell
+NUGET INSTALL CoreProfiler.Web -Version 1.1.4
+```
+
+NCӶqnlܪ{X]˦nAAӦwˤKdApU:
+
+```C#
+// ./CoreProfilerExample/Infrastructure/Extensions/DependencyInjectionExtension.cs
+
+public static IApplicationBuilder UseCoreProfiler(this IApplicationBuilder app)
+{
+ CoreProfilerOption.UseCoreProfilerSetting();
+
+ app.UseCoreProfiler(true);
+
+ return app;
+}
+```
+
+ϥCoreProfilerOption.UseCoreProfilerSetting()kӲGUIһݪ]wѼƫAϥapp.UseCoreProfiler(true)`Jε{AѼtrueܨC@ӬqO_nUdO_LqC
+
+Ұʫs /nanoprofiler/view T{O_ҥΦ\C
+
+pU:
+
+
+
+ԲӦpU:
+
+
\ No newline at end of file