diff --git a/Metrics.sln b/Metrics.sln index 26f01781..3be55e56 100644 --- a/Metrics.sln +++ b/Metrics.sln @@ -53,15 +53,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Metrics.StupidBenchmarks", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NancyFx.Sample", "Samples\NancyFx.Sample\NancyFx.Sample.csproj", "{B7C6EF21-0797-4B53-A917-1CFF8267CD67}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Sample", "Samples\Owin.Sample\Owin.Sample.csproj", "{828188F9-26C2-4C93-A156-D9EA13D7E2FA}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Metrics", "Src\Adapters\Owin.Metrics\Owin.Metrics.csproj", "{025CD6D0-1A1E-4B14-A7DB-AF5DFF887210}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2E004760-A644-4312-8489-6057B8B7554A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Metrics.TestConsole", "Src\Metrics.TestConsole\Metrics.TestConsole.csproj", "{1E8F49B4-B8D9-4932-909D-821AEFB869B0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Metrics.AspSample", "Samples\Metrics.AspSample\Metrics.AspSample.csproj", "{83F38EB9-504D-4B85-A181-7309EA08FAC2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.Metrics", "Src\Adapters\AspNetCore.Metrics\AspNetCore.Metrics.csproj", "{8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Sample", "Samples\Owin.Sample\Owin.Sample.csproj", "{C400B4D6-98FD-46AD-B3E4-2FC3D3DC6C6C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.Sample", "Samples\AspNetCore.Sample\AspNetCore.Sample.csproj", "{52C0EDCD-3573-4B8B-ACB1-DDC9B7518DB3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -113,10 +115,6 @@ Global {B7C6EF21-0797-4B53-A917-1CFF8267CD67}.Debug|Any CPU.Build.0 = Debug|Any CPU {B7C6EF21-0797-4B53-A917-1CFF8267CD67}.Release|Any CPU.ActiveCfg = Release|Any CPU {B7C6EF21-0797-4B53-A917-1CFF8267CD67}.Release|Any CPU.Build.0 = Release|Any CPU - {828188F9-26C2-4C93-A156-D9EA13D7E2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {828188F9-26C2-4C93-A156-D9EA13D7E2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {828188F9-26C2-4C93-A156-D9EA13D7E2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {828188F9-26C2-4C93-A156-D9EA13D7E2FA}.Release|Any CPU.Build.0 = Release|Any CPU {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210}.Debug|Any CPU.Build.0 = Debug|Any CPU {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -125,10 +123,18 @@ Global {1E8F49B4-B8D9-4932-909D-821AEFB869B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E8F49B4-B8D9-4932-909D-821AEFB869B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E8F49B4-B8D9-4932-909D-821AEFB869B0}.Release|Any CPU.Build.0 = Release|Any CPU - {83F38EB9-504D-4B85-A181-7309EA08FAC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {83F38EB9-504D-4B85-A181-7309EA08FAC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83F38EB9-504D-4B85-A181-7309EA08FAC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83F38EB9-504D-4B85-A181-7309EA08FAC2}.Release|Any CPU.Build.0 = Release|Any CPU + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4}.Release|Any CPU.Build.0 = Release|Any CPU + {C400B4D6-98FD-46AD-B3E4-2FC3D3DC6C6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C400B4D6-98FD-46AD-B3E4-2FC3D3DC6C6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C400B4D6-98FD-46AD-B3E4-2FC3D3DC6C6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C400B4D6-98FD-46AD-B3E4-2FC3D3DC6C6C}.Release|Any CPU.Build.0 = Release|Any CPU + {52C0EDCD-3573-4B8B-ACB1-DDC9B7518DB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52C0EDCD-3573-4B8B-ACB1-DDC9B7518DB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52C0EDCD-3573-4B8B-ACB1-DDC9B7518DB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52C0EDCD-3573-4B8B-ACB1-DDC9B7518DB3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -143,9 +149,10 @@ Global {DAF70394-CE63-4D2F-B52B-839941827B4E} = {DEC3A50A-7243-45C0-9995-F829BFF99453} {A9074D3E-3421-483D-AF98-4AAEEED11ECA} = {DEC3A50A-7243-45C0-9995-F829BFF99453} {B7C6EF21-0797-4B53-A917-1CFF8267CD67} = {DEC3A50A-7243-45C0-9995-F829BFF99453} - {828188F9-26C2-4C93-A156-D9EA13D7E2FA} = {DEC3A50A-7243-45C0-9995-F829BFF99453} {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210} = {443860DA-6378-47D0-A4AE-4E79975C5E1C} {1E8F49B4-B8D9-4932-909D-821AEFB869B0} = {2E004760-A644-4312-8489-6057B8B7554A} - {83F38EB9-504D-4B85-A181-7309EA08FAC2} = {DEC3A50A-7243-45C0-9995-F829BFF99453} + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4} = {443860DA-6378-47D0-A4AE-4E79975C5E1C} + {C400B4D6-98FD-46AD-B3E4-2FC3D3DC6C6C} = {DEC3A50A-7243-45C0-9995-F829BFF99453} + {52C0EDCD-3573-4B8B-ACB1-DDC9B7518DB3} = {DEC3A50A-7243-45C0-9995-F829BFF99453} EndGlobalSection EndGlobal diff --git a/Metrics.sln.DotSettings b/Metrics.sln.DotSettings index e7c9ed2a..821e89d2 100644 --- a/Metrics.sln.DotSettings +++ b/Metrics.sln.DotSettings @@ -8,6 +8,7 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + True True True True \ No newline at end of file diff --git a/Samples/AspNetCore.Sample/App.config b/Samples/AspNetCore.Sample/App.config new file mode 100644 index 00000000..f5a1bc81 --- /dev/null +++ b/Samples/AspNetCore.Sample/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Samples/AspNetCore.Sample/AspNetCore.Sample.csproj b/Samples/AspNetCore.Sample/AspNetCore.Sample.csproj new file mode 100644 index 00000000..3027823c --- /dev/null +++ b/Samples/AspNetCore.Sample/AspNetCore.Sample.csproj @@ -0,0 +1,28 @@ + + + netcoreapp2.0 + false + Exe + + + + + + + + + + + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4} + AspNetCore.Metrics + + + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} + Metrics + + + {D08A63D0-F440-477C-9565-1264AE0879D0} + Metrics.Samples + + + \ No newline at end of file diff --git a/Samples/AspNetCore.Sample/Controllers/SampleController.cs b/Samples/AspNetCore.Sample/Controllers/SampleController.cs new file mode 100644 index 00000000..370daa5a --- /dev/null +++ b/Samples/AspNetCore.Sample/Controllers/SampleController.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; + +namespace AspNetCore.Sample.Controllers +{ + [Route("sample")] + public class SampleController : Controller + { + [HttpGet] + public IEnumerable Get() + { + return new[] { "value1", "value2" }; + } + + [HttpGet("withparams/{x}/{y}")] + public IEnumerable Get(int x, string y) + { + return new[] { "value1", "value2" }; + } + } +} diff --git a/Samples/AspNetCore.Sample/Controllers/SampleIgnoreController.cs b/Samples/AspNetCore.Sample/Controllers/SampleIgnoreController.cs new file mode 100644 index 00000000..82ddf269 --- /dev/null +++ b/Samples/AspNetCore.Sample/Controllers/SampleIgnoreController.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; + +namespace AspNetCore.Sample.Controllers +{ + [Route("sampleignore")] + public class SampleIgnoreController : Controller + { + [HttpGet] + public string Get() + { + return "get"; + } + } +} diff --git a/Samples/AspNetCore.Sample/Program.cs b/Samples/AspNetCore.Sample/Program.cs new file mode 100644 index 00000000..461606f8 --- /dev/null +++ b/Samples/AspNetCore.Sample/Program.cs @@ -0,0 +1,45 @@ +using System; +using Metrics.Samples; +using Metrics.Utils; +using Microsoft.AspNetCore.Hosting; + +namespace AspNetCore.Sample +{ + public class Program + { + static void Main(string[] args) + { + const string url = "http://localhost:32132/"; + + using (var scheduler = new ActionScheduler()) + { + using (var webHost = new WebHostBuilder() + .UseKestrel() + .UseStartup() + .UseUrls(url) + .Build()) + { + Console.WriteLine("AspNetCore Running at {0}", url); + Console.WriteLine("Press any key to exit"); + //Process.Start(string.Format("{0}metrics/", url)); + + SampleMetrics.RunSomeRequests(); + + scheduler.Start(TimeSpan.FromMilliseconds(500), () => + { + SetCounterSample.RunSomeRequests(); + SetMeterSample.RunSomeRequests(); + UserValueHistogramSample.RunSomeRequests(); + UserValueTimerSample.RunSomeRequests(); + SampleMetrics.RunSomeRequests(); + }); + + HealthChecksSample.RegisterHealthChecks(); + + webHost.Run(); + + } + } + } + } +} diff --git a/Samples/AspNetCore.Sample/Properties/AssemblyInfo.cs b/Samples/AspNetCore.Sample/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..cc2c2ac7 --- /dev/null +++ b/Samples/AspNetCore.Sample/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +//TODO: Migrate to csproj +//// General Information about an assembly is controlled through the following +//// set of attributes. Change these attribute values to modify the information +//// associated with an assembly. +//[assembly: AssemblyTitle("WebApi.Sample")] +//[assembly: AssemblyDescription("")] +//[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +//[assembly: AssemblyProduct("WebApi.Sample")] +//[assembly: AssemblyCopyright("Copyright © 2014")] +//[assembly: AssemblyTrademark("")] +//[assembly: AssemblyCulture("")] +// +//// Setting ComVisible to false makes the types in this assembly not visible +//// to COM components. If you need to access a type in this assembly from +//// COM, set the ComVisible attribute to true on that type. +//[assembly: ComVisible(false)] +// +//// The following GUID is for the ID of the typelib if this project is exposed to COM +//[assembly: Guid("4118530f-7ae9-4639-b9ce-6e64c404ea8f")] +// +//// Version information for an assembly consists of the following four values: +//// +//// Major Version +//// Minor Version +//// Build Number +//// Revision +//// +//// You can specify all the values or you can default the Build and Revision Numbers +//// by using the '*' as shown below: +//// [assembly: AssemblyVersion("1.0.*")] +//[assembly: AssemblyVersion("1.0.0.0")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/AspNetCore.Sample/Startup.cs b/Samples/AspNetCore.Sample/Startup.cs new file mode 100644 index 00000000..4eee711a --- /dev/null +++ b/Samples/AspNetCore.Sample/Startup.cs @@ -0,0 +1,51 @@ +using System.Text.RegularExpressions; +using AspNetCore.Metrics; +using Metrics; +using Metrics.Endpoints; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using Formatting = Newtonsoft.Json.Formatting; + +namespace AspNetCore.Sample +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + } + + + public void Configure(IApplicationBuilder app) + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + + app.UseCors(c => c.AllowAnyOrigin()); + + Metric.Config + //.WithReporting(r => r.WithConsoleReport(TimeSpan.FromSeconds(30))) + .WithAspNetCore( + middleware => app.Use(middleware), + config => config + .WithRequestMetricsConfig(c => c.WithAllAspNetCoreMetrics(), new[] + { + new Regex("(?i)^sampleignore"), + new Regex("(?i)^metrics"), + new Regex("(?i)^health"), + new Regex("(?i)^json") + }) + .WithMetricsEndpoint(conf => conf + .WithEndpointReport("/test", (d, h, r) => new MetricsEndpointResponse("test", "text/plain"))) + ); + + app.UseMvc(); + } + + } +} diff --git a/Samples/ConsoleApplication/App.config b/Samples/ConsoleApplication/App.config new file mode 100644 index 00000000..8e156463 --- /dev/null +++ b/Samples/ConsoleApplication/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Samples/ConsoleApplication/AssemblyInfo.fs b/Samples/ConsoleApplication/AssemblyInfo.fs new file mode 100644 index 00000000..3115de0f --- /dev/null +++ b/Samples/ConsoleApplication/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace ConsoleApplication.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/Samples/ConsoleApplication/ConsoleApplication.fsproj b/Samples/ConsoleApplication/ConsoleApplication.fsproj new file mode 100644 index 00000000..003ede78 --- /dev/null +++ b/Samples/ConsoleApplication/ConsoleApplication.fsproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + 2.0 + {513A11F7-D772-4F00-978B-6F8D192005A1} + Exe + ConsoleApplication + ConsoleApplication + v4.5 + true + bin\$(Configuration)\$(AssemblyName).xml + ConsoleApplication + + + true + full + false + false + bin\$(Configuration)\ + DEBUG;TRACE + 3 + --warnon:1182 + + + pdbonly + true + true + bin\$(Configuration)\ + TRACE + 3 + --warnon:1182 + + + + + + + + ..\..\packages\FSharp.Core.4.1.18\lib\net45\FSharp.Core.dll + + + ..\..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll + + + + + + + + + + ..\..\packages\FSharp.Compiler.Tools.4.1.23\tools\Microsoft.FSharp.Targets + + + \ No newline at end of file diff --git a/Samples/ConsoleApplication/Program.fs b/Samples/ConsoleApplication/Program.fs new file mode 100644 index 00000000..d193dab2 --- /dev/null +++ b/Samples/ConsoleApplication/Program.fs @@ -0,0 +1,4 @@ +[] +let main argv = + printfn "%A" argv + 0 // return an integer exit code diff --git a/Samples/ConsoleApplication/packages.config b/Samples/ConsoleApplication/packages.config new file mode 100644 index 00000000..5a54e3f3 --- /dev/null +++ b/Samples/ConsoleApplication/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Samples/Metrics.SampleReporter/Metrics.SampleReporter.csproj b/Samples/Metrics.SampleReporter/Metrics.SampleReporter.csproj index 46b922fa..f3b4db90 100644 --- a/Samples/Metrics.SampleReporter/Metrics.SampleReporter.csproj +++ b/Samples/Metrics.SampleReporter/Metrics.SampleReporter.csproj @@ -1,82 +1,24 @@ - - - + - Debug - AnyCPU - {18E808CB-98F9-4754-9872-D3D00F9CE72B} - Library - Properties - Metrics.SampleReporter - Metrics.SampleReporter - v4.5 - 512 - ..\..\ - true - - - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - - - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - true - - - 1591 + netstandard2.0 + false - - ..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - - - - - - - + + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} + Metrics + + + + - - - + - - {95e29d40-dbec-49e2-9cc5-26b88966dade} - Metrics - + - + - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Samples/Metrics.SampleReporter/packages.config b/Samples/Metrics.SampleReporter/packages.config deleted file mode 100644 index 3a86f257..00000000 --- a/Samples/Metrics.SampleReporter/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Samples/Metrics.Samples.FSharp/Metrics.Samples.FSharp.fsproj b/Samples/Metrics.Samples.FSharp/Metrics.Samples.FSharp.fsproj index 2f9d74c5..f56ad2fe 100644 --- a/Samples/Metrics.Samples.FSharp/Metrics.Samples.FSharp.fsproj +++ b/Samples/Metrics.Samples.FSharp/Metrics.Samples.FSharp.fsproj @@ -1,86 +1,21 @@ - - - + - Debug - AnyCPU - 2.0 - daf70394-ce63-4d2f-b52b-839941827b4e - Library - Metrics.Samples.FSharp - Metrics.Samples.FSharp - v4.5 - 4.3.1.0 - Metrics.Samples.FSharp - + netcoreapp2.0 + false + Exe - - true - full - false - false - ..\..\bin\Debug\ - DEBUG;TRACE - 3 - - - pdbonly - true - true - ..\..\bin\Release\ - TRACE - 3 - - - - - True - - - - - - - - - + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - {95e29d40-dbec-49e2-9cc5-26b88966dade} - True + + + {D08A63D0-F440-477C-9565-1264AE0879D0} + Metrics.Samples - - 11 - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - + + + + \ No newline at end of file diff --git a/Samples/Metrics.Samples/Metrics.Samples.csproj b/Samples/Metrics.Samples/Metrics.Samples.csproj index 580ac986..7875ecec 100644 --- a/Samples/Metrics.Samples/Metrics.Samples.csproj +++ b/Samples/Metrics.Samples/Metrics.Samples.csproj @@ -1,74 +1,12 @@ - - - + - Debug - AnyCPU - {D08A63D0-F440-477C-9565-1264AE0879D0} - Library - Properties - Metrics.Samples - Metrics.Samples - v4.5 - 512 - ..\..\ - true + netstandard2.0 + false - - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Samples/Metrics.Samples/Properties/AssemblyInfo.cs b/Samples/Metrics.Samples/Properties/AssemblyInfo.cs index 6efc8bc6..715b8263 100644 --- a/Samples/Metrics.Samples/Properties/AssemblyInfo.cs +++ b/Samples/Metrics.Samples/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Metrics.Samples")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Metrics.Samples")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a9f34801-2970-4957-a69c-17b549fb5ae8")] - -// Version information for an assembly consists of the following four values: +//using System.Reflection; +//using System.Runtime.CompilerServices; +//using System.Runtime.InteropServices; +// TODO: to csproj +//// General Information about an assembly is controlled through the following +//// set of attributes. Change these attribute values to modify the information +//// associated with an assembly. +//[assembly: AssemblyTitle("Metrics.Samples")] +//[assembly: AssemblyDescription("")] +//[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +//[assembly: AssemblyProduct("Metrics.Samples")] +//[assembly: AssemblyCopyright("Copyright © 2014")] +//[assembly: AssemblyTrademark("")] +//[assembly: AssemblyCulture("")] // -// Major Version -// Minor Version -// Build Number -// Revision +//// Setting ComVisible to false makes the types in this assembly not visible +//// to COM components. If you need to access a type in this assembly from +//// COM, set the ComVisible attribute to true on that type. +//[assembly: ComVisible(false)] // -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +//// The following GUID is for the ID of the typelib if this project is exposed to COM +//[assembly: Guid("a9f34801-2970-4957-a69c-17b549fb5ae8")] +// +//// Version information for an assembly consists of the following four values: +//// +//// Major Version +//// Minor Version +//// Build Number +//// Revision +//// +//// You can specify all the values or you can default the Build and Revision Numbers +//// by using the '*' as shown below: +//// [assembly: AssemblyVersion("1.0.*")] +//[assembly: AssemblyVersion("1.0.0.0")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Metrics.SamplesConsole/Metrics.SamplesConsole.csproj b/Samples/Metrics.SamplesConsole/Metrics.SamplesConsole.csproj index 9e7deacc..7d31c8f3 100644 --- a/Samples/Metrics.SamplesConsole/Metrics.SamplesConsole.csproj +++ b/Samples/Metrics.SamplesConsole/Metrics.SamplesConsole.csproj @@ -1,92 +1,16 @@ - - - + - Debug - AnyCPU - {7416F90D-FFD6-4E34-8638-5234C8B9EC39} - Exe - Properties - Metrics.SamplesConsole - Metrics.SamplesConsole - v4.5.1 - 512 - true - ..\..\ - true - + netcoreapp2.0 + false - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - - - - - - Always - - - - {68f25a01-af00-4d57-9d1a-81213e4ef56f} - Metrics.NLog - - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - {18e808cb-98f9-4754-9872-d3d00f9ce72b} - Metrics.SampleReporter - - {d08a63d0-f440-477c-9565-1264ae0879d0} + {D08A63D0-F440-477C-9565-1264AE0879D0} Metrics.Samples - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Samples/Metrics.StupidBenchmarks/Metrics.StupidBenchmarks.csproj b/Samples/Metrics.StupidBenchmarks/Metrics.StupidBenchmarks.csproj index 41209b28..adae05ab 100644 --- a/Samples/Metrics.StupidBenchmarks/Metrics.StupidBenchmarks.csproj +++ b/Samples/Metrics.StupidBenchmarks/Metrics.StupidBenchmarks.csproj @@ -1,84 +1,15 @@ - - - + - Debug - AnyCPU - {A9074D3E-3421-483D-AF98-4AAEEED11ECA} - Exe - Properties - Metrics.StupidBenchmarks - Metrics.StupidBenchmarks - v4.5.1 - 512 - true - ..\..\ - true - + netcoreapp2.0 + false - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - false - - - - ..\..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll - - - - - - - - - - - - - - - - - - - - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + + + \ No newline at end of file diff --git a/Samples/Metrics.StupidBenchmarks/Program.cs b/Samples/Metrics.StupidBenchmarks/Program.cs index 7d9ca44a..2aa46262 100644 --- a/Samples/Metrics.StupidBenchmarks/Program.cs +++ b/Samples/Metrics.StupidBenchmarks/Program.cs @@ -8,93 +8,38 @@ namespace Metrics.StupidBenchmarks { class CommonOptions { - [Option('c', HelpText = "Max Threads", DefaultValue = 32)] + [Value(0)] + public string Target { get; set; } + + [Option('c', HelpText = "Max Threads", Default = 32)] public int MaxThreads { get; set; } - [Option('s', HelpText = "Seconds", DefaultValue = 5)] + [Option('s', HelpText = "Seconds", Default = 5)] public int Seconds { get; set; } - [Option('d', HelpText = "Number of threads to decrement each step", DefaultValue = 4)] + [Option('d', HelpText = "Number of threads to decrement each step", Default = 4)] public int Decrement { get; set; } - - [HelpOption] - public string GetUsage() - { - return HelpText.AutoBuild(this); - } } - class Options + class Program { - [VerbOption("Counter")] - public CommonOptions Counter { get; set; } - - [VerbOption("Meter")] - public CommonOptions Meter { get; set; } - - [VerbOption("Histogram")] - public CommonOptions Histogram { get; set; } - - [VerbOption("Timer")] - public CommonOptions Timer { get; set; } - - [VerbOption("EWMA")] - public CommonOptions Ewma { get; set; } - - [VerbOption("EDR")] - public CommonOptions Edr { get; set; } - - [VerbOption("hdr")] - public CommonOptions Hdr { get; set; } - - [VerbOption("hdrtimer")] - public CommonOptions HdrTimer { get; set; } - - [VerbOption("hdrsync")] - public CommonOptions HdrSync { get; set; } - - [VerbOption("hdrsynctimer")] - public CommonOptions HdrSyncTimer { get; set; } - - [VerbOption("Uniform")] - public CommonOptions Uniform { get; set; } - - [VerbOption("Sliding")] - public CommonOptions Sliding { get; set; } - - [VerbOption("TimerImpact")] - public CommonOptions TimerImpact { get; set; } - - [VerbOption("NoOp")] - public CommonOptions NoOp { get; set; } - - [HelpVerbOption] - public string GetUsage(string verb) + static int Main(string[] args) { - return HelpText.AutoBuild(this); + return Parser.Default.ParseArguments(args) + .MapResult( + (CommonOptions opts) => RunCommitAndReturnExitCode(opts), + errs => -1); } - } - class Program - { - private static string target; - private static CommonOptions targetOptions; - - static void Main(string[] args) + private static int RunCommitAndReturnExitCode(CommonOptions opts) { - var options = new Options(); - if (!Parser.Default.ParseArguments(args, options, (t, o) => { target = t; targetOptions = o as CommonOptions; })) - { - Console.WriteLine(new CommonOptions().GetUsage()); - Environment.Exit(CommandLine.Parser.DefaultExitCodeFail); - } - - BenchmarkRunner.DefaultTotalSeconds = targetOptions.Seconds; - BenchmarkRunner.DefaultMaxThreads = targetOptions.MaxThreads; + + BenchmarkRunner.DefaultTotalSeconds = opts.Seconds; + BenchmarkRunner.DefaultMaxThreads = opts.MaxThreads; //Metric.Config.WithHttpEndpoint("http://localhost:1234/"); - switch (target) + switch (opts.Target) { case "noop": BenchmarkRunner.Run("Noop", () => { }); @@ -145,6 +90,7 @@ static void Main(string[] args) BenchmarkRunner.Run("WorkWithTimer", () => load.DoSomeWorkWithATimer(), iterationsChunk: 10); break; } + return 0; } } } diff --git a/Samples/NancyFx.Sample/App.config b/Samples/NancyFx.Sample/App.config index 1600c150..9540b043 100644 --- a/Samples/NancyFx.Sample/App.config +++ b/Samples/NancyFx.Sample/App.config @@ -1,8 +1,5 @@ - - - diff --git a/Samples/NancyFx.Sample/NancyFx.Sample.csproj b/Samples/NancyFx.Sample/NancyFx.Sample.csproj index 4b1ebc51..4e40927e 100644 --- a/Samples/NancyFx.Sample/NancyFx.Sample.csproj +++ b/Samples/NancyFx.Sample/NancyFx.Sample.csproj @@ -1,112 +1,26 @@ - - - + - Debug - AnyCPU - {B7C6EF21-0797-4B53-A917-1CFF8267CD67} - Exe - Properties - NancyFx.Sample - NancyFx.Sample - v4.5.1 - 512 - true - ..\..\ - true - - - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - false + netcoreapp2.0 + false - - False - ..\..\packages\Nancy.1.2.0\lib\net40\Nancy.dll - - - False - ..\..\packages\Nancy.Authentication.Stateless.1.2.0\lib\net40\Nancy.Authentication.Stateless.dll - - - False - ..\..\packages\Nancy.Hosting.Self.1.2.0\lib\net40\Nancy.Hosting.Self.dll - - - False - ..\..\packages\Nancy.Serialization.JsonNet.1.2.0\lib\net40\Nancy.Serialization.JsonNet.dll - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - - - - - - - - + + - - - - + + + {D08A63D0-F440-477C-9565-1264AE0879D0} + Metrics.Samples + - - + - - {fbff51d8-52f4-4eef-8498-122a14b37d6c} - Nancy.Metrics - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} - Metrics - - - {18e808cb-98f9-4754-9872-d3d00f9ce72b} - Metrics.SampleReporter - - - {d08a63d0-f440-477c-9565-1264ae0879d0} - Metrics.Samples - + + + + - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Samples/NancyFx.Sample/SampleBootstrapper.cs b/Samples/NancyFx.Sample/SampleBootstrapper.cs index d1c7b69f..fda2b01e 100644 --- a/Samples/NancyFx.Sample/SampleBootstrapper.cs +++ b/Samples/NancyFx.Sample/SampleBootstrapper.cs @@ -27,7 +27,7 @@ protected override void ApplicationStartup(TinyIoCContainer container, IPipeline { base.ApplicationStartup(container, pipelines); - StatelessAuthentication.Enable(pipelines, new StatelessAuthenticationConfiguration(AuthenticateUser)); + StatelessAuthentication.Enable(pipelines, new StatelessAuthenticationConfiguration(context => context.CurrentUser)); Metric.Config .WithReporting(r => @@ -57,20 +57,6 @@ protected override void ApplicationStartup(TinyIoCContainer container, IPipeline }; } - class FakeUser : IUserIdentity - { - public IEnumerable Claims { get { yield return "Admin"; } } - public string UserName - { - get { return "admin"; } - } - } - - private IUserIdentity AuthenticateUser(NancyContext context) - { - return new FakeUser(); - } - protected override void ConfigureApplicationContainer(TinyIoCContainer container) { base.ConfigureApplicationContainer(container); diff --git a/Samples/NancyFx.Sample/SampleModule.cs b/Samples/NancyFx.Sample/SampleModule.cs index 1f463861..3f5f2f9b 100644 --- a/Samples/NancyFx.Sample/SampleModule.cs +++ b/Samples/NancyFx.Sample/SampleModule.cs @@ -12,13 +12,13 @@ public SampleModule() this.MetricForRequestTimeAndResponseSize("TestRequest", "Get", "/test"); this.MetricForRequestSize("TestRequestSize", "Post", "/action"); - Get["/test"] = _ => Response.AsText("test"); + Get("/test", _ => Response.AsText("test")); - Post["/action"] = _ => HttpStatusCode.Accepted; + Post("/action", _ => HttpStatusCode.Accepted); - Get["/error"] = _ => { throw new InvalidOperationException(); }; + Get("/error", _ => throw new InvalidOperationException()); - Get["/item/{id}"] = p => Response.AsText((string)p.id, "text/plain"); + Get("/item/{id}", p => Response.AsText((string)p.id, "text/plain")); } } } diff --git a/Samples/NancyFx.Sample/packages.config b/Samples/NancyFx.Sample/packages.config deleted file mode 100644 index efecd0f2..00000000 --- a/Samples/NancyFx.Sample/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/Samples/Owin.Sample/App.config b/Samples/Owin.Sample/App.config index afb88d4f..f5a1bc81 100644 --- a/Samples/Owin.Sample/App.config +++ b/Samples/Owin.Sample/App.config @@ -1,29 +1,6 @@  - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Samples/Owin.Sample/Controllers/SampleController.cs b/Samples/Owin.Sample/Controllers/SampleController.cs index 7bc7a0cc..b9e510ce 100644 --- a/Samples/Owin.Sample/Controllers/SampleController.cs +++ b/Samples/Owin.Sample/Controllers/SampleController.cs @@ -1,18 +1,18 @@ using System.Collections.Generic; -using System.Web.Http; +using Microsoft.AspNetCore.Mvc; namespace Owin.Sample.Controllers { - [RoutePrefix("sample")] - public class SampleController : ApiController + [Route("sample")] + public class SampleController : Controller { - [Route("")] + [HttpGet] public IEnumerable Get() { return new[] { "value1", "value2" }; } - [Route("withparams/{x}/{y}")] + [HttpGet("withparams/{x}/{y}")] public IEnumerable Get(int x, string y) { return new[] { "value1", "value2" }; diff --git a/Samples/Owin.Sample/Controllers/SampleIgnoreController.cs b/Samples/Owin.Sample/Controllers/SampleIgnoreController.cs index 882d5766..a4e85532 100644 --- a/Samples/Owin.Sample/Controllers/SampleIgnoreController.cs +++ b/Samples/Owin.Sample/Controllers/SampleIgnoreController.cs @@ -1,12 +1,11 @@ - +using Microsoft.AspNetCore.Mvc; + namespace Owin.Sample.Controllers { - using System.Web.Http; - - [RoutePrefix("sampleignore")] - public class SampleIgnoreController : ApiController + [Route("sampleignore")] + public class SampleIgnoreController : Controller { - [Route("")] + [HttpGet] public string Get() { return "get"; diff --git a/Samples/Owin.Sample/Owin.Sample.csproj b/Samples/Owin.Sample/Owin.Sample.csproj index 147e416f..8deaaeff 100644 --- a/Samples/Owin.Sample/Owin.Sample.csproj +++ b/Samples/Owin.Sample/Owin.Sample.csproj @@ -1,131 +1,29 @@ - - - + - Debug - AnyCPU - {828188F9-26C2-4C93-A156-D9EA13D7E2FA} + netcoreapp2.0 + false Exe - Properties - Owin.Sample - Owin.Sample - v4.5.1 - 512 - ..\..\ - true - - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - false - - - - False - ..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - False - ..\..\packages\Microsoft.Owin.Cors.3.0.1\lib\net45\Microsoft.Owin.Cors.dll - - - False - ..\..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll - - - ..\..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll - True - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - - - False - ..\..\packages\Owin.1.0\lib\net40\Owin.dll - - - - - - False - ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll - - - - False - ..\..\packages\Microsoft.AspNet.Cors.5.2.3\lib\net45\System.Web.Cors.dll - - - False - ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - - - False - ..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll - - - - - - - - - - - - - - - - - + + + + + + - {025cd6d0-1a1e-4b14-a7db-af5dff887210} + {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210} Owin.Metrics - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - {d08a63d0-f440-477c-9565-1264ae0879d0} + {D08A63D0-F440-477C-9565-1264AE0879D0} Metrics.Samples - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Samples/Owin.Sample/Program.cs b/Samples/Owin.Sample/Program.cs index d9a58150..cd956644 100644 --- a/Samples/Owin.Sample/Program.cs +++ b/Samples/Owin.Sample/Program.cs @@ -1,8 +1,10 @@ using System; using System.Diagnostics; +using System.Threading.Tasks; using Metrics.Samples; using Metrics.Utils; -using Microsoft.Owin.Hosting; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; namespace Owin.Sample { @@ -10,15 +12,19 @@ public class Program { static void Main(string[] args) { - const string url = "http://localhost:1235/"; + const string url = "http://localhost:32132/"; using (var scheduler = new ActionScheduler()) { - using (WebApp.Start(url)) + using (var webHost = new WebHostBuilder() + .UseKestrel() + .UseStartup() + .UseUrls(url) + .Build()) { Console.WriteLine("Owin Running at {0}", url); Console.WriteLine("Press any key to exit"); - Process.Start(string.Format("{0}metrics/", url)); + //Process.Start(string.Format("{0}metrics/", url)); SampleMetrics.RunSomeRequests(); @@ -33,7 +39,8 @@ static void Main(string[] args) HealthChecksSample.RegisterHealthChecks(); - Console.ReadKey(); + webHost.Run(); + } } } diff --git a/Samples/Owin.Sample/Properties/AssemblyInfo.cs b/Samples/Owin.Sample/Properties/AssemblyInfo.cs index b793163c..cc2c2ac7 100644 --- a/Samples/Owin.Sample/Properties/AssemblyInfo.cs +++ b/Samples/Owin.Sample/Properties/AssemblyInfo.cs @@ -2,35 +2,36 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("WebApi.Sample")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WebApi.Sample")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4118530f-7ae9-4639-b9ce-6e64c404ea8f")] - -// Version information for an assembly consists of the following four values: +//TODO: Migrate to csproj +//// General Information about an assembly is controlled through the following +//// set of attributes. Change these attribute values to modify the information +//// associated with an assembly. +//[assembly: AssemblyTitle("WebApi.Sample")] +//[assembly: AssemblyDescription("")] +//[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +//[assembly: AssemblyProduct("WebApi.Sample")] +//[assembly: AssemblyCopyright("Copyright © 2014")] +//[assembly: AssemblyTrademark("")] +//[assembly: AssemblyCulture("")] +// +//// Setting ComVisible to false makes the types in this assembly not visible +//// to COM components. If you need to access a type in this assembly from +//// COM, set the ComVisible attribute to true on that type. +//[assembly: ComVisible(false)] // -// Major Version -// Minor Version -// Build Number -// Revision +//// The following GUID is for the ID of the typelib if this project is exposed to COM +//[assembly: Guid("4118530f-7ae9-4639-b9ce-6e64c404ea8f")] // -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +//// Version information for an assembly consists of the following four values: +//// +//// Major Version +//// Minor Version +//// Build Number +//// Revision +//// +//// You can specify all the values or you can default the Build and Revision Numbers +//// by using the '*' as shown below: +//// [assembly: AssemblyVersion("1.0.*")] +//[assembly: AssemblyVersion("1.0.0.0")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/Owin.Sample/SetOwinRouteTemplateMessageHandler.cs b/Samples/Owin.Sample/SetOwinRouteTemplateMessageHandler.cs deleted file mode 100644 index 09677313..00000000 --- a/Samples/Owin.Sample/SetOwinRouteTemplateMessageHandler.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Web.Http.Routing; - -namespace Owin.Sample -{ - public class SetOwinRouteTemplateMessageHandler : DelegatingHandler - { - /// - /// Sends an HTTP request to the inner handler to send to the server as an asynchronous operation. - /// - /// The HTTP request message to send to the server. - /// A cancellation token to cancel operation. - /// - /// Returns . The task object representing the asynchronous operation. - /// - protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - var owinContext = request.GetOwinContext(); - - if (owinContext == null) return base.SendAsync(request, cancellationToken); - - var routes = request.GetConfiguration().Routes; - - if (routes == null) return base.SendAsync(request, cancellationToken); - - var routeData = routes.GetRouteData(request); - - if (routeData == null) return base.SendAsync(request, cancellationToken); - - var subRoutes = routeData.Values["MS_SubRoutes"] as IHttpRouteData[]; - - if (subRoutes == null) return base.SendAsync(request, cancellationToken); - - var routeTemplate = subRoutes[0].Route.RouteTemplate; - - owinContext.Environment.Add("metrics-net.routetemplate", routeTemplate); - - return base.SendAsync(request, cancellationToken); - } - } -} diff --git a/Samples/Owin.Sample/Startup.cs b/Samples/Owin.Sample/Startup.cs index 358655ad..e2dc0200 100644 --- a/Samples/Owin.Sample/Startup.cs +++ b/Samples/Owin.Sample/Startup.cs @@ -1,19 +1,25 @@ using System; using System.Text.RegularExpressions; -using System.Web.Http; using Metrics; using Metrics.Endpoints; -using Microsoft.Owin.Cors; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Owin.Metrics; +using Formatting = Newtonsoft.Json.Formatting; namespace Owin.Sample { public class Startup { + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + } + - public void Configuration(IAppBuilder app) + public void Configure(IApplicationBuilder app) { JsonConvert.DefaultSettings = () => new JsonSerializerSettings { @@ -21,29 +27,25 @@ public void Configuration(IAppBuilder app) ContractResolver = new CamelCasePropertyNamesContractResolver() }; - app.UseCors(CorsOptions.AllowAll); - - var httpconfig = new HttpConfiguration(); - httpconfig.MapHttpAttributeRoutes(); - - // Sets the route template for the current request in the OWIN context - httpconfig.MessageHandlers.Add(new SetOwinRouteTemplateMessageHandler()); - + app.UseCors(c => c.AllowAnyOrigin()); + Metric.Config - .WithReporting(r => r.WithConsoleReport(TimeSpan.FromSeconds(30))) - .WithOwin(middleware => app.Use(middleware), config => config - .WithRequestMetricsConfig(c => c.WithAllOwinMetrics(), new[] - { - new Regex("(?i)^sampleignore"), - new Regex("(?i)^metrics"), - new Regex("(?i)^health"), - new Regex("(?i)^json") - }) - .WithMetricsEndpoint(conf => conf - .WithEndpointReport("/test", (d, h, r) => new MetricsEndpointResponse("test", "text/plain"))) + //.WithReporting(r => r.WithConsoleReport(TimeSpan.FromSeconds(30))) + .WithOwin( + middleware => app.UseOwin(x => x(middleware)), + config => config + .WithRequestMetricsConfig(c => c.WithAllOwinMetrics(), new[] + { + new Regex("(?i)^sampleignore"), + new Regex("(?i)^metrics"), + new Regex("(?i)^health"), + new Regex("(?i)^json") + }) + .WithMetricsEndpoint(conf => conf + .WithEndpointReport("/test", (d, h, r) => new MetricsEndpointResponse("test", "text/plain"))) ); - app.UseWebApi(httpconfig); + app.UseMvc(); } } diff --git a/Samples/Owin.Sample/packages.config b/Samples/Owin.Sample/packages.config deleted file mode 100644 index cc794c71..00000000 --- a/Samples/Owin.Sample/packages.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/AspNetCore.Metrics.csproj b/Src/Adapters/AspNetCore.Metrics/AspNetCore.Metrics.csproj new file mode 100644 index 00000000..455e88e1 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/AspNetCore.Metrics.csproj @@ -0,0 +1,14 @@ + + + netstandard2.0 + + + + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} + Metrics + + + + + + \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/AspNetCoreMetrics.cs b/Src/Adapters/AspNetCore.Metrics/AspNetCoreMetrics.cs new file mode 100644 index 00000000..eb8681b9 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/AspNetCoreMetrics.cs @@ -0,0 +1,47 @@ +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using Metrics; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics +{ + /// + /// Helper class to register OWIN Metrics + /// + public static class AspNetCoreMetrics + { + /// + /// Add Metrics Middleware to the AspNetCore pipeline. + /// Sample: Metric.Config.WithAspNetCore( m => app.Use(m)) + /// Where app is the IAppBuilder + /// + /// Chainable configuration object. + /// Action used to register middleware. This should generally be app.Use(middleware) + /// Chainable configuration object. + public static MetricsConfig WithAspNetCore(this MetricsConfig config, Action, Task>> middlewareRegistration) + { + return config.WithAspNetCore(middlewareRegistration, owin => + owin.WithRequestMetricsConfig()); + } + + /// + /// Add Metrics Middleware to the AspNetCore pipeline. + /// Sample: Metric.Config.WithAspNetCore( m => app.Use(m)) + /// Where app is the IAppBuilder + /// + /// Chainable configuration object. + /// Action used to register middleware. This should generally be app.Use(middleware) + /// Action used to configure AspNetCore metrics. + /// Chainable configuration object. + public static MetricsConfig WithAspNetCore(this MetricsConfig config, Action, Task>> middlewareRegistration, Action aspNetCoreConfig) + { + var aspNetCore = config.WithConfigExtension((ctx, hs) => + new AspNetCoreMetricsConfig(middlewareRegistration, ctx, hs), () => AspNetCoreMetricsConfig.Disabled); + aspNetCoreConfig(aspNetCore); + return config; + } + } + +} \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/AspNetCoreMetricsConfig.cs b/Src/Adapters/AspNetCore.Metrics/AspNetCoreMetricsConfig.cs new file mode 100644 index 00000000..e624dd35 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/AspNetCoreMetricsConfig.cs @@ -0,0 +1,105 @@ +using System; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using AspNetCore.Metrics.Middleware; +using Metrics; +using Metrics.Reports; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics +{ + public class AspNetCoreMetricsConfig + { + public static readonly AspNetCoreMetricsConfig Disabled = new AspNetCoreMetricsConfig(); + + private readonly Action, Task>> middlewareRegistration; + private readonly MetricsContext context; + private readonly Func healthStatus; + + private readonly bool isDisabled; + + public AspNetCoreMetricsConfig(Action, Task>> middlewareRegistration, MetricsContext context, Func healthStatus) + { + this.middlewareRegistration = middlewareRegistration; + this.context = context; + this.healthStatus = healthStatus; + } + + private AspNetCoreMetricsConfig() + { + this.isDisabled = true; + } + + /// + /// Register all predefined AspNetCore metrics. + /// + /// Patterns for paths to ignore. + /// Name of the metrics context where to register the metrics. + /// Chainable configuration object. + public AspNetCoreMetricsConfig WithRequestMetricsConfig(Regex[] ignoreRequestPathPatterns = null, string aspNetCoreContext = "AspNetCore") + { + if (this.isDisabled) + { + return this; + } + + return WithRequestMetricsConfig(config => config.WithAllAspNetCoreMetrics(), ignoreRequestPathPatterns, aspNetCoreContext); + } + + /// + /// Configure which AspNetCore metrics to be registered. + /// + /// Action used to configure AspNetCore metrics. + /// Patterns for paths to ignore. + /// Name of the metrics context where to register the metrics. + /// Chainable configuration object. + public AspNetCoreMetricsConfig WithRequestMetricsConfig(Action config, + Regex[] ignoreRequestPathPatterns = null, string aspNetCoreContext = "AspNetCore") + { + if (this.isDisabled) + { + return this; + } + + AspNetCoreRequestMetricsConfig requestConfig = new AspNetCoreRequestMetricsConfig(this.middlewareRegistration, this.context.Context(aspNetCoreContext), ignoreRequestPathPatterns); + config(requestConfig); + return this; + } + + /// + /// Expose AspNetCore metrics endpoint + /// + /// Chainable configuration object. + public AspNetCoreMetricsConfig WithMetricsEndpoint() + { + if (this.isDisabled) + { + return this; + } + + WithMetricsEndpoint(_ => { }); + return this; + } + + /// + /// Configure AspNetCore metrics endpoint. + /// + /// Action used to configure the Owin Metrics endpoint. + /// The relative path the endpoint will be available at. + /// Chainable configuration object. + public AspNetCoreMetricsConfig WithMetricsEndpoint(Action config, string endpointPrefix = "metrics") + { + if (this.isDisabled) + { + return this; + } + + var endpointConfig = new MetricsEndpointReports(this.context.DataProvider, this.healthStatus); + config(endpointConfig); + + var metricsEndpointMiddleware = new AspNetCoreMetricsEndpointMiddleware(endpointPrefix, endpointConfig); + this.middlewareRegistration(metricsEndpointMiddleware.Invoke); + return this; + } + } +} \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/AspNetCoreRequestMetricsConfig.cs b/Src/Adapters/AspNetCore.Metrics/AspNetCoreRequestMetricsConfig.cs new file mode 100644 index 00000000..15ef3922 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/AspNetCoreRequestMetricsConfig.cs @@ -0,0 +1,110 @@ +using System; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using AspNetCore.Metrics.Middleware; +using Metrics; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics +{ + public class AspNetCoreRequestMetricsConfig + { + private readonly MetricsContext metricsContext; + private readonly Action, Task>> middlewareRegistration; + private readonly Regex[] ignoreRequestPathPatterns; + + public AspNetCoreRequestMetricsConfig(Action, Task>> middlewareRegistration, MetricsContext metricsContext, Regex[] ignoreRequestPathPatterns) + { + this.middlewareRegistration = middlewareRegistration; + this.metricsContext = metricsContext; + this.ignoreRequestPathPatterns = ignoreRequestPathPatterns; + } + + /// + /// Configure global OWIN Metrics. + /// Available global metrics are: Request Timer, Active Requests Counter, Error Meter + /// + /// + /// This instance to allow chaining of the configuration. + /// + public AspNetCoreRequestMetricsConfig WithAllAspNetCoreMetrics() + { + WithRequestTimer(); + WithActiveRequestCounter(); + WithPostAndPutRequestSizeHistogram(); + WithTimerForEachRequest(); + WithErrorsMeter(); + return this; + } + + /// + /// Registers a Timer metric named "Owin.Requests" that records how many requests per second are handled and also + /// keeps a histogram of the request duration. + /// + /// Name of the metric. + public AspNetCoreRequestMetricsConfig WithRequestTimer(string metricName = "Requests") + { + var metricsMiddleware = new RequestTimerMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); + this.middlewareRegistration(metricsMiddleware.Invoke); + return this; + } + + /// + /// Registers a Counter metric named "Owin.ActiveRequests" that shows the current number of active requests + /// + /// Name of the metric. + public AspNetCoreRequestMetricsConfig WithActiveRequestCounter(string metricName = "Active Requests") + { + var metricsMiddleware = new ActiveRequestCounterMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); + this.middlewareRegistration(metricsMiddleware.Invoke); + return this; + } + + /// + /// Register a Histogram metric named "Owin.PostAndPutRequestsSize" on the size of the POST and PUT requests + /// + /// Name of the metric. + public AspNetCoreRequestMetricsConfig WithPostAndPutRequestSizeHistogram(string metricName = "Post & Put Request Size") + { + var metricsMiddleware = new PostAndPutRequestSizeHistogramMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); + this.middlewareRegistration(metricsMiddleware.Invoke); + return this; + } + + /// + /// Registers a timer for each request. + /// Timer is created based on route and will be named: + /// Owin.{HTTP_METHOD_NAME} [{ROUTE_PATH}] + /// + public AspNetCoreRequestMetricsConfig WithTimerForEachRequest() + { + var metricsMiddleware = new TimerForEachRequestMiddleware(this.metricsContext, this.ignoreRequestPathPatterns); + this.middlewareRegistration(metricsMiddleware.Invoke); + return this; + } + + /// + /// Registers a Meter metric named "Owin.Errors" that records the rate at which unhanded errors occurred while + /// processing Nancy requests. + /// + /// Name of the metric. + public AspNetCoreRequestMetricsConfig WithErrorsMeter(string metricName = "Errors") + { + var metricsMiddleware = new ErrorMeterMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); + this.middlewareRegistration(metricsMiddleware.Invoke); + return this; + } + + /// + /// Registers a Meter metric named "Owin.HttpStatusCodes" that records the rate at which given HTTP stats codes + /// are returned. + /// + /// Name of the metric. + public AspNetCoreRequestMetricsConfig WithHttpStatusCodeMeter(string metricName = "HttpStatusCodes") + { + var metricsMiddleware = new HttpStatusCodeMeterMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); + this.middlewareRegistration(metricsMiddleware.Invoke); + return this; + } + } +} \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/ActiveRequestCounterMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/ActiveRequestCounterMiddleware.cs new file mode 100644 index 00000000..4ce3e7a7 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/ActiveRequestCounterMiddleware.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Metrics; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + /// + /// Owin middleware that counts the number of active requests. + /// + public class ActiveRequestCounterMiddleware : MetricMiddleware + { + private readonly Counter activeRequests; + + public ActiveRequestCounterMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) + : base(ignorePatterns) + { + this.activeRequests = context.Counter(metricName, Unit.Custom("ActiveRequests")); + } + + public async Task Invoke(HttpContext context, Func next) + { + if (PerformMetric(context)) + { + this.activeRequests.Increment(); + + await next(); + + this.activeRequests.Decrement(); + } + else + { + await next(); + } + } + } +} diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/AspNetCoreMetricsEndpointHandler.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/AspNetCoreMetricsEndpointHandler.cs new file mode 100644 index 00000000..b6fc8847 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/AspNetCoreMetricsEndpointHandler.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Linq; +using Metrics.Endpoints; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + internal class AspNetCoreMetricsEndpointHandler : AbstractMetricsEndpointHandler + { + public AspNetCoreMetricsEndpointHandler(IEnumerable endpoints) : base(endpoints) { } + + protected override MetricsEndpointRequest CreateRequest(HttpContext context) + { + IDictionary header = context.Request.Headers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray()); + return new MetricsEndpointRequest(header); + } + } +} diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/ErrorMeterMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/ErrorMeterMiddleware.cs new file mode 100644 index 00000000..3433aa79 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/ErrorMeterMiddleware.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Metrics; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + public class ErrorMeterMiddleware : MetricMiddleware + { + private readonly Meter errorMeter; + + public ErrorMeterMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) + : base(ignorePatterns) + { + this.errorMeter = context.Meter(metricName, Unit.Errors); + } + + public async Task Invoke(HttpContext context, Func next) + { + await next(); + + if (PerformMetric(context)) + { + var httpResponseStatusCode = int.Parse(context.Response.StatusCode.ToString()); + + if (httpResponseStatusCode == (int)HttpStatusCode.InternalServerError) + { + this.errorMeter.Mark(); + } + } + } + } +} diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs new file mode 100644 index 00000000..4c7ece72 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Metrics; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + using AppFunc = Func, Task>; + + public class HttpStatusCodeMeterMiddleware : MetricMiddleware + { + private readonly Meter httpStatusCodeMeter; + + public HttpStatusCodeMeterMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) + : base(ignorePatterns) + { + this.httpStatusCodeMeter = context.Meter(metricName, Unit.Errors); + } + + public async Task Invoke(HttpContext context, Func next) + { + await next(); + + if (PerformMetric(context)) + { + this.httpStatusCodeMeter.Mark(context.Response.StatusCode.ToString()); + } + } + } +} diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/MetricMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/MetricMiddleware.cs new file mode 100644 index 00000000..6c654fff --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/MetricMiddleware.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text.RegularExpressions; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics +{ + public abstract class MetricMiddleware + { + private readonly Regex[] ignorePatterns; + + protected MetricMiddleware(Regex[] ignorePatterns) + { + this.ignorePatterns = ignorePatterns; + } + + protected bool PerformMetric(HttpContext context) + { + if (ignorePatterns == null) + { + return true; + } + + var requestPath = context.Request.Path.Value; + + if (string.IsNullOrWhiteSpace(requestPath)) return false; + + return !this.ignorePatterns.Any(ignorePattern => ignorePattern.IsMatch(requestPath.TrimStart('/'))); + } + } +} \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/MetricsEndpointMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/MetricsEndpointMiddleware.cs new file mode 100644 index 00000000..4676e415 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/MetricsEndpointMiddleware.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using Metrics.Endpoints; +using Metrics.Reports; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + public class AspNetCoreMetricsEndpointMiddleware + { + private readonly string endpointPrefix; + private readonly AspNetCoreMetricsEndpointHandler endpointHandler; + + public AspNetCoreMetricsEndpointMiddleware(string endpointPrefix, MetricsEndpointReports endpointConfig) + { + this.endpointPrefix = NormalizePrefix(endpointPrefix); + this.endpointHandler = new AspNetCoreMetricsEndpointHandler(endpointConfig.Endpoints); + } + + public Task Invoke(HttpContext context, Func next) + { + var requestPath = context.Request.Path.ToString(); + if (requestPath.StartsWith(this.endpointPrefix, StringComparison.OrdinalIgnoreCase)) + { + requestPath = requestPath.Substring(this.endpointPrefix.Length); + + if (requestPath == "/") + { + return GetFlotWebApp(context); + } + + var response = this.endpointHandler.Process(requestPath, context); + if (response != null) + { + return WriteResponse(response, context); + } + } + + return next(); + } + + private static string NormalizePrefix(string prefix) + { + if (string.IsNullOrEmpty(prefix) || prefix == "/") + { + return string.Empty; + } + + if (prefix.StartsWith("/")) + { + return prefix; + } + + return $"/{prefix}"; + } + + private static Task GetFlotWebApp(HttpContext context) + { + var content = FlotWebApp.GetFlotApp(); + return WriteResponse(context, content, "text/html"); + } + + private static async Task WriteResponse(HttpContext context, string content, string contentType, HttpStatusCode code = HttpStatusCode.OK) + { + var response = context.Response.Body; + var headers = context.Response.Headers; + + var contentBytes = Encoding.UTF8.GetBytes(content); + + headers["Content-Type"] = new[] { contentType }; + headers["Cache-Control"] = new[] { "no-cache, no-store, must-revalidate" }; + headers["Pragma"] = new[] { "no-cache" }; + headers["Expires"] = new[] { "0" }; + + context.Response.StatusCode = (int)code; + + await response.WriteAsync(contentBytes, 0, contentBytes.Length); + } + + private static async Task WriteResponse(MetricsEndpointResponse response, HttpContext context) + { + var responseStream = context.Response.Body; + var headers = context.Response.Headers; + + var contentBytes = response.Encoding.GetBytes(response.Content); + + headers["Content-Type"] = new[] { response.ContentType }; + headers["Cache-Control"] = new[] { "no-cache, no-store, must-revalidate" }; + headers["Pragma"] = new[] { "no-cache" }; + headers["Expires"] = new[] { "0" }; + + context.Response.StatusCode = (int)response.StatusCode; + + await responseStream.WriteAsync(contentBytes, 0, contentBytes.Length); + } + } +} diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs new file mode 100644 index 00000000..25aeaf3c --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Metrics; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + public class PostAndPutRequestSizeHistogramMiddleware : MetricMiddleware + { + private readonly Histogram histogram; + + public PostAndPutRequestSizeHistogramMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) + : base(ignorePatterns) + { + this.histogram = context.Histogram(metricName, Unit.Bytes); + } + + public async Task Invoke(HttpContext context, Func next) + { + if (PerformMetric(context)) + { + var httpMethod = context.Request.Method.ToString().ToUpper(); + + if (httpMethod == "POST" || httpMethod == "PUT") + { + var contentLength = context.Request.Headers.ContentLength; + if (contentLength.HasValue) + { + this.histogram.Update(contentLength.Value); + } + } + } + + await next(); + } + } +} diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/RequestTimerMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/RequestTimerMiddleware.cs new file mode 100644 index 00000000..e95ece57 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/RequestTimerMiddleware.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Metrics; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + public class RequestTimerMiddleware : MetricMiddleware + { + private readonly Timer requestTimer; + + public RequestTimerMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) + : base(ignorePatterns) + { + this.requestTimer = context.Timer(metricName, Unit.Requests); + } + + public async Task Invoke(HttpContext context, Func next) + { + if (base.PerformMetric(context)) + { + using (this.requestTimer.NewContext()) + { + await next(); + } + } + else + { + await next(); + } + } + } +} \ No newline at end of file diff --git a/Src/Adapters/AspNetCore.Metrics/Middleware/TimerForEachRequestMiddleware.cs b/Src/Adapters/AspNetCore.Metrics/Middleware/TimerForEachRequestMiddleware.cs new file mode 100644 index 00000000..be1683e6 --- /dev/null +++ b/Src/Adapters/AspNetCore.Metrics/Middleware/TimerForEachRequestMiddleware.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Metrics; +using Metrics.Utils; +using Microsoft.AspNetCore.Http; + +namespace AspNetCore.Metrics.Middleware +{ + public class TimerForEachRequestMiddleware : MetricMiddleware + { + private readonly MetricsContext context; + + public TimerForEachRequestMiddleware(MetricsContext context, Regex[] ignorePatterns) + : base(ignorePatterns) + { + this.context = context; + } + + public async Task Invoke(HttpContext context, Func next) + { + if (PerformMetric(context)) + { + var startTime = Clock.Default.Nanoseconds; + + await next(); + + var httpResponseStatusCode = int.Parse(context.Response.StatusCode.ToString()); + var metricName = context.Request.Path.ToString(); + +// if (environment.ContainsKey("metrics-net.routetemplate")) +// { +// var requestMethod = environment["owin.RequestMethod"] as string; +// var routeTemplate = environment["metrics-net.routetemplate"] as string; +// +// metricName = requestMethod.ToUpperInvariant() + " " + routeTemplate; +// } + + if (httpResponseStatusCode != (int)HttpStatusCode.NotFound) + { + var elapsed = Clock.Default.Nanoseconds - startTime; + this.context.Timer(metricName, Unit.Requests) + .Record(elapsed, TimeUnit.Nanoseconds); + } + } + else + { + await next(); + } + } + } +} diff --git a/Src/Adapters/Metrics.NLog/Metrics.NLog.csproj b/Src/Adapters/Metrics.NLog/Metrics.NLog.csproj index a5a3b82f..1c41d4b1 100644 --- a/Src/Adapters/Metrics.NLog/Metrics.NLog.csproj +++ b/Src/Adapters/Metrics.NLog/Metrics.NLog.csproj @@ -1,87 +1,14 @@ - - - + - Debug - AnyCPU - {68F25A01-AF00-4D57-9D1A-81213E4EF56F} - Library - Properties - Metrics.NLog - Metrics.NLog - v4.5 - 512 - ..\..\..\ - true + netstandard2.0 - - true - full - false - ..\..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - - - - - pdbonly - true - ..\..\..\bin\Release\ - TRACE - prompt - 4 - true - 1591 - ..\..\..\bin\Release\Metrics.NLog.XML - - - - False - ..\..\..\packages\NLog.3.2.0.0\lib\net45\NLog.dll - - - - - - - - - - - - - - - - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - + - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Src/Adapters/Metrics.NLog/Properties/AssemblyInfo.cs b/Src/Adapters/Metrics.NLog/Properties/AssemblyInfo.cs index 7fca5e5d..0bb9359d 100644 --- a/Src/Adapters/Metrics.NLog/Properties/AssemblyInfo.cs +++ b/Src/Adapters/Metrics.NLog/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Metrics.NLog")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Metrics.NLog")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("c23d9cd1-1138-449a-ab35-bc106bd113af")] - -// Version information for an assembly consists of the following four values: +// TODO: migrate to csproj +//// General Information about an assembly is controlled through the following +//// set of attributes. Change these attribute values to modify the information +//// associated with an assembly. +//[assembly: AssemblyTitle("Metrics.NLog")] +//[assembly: AssemblyDescription("")] +//[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +//[assembly: AssemblyProduct("Metrics.NLog")] +//[assembly: AssemblyCopyright("Copyright © 2014")] +//[assembly: AssemblyTrademark("")] +//[assembly: AssemblyCulture("")] // -// Major Version -// Minor Version -// Build Number -// Revision +//// Setting ComVisible to false makes the types in this assembly not visible +//// to COM components. If you need to access a type in this assembly from +//// COM, set the ComVisible attribute to true on that type. +//[assembly: ComVisible(false)] // -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +//// The following GUID is for the ID of the typelib if this project is exposed to COM +//[assembly: Guid("c23d9cd1-1138-449a-ab35-bc106bd113af")] +// +//// Version information for an assembly consists of the following four values: +//// +//// Major Version +//// Minor Version +//// Build Number +//// Revision +//// +//// You can specify all the values or you can default the Build and Revision Numbers +//// by using the '*' as shown below: +//// [assembly: AssemblyVersion("1.0.*")] +//[assembly: AssemblyVersion("1.0.0.0")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Src/Adapters/Nancy.Metrics/MetricsModule.cs b/Src/Adapters/Nancy.Metrics/MetricsModule.cs index df5f0365..bbedef69 100644 --- a/Src/Adapters/Nancy.Metrics/MetricsModule.cs +++ b/Src/Adapters/Nancy.Metrics/MetricsModule.cs @@ -46,7 +46,7 @@ public MetricsModule() Config.ModuleConfigAction?.Invoke(this); - Get["/"] = _ => + Get("/", _ => { if (!this.Request.Url.Path.EndsWith("/")) { @@ -59,14 +59,14 @@ public MetricsModule() response.WithHeader("Content-Encoding", "gzip"); } return response; - }; + }); - Get["/{path*}"] = p => + Get("/{path*}", p => { var path = (string)p.path; var endpointResponse = Config.Handler.Process(path, this.Request); return endpointResponse != null ? GetResponse(endpointResponse) : HttpStatusCode.NotFound; - }; + }); } private static Response GetResponse(MetricsEndpointResponse endpointResponse) diff --git a/Src/Adapters/Nancy.Metrics/Nancy.Metrics.csproj b/Src/Adapters/Nancy.Metrics/Nancy.Metrics.csproj index d30c5216..00e61a37 100644 --- a/Src/Adapters/Nancy.Metrics/Nancy.Metrics.csproj +++ b/Src/Adapters/Nancy.Metrics/Nancy.Metrics.csproj @@ -1,86 +1,14 @@ - - - + - Debug - AnyCPU - {FBFF51D8-52F4-4EEF-8498-122A14B37D6C} - Library - Properties - Nancy.Metrics - Nancy.Metrics - 512 - v4.5 - ..\..\..\ - true - - - true - full - false - ..\..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - - - - - pdbonly - true - ..\..\..\bin\Release\ - TRACE - prompt - 4 - true - 1591 - ..\..\..\bin\Release\Nancy.Metrics.XML + netstandard2.0 - - Properties\SharedAssemblyInfo.cs - - - - - - - - + - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - - - False - ..\..\..\packages\Nancy.1.2.0\lib\net40\Nancy.dll - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Src/Adapters/Nancy.Metrics/Properties/AssemblyInfo.cs b/Src/Adapters/Nancy.Metrics/Properties/AssemblyInfo.cs index 76d3d110..885ac21e 100644 --- a/Src/Adapters/Nancy.Metrics/Properties/AssemblyInfo.cs +++ b/Src/Adapters/Nancy.Metrics/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ using System.Reflection; - +// TODO: Migrate to csproj [assembly: AssemblyTitle("Nancy.Metrics")] [assembly: AssemblyDescription("NancyFx adapter for the Metrics.NET Library")] diff --git a/Src/Adapters/Owin.Metrics/Middleware/ActiveRequestCounterMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/ActiveRequestCounterMiddleware.cs index 17cc9608..b176f443 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/ActiveRequestCounterMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/ActiveRequestCounterMiddleware.cs @@ -6,13 +6,21 @@ namespace Owin.Metrics.Middleware { + using AppFunc = Func, Task>; + /// /// Owin middleware that counts the number of active requests. /// public class ActiveRequestCounterMiddleware : MetricMiddleware { private readonly Counter activeRequests; - private Func, Task> next; + private AppFunc next; + + public ActiveRequestCounterMiddleware(AppFunc next, MetricsContext context, string metricName, Regex[] ignorePatterns) + : this(context, metricName, ignorePatterns) + { + this.next = next; + } public ActiveRequestCounterMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) : base(ignorePatterns) @@ -20,7 +28,7 @@ public ActiveRequestCounterMiddleware(MetricsContext context, string metricName, this.activeRequests = context.Counter(metricName, Unit.Custom("ActiveRequests")); } - public void Initialize(Func, Task> next) + public void Initialize(AppFunc next) { this.next = next; } diff --git a/Src/Adapters/Owin.Metrics/Middleware/ErrorMeterMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/ErrorMeterMiddleware.cs index b2e15e02..f68f6388 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/ErrorMeterMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/ErrorMeterMiddleware.cs @@ -14,6 +14,12 @@ public class ErrorMeterMiddleware : MetricMiddleware private readonly Meter errorMeter; private AppFunc next; + public ErrorMeterMiddleware(AppFunc next, MetricsContext context, string metricName, Regex[] ignorePatterns) + : this(context, metricName, ignorePatterns) + { + this.next = next; + } + public ErrorMeterMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) : base(ignorePatterns) { diff --git a/Src/Adapters/Owin.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs index 5413fc48..463184f7 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/HttpStatusCodeMeterMiddleware.cs @@ -13,6 +13,12 @@ public class HttpStatusCodeMeterMiddleware : MetricMiddleware private readonly Meter httpStatusCodeMeter; private AppFunc next; + public HttpStatusCodeMeterMiddleware(AppFunc next, MetricsContext context, string metricName, Regex[] ignorePatterns) + : this(context, metricName, ignorePatterns) + { + this.next = next; + } + public HttpStatusCodeMeterMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) : base(ignorePatterns) { diff --git a/Src/Adapters/Owin.Metrics/Middleware/MetricsEndpointMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/MetricsEndpointMiddleware.cs index 52ee43d2..12378a57 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/MetricsEndpointMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/MetricsEndpointMiddleware.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Net; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using Metrics.Endpoints; @@ -17,6 +18,12 @@ public class MetricsEndpointMiddleware private readonly OwinMetricsEndpointHandler endpointHandler; private AppFunc next; + public MetricsEndpointMiddleware(AppFunc next, string endpointPrefix, MetricsEndpointReports endpointConfig) + : this(endpointPrefix, endpointConfig) + { + this.next = next; + } + public MetricsEndpointMiddleware(string endpointPrefix, MetricsEndpointReports endpointConfig) { this.endpointPrefix = NormalizePrefix(endpointPrefix); diff --git a/Src/Adapters/Owin.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs index f06a1266..b493f55c 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/PostAndPutRequestSizeHistogramMiddleware.cs @@ -14,6 +14,12 @@ public class PostAndPutRequestSizeHistogramMiddleware : MetricMiddleware private readonly Histogram histogram; private AppFunc next; + public PostAndPutRequestSizeHistogramMiddleware(AppFunc next, MetricsContext context, string metricName, Regex[] ignorePatterns) + : this(context, metricName, ignorePatterns) + { + this.next = next; + } + public PostAndPutRequestSizeHistogramMiddleware(MetricsContext context, string metricName, Regex[] ignorePatterns) : base(ignorePatterns) { diff --git a/Src/Adapters/Owin.Metrics/Middleware/RequestTimerMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/RequestTimerMiddleware.cs index 3ec30de6..4b8fafc6 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/RequestTimerMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/RequestTimerMiddleware.cs @@ -20,6 +20,12 @@ public RequestTimerMiddleware(MetricsContext context, string metricName, Regex[] { this.requestTimer = context.Timer(metricName, Unit.Requests); } + + public RequestTimerMiddleware(AppFunc next, MetricsContext context, string metricName, Regex[] ignorePatterns) + : this(context, metricName, ignorePatterns) + { + this.next = next; + } public void Initialize(AppFunc next) { diff --git a/Src/Adapters/Owin.Metrics/Middleware/TimerForEachRequestMiddleware.cs b/Src/Adapters/Owin.Metrics/Middleware/TimerForEachRequestMiddleware.cs index dd0c7e1d..95b91a1e 100644 --- a/Src/Adapters/Owin.Metrics/Middleware/TimerForEachRequestMiddleware.cs +++ b/Src/Adapters/Owin.Metrics/Middleware/TimerForEachRequestMiddleware.cs @@ -18,6 +18,11 @@ public class TimerForEachRequestMiddleware : MetricMiddleware private AppFunc next; + public TimerForEachRequestMiddleware(AppFunc next, MetricsContext context, Regex[] ignorePatterns) + : this(context, ignorePatterns) + { + this.next = next; + } public TimerForEachRequestMiddleware(MetricsContext context, Regex[] ignorePatterns) : base(ignorePatterns) { diff --git a/Src/Adapters/Owin.Metrics/Owin.Metrics.csproj b/Src/Adapters/Owin.Metrics/Owin.Metrics.csproj index f590606c..e73073f9 100644 --- a/Src/Adapters/Owin.Metrics/Owin.Metrics.csproj +++ b/Src/Adapters/Owin.Metrics/Owin.Metrics.csproj @@ -1,79 +1,14 @@ - - - + - Debug - AnyCPU - {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210} - Library - Properties - Owin.Metrics - Owin.Metrics - v4.5 - 512 - ..\..\..\ - true - + netstandard2.0 - - true - full - false - ..\..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - 1591 - true - - - pdbonly - true - ..\..\..\Release\ - TRACE - prompt - 4 - false - ..\..\..\Release\Owin.Metrics.XML - 1591 - - - - - - - - - - - - - - - - - - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + + + \ No newline at end of file diff --git a/Src/Adapters/Owin.Metrics/OwinMetrics.cs b/Src/Adapters/Owin.Metrics/OwinMetrics.cs index 0f54bed6..4d30e80d 100644 --- a/Src/Adapters/Owin.Metrics/OwinMetrics.cs +++ b/Src/Adapters/Owin.Metrics/OwinMetrics.cs @@ -1,13 +1,22 @@ using System; +using System.Collections.Generic; +using System.Threading.Tasks; using Metrics; namespace Owin.Metrics { + using MidFunc = System.Func, + System.Threading.Tasks.Task>, System.Func, + System.Threading.Tasks.Task>>; + using OwinPipeline = Action, + System.Threading.Tasks.Task>, System.Func, + System.Threading.Tasks.Task>>>>; /// /// Helper class to register OWIN Metrics /// public static class OwinMetrics { + /// /// Add Metrics Middleware to the Owin pipeline. /// Sample: Metric.Config.WithOwin( m => app.Use(m)) @@ -16,7 +25,7 @@ public static class OwinMetrics /// Chainable configuration object. /// Action used to register middleware. This should generally be app.Use(middleware) /// Chainable configuration object. - public static MetricsConfig WithOwin(this MetricsConfig config, Action middlewareRegistration) + public static MetricsConfig WithOwin(this MetricsConfig config, Action middlewareRegistration) { return config.WithOwin(middlewareRegistration, owin => owin.WithRequestMetricsConfig() @@ -32,7 +41,7 @@ public static MetricsConfig WithOwin(this MetricsConfig config, Action m /// Action used to register middleware. This should generally be app.Use(middleware) /// Action used to configure Owin metrics. /// Chainable configuration object. - public static MetricsConfig WithOwin(this MetricsConfig config, Action middlewareRegistration, Action owinConfig) + public static MetricsConfig WithOwin(this MetricsConfig config, Action middlewareRegistration, Action owinConfig) { var owin = config.WithConfigExtension((ctx, hs) => new OwinMetricsConfig(middlewareRegistration, ctx, hs), () => OwinMetricsConfig.Disabled); owinConfig(owin); diff --git a/Src/Adapters/Owin.Metrics/OwinMetricsConfig.cs b/Src/Adapters/Owin.Metrics/OwinMetricsConfig.cs index 81df1823..ac6d8b9e 100644 --- a/Src/Adapters/Owin.Metrics/OwinMetricsConfig.cs +++ b/Src/Adapters/Owin.Metrics/OwinMetricsConfig.cs @@ -1,21 +1,27 @@ using System; +using System.Collections.Generic; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Metrics; using Metrics.Reports; using Owin.Metrics.Middleware; namespace Owin.Metrics { + using MidFunc = System.Func, + System.Threading.Tasks.Task>, System.Func, + System.Threading.Tasks.Task>>; + public class OwinMetricsConfig { public static readonly OwinMetricsConfig Disabled = new OwinMetricsConfig(); - private readonly Action middlewareRegistration; + private readonly Action middlewareRegistration; private readonly MetricsContext context; private readonly Func healthStatus; private readonly bool isDisabled; - public OwinMetricsConfig(Action middlewareRegistration, MetricsContext context, Func healthStatus) + public OwinMetricsConfig(Action middlewareRegistration, MetricsContext context, Func healthStatus) { this.middlewareRegistration = middlewareRegistration; this.context = context; @@ -93,8 +99,8 @@ public OwinMetricsConfig WithMetricsEndpoint(Action conf var endpointConfig = new MetricsEndpointReports(this.context.DataProvider, this.healthStatus); config(endpointConfig); - var metricsEndpointMiddleware = new MetricsEndpointMiddleware(endpointPrefix, endpointConfig); - this.middlewareRegistration(metricsEndpointMiddleware); + + this.middlewareRegistration(next => new MetricsEndpointMiddleware(next, endpointPrefix, endpointConfig).Invoke); return this; } } diff --git a/Src/Adapters/Owin.Metrics/OwinRequestMetricsConfig.cs b/Src/Adapters/Owin.Metrics/OwinRequestMetricsConfig.cs index cbaf38ee..167c7305 100644 --- a/Src/Adapters/Owin.Metrics/OwinRequestMetricsConfig.cs +++ b/Src/Adapters/Owin.Metrics/OwinRequestMetricsConfig.cs @@ -4,14 +4,18 @@ using Owin.Metrics.Middleware; namespace Owin.Metrics -{ +{ + using MidFunc = System.Func, + System.Threading.Tasks.Task>, System.Func, + System.Threading.Tasks.Task>>; + public class OwinRequestMetricsConfig { private readonly MetricsContext metricsContext; - private readonly Action middlewareRegistration; + private readonly Action middlewareRegistration; private readonly Regex[] ignoreRequestPathPatterns; - public OwinRequestMetricsConfig(Action middlewareRegistration, MetricsContext metricsContext, Regex[] ignoreRequestPathPatterns) + public OwinRequestMetricsConfig(Action middlewareRegistration, MetricsContext metricsContext, Regex[] ignoreRequestPathPatterns) { this.middlewareRegistration = middlewareRegistration; this.metricsContext = metricsContext; @@ -42,8 +46,7 @@ public OwinRequestMetricsConfig WithAllOwinMetrics() /// Name of the metric. public OwinRequestMetricsConfig WithRequestTimer(string metricName = "Requests") { - var metricsMiddleware = new RequestTimerMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); - middlewareRegistration(metricsMiddleware); + middlewareRegistration(next => new RequestTimerMiddleware(next, this.metricsContext, metricName, this.ignoreRequestPathPatterns).Invoke); return this; } @@ -53,8 +56,7 @@ public OwinRequestMetricsConfig WithRequestTimer(string metricName = "Requests") /// Name of the metric. public OwinRequestMetricsConfig WithActiveRequestCounter(string metricName = "Active Requests") { - var metricsMiddleware = new ActiveRequestCounterMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); - middlewareRegistration(metricsMiddleware); + middlewareRegistration(next => new ActiveRequestCounterMiddleware(next, this.metricsContext, metricName, this.ignoreRequestPathPatterns).Invoke); return this; } @@ -64,8 +66,7 @@ public OwinRequestMetricsConfig WithActiveRequestCounter(string metricName = "Ac /// Name of the metric. public OwinRequestMetricsConfig WithPostAndPutRequestSizeHistogram(string metricName = "Post & Put Request Size") { - var metricsMiddleware = new PostAndPutRequestSizeHistogramMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); - middlewareRegistration(metricsMiddleware); + middlewareRegistration(next => new PostAndPutRequestSizeHistogramMiddleware(next, this.metricsContext, metricName, this.ignoreRequestPathPatterns).Invoke); return this; } @@ -76,8 +77,7 @@ public OwinRequestMetricsConfig WithPostAndPutRequestSizeHistogram(string metric /// public OwinRequestMetricsConfig WithTimerForEachRequest() { - var metricsMiddleware = new TimerForEachRequestMiddleware(this.metricsContext, this.ignoreRequestPathPatterns); - middlewareRegistration(metricsMiddleware); + middlewareRegistration(next => new TimerForEachRequestMiddleware(next, this.metricsContext, this.ignoreRequestPathPatterns).Invoke); return this; } @@ -88,8 +88,7 @@ public OwinRequestMetricsConfig WithTimerForEachRequest() /// Name of the metric. public OwinRequestMetricsConfig WithErrorsMeter(string metricName = "Errors") { - var metricsMiddleware = new ErrorMeterMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); - middlewareRegistration(metricsMiddleware); + middlewareRegistration(next => new ErrorMeterMiddleware(next, this.metricsContext, metricName, this.ignoreRequestPathPatterns).Invoke); return this; } @@ -100,8 +99,7 @@ public OwinRequestMetricsConfig WithErrorsMeter(string metricName = "Errors") /// Name of the metric. public OwinRequestMetricsConfig WithHttpStatusCodeMeter(string metricName = "HttpStatusCodes") { - var metricsMiddleware = new HttpStatusCodeMeterMiddleware(this.metricsContext, metricName, this.ignoreRequestPathPatterns); - middlewareRegistration(metricsMiddleware); + middlewareRegistration(next => new HttpStatusCodeMeterMiddleware(next, this.metricsContext, metricName, this.ignoreRequestPathPatterns).Invoke); return this; } } diff --git a/Src/Metrics.Central/Metrics.Central.csproj b/Src/Metrics.Central/Metrics.Central.csproj index 3e1d092c..ac6505a3 100644 --- a/Src/Metrics.Central/Metrics.Central.csproj +++ b/Src/Metrics.Central/Metrics.Central.csproj @@ -1,87 +1,19 @@ - - - + - Debug - AnyCPU - {450184A4-9916-4AE5-87F8-A8067105CE40} + netcoreapp2.0 Exe - Properties - Metrics.Central - Metrics.Central - v4.5 - 512 - ..\..\ - true - - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - ..\..\packages\Topshelf.3.1.4\lib\net40-full\Topshelf.dll - + - - - + - - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} - Metrics - - - Always - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Src/Metrics.Central/MetricsService.cs b/Src/Metrics.Central/MetricsService.cs index 06e42793..bbbbfefd 100644 --- a/Src/Metrics.Central/MetricsService.cs +++ b/Src/Metrics.Central/MetricsService.cs @@ -4,20 +4,22 @@ using System.Linq; using Metrics.Json; using Newtonsoft.Json; -using Topshelf; namespace Metrics.Central { - public class MetricsService : ServiceControl + public class MetricsService { private const string remotesFile = "remotes.txt"; - public bool Start(HostControl hostControl) + public bool Start() { Metric.Config - .WithJsonDeserialzier(JsonConvert.DeserializeObject) + .WithJsonDeserializer(JsonConvert.DeserializeObject) +#if NET45 .WithAllCounters(); - +#else + .WithHttpEndpoint(""); +#endif var remotes = ReadRemotesFromConfig(); foreach (var uri in remotes) @@ -58,7 +60,7 @@ private IEnumerable ReadRemotesFromConfig() } } - public bool Stop(HostControl hostControl) + public bool Stop() { return true; } diff --git a/Src/Metrics.Central/Program.cs b/Src/Metrics.Central/Program.cs index fc8ce482..dc74da30 100644 --- a/Src/Metrics.Central/Program.cs +++ b/Src/Metrics.Central/Program.cs @@ -1,4 +1,4 @@ -using Topshelf; +using System; namespace Metrics.Central { @@ -6,17 +6,14 @@ class Program { static void Main(string[] args) { - HostFactory.Run(x => - { - x.Service(); + MetricsService ms = new MetricsService(); - x.StartAutomatically() - .RunAsLocalService(); + ms.Start(); - x.SetDescription("Metrics.NET Central Service"); - x.SetDisplayName("Metrics.NET Central"); - x.SetServiceName("Metrics.Central"); - }); + Console.WriteLine("Press any key to exit..."); + Console.ReadKey(); + + ms.Stop(); } } } diff --git a/Src/Metrics.Central/Properties/AssemblyInfo.cs b/Src/Metrics.Central/Properties/AssemblyInfo.cs deleted file mode 100644 index 46e02bd1..00000000 --- a/Src/Metrics.Central/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Metrics.Central")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Metrics.Central")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("dfc7dd50-d15e-4517-b4f2-330c53a82a9b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Src/Metrics.TestConsole/Metrics.TestConsole.csproj b/Src/Metrics.TestConsole/Metrics.TestConsole.csproj index 3afead26..0a809b04 100644 --- a/Src/Metrics.TestConsole/Metrics.TestConsole.csproj +++ b/Src/Metrics.TestConsole/Metrics.TestConsole.csproj @@ -1,67 +1,12 @@ - - - + - Debug - AnyCPU - {1E8F49B4-B8D9-4932-909D-821AEFB869B0} - Exe - Properties - Metrics.TestConsole - Metrics.TestConsole - v4.5.1 - 512 - true + netcoreapp2.0 + false - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - true - - - - - - - - - - - - - - - - - - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - \ No newline at end of file diff --git a/Src/Metrics.TestConsole/Properties/AssemblyInfo.cs b/Src/Metrics.TestConsole/Properties/AssemblyInfo.cs index cbe28326..010cea49 100644 --- a/Src/Metrics.TestConsole/Properties/AssemblyInfo.cs +++ b/Src/Metrics.TestConsole/Properties/AssemblyInfo.cs @@ -5,32 +5,33 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Metrics.TestConsole")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Metrics.TestConsole")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("959b540f-fe51-4bbc-aa87-c24325ae1a2e")] - -// Version information for an assembly consists of the following four values: +//[assembly: AssemblyTitle("Metrics.TestConsole")] +//[assembly: AssemblyDescription("")] +//[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +//[assembly: AssemblyProduct("Metrics.TestConsole")] +//[assembly: AssemblyCopyright("Copyright © 2015")] +//[assembly: AssemblyTrademark("")] +//[assembly: AssemblyCulture("")] +// +//// Setting ComVisible to false makes the types in this assembly not visible +//// to COM components. If you need to access a type in this assembly from +//// COM, set the ComVisible attribute to true on that type. +//[assembly: ComVisible(false)] // -// Major Version -// Minor Version -// Build Number -// Revision +//// The following GUID is for the ID of the typelib if this project is exposed to COM +//[assembly: Guid("959b540f-fe51-4bbc-aa87-c24325ae1a2e")] // -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +//// Version information for an assembly consists of the following four values: +//// +//// Major Version +//// Minor Version +//// Build Number +//// Revision +//// +//// You can specify all the values or you can default the Build and Revision Numbers +//// by using the '*' as shown below: +//// [assembly: AssemblyVersion("1.0.*")] +//[assembly: AssemblyVersion("1.0.0.0")] +//[assembly: AssemblyFileVersion("1.0.0.0")] +// todo: migrate to csproj \ No newline at end of file diff --git a/Src/Metrics.Tests/AspNetCoreAdapter/AspNetCoreMiddlewareTests.cs b/Src/Metrics.Tests/AspNetCoreAdapter/AspNetCoreMiddlewareTests.cs new file mode 100644 index 00000000..4429ed80 --- /dev/null +++ b/Src/Metrics.Tests/AspNetCoreAdapter/AspNetCoreMiddlewareTests.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using AspNetCore.Metrics; +using FluentAssertions; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.TestHost; +using AspNetCore.Metrics; +using Xunit; + +namespace Metrics.Tests.AspNetCoreAdapter +{ + public class AspNetCoreMiddlewareTests + { + private const int timePerRequest = 100; + + private readonly TestContext context = new TestContext(); + private readonly MetricsConfig config; + private readonly TestServer server; + + public AspNetCoreMiddlewareTests() + { + this.config = new MetricsConfig(this.context); + + var builder = new WebHostBuilder() + .Configure(app => + { + this.config.WithAspNetCore(m => app.Use(m)); + + app.Run(ctx => + { + this.context.Clock.Advance(TimeUnit.Milliseconds, timePerRequest); + if (ctx.Request.Path.ToString() == "/test/action") + { + return ctx.Response.WriteAsync("response"); + } + + if (ctx.Request.Path.ToString() == "/test/error") + { + ctx.Response.StatusCode = 500; + return ctx.Response.WriteAsync("response"); + } + + if (ctx.Request.Path.ToString() == "/test/size") + { + return ctx.Response.WriteAsync("response"); + } + + if (ctx.Request.Path.ToString() == "/test/post") + { + return ctx.Response.WriteAsync("response"); + } + + ctx.Response.StatusCode = 404; + return ctx.Response.WriteAsync("not found"); + }); + + }); + + this.server = new TestServer(builder); + } + + + [Fact] + public async Task AspNetCoreMetrics_ShouldBeAbleToRecordErrors() + { + this.context.MeterValue("AspNetCore", "Errors").Count.Should().Be(0); + (await this.server.CreateRequest("http://local.test/test/error").GetAsync()).StatusCode.Should().Be(HttpStatusCode.InternalServerError); + this.context.MeterValue("AspNetCore", "Errors").Count.Should().Be(1); + + (await this.server.CreateRequest("http://local.test/test/error").GetAsync()).StatusCode.Should().Be(HttpStatusCode.InternalServerError); + this.context.MeterValue("AspNetCore", "Errors").Count.Should().Be(2); + } + + [Fact] + public async Task AspNetCoreMetrics_ShouldBeAbleToRecordActiveRequestCounts() + { + this.context.TimerValue("AspNetCore", "Requests").Rate.Count.Should().Be(0); + (await this.server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); + this.context.TimerValue("AspNetCore", "Requests").Rate.Count.Should().Be(1); + (await this.server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); + this.context.TimerValue("AspNetCore", "Requests").Rate.Count.Should().Be(2); + (await this.server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); + this.context.TimerValue("AspNetCore", "Requests").Rate.Count.Should().Be(3); + (await this.server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); + this.context.TimerValue("AspNetCore", "Requests").Rate.Count.Should().Be(4); + + var timer = this.context.TimerValue("AspNetCore", "Requests"); + + timer.Histogram.Min.Should().Be(timePerRequest); + timer.Histogram.Max.Should().Be(timePerRequest); + timer.Histogram.Mean.Should().Be(timePerRequest); + } + + [Fact] + public async Task AspNetCoreMetrics_ShouldRecordHistogramMetricsForPostSizeAndTimePerRequest() + { + const string json = "{ 'id': '1'} "; + var postContent = new StringContent(json); + postContent.Headers.Add("Content-Length", json.Length.ToString()); + await this.server.CreateRequest("http://local.test/test/post").And(r => r.Content = postContent).PostAsync(); + + var histogram = this.context.HistogramValue("AspNetCore", "Post & Put Request Size"); + + histogram.Count.Should().Be(1); + histogram.LastValue.Should().Be(json.Length); + } + } +} diff --git a/Src/Metrics.Tests/Core/DefaultContextTests.cs b/Src/Metrics.Tests/Core/DefaultContextTests.cs index d3bc0716..161388be 100644 --- a/Src/Metrics.Tests/Core/DefaultContextTests.cs +++ b/Src/Metrics.Tests/Core/DefaultContextTests.cs @@ -8,7 +8,7 @@ namespace Metrics.Tests.Core { public class DefaultContextTests { - private readonly MetricsContext context = new DefaultMetricsContext(); + private readonly DefaultMetricsContext context = new DefaultMetricsContext(); public MetricsData CurrentData { get { return this.context.DataProvider.CurrentMetricsData; } } [Fact] @@ -56,17 +56,20 @@ public void MetricsContext_MetricsArePresentInMetricsData() [Fact] public void MetricsContext_RaisesShutdownEventOnMetricsDisable() { - context.MonitorEvents(); + + var m = context.Monitor(); + context.Advanced.CompletelyDisableMetrics(); - context.ShouldRaise("ContextShuttingDown"); + + m.Should().Raise("ContextShuttingDown"); } [Fact] public void MetricsContext_RaisesShutdownEventOnDispose() { - context.MonitorEvents(); + var m = context.Monitor(); context.Dispose(); - context.ShouldRaise("ContextShuttingDown"); + m.Should().Raise("ContextShuttingDown"); } [Fact] @@ -125,7 +128,7 @@ public void MetricsContext_DowsNotThrowOnMetricsOfDifferentTypeWithSameName() context.Meter(name, Unit.Calls); context.Histogram(name, Unit.Calls); context.Timer(name, Unit.Calls); - })).ShouldNotThrow(); + })).Should().NotThrow(); } [Fact] diff --git a/Src/Metrics.Tests/Endpoints/FlotVisualizationTests.cs b/Src/Metrics.Tests/Endpoints/FlotVisualizationTests.cs index 418f0056..ed7877ab 100644 --- a/Src/Metrics.Tests/Endpoints/FlotVisualizationTests.cs +++ b/Src/Metrics.Tests/Endpoints/FlotVisualizationTests.cs @@ -1,5 +1,4 @@ using System; -using CsQuery; using FluentAssertions; using Metrics.Endpoints; using Xunit; @@ -13,9 +12,6 @@ public void FlotVisualization_CanReadAppFromResource() { var html = FlotWebApp.GetFlotApp(); html.Should().NotBeEmpty(); - - Action createHtml = () => CQ.CreateDocument(html); - createHtml.ShouldNotThrow(); } } } diff --git a/Src/Metrics.Tests/Endpoints/MetricsEndpointRequestTests.cs b/Src/Metrics.Tests/Endpoints/MetricsEndpointRequestTests.cs index fea86195..d67c9e35 100644 --- a/Src/Metrics.Tests/Endpoints/MetricsEndpointRequestTests.cs +++ b/Src/Metrics.Tests/Endpoints/MetricsEndpointRequestTests.cs @@ -11,7 +11,7 @@ public class MetricsEndpointRequestTests public void MetricsEndpointRequest_CannotCreateWithNullHeaders() { var action = new Action(() => new MetricsEndpointRequest(null)); - action.ShouldThrow(); + action.Should().Throw(); } } } diff --git a/Src/Metrics.Tests/Endpoints/MetricsEndpointResponseTests.cs b/Src/Metrics.Tests/Endpoints/MetricsEndpointResponseTests.cs index f45aecaf..ac5bb1a5 100644 --- a/Src/Metrics.Tests/Endpoints/MetricsEndpointResponseTests.cs +++ b/Src/Metrics.Tests/Endpoints/MetricsEndpointResponseTests.cs @@ -30,7 +30,7 @@ public void MetricsEndpointResponse_HasSaneDefaults() public void MetricsEndpointResponse_CannotCreateWithoutContent() { var action = new Action(() => new MetricsEndpointResponse(null, "content-type", Encoding.ASCII)); - action.ShouldThrow(); + action.Should().Throw(); } [Fact] @@ -39,23 +39,23 @@ public void MetricsEndpointResponse_CannotCreateWithInvalidContentType() var action1 = new Action(() => new MetricsEndpointResponse("content", null, Encoding.ASCII)); var action2 = new Action(() => new MetricsEndpointResponse("content", string.Empty, Encoding.ASCII)); var action3 = new Action(() => new MetricsEndpointResponse("content", " ", Encoding.ASCII)); - action1.ShouldThrow(); - action2.ShouldThrow(); - action3.ShouldThrow(); + action1.Should().Throw(); + action2.Should().Throw(); + action3.Should().Throw(); } [Fact] public void MetricsEndpointResponse_CannotCreateWithoutEncoding() { var action = new Action(() => new MetricsEndpointResponse("content", "content-type", null)); - action.ShouldThrow(); + action.Should().Throw(); } [Fact] public void MetricsEndpointResponse_CannotCreateWithoutStatusCodeDescription() { var action = new Action(() => new MetricsEndpointResponse("content", "content-type", Encoding.ASCII, 200, null)); - action.ShouldThrow(); + action.Should().Throw(); } } } diff --git a/Src/Metrics.Tests/Endpoints/MetricsEndpointTests.cs b/Src/Metrics.Tests/Endpoints/MetricsEndpointTests.cs index f1b45406..b8a048a1 100644 --- a/Src/Metrics.Tests/Endpoints/MetricsEndpointTests.cs +++ b/Src/Metrics.Tests/Endpoints/MetricsEndpointTests.cs @@ -15,9 +15,9 @@ public void MetricsEndpoint_CannotCreateWithEmptyPath() var action2 = new Action(() => new MetricsEndpoint(" ", c => new MetricsEndpointResponse("test", "text/plain"))); var action3 = new Action(() => new MetricsEndpoint("/", c => new MetricsEndpointResponse("test", "text/plain"))); - action1.ShouldThrow(); - action2.ShouldThrow(); - action3.ShouldThrow(); + action1.Should().Throw(); + action2.Should().Throw(); + action3.Should().Throw(); } [Fact] diff --git a/Src/Metrics.Tests/Endpoints/MetricsHttpListenerTests.cs b/Src/Metrics.Tests/Endpoints/MetricsHttpListenerTests.cs index 48272efc..90e389ed 100644 --- a/Src/Metrics.Tests/Endpoints/MetricsHttpListenerTests.cs +++ b/Src/Metrics.Tests/Endpoints/MetricsHttpListenerTests.cs @@ -81,7 +81,7 @@ public void MetricsHttpListener_MetricsConfig_SecondCallToWithHttpEndpointThrows using (var config = CreateConfig().WithHttpEndpoint("http://localhost:58888/metricstest/HttpListenerTests/sameendpoint/")) { var action = new Action(() => config.WithHttpEndpoint("http://localhost:58888/metricstest/HttpListenerTests/sameendpoint/")); - action.ShouldThrow(); + action.Should().Throw(); } } diff --git a/Src/Metrics.Tests/HealthChecksTests/HealthCheckRegistryTests.cs b/Src/Metrics.Tests/HealthChecksTests/HealthCheckRegistryTests.cs index 8f537043..8a59bea2 100644 --- a/Src/Metrics.Tests/HealthChecksTests/HealthCheckRegistryTests.cs +++ b/Src/Metrics.Tests/HealthChecksTests/HealthCheckRegistryTests.cs @@ -62,7 +62,7 @@ public void HealthCheck_RegistryDoesNotThrowOnDuplicateRegistration() HealthChecks.RegisterHealthCheck(new HealthCheck("test", () => { })); Action action = () => HealthChecks.RegisterHealthCheck(new HealthCheck("test", () => { })); - action.ShouldNotThrow(); + action.Should().NotThrow(); } } } diff --git a/Src/Metrics.Tests/Json/JsonSerializationTests.cs b/Src/Metrics.Tests/Json/JsonSerializationTests.cs index 76be964d..877214be 100644 --- a/Src/Metrics.Tests/Json/JsonSerializationTests.cs +++ b/Src/Metrics.Tests/Json/JsonSerializationTests.cs @@ -103,7 +103,7 @@ public void JsonSerialization_CanSerializeGauge() var result = JsonConvert.DeserializeObject(json); - result.Gauges.ShouldBeEquivalentTo(jsonContext.Gauges); + result.Gauges.Should().BeEquivalentTo(jsonContext.Gauges); } [Fact] @@ -122,7 +122,7 @@ public void JsonSerialization_CanSerializeCounter() var result = JsonConvert.DeserializeObject(json); - result.Counters.ShouldBeEquivalentTo(jsonContext.Counters); + result.Counters.Should().BeEquivalentTo(jsonContext.Counters); } [Fact] @@ -152,7 +152,7 @@ public void JsonSerialization_CanSerializeMeter() var result = JsonConvert.DeserializeObject(json); - result.Meters.ShouldBeEquivalentTo(jsonContext.Meters); + result.Meters.Should().BeEquivalentTo(jsonContext.Meters); } [Fact] @@ -191,7 +191,7 @@ public void JsonSerialization_CanSerializeHistogram() var result = JsonConvert.DeserializeObject(json); - result.Histograms.ShouldBeEquivalentTo(jsonContext.Histograms); + result.Histograms.Should().BeEquivalentTo(jsonContext.Histograms); } [Fact] @@ -208,7 +208,7 @@ public void JsonSerialization_CanSerializeTimer() var result = JsonConvert.DeserializeObject(json); - result.Histograms.ShouldBeEquivalentTo(jsonContext.Histograms); + result.Histograms.Should().BeEquivalentTo(jsonContext.Histograms); } } } diff --git a/Src/Metrics.Tests/Metrics.Tests.csproj b/Src/Metrics.Tests/Metrics.Tests.csproj index 9676d7cc..8f9cea32 100644 --- a/Src/Metrics.Tests/Metrics.Tests.csproj +++ b/Src/Metrics.Tests/Metrics.Tests.csproj @@ -1,189 +1,37 @@ - - - - - + - Debug - AnyCPU - {4E0F8CB9-6919-48B8-8212-BCE75D04E0D9} - Library - Properties - Metrics.Tests - Metrics.Tests - v4.5 - 512 - ..\..\ - true - 6d825ae5 + netcoreapp2.0 + false - - true - full - false - ..\..\bin\Debug\Tests\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\..\bin\Release\Tests\ - TRACE - prompt - 4 - - - - False - ..\..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll - - - False - ..\..\packages\FluentAssertions.3.3.0\lib\net45\FluentAssertions.dll - - - False - ..\..\packages\FluentAssertions.3.3.0\lib\net45\FluentAssertions.Core.dll - - - False - ..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - False - ..\..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll - - - False - ..\..\packages\Microsoft.Owin.Testing.3.0.1\lib\net45\Microsoft.Owin.Testing.dll - - - False - ..\..\packages\Nancy.1.2.0\lib\net40\Nancy.dll - - - False - ..\..\packages\Nancy.Testing.1.2.0\lib\net40\Nancy.Testing.dll - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - - - False - ..\..\packages\Owin.1.0\lib\net40\Owin.dll - - - - - - False - ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll - - - False - ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - - - False - ..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll - - - - - - - - ..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll - - - ..\..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll - - - ..\..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll - - + + + + + + - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - {fbff51d8-52f4-4eef-8498-122a14b37d6c} - Nancy.Metrics + + {8AD2C970-EC7F-405B-B267-9F0C1AAD7CC4} + AspNetCore.Metrics + - {025cd6d0-1a1e-4b14-a7db-af5dff887210} + {025CD6D0-1A1E-4B14-A7DB-AF5DFF887210} Owin.Metrics - {95e29d40-dbec-49e2-9cc5-26b88966dade} + {95E29D40-DBEC-49E2-9CC5-26B88966DADE} Metrics - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - \ No newline at end of file diff --git a/Src/Metrics.Tests/Metrics/TimerMetricTests.cs b/Src/Metrics.Tests/Metrics/TimerMetricTests.cs index df8cadbd..3945136d 100644 --- a/Src/Metrics.Tests/Metrics/TimerMetricTests.cs +++ b/Src/Metrics.Tests/Metrics/TimerMetricTests.cs @@ -36,7 +36,7 @@ public void TimerMetric_CountsEvenIfActionThrows() { Action action = () => this.timer.Time(() => { throw new InvalidOperationException(); }); - action.ShouldThrow(); + action.Should().Throw(); this.timer.Value.Rate.Count.Should().Be(1); } diff --git a/Src/Metrics.Tests/NancyAdapter/NancyAdapterGlobalMetrics.cs b/Src/Metrics.Tests/NancyAdapter/NancyAdapterGlobalMetrics.cs index b9584f76..b06b0941 100644 --- a/Src/Metrics.Tests/NancyAdapter/NancyAdapterGlobalMetrics.cs +++ b/Src/Metrics.Tests/NancyAdapter/NancyAdapterGlobalMetrics.cs @@ -14,8 +14,8 @@ public class ActiveRequestsModule : NancyModule public ActiveRequestsModule(Task trigger, TaskCompletionSource request1, TaskCompletionSource request2) : base("/concurrent") { - Get["/request1"] = _ => { request1.SetResult(0); Task.WaitAll(trigger); return HttpStatusCode.OK; }; - Get["/request2"] = _ => { request2.SetResult(0); Task.WaitAll(trigger); return HttpStatusCode.OK; }; + Get("/request1", _ => { request1.SetResult(0); Task.WaitAll(trigger); return HttpStatusCode.OK; }); + Get("/request2", _ => { request2.SetResult(0); Task.WaitAll(trigger); return HttpStatusCode.OK; }); } } @@ -24,31 +24,31 @@ public class TestModule : NancyModule public TestModule(TestClock clock) : base("/test") { - Get["/action"] = _ => + Get("/action", _ => { clock.Advance(TimeUnit.Milliseconds, 100); return Response.AsText("response"); - }; + }); - Post["/post"] = _ => + Post("/post", _ => { clock.Advance(TimeUnit.Milliseconds, 200); return HttpStatusCode.OK; - }; + }); - Put["/put"] = _ => + Put("/put", _ => { clock.Advance(TimeUnit.Milliseconds, 200); return HttpStatusCode.OK; - }; + }); - Patch["/patch"] = _ => + Patch("/patch", _ => { clock.Advance(TimeUnit.Milliseconds, 200); return HttpStatusCode.OK; - }; + }); - Get["/error"] = _ => { throw new InvalidOperationException(); }; + Get("/error",_ => { throw new InvalidOperationException(); }); } } @@ -77,11 +77,11 @@ public NancyAdapterGlobalMetrics() } [Fact] - public void NancyMetrics_ShouldBeAbleToRecordTimeForAllRequests() + public async Task NancyMetrics_ShouldBeAbleToRecordTimeForAllRequests() { this.context.TimerValue("NancyFx", "Requests").Rate.Count.Should().Be(0); - browser.Get("/test/action").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Get("/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); var timer = this.context.TimerValue("NancyFx", "Requests"); @@ -91,7 +91,7 @@ public void NancyMetrics_ShouldBeAbleToRecordTimeForAllRequests() timer.Histogram.Max.Should().Be(100); timer.Histogram.Min.Should().Be(100); - browser.Post("/test/post").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Post("/test/post")).StatusCode.Should().Be(HttpStatusCode.OK); timer = this.context.TimerValue("NancyFx", "Requests"); @@ -103,59 +103,60 @@ public void NancyMetrics_ShouldBeAbleToRecordTimeForAllRequests() } [Fact] - public void NancyMetrics_ShouldBeAbleToCountErrors() + public async Task NancyMetrics_ShouldBeAbleToCountErrors() { this.context.MeterValue("NancyFx", "Errors").Count.Should().Be(0); - Assert.Throws(() => browser.Get("/test/error")); + await Assert.ThrowsAsync(() => browser.Get("/test/error")); this.context.MeterValue("NancyFx", "Errors").Count.Should().Be(1); - Assert.Throws(() => browser.Get("/test/error")); + await Assert.ThrowsAsync(() => browser.Get("/test/error")); this.context.MeterValue("NancyFx", "Errors").Count.Should().Be(2); } [Fact] - public void NancyMetrics_ShouldBeAbleToCountActiveRequests() + public async Task NancyMetrics_ShouldBeAbleToCountActiveRequests() { this.context.CounterValue("NancyFx", "Active Requests").Count.Should().Be(0); - var request1 = Task.Factory.StartNew(() => browser.Get("/concurrent/request1")); + var request1 = Task.Run(() => browser.Get("/concurrent/request1")); - result1.Task.Wait(); + await result1.Task; this.context.CounterValue("NancyFx", "Active Requests").Count.Should().Be(1); - var request2 = Task.Factory.StartNew(() => browser.Get("/concurrent/request2")); - result2.Task.Wait(); + var request2 = Task.Run(() => browser.Get("/concurrent/request2")); + + await result2.Task; this.context.CounterValue("NancyFx", "Active Requests").Count.Should().Be(2); requestTrigger.SetResult(0); - Task.WaitAll(request1, request2); + await Task.WhenAll(request1, request2); this.context.CounterValue("NancyFx", "Active Requests").Count.Should().Be(0); } [Fact] - public void NancyMetrics_ShoulBeAbleToRecordPostPutAndPatchRequestSize() + public async Task NancyMetrics_ShoulBeAbleToRecordPostPutAndPatchRequestSize() { this.context.HistogramValue("NancyFx", "Post, Put & Patch Request Size").Count.Should().Be(0); - browser.Get("/test/action").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Get("/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); this.context.HistogramValue("NancyFx", "Post, Put & Patch Request Size").Count.Should().Be(0); - browser.Post("/test/post", ctx => + (await browser.Post("/test/post", ctx => { ctx.Header("Content-Length", "content".Length.ToString()); ctx.Body("content"); - }).StatusCode.Should().Be(HttpStatusCode.OK); + })).StatusCode.Should().Be(HttpStatusCode.OK); - browser.Put("/test/put", ctx => + (await browser.Put("/test/put", ctx => { ctx.Header("Content-Length", "content".Length.ToString()); ctx.Body("content"); - }).StatusCode.Should().Be(HttpStatusCode.OK); + })).StatusCode.Should().Be(HttpStatusCode.OK); - browser.Patch("/test/patch", ctx => + (await browser.Patch("/test/patch", ctx => { ctx.Header("Content-Length", "content".Length.ToString()); ctx.Body("content"); - }).StatusCode.Should().Be(HttpStatusCode.OK); + })).StatusCode.Should().Be(HttpStatusCode.OK); this.context.HistogramValue("NancyFx", "Post, Put & Patch Request Size").Count.Should().Be(3); this.context.HistogramValue("NancyFx", "Post, Put & Patch Request Size").Min.Should().Be("content".Length); @@ -163,18 +164,18 @@ public void NancyMetrics_ShoulBeAbleToRecordPostPutAndPatchRequestSize() } [Fact] - public void NancyMetrics_ShouldBeAbleToRecordTimeForEachRequests() + public async Task NancyMetrics_ShouldBeAbleToRecordTimeForEachRequests() { this.context.TimerValue("NancyFx", "Requests").Rate.Count.Should().Be(0); - browser.Get("/test/action").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Get("/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); var timer = this.context.TimerValue("NancyFx", "GET /test/action"); timer.Rate.Count.Should().Be(1); timer.Histogram.Count.Should().Be(1); - browser.Post("/test/post").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Post("/test/post")).StatusCode.Should().Be(HttpStatusCode.OK); timer = this.context.TimerValue("NancyFx", "POST /test/post"); diff --git a/Src/Metrics.Tests/NancyAdapter/NancyAdapterModuleMetricsTests.cs b/Src/Metrics.Tests/NancyAdapter/NancyAdapterModuleMetricsTests.cs index 1fe37649..d4e4b41b 100644 --- a/Src/Metrics.Tests/NancyAdapter/NancyAdapterModuleMetricsTests.cs +++ b/Src/Metrics.Tests/NancyAdapter/NancyAdapterModuleMetricsTests.cs @@ -1,4 +1,5 @@ -using FluentAssertions; +using System.Threading.Tasks; +using FluentAssertions; using Nancy; using Nancy.Metrics; using Nancy.Testing; @@ -16,19 +17,19 @@ public TestModule(TestClock clock) this.MetricForRequestTimeAndResponseSize("Action Request", "Get", "/"); this.MetricForRequestSize("Request Size", "Put", "/"); - Get["/action"] = _ => + Get("/action", _ => { clock.Advance(TimeUnit.Milliseconds, 100); return Response.AsText("response"); - }; + }); - Get["/contentWithLength"] = _ => + Get("/contentWithLength", _ => { clock.Advance(TimeUnit.Milliseconds, 100); return Response.AsText("response").WithHeader("Content-Length", "100"); - }; + }); - Put["/size"] = _ => HttpStatusCode.OK; + Put("/size", _ => HttpStatusCode.OK); } } @@ -51,10 +52,10 @@ public NancyAdapterModuleMetricsTests() } [Fact] - public void NancyMetrics_ShouldBeAbleToMonitorTimeForModuleRequest() + public async Task NancyMetrics_ShouldBeAbleToMonitorTimeForModuleRequest() { this.context.TimerValue("NancyFx", "Action Request").Rate.Count.Should().Be(0); - browser.Get("/test/action").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Get("/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); var timer = this.context.TimerValue("NancyFx", "Action Request"); @@ -64,9 +65,9 @@ public void NancyMetrics_ShouldBeAbleToMonitorTimeForModuleRequest() } [Fact] - public void NancyMetrics_ShouldBeAbleToMonitorSizeForRouteReponse() + public async Task NancyMetrics_ShouldBeAbleToMonitorSizeForRouteReponse() { - browser.Get("/test/action").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Get("/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); var sizeHistogram = this.context.HistogramValue("NancyFx", "Action Request"); @@ -74,7 +75,7 @@ public void NancyMetrics_ShouldBeAbleToMonitorSizeForRouteReponse() sizeHistogram.Min.Should().Be("response".Length); sizeHistogram.Max.Should().Be("response".Length); - browser.Get("/test/contentWithLength").StatusCode.Should().Be(HttpStatusCode.OK); + (await browser.Get("/test/contentWithLength")).StatusCode.Should().Be(HttpStatusCode.OK); sizeHistogram = this.context.HistogramValue("NancyFx", "Action Request"); @@ -84,15 +85,15 @@ public void NancyMetrics_ShouldBeAbleToMonitorSizeForRouteReponse() } [Fact] - public void NancyMetrics_ShouldBeAbleToMonitorSizeForRequest() + public async Task NancyMetrics_ShouldBeAbleToMonitorSizeForRequest() { this.context.HistogramValue("NancyFx", "Request Size").Count.Should().Be(0); - browser.Put("/test/size", ctx => + (await browser.Put("/test/size", ctx => { ctx.Header("Content-Length", "content".Length.ToString()); ctx.Body("content"); - }).StatusCode.Should().Be(HttpStatusCode.OK); + })).StatusCode.Should().Be(HttpStatusCode.OK); var sizeHistogram = this.context.HistogramValue("NancyFx", "Request Size"); diff --git a/Src/Metrics.Tests/OwinAdapter/OwinMiddlewareTests.cs b/Src/Metrics.Tests/OwinAdapter/OwinMiddlewareTests.cs index 94bf0aec..42fa8fbb 100644 --- a/Src/Metrics.Tests/OwinAdapter/OwinMiddlewareTests.cs +++ b/Src/Metrics.Tests/OwinAdapter/OwinMiddlewareTests.cs @@ -1,69 +1,94 @@ -using System.Net; +using System; +using System.Collections.Generic; +using System.Net; using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; -using Microsoft.Owin.Testing; -using Owin; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.TestHost; using Owin.Metrics; using Xunit; namespace Metrics.Tests.OwinAdapter { - public class OwinMiddlewareTests + using AppFunc = Func, Task>; + + using OwinPipeline = Action, Task>, Func, Task>>>; + + +public class OwinMiddlewareTests { + + private const int timePerRequest = 100; private readonly TestContext context = new TestContext(); private readonly MetricsConfig config; private readonly TestServer server; + private AppFunc DoNothing(AppFunc f) + { + return f; + } + + void RunPipeline(OwinPipeline pipeline) + { + pipeline(DoNothing); + } + public OwinMiddlewareTests() { this.config = new MetricsConfig(this.context); - this.server = TestServer.Create(app => - { - this.config.WithOwin(m => app.Use(m)); - - app.Run(ctx => + var builder = new WebHostBuilder() + .Configure(app => { - this.context.Clock.Advance(TimeUnit.Milliseconds, timePerRequest); - if (ctx.Request.Path.ToString() == "/test/action") - { - return ctx.Response.WriteAsync("response"); - } - - if (ctx.Request.Path.ToString() == "/test/error") - { - ctx.Response.StatusCode = 500; - return ctx.Response.WriteAsync("response"); - } + this.config.WithOwin(m => app.UseOwin(cfg => cfg(m))); - if (ctx.Request.Path.ToString() == "/test/size") + app.Run(ctx => { - return ctx.Response.WriteAsync("response"); - } + this.context.Clock.Advance(TimeUnit.Milliseconds, timePerRequest); + if (ctx.Request.Path.ToString() == "/test/action") + { + return ctx.Response.WriteAsync("response"); + } + + if (ctx.Request.Path.ToString() == "/test/error") + { + ctx.Response.StatusCode = 500; + return ctx.Response.WriteAsync("response"); + } + + if (ctx.Request.Path.ToString() == "/test/size") + { + return ctx.Response.WriteAsync("response"); + } + + if (ctx.Request.Path.ToString() == "/test/post") + { + return ctx.Response.WriteAsync("response"); + } + + ctx.Response.StatusCode = 404; + return ctx.Response.WriteAsync("not found"); + }); - if (ctx.Request.Path.ToString() == "/test/post") - { - return ctx.Response.WriteAsync("response"); - } - - ctx.Response.StatusCode = 404; - return ctx.Response.WriteAsync("not found"); }); - - }); + + this.server = new TestServer(builder); } + [Fact] public async Task OwinMetrics_ShouldBeAbleToRecordErrors() { context.MeterValue("Owin", "Errors").Count.Should().Be(0); - (await server.HttpClient.GetAsync("http://local.test/test/error")).StatusCode.Should().Be(HttpStatusCode.InternalServerError); + (await server.CreateRequest("http://local.test/test/error").GetAsync()).StatusCode.Should().Be(HttpStatusCode.InternalServerError); context.MeterValue("Owin", "Errors").Count.Should().Be(1); - (await server.HttpClient.GetAsync("http://local.test/test/error")).StatusCode.Should().Be(HttpStatusCode.InternalServerError); + (await server.CreateRequest("http://local.test/test/error").GetAsync()).StatusCode.Should().Be(HttpStatusCode.InternalServerError); context.MeterValue("Owin", "Errors").Count.Should().Be(2); } @@ -71,13 +96,13 @@ public async Task OwinMetrics_ShouldBeAbleToRecordErrors() public async Task OwinMetrics_ShouldBeAbleToRecordActiveRequestCounts() { context.TimerValue("Owin", "Requests").Rate.Count.Should().Be(0); - (await server.HttpClient.GetAsync("http://local.test/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); + (await server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); context.TimerValue("Owin", "Requests").Rate.Count.Should().Be(1); - (await server.HttpClient.GetAsync("http://local.test/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); + (await server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); context.TimerValue("Owin", "Requests").Rate.Count.Should().Be(2); - (await server.HttpClient.GetAsync("http://local.test/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); + (await server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); context.TimerValue("Owin", "Requests").Rate.Count.Should().Be(3); - (await server.HttpClient.GetAsync("http://local.test/test/action")).StatusCode.Should().Be(HttpStatusCode.OK); + (await server.CreateRequest("http://local.test/test/action").GetAsync()).StatusCode.Should().Be(HttpStatusCode.OK); context.TimerValue("Owin", "Requests").Rate.Count.Should().Be(4); var timer = context.TimerValue("Owin", "Requests"); @@ -93,7 +118,7 @@ public async Task OwinMetrics_ShouldRecordHistogramMetricsForPostSizeAndTimePerR const string json = "{ 'id': '1'} "; var postContent = new StringContent(json); postContent.Headers.Add("Content-Length", json.Length.ToString()); - await server.HttpClient.PostAsync("http://local.test/test/post", postContent); + await server.CreateRequest("http://local.test/test/post").And(r => r.Content = postContent).PostAsync(); var histogram = context.HistogramValue("Owin", "Post & Put Request Size"); diff --git a/Src/Metrics.Tests/Properties/AssemblyInfo.cs b/Src/Metrics.Tests/Properties/AssemblyInfo.cs index 18adf984..e4023b3b 100644 --- a/Src/Metrics.Tests/Properties/AssemblyInfo.cs +++ b/Src/Metrics.Tests/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Reflection; -[assembly: AssemblyTitle("Metrics.Tests")] -[assembly: AssemblyDescription("Metrics.NET Tests")] +// TODO : migrate to csproj +//[assembly: AssemblyTitle("Metrics.Tests")] +//[assembly: AssemblyDescription("Metrics.NET Tests")] diff --git a/Src/Metrics.Tests/Sampling/UniformSnapshotTests.cs b/Src/Metrics.Tests/Sampling/UniformSnapshotTests.cs index 0fd22e33..22e0aeeb 100644 --- a/Src/Metrics.Tests/Sampling/UniformSnapshotTests.cs +++ b/Src/Metrics.Tests/Sampling/UniformSnapshotTests.cs @@ -132,9 +132,9 @@ public void UniformSnapshot_CalculatesAStdDevOfZeroForASingletonSnapshot() [Fact] public void UniformSnapshot_ThrowsOnBadQuantileValue() { - ((Action)(() => snapshot.GetValue(-0.5))).ShouldThrow(); - ((Action)(() => snapshot.GetValue(1.5))).ShouldThrow(); - ((Action)(() => snapshot.GetValue(double.NaN))).ShouldThrow(); + ((Action)(() => snapshot.GetValue(-0.5))).Should().Throw(); + ((Action)(() => snapshot.GetValue(1.5))).Should().Throw(); + ((Action)(() => snapshot.GetValue(double.NaN))).Should().Throw(); } } } diff --git a/Src/Metrics.Tests/Sampling/WeightedSnapshotTests.cs b/Src/Metrics.Tests/Sampling/WeightedSnapshotTests.cs index 6e707455..85e65556 100644 --- a/Src/Metrics.Tests/Sampling/WeightedSnapshotTests.cs +++ b/Src/Metrics.Tests/Sampling/WeightedSnapshotTests.cs @@ -145,9 +145,9 @@ public void WeightedSnapshot_CalculatesAStdDevOfZeroForASingletonSnapshot() [Fact] public void WeightedSnapshot_ThrowsOnBadQuantileValue() { - ((Action)(() => snapshot.GetValue(-0.5))).ShouldThrow(); - ((Action)(() => snapshot.GetValue(1.5))).ShouldThrow(); - ((Action)(() => snapshot.GetValue(double.NaN))).ShouldThrow(); + ((Action)(() => snapshot.GetValue(-0.5))).Should().Throw(); + ((Action)(() => snapshot.GetValue(1.5))).Should().Throw(); + ((Action)(() => snapshot.GetValue(double.NaN))).Should().Throw(); } } } diff --git a/Src/Metrics.Tests/TestMetricsBuilder.cs b/Src/Metrics.Tests/TestMetricsBuilder.cs index 2d7e23cc..52b85ff8 100644 --- a/Src/Metrics.Tests/TestMetricsBuilder.cs +++ b/Src/Metrics.Tests/TestMetricsBuilder.cs @@ -1,7 +1,6 @@ using System; using Metrics.Core; using Metrics.MetricData; -using Metrics.PerfCounters; using Metrics.Sampling; using Metrics.Utils; @@ -18,11 +17,18 @@ public TestMetricsBuilder(Clock clock, Scheduler scheduler) this.scheduler = scheduler; } +#if NET45 public MetricValueProvider BuildPerformanceCounter(string name, Unit unit, string counterCategory, string counterName, string counterInstance) { - return new PerformanceCounterGauge(counterCategory, counterName, counterInstance); + return new Metrics.PerfCounters.PerformanceCounterGauge(counterCategory, counterName, counterInstance); } - +#else + public MetricValueProvider BuildPerformanceCounter(string name, Unit unit, string counterCategory, string counterName, string counterInstance) + { + throw new NotSupportedException(); + } +#endif + public MetricValueProvider BuildGauge(string name, Unit unit, Func valueProvider) { return new FunctionGauge(valueProvider); diff --git a/Src/Metrics.Tests/Utils/ActionSchedulerTests.cs b/Src/Metrics.Tests/Utils/ActionSchedulerTests.cs index 9ea8c058..e3bca171 100644 --- a/Src/Metrics.Tests/Utils/ActionSchedulerTests.cs +++ b/Src/Metrics.Tests/Utils/ActionSchedulerTests.cs @@ -127,7 +127,7 @@ public void ActionScheduler_ReportsExceptionWithGlobalMetricHandler() public void ActionScheduler_CannotCreateWithInvalidParameter() { var action = new Action(() => new ActionScheduler(-2)); - action.ShouldThrow(); + action.Should().Throw(); } [Fact] diff --git a/Src/Metrics.Tests/packages.config b/Src/Metrics.Tests/packages.config deleted file mode 100644 index 666e3095..00000000 --- a/Src/Metrics.Tests/packages.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Metrics/Core/BaseMetricsContext.cs b/Src/Metrics/Core/BaseMetricsContext.cs index 36a39857..8d9d528e 100644 --- a/Src/Metrics/Core/BaseMetricsContext.cs +++ b/Src/Metrics/Core/BaseMetricsContext.cs @@ -80,76 +80,80 @@ public void ShutdownContext(string contextName) } } - public void PerformanceCounter(string name, string counterCategory, string counterName, string counterInstance, Unit unit, MetricTags tags) + public void PerformanceCounter(string name, string counterCategory, string counterName, string counterInstance, Unit unit, MetricTags tags = default(MetricTags)) { this.Gauge(name, () => this.metricsBuilder.BuildPerformanceCounter(name, unit, counterCategory, counterName, counterInstance), unit, tags); } - public void Gauge(string name, Func valueProvider, Unit unit, MetricTags tags) + public void Gauge(string name, Func valueProvider, Unit unit, MetricTags tags = default(MetricTags)) { this.Gauge(name, () => this.metricsBuilder.BuildGauge(name, unit, valueProvider), unit, tags); } - public void Gauge(string name, Func> valueProvider, Unit unit, MetricTags tags) + public void Gauge(string name, Func> valueProvider, Unit unit, MetricTags tags = default(MetricTags)) { this.registry.Gauge(name, valueProvider, unit, tags); } - - public Counter Counter(string name, Unit unit, MetricTags tags) + public Counter Counter(string name, Unit unit, MetricTags tags = default(MetricTags)) { return this.Counter(name, unit, () => this.metricsBuilder.BuildCounter(name, unit), tags); } - public Counter Counter(string name, Unit unit, Func builder, MetricTags tags) + public Counter Counter(string name, Unit unit, Func builder,MetricTags tags = default(MetricTags)) where T : CounterImplementation { return this.registry.Counter(name, builder, unit, tags); } - public Meter Meter(string name, Unit unit, TimeUnit rateUnit, MetricTags tags) + public Meter Meter(string name, Unit unit, TimeUnit rateUnit = TimeUnit.Seconds, MetricTags tags = default(MetricTags)) { return this.Meter(name, unit, () => this.metricsBuilder.BuildMeter(name, unit, rateUnit), rateUnit, tags); } - public Meter Meter(string name, Unit unit, Func builder, TimeUnit rateUnit, MetricTags tags) + public Meter Meter(string name, Unit unit, Func builder, TimeUnit rateUnit = TimeUnit.Seconds, MetricTags tags = default(MetricTags)) where T : MeterImplementation { return this.registry.Meter(name, builder, unit, rateUnit, tags); } - public Histogram Histogram(string name, Unit unit, SamplingType samplingType, MetricTags tags) + public Histogram Histogram(string name, Unit unit, SamplingType samplingType = SamplingType.Default, MetricTags tags = default(MetricTags)) { return this.Histogram(name, unit, () => this.metricsBuilder.BuildHistogram(name, unit, samplingType), tags); } - public Histogram Histogram(string name, Unit unit, Func builder, MetricTags tags) + public Histogram Histogram(string name, Unit unit, Func builder, MetricTags tags = default(MetricTags)) where T : HistogramImplementation { return this.registry.Histogram(name, builder, unit, tags); } - public Histogram Histogram(string name, Unit unit, Func builder, MetricTags tags) + public Histogram Histogram(string name, Unit unit, Func builder, MetricTags tags = default(MetricTags)) { return Histogram(name, unit, () => this.metricsBuilder.BuildHistogram(name, unit, builder()), tags); } - public Timer Timer(string name, Unit unit, SamplingType samplingType, TimeUnit rateUnit, TimeUnit durationUnit, MetricTags tags) + public Timer Timer(string name, + Unit unit, + SamplingType samplingType = SamplingType.Default, + TimeUnit rateUnit = TimeUnit.Seconds, + TimeUnit durationUnit = TimeUnit.Milliseconds, + MetricTags tags = default(MetricTags)) { return this.registry.Timer(name, () => this.metricsBuilder.BuildTimer(name, unit, rateUnit, durationUnit, samplingType), unit, rateUnit, durationUnit, tags); } - public Timer Timer(string name, Unit unit, Func builder, TimeUnit rateUnit, TimeUnit durationUnit, MetricTags tags) + public Timer Timer(string name, Unit unit, Func builder, TimeUnit rateUnit = TimeUnit.Seconds, TimeUnit durationUnit = TimeUnit.Milliseconds, MetricTags tags = default(MetricTags)) where T : TimerImplementation { return this.registry.Timer(name, builder, unit, rateUnit, durationUnit, tags); } - public Timer Timer(string name, Unit unit, Func builder, TimeUnit rateUnit, TimeUnit durationUnit, MetricTags tags) + public Timer Timer(string name, Unit unit, Func builder, TimeUnit rateUnit = TimeUnit.Seconds, TimeUnit durationUnit = TimeUnit.Milliseconds, MetricTags tags = default(MetricTags)) { return this.Timer(name, unit, () => this.metricsBuilder.BuildTimer(name, unit, rateUnit, durationUnit, builder()), rateUnit, durationUnit, tags); } - public Timer Timer(string name, Unit unit, Func builder, TimeUnit rateUnit, TimeUnit durationUnit, MetricTags tags) + public Timer Timer(string name, Unit unit, Func builder, TimeUnit rateUnit = TimeUnit.Seconds, TimeUnit durationUnit = TimeUnit.Milliseconds, MetricTags tags = default(MetricTags)) { return this.Timer(name, unit, () => this.metricsBuilder.BuildTimer(name, unit, rateUnit, durationUnit, builder()), rateUnit, durationUnit, tags); } diff --git a/Src/Metrics/Core/DefaultMetricsBuilder.cs b/Src/Metrics/Core/DefaultMetricsBuilder.cs index fff783ef..f7a0db20 100644 --- a/Src/Metrics/Core/DefaultMetricsBuilder.cs +++ b/Src/Metrics/Core/DefaultMetricsBuilder.cs @@ -1,17 +1,22 @@  using System; using Metrics.MetricData; -using Metrics.PerfCounters; using Metrics.Sampling; namespace Metrics.Core { public sealed class DefaultMetricsBuilder : MetricsBuilder { +#if NET45 public MetricValueProvider BuildPerformanceCounter(string name, Unit unit, string counterCategory, string counterName, string counterInstance) { - return new PerformanceCounterGauge(counterCategory, counterName, counterInstance); + return new Metrics.PerfCounters.PerformanceCounterGauge(counterCategory, counterName, counterInstance); } - +#else + public MetricValueProvider BuildPerformanceCounter(string name, Unit unit, string counterCategory, string counterName, string counterInstance) + { + throw new NotSupportedException(); + } +#endif public MetricValueProvider BuildGauge(string name, Unit unit, Func valueProvider) { return new FunctionGauge(valueProvider); diff --git a/Src/Metrics/Endpoints/MetricsHttpListener.cs b/Src/Metrics/Endpoints/MetricsHttpListener.cs index d63fae8c..bbdccf48 100644 --- a/Src/Metrics/Endpoints/MetricsHttpListener.cs +++ b/Src/Metrics/Endpoints/MetricsHttpListener.cs @@ -13,7 +13,7 @@ namespace Metrics.Endpoints { public sealed class MetricsHttpListener : IDisposable { - private static readonly ILog log = LogProvider.GetCurrentClassLogger(); + private static readonly ILog log = LogProvider.GetLogger(typeof(MetricsHttpListener)); private const string NotFoundResponse = "Resource not found"; private readonly HttpListener httpListener; diff --git a/Src/Metrics/Metric.cs b/Src/Metrics/Metric.cs index 2c333194..ebbb4d09 100644 --- a/Src/Metrics/Metric.cs +++ b/Src/Metrics/Metric.cs @@ -13,7 +13,7 @@ namespace Metrics /// public static class Metric { - private static readonly ILog log = LogProvider.GetCurrentClassLogger(); + private static readonly ILog log = LogProvider.GetLogger(typeof(Metric)); private static readonly DefaultMetricsContext globalContext; private static readonly MetricsConfig config; diff --git a/Src/Metrics/Metrics.csproj b/Src/Metrics/Metrics.csproj index 78300f91..1275e587 100644 --- a/Src/Metrics/Metrics.csproj +++ b/Src/Metrics/Metrics.csproj @@ -1,216 +1,24 @@ - - - + - Debug - AnyCPU - {95E29D40-DBEC-49E2-9CC5-26B88966DADE} - Library - Properties - Metrics - Metrics - v4.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - - - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - true - ..\..\bin\Release\Metrics.XML - 1591; 1570; 1587; + netstandard2.0 + LIBLOG_PORTABLE + + + + + + - - - - + + + + - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - Code - - - Code - - - - - - Code - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - Endpoints\metrics_32.png - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Src/Metrics/MetricsConfig.cs b/Src/Metrics/MetricsConfig.cs index 41c30bb8..6e3b1c76 100644 --- a/Src/Metrics/MetricsConfig.cs +++ b/Src/Metrics/MetricsConfig.cs @@ -13,7 +13,7 @@ namespace Metrics { public sealed class MetricsConfig : IDisposable, Utils.IHideObjectMembers { - private static readonly ILog log = LogProvider.GetCurrentClassLogger(); + private static readonly ILog log = LogProvider.GetLogger(typeof(MetricsConfig)); public static readonly bool GloballyDisabledMetrics = ReadGloballyDisableMetricsSetting(); diff --git a/Src/Metrics/MetricsErrorHandler.cs b/Src/Metrics/MetricsErrorHandler.cs index 2a3b068a..af5091f3 100644 --- a/Src/Metrics/MetricsErrorHandler.cs +++ b/Src/Metrics/MetricsErrorHandler.cs @@ -7,7 +7,7 @@ namespace Metrics { public class MetricsErrorHandler { - private static readonly ILog log = LogProvider.GetCurrentClassLogger(); + private static readonly ILog log = LogProvider.GetLogger(typeof(MetricsErrorHandler)); private static readonly Meter errorMeter = Metric.Internal.Meter("Metrics Errors", Unit.Errors); private readonly ConcurrentBag> handlers = new ConcurrentBag>(); diff --git a/Src/Metrics/PerfCounters/PerformanceCounterGauge.cs b/Src/Metrics/PerfCounters/PerformanceCounterGauge.cs index c06e7fdb..be868021 100644 --- a/Src/Metrics/PerfCounters/PerformanceCounterGauge.cs +++ b/Src/Metrics/PerfCounters/PerformanceCounterGauge.cs @@ -1,4 +1,6 @@ -using Metrics.MetricData; +#if NET45 + +using Metrics.MetricData; using System; using System.Diagnostics; using System.Security.Principal; @@ -66,3 +68,4 @@ public double Value } } } +#endif \ No newline at end of file diff --git a/Src/Metrics/PerfCounters/PerformanceCounters.cs b/Src/Metrics/PerfCounters/PerformanceCounters.cs index deb2fe24..0f17d1f9 100644 --- a/Src/Metrics/PerfCounters/PerformanceCounters.cs +++ b/Src/Metrics/PerfCounters/PerformanceCounters.cs @@ -1,4 +1,5 @@ - +#if NET45 + using Metrics.Core; using Metrics.Logging; using System; @@ -157,3 +158,4 @@ private static void WrappedRegister(MetricsContext context, string name, Unit un } } } +#endif \ No newline at end of file diff --git a/Src/Metrics/PerfCounters/PerformanceCountersConfigExtensions.cs b/Src/Metrics/PerfCounters/PerformanceCountersConfigExtensions.cs index 9699a726..c6df417e 100644 --- a/Src/Metrics/PerfCounters/PerformanceCountersConfigExtensions.cs +++ b/Src/Metrics/PerfCounters/PerformanceCountersConfigExtensions.cs @@ -1,4 +1,5 @@ -using Metrics.PerfCounters; +#if NET45 +using Metrics.PerfCounters; namespace Metrics { @@ -45,3 +46,4 @@ public static MetricsConfig WithAppCounters(this MetricsConfig config, string co } } } +#endif \ No newline at end of file diff --git a/Src/Metrics/PerfCounters/ThreadPoolMetrics.cs b/Src/Metrics/PerfCounters/ThreadPoolMetrics.cs index 994760af..28d22a81 100644 --- a/Src/Metrics/PerfCounters/ThreadPoolMetrics.cs +++ b/Src/Metrics/PerfCounters/ThreadPoolMetrics.cs @@ -1,4 +1,5 @@ -using System; +#if NET45 +using System; using System.Diagnostics; using System.Threading; @@ -25,3 +26,4 @@ internal static void RegisterThreadPoolGauges(MetricsContext context) } } } +#endif diff --git a/Src/Metrics/Properties/AssemblyInfo.cs b/Src/Metrics/Properties/AssemblyInfo.cs deleted file mode 100644 index dadb3805..00000000 --- a/Src/Metrics/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Reflection; - -[assembly: AssemblyTitle("Metrics.NET")] -[assembly: AssemblyDescription("Metrics monitoring and reporting library")] \ No newline at end of file diff --git a/Src/Metrics/RemoteMetrics/RemoteMetricsExtensions.cs b/Src/Metrics/RemoteMetrics/RemoteMetricsExtensions.cs index 40e2ee2b..626cf016 100644 --- a/Src/Metrics/RemoteMetrics/RemoteMetricsExtensions.cs +++ b/Src/Metrics/RemoteMetrics/RemoteMetricsExtensions.cs @@ -9,7 +9,7 @@ public static class RemoteMetricsExtensions private static Func jsonDeserializer; - public static MetricsConfig WithJsonDeserialzier(this MetricsConfig config, Func jsonDeserializer) + public static MetricsConfig WithJsonDeserializer(this MetricsConfig config, Func jsonDeserializer) { RemoteMetricsExtensions.jsonDeserializer = jsonDeserializer; return config; diff --git a/Src/Metrics/Utils/AppEnvironment.cs b/Src/Metrics/Utils/AppEnvironment.cs index 675851f1..b6044032 100644 --- a/Src/Metrics/Utils/AppEnvironment.cs +++ b/Src/Metrics/Utils/AppEnvironment.cs @@ -12,7 +12,7 @@ namespace Metrics.Utils { public static class AppEnvironment { - private static readonly ILog log = LogProvider.GetCurrentClassLogger(); + private static readonly ILog log = LogProvider.GetLogger(typeof(AppEnvironment)); public static IEnumerable Current { diff --git a/Src/Metrics/packages.config b/Src/Metrics/packages.config deleted file mode 100644 index ac15f9aa..00000000 --- a/Src/Metrics/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file