From aba7241dce6a54441ddf725d41250c2a1390852b Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Sat, 19 Nov 2016 22:59:58 -0500 Subject: [PATCH] all the core support :tada: --- .gitignore | 3 +- README.md | 9 +- .../LogLatencyAttribute.cs | 42 ---- .../Properties/AssemblyInfo.cs | 36 ---- .../StatsdClient.ASPNET-MVC.csproj | 87 -------- StatsdClient.ASPNET-MVC/packages.config | 8 - StatsdClient.sln | 44 ++-- StatsdClient/NullOutputChannel.cs | 11 - StatsdClient/OutputChannelExtensions.cs | 10 - StatsdClient/Properties/AssemblyInfo.cs | 36 ---- StatsdClient/StatsdClient-DotNet35.csproj | 66 ------ StatsdClient/StatsdClient-DotNet40.csproj | 70 ------- StatsdClient/StatsdClient.csproj | 67 ------ StatsdClient/UdpOutputChannel.cs | 40 ---- StatsdClientTests/Properties/AssemblyInfo.cs | 36 ---- StatsdClientTests/StatsdClientTests.csproj | 98 --------- StatsdClientTests/StatsdExtensionsTests.cs | 60 ------ StatsdClientTests/StatsdTests.cs | 186 ----------------- StatsdClientTests/packages.config | 4 - nuget/StatsdClient.nuspec | 38 ---- .../Properties/AssemblyInfo.cs | 19 ++ .../StatsdCore.Net.Tests.xproj | 22 ++ .../StatsdExtensionsTests.cs | 62 ++++++ src/StatsdCore.Net.Tests/StatsdTests.cs | 195 ++++++++++++++++++ .../StatsdCore.Net.Tests}/TestData.cs | 0 src/StatsdCore.Net.Tests/project.json | 20 ++ .../StatsdCore.Net}/AsyncLock.cs | 0 .../CalendargramRetentionPeriod.cs | 0 src/StatsdCore.Net/Class1.cs | 14 ++ .../StatsdCore.Net}/ConnectionType.cs | 0 .../StatsdCore.Net}/IOutputChannel.cs | 5 +- .../StatsdCore.Net}/IStatsd.cs | 0 .../StatsdCore.Net}/MetricType.cs | 0 src/StatsdCore.Net/NullOutputChannel.cs | 14 ++ src/StatsdCore.Net/Properties/AssemblyInfo.cs | 19 ++ .../StatsdCore.Net}/Statsd.cs | 60 +++--- .../StatsdCore.Net}/StatsdClientExtensions.cs | 23 ++- src/StatsdCore.Net/StatsdCore.Net.xproj | 21 ++ .../StatsdCore.Net}/StatsdExtensions.cs | 0 .../StatsdCore.Net}/TcpOutputChannel.cs | 25 ++- .../StatsdCore.Net}/TimingToken.cs | 2 +- src/StatsdCore.Net/UdpOutputChannel.cs | 90 ++++++++ src/StatsdCore.Net/project.json | 16 ++ 43 files changed, 582 insertions(+), 976 deletions(-) delete mode 100644 StatsdClient.ASPNET-MVC/LogLatencyAttribute.cs delete mode 100644 StatsdClient.ASPNET-MVC/Properties/AssemblyInfo.cs delete mode 100644 StatsdClient.ASPNET-MVC/StatsdClient.ASPNET-MVC.csproj delete mode 100644 StatsdClient.ASPNET-MVC/packages.config delete mode 100644 StatsdClient/NullOutputChannel.cs delete mode 100644 StatsdClient/OutputChannelExtensions.cs delete mode 100644 StatsdClient/Properties/AssemblyInfo.cs delete mode 100644 StatsdClient/StatsdClient-DotNet35.csproj delete mode 100644 StatsdClient/StatsdClient-DotNet40.csproj delete mode 100644 StatsdClient/StatsdClient.csproj delete mode 100644 StatsdClient/UdpOutputChannel.cs delete mode 100644 StatsdClientTests/Properties/AssemblyInfo.cs delete mode 100644 StatsdClientTests/StatsdClientTests.csproj delete mode 100644 StatsdClientTests/StatsdExtensionsTests.cs delete mode 100644 StatsdClientTests/StatsdTests.cs delete mode 100644 StatsdClientTests/packages.config delete mode 100644 nuget/StatsdClient.nuspec create mode 100644 src/StatsdCore.Net.Tests/Properties/AssemblyInfo.cs create mode 100644 src/StatsdCore.Net.Tests/StatsdCore.Net.Tests.xproj create mode 100644 src/StatsdCore.Net.Tests/StatsdExtensionsTests.cs create mode 100644 src/StatsdCore.Net.Tests/StatsdTests.cs rename {StatsdClientTests => src/StatsdCore.Net.Tests}/TestData.cs (100%) create mode 100644 src/StatsdCore.Net.Tests/project.json rename {StatsdClient => src/StatsdCore.Net}/AsyncLock.cs (100%) rename {StatsdClient => src/StatsdCore.Net}/CalendargramRetentionPeriod.cs (100%) create mode 100644 src/StatsdCore.Net/Class1.cs rename {StatsdClient => src/StatsdCore.Net}/ConnectionType.cs (100%) rename {StatsdClient => src/StatsdCore.Net}/IOutputChannel.cs (74%) rename {StatsdClient => src/StatsdCore.Net}/IStatsd.cs (100%) rename {StatsdClient => src/StatsdCore.Net}/MetricType.cs (100%) create mode 100644 src/StatsdCore.Net/NullOutputChannel.cs create mode 100644 src/StatsdCore.Net/Properties/AssemblyInfo.cs rename {StatsdClient => src/StatsdCore.Net}/Statsd.cs (78%) rename {StatsdClient => src/StatsdCore.Net}/StatsdClientExtensions.cs (72%) create mode 100644 src/StatsdCore.Net/StatsdCore.Net.xproj rename {StatsdClient => src/StatsdCore.Net}/StatsdExtensions.cs (100%) rename {StatsdClient => src/StatsdCore.Net}/TcpOutputChannel.cs (83%) rename {StatsdClient => src/StatsdCore.Net}/TimingToken.cs (91%) create mode 100644 src/StatsdCore.Net/UdpOutputChannel.cs create mode 100644 src/StatsdCore.Net/project.json diff --git a/.gitignore b/.gitignore index b35311b..ca5d878 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,8 @@ TestResults *.suo *.user *.sln.docstates - +project.lock.json +.vs # Build results [Dd]ebug/ [Rr]elease/ diff --git a/README.md b/README.md index e609503..2b0f056 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# statsd-csharp-client +# statsdcore.net -A simple c# client library for [statsd.net](https://github.com/lukevenediger/statsd.net/) and [statsd](https://github.com/etsy/statsd/). +A simple c# client library for [statsd.net](https://github.com/lukevenediger/statsd.net/) and [statsd](https://github.com/etsy/statsd/) compatible with dotnet core!!! This was originally a fork of [another client](https://github.com/lukevenediger/statsd.net). # Features * Log counts, timings, gauges, sets, calendargrams and raw metrics @@ -75,12 +75,11 @@ The connection will attempt to reconnect if something goes wrong, and will try t # Project Information ## Target Runtimes -* .Net 3.5 -* .Net 4.0 -* .Net 4.5 +* netstandard1.3 ## Authors Luke Venediger - lukev@lukev.net and [@lukevenediger](http://twitter.com/lukevenediger) +Tommy Parnell - tommy@terribledev.io and [@TerribleDev](http://twitter.com/terribledev) ## See Also * [statsd.net](https://github.com/lukevenediger/statsd.net/) diff --git a/StatsdClient.ASPNET-MVC/LogLatencyAttribute.cs b/StatsdClient.ASPNET-MVC/LogLatencyAttribute.cs deleted file mode 100644 index 5b08ced..0000000 --- a/StatsdClient.ASPNET-MVC/LogLatencyAttribute.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web.Mvc; - -namespace StatsdClient.ASPNET_MVC -{ - public class LogLatencyAttribute : ActionFilterAttribute - { - private Stopwatch _stopwatch; - private string _name; - private IStatsd _statsd; - - public LogLatencyAttribute(string name) - { - if (string.IsNullOrEmpty(name)) - { - throw new ArgumentException("Name cannot be null or empty.", "name"); - } - _name = name; - } - - public override void OnActionExecuting(ActionExecutingContext filterContext) - { - _stopwatch = Stopwatch.StartNew(); - if (!filterContext.Controller.TempData.ContainsKey("statsdclient")) - { - throw new ArgumentNullException("statsdclient", "Could not find the statsdclient reference in the controller's TempData."); - } - _statsd = filterContext.Controller.TempData["statsdclient"] as IStatsd; - } - - public override void OnActionExecuted(ActionExecutedContext filterContext) - { - _stopwatch.Stop(); - _statsd.LogTiming(_name, (int)_stopwatch.ElapsedMilliseconds); - } - } -} diff --git a/StatsdClient.ASPNET-MVC/Properties/AssemblyInfo.cs b/StatsdClient.ASPNET-MVC/Properties/AssemblyInfo.cs deleted file mode 100644 index 70aac07..0000000 --- a/StatsdClient.ASPNET-MVC/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("StatsdClient.ASPNET-MVC")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("StatsdClient.ASPNET-MVC")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[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("6c5d32a9-970e-4c4e-88e6-f57b3f219da0")] - -// 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/StatsdClient.ASPNET-MVC/StatsdClient.ASPNET-MVC.csproj b/StatsdClient.ASPNET-MVC/StatsdClient.ASPNET-MVC.csproj deleted file mode 100644 index 00d4a74..0000000 --- a/StatsdClient.ASPNET-MVC/StatsdClient.ASPNET-MVC.csproj +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Debug - AnyCPU - {4C01CFEE-CE8D-447F-9919-08FF7C548BF8} - Library - Properties - StatsdClient.ASPNET_MVC - StatsdClient.ASPNET-MVC - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - ..\packages\StatsdCsharpClient.1.0.0.0\lib\net45\StatsdClient.dll - - - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll - - - True - ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll - - - True - ..\packages\Microsoft.AspNet.Razor.2.0.20715.0\lib\net40\System.Web.Razor.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/StatsdClient.ASPNET-MVC/packages.config b/StatsdClient.ASPNET-MVC/packages.config deleted file mode 100644 index ecb1c16..0000000 --- a/StatsdClient.ASPNET-MVC/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/StatsdClient.sln b/StatsdClient.sln index e7f9c14..0b6b765 100644 --- a/StatsdClient.sln +++ b/StatsdClient.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3981BC36-0C55-4127-827F-292024E6A8E9}" ProjectSection(SolutionItems) = preProject CHANGELOG.md = CHANGELOG.md @@ -8,15 +10,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution nuget\StatsdClient.nuspec = nuget\StatsdClient.nuspec EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatsdClient", "StatsdClient\StatsdClient.csproj", "{D9C7B372-074B-4649-B45E-01FE10724AF9}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StatsdCore.Net", "src\StatsdCore.Net\StatsdCore.Net.xproj", "{4F80CF24-D107-44CE-B9F7-EEF6C1E5B3A1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatsdClientTests", "StatsdClientTests\StatsdClientTests.csproj", "{15A2A9A7-D5A0-499D-A74B-2A06BD13B954}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{415D2BEB-C25D-4B69-A308-835C93EDB2D1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatsdClient.ASPNET-MVC", "StatsdClient.ASPNET-MVC\StatsdClient.ASPNET-MVC.csproj", "{4C01CFEE-CE8D-447F-9919-08FF7C548BF8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatsdClient-DotNet40", "StatsdClient\StatsdClient-DotNet40.csproj", "{4C053A87-70F9-4059-8A42-BC08626A8B22}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatsdClient-DotNet35", "StatsdClient\StatsdClient-DotNet35.csproj", "{BD729A99-C965-40F3-A69B-EFC81D6DA023}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StatsdCore.Net.Tests", "src\StatsdCore.Net.Tests\StatsdCore.Net.Tests.xproj", "{92092AC3-65A9-44D4-A4B2-27502D139D22}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -24,26 +22,20 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D9C7B372-074B-4649-B45E-01FE10724AF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9C7B372-074B-4649-B45E-01FE10724AF9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9C7B372-074B-4649-B45E-01FE10724AF9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9C7B372-074B-4649-B45E-01FE10724AF9}.Release|Any CPU.Build.0 = Release|Any CPU - {15A2A9A7-D5A0-499D-A74B-2A06BD13B954}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {15A2A9A7-D5A0-499D-A74B-2A06BD13B954}.Debug|Any CPU.Build.0 = Debug|Any CPU - {15A2A9A7-D5A0-499D-A74B-2A06BD13B954}.Release|Any CPU.ActiveCfg = Release|Any CPU - {15A2A9A7-D5A0-499D-A74B-2A06BD13B954}.Release|Any CPU.Build.0 = Release|Any CPU - {4C01CFEE-CE8D-447F-9919-08FF7C548BF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4C01CFEE-CE8D-447F-9919-08FF7C548BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4C01CFEE-CE8D-447F-9919-08FF7C548BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4C01CFEE-CE8D-447F-9919-08FF7C548BF8}.Release|Any CPU.Build.0 = Release|Any CPU - {4C053A87-70F9-4059-8A42-BC08626A8B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4C053A87-70F9-4059-8A42-BC08626A8B22}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4C053A87-70F9-4059-8A42-BC08626A8B22}.Release|Any CPU.Build.0 = Release|Any CPU - {BD729A99-C965-40F3-A69B-EFC81D6DA023}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BD729A99-C965-40F3-A69B-EFC81D6DA023}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BD729A99-C965-40F3-A69B-EFC81D6DA023}.Release|Any CPU.Build.0 = Release|Any CPU + {4F80CF24-D107-44CE-B9F7-EEF6C1E5B3A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F80CF24-D107-44CE-B9F7-EEF6C1E5B3A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F80CF24-D107-44CE-B9F7-EEF6C1E5B3A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F80CF24-D107-44CE-B9F7-EEF6C1E5B3A1}.Release|Any CPU.Build.0 = Release|Any CPU + {92092AC3-65A9-44D4-A4B2-27502D139D22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92092AC3-65A9-44D4-A4B2-27502D139D22}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92092AC3-65A9-44D4-A4B2-27502D139D22}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92092AC3-65A9-44D4-A4B2-27502D139D22}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {4F80CF24-D107-44CE-B9F7-EEF6C1E5B3A1} = {415D2BEB-C25D-4B69-A308-835C93EDB2D1} + {92092AC3-65A9-44D4-A4B2-27502D139D22} = {415D2BEB-C25D-4B69-A308-835C93EDB2D1} + EndGlobalSection EndGlobal diff --git a/StatsdClient/NullOutputChannel.cs b/StatsdClient/NullOutputChannel.cs deleted file mode 100644 index 42d67be..0000000 --- a/StatsdClient/NullOutputChannel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading.Tasks; - -namespace StatsdClient -{ - internal sealed class NullOutputChannel : IOutputChannel - { - public async Task SendAsync(string line) - { - } - } -} \ No newline at end of file diff --git a/StatsdClient/OutputChannelExtensions.cs b/StatsdClient/OutputChannelExtensions.cs deleted file mode 100644 index 0ccfcf7..0000000 --- a/StatsdClient/OutputChannelExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace StatsdClient -{ - public static class OutputChannelExtensions - { - public static void Send(this IOutputChannel outputChannel, string line) - { - outputChannel.SendAsync(line).Wait(); - } - } -} \ No newline at end of file diff --git a/StatsdClient/Properties/AssemblyInfo.cs b/StatsdClient/Properties/AssemblyInfo.cs deleted file mode 100644 index 954170b..0000000 --- a/StatsdClient/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("StatsdClient")] -[assembly: AssemblyDescription("A statsd.net and statsd client for c#")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Luke Venediger")] -[assembly: AssemblyProduct("StatsdClient")] -[assembly: AssemblyCopyright("Copyright © Luke Venediger 2013")] -[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("8ac00668-c22c-4335-bc35-fc310f50d42a")] - -// 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.3.0.0")] -[assembly: AssemblyFileVersion("1.3.0.0")] diff --git a/StatsdClient/StatsdClient-DotNet35.csproj b/StatsdClient/StatsdClient-DotNet35.csproj deleted file mode 100644 index 2f2ca55..0000000 --- a/StatsdClient/StatsdClient-DotNet35.csproj +++ /dev/null @@ -1,66 +0,0 @@ - - - - - Debug - AnyCPU - {BD729A99-C965-40F3-A69B-EFC81D6DA023} - Library - Properties - StatsdClient - StatsdClient - v3.5 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - none - true - ..\Nuget Releases\lib\net35\ - TRACE - prompt - 4 - ..\Nuget Releases\lib\net35\StatsdClient.XML - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/StatsdClient/StatsdClient-DotNet40.csproj b/StatsdClient/StatsdClient-DotNet40.csproj deleted file mode 100644 index decc411..0000000 --- a/StatsdClient/StatsdClient-DotNet40.csproj +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Debug - AnyCPU - {4C053A87-70F9-4059-8A42-BC08626A8B22} - Library - Properties - StatsdClient - StatsdClient - v4.0 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - - - none - true - ..\Nuget Releases\lib\net40\ - TRACE - prompt - 4 - ..\Nuget Releases\lib\net40\StatsdClient.XML - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/StatsdClient/StatsdClient.csproj b/StatsdClient/StatsdClient.csproj deleted file mode 100644 index 10775e5..0000000 --- a/StatsdClient/StatsdClient.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - Debug - AnyCPU - {D9C7B372-074B-4649-B45E-01FE10724AF9} - Library - Properties - StatsdClient - StatsdClient - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - none - true - ..\Nuget Releases\lib\net45\ - TRACE - prompt - 4 - ..\Nuget Releases\lib\net45\StatsdClient.XML - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/StatsdClient/UdpOutputChannel.cs b/StatsdClient/UdpOutputChannel.cs deleted file mode 100644 index 1b212df..0000000 --- a/StatsdClient/UdpOutputChannel.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace StatsdClient -{ - internal sealed class UdpOutputChannel : IOutputChannel - { - private readonly UdpClient _udpClient; - - public Socket ClientSocket - { - get - { - return _udpClient.Client; - } - } - - public UdpOutputChannel(string hostOrIPAddress, int port) - { - IPAddress ipAddress; - // Is this an IP address already? - if (!IPAddress.TryParse(hostOrIPAddress, out ipAddress)) - { - // Convert to ipv4 address - ipAddress = Dns.GetHostAddresses(hostOrIPAddress).First(p => p.AddressFamily == AddressFamily.InterNetwork); - } - _udpClient = new UdpClient(); - _udpClient.Connect(ipAddress, port); - } - - public async Task SendAsync(string line) - { - var payload = Encoding.UTF8.GetBytes(line); - await _udpClient.SendAsync(payload, payload.Length); - } - } -} \ No newline at end of file diff --git a/StatsdClientTests/Properties/AssemblyInfo.cs b/StatsdClientTests/Properties/AssemblyInfo.cs deleted file mode 100644 index 29c09f4..0000000 --- a/StatsdClientTests/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("StatsdClientTests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("StatsdClientTests")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[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("90fef403-171b-449e-8400-5f2e6f8ffc7e")] - -// 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/StatsdClientTests/StatsdClientTests.csproj b/StatsdClientTests/StatsdClientTests.csproj deleted file mode 100644 index 9701921..0000000 --- a/StatsdClientTests/StatsdClientTests.csproj +++ /dev/null @@ -1,98 +0,0 @@ - - - - Debug - AnyCPU - {15A2A9A7-D5A0-499D-A74B-2A06BD13B954} - Library - Properties - StatsdClientTests - StatsdClientTests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - ..\packages\Moq.4.0.10827\lib\NET40\Moq.dll - - - - - - - - - - - - - - - - - - - - - - - - {d9c7b372-074b-4649-b45e-01fe10724af9} - StatsdClient - - - - - - - - - - False - - - False - - - False - - - False - - - - - - - - \ No newline at end of file diff --git a/StatsdClientTests/StatsdExtensionsTests.cs b/StatsdClientTests/StatsdExtensionsTests.cs deleted file mode 100644 index f2c0973..0000000 --- a/StatsdClientTests/StatsdExtensionsTests.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using StatsdClient; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StatsdClientTests -{ - [TestClass] - public class StatsdExtensionsTests - { - private Mock _outputChannel; - private Statsd _statsd; - private TestData _testData; - - [TestInitialize] - public void Initialise() - { - _outputChannel = new Mock(); - _statsd = new Statsd("localhost", 12000, outputChannel : _outputChannel.Object); - _testData = new TestData(); - } - - [TestMethod] - public void count_SendToStatsd_Success() - { - _outputChannel.Setup(p => p.Send("foo.bar:1|c")).Verifiable(); - _statsd.count().foo.bar += 1; - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void gauge_SendToStatsd_Success() - { - _outputChannel.Setup(p => p.Send("foo.bar:1|g")).Verifiable(); - _statsd.gauge().foo.bar += 1; - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void timing_SendToStatsd_Success() - { - _outputChannel.Setup(p => p.Send("foo.bar:1|ms")).Verifiable(); - _statsd.timing().foo.bar += 1; - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void count_AddNamePartAsString_Success() - { - _outputChannel.Setup(p => p.Send("foo.bar:1|ms")).Verifiable(); - _statsd.timing().foo._("bar")._ += 1; - _outputChannel.VerifyAll(); - } - } - -} diff --git a/StatsdClientTests/StatsdTests.cs b/StatsdClientTests/StatsdTests.cs deleted file mode 100644 index a4f477d..0000000 --- a/StatsdClientTests/StatsdTests.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using StatsdClient; -using Moq; - -namespace StatsdClientTests -{ - [TestClass] - public class StatsdTests - { - private Mock _outputChannel; - private Statsd _statsd; - private TestData _testData; - - public StatsdTests() - { - _testData = new TestData(); - } - - [TestInitialize] - public void Initialise() - { - _outputChannel = new Mock(); - _statsd = new Statsd("localhost", 12000, outputChannel : _outputChannel.Object); - } - - #region Parameter Checks - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void LogCount_NameIsNull_ExpectArgumentNullException() - { - _statsd.LogCount(null); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void LogCount_ValueIsLessThanZero_ExpectArgumentOutOfRangeException() - { - _statsd.LogCount("foo", -1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void LogGauge_NameIsNull_ExpectArgumentNullException() - { - _statsd.LogGauge(null, _testData.NextInteger); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void LogGauge_ValueIsLessThanZero_ExpectArgumentOutOfRangeException() - { - _statsd.LogGauge("foo", -1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void LogTiming_NameIsNull_ExpectArgumentNullException() - { - _statsd.LogTiming(null, _testData.NextInteger); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void LogTiming_ValueIsLessThanZero_ExpectArgumentOutOfRangeException() - { - _statsd.LogTiming("foo", -1); - } - #endregion - - [TestMethod] - public void LogCount_ValidInput_Success() - { - var stat = _testData.NextStatName; - var count = _testData.NextInteger; - _outputChannel.Setup(p => p.Send(stat + ":" + count.ToString() + "|c")).Verifiable(); - - _statsd.LogCount(stat, count); - - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void LogTiming_ValidInput_Success() - { - var stat = _testData.NextStatName; - var count = _testData.NextInteger; - _outputChannel.Setup(p => p.Send(stat + ":" + count.ToString() + "|ms")).Verifiable(); - - _statsd.LogTiming(stat, count); - - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void LogGauge_ValidInput_Success() - { - var stat = _testData.NextStatName; - var count = _testData.NextInteger; - _outputChannel.Setup(p => p.Send(stat + ":" + count.ToString() + "|g")).Verifiable(); - - _statsd.LogGauge(stat, count); - - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void Constructor_PrefixEndsInPeriod_RemovePeriod() - { - var statsd = new Statsd("localhost", 12000, "foo.", outputChannel : _outputChannel.Object); - var stat = _testData.NextStatName; - var count = _testData.NextInteger; - _outputChannel.Setup(p => p.Send("foo." + stat + ":" + count.ToString() + "|c")).Verifiable(); - - statsd.LogCount(stat, count); - - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void LogCount_NullPrefix_DoesNotStartNameWithPeriod() - { - var statsd = new Statsd("localhost", 12000, prefix : null, outputChannel : _outputChannel.Object); - var inputStat = "some.stat:1|c"; - _outputChannel.Setup(p => p.Send(It.Is(q => q == inputStat))) - .Verifiable(); - statsd.LogCount("some.stat"); - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void LogCount_EmptyStringPrefix_DoesNotStartNameWithPeriod() - { - var statsd = new Statsd("localhost", 12000, prefix : "", outputChannel : _outputChannel.Object); - var inputStat = "some.stat:1|c"; - _outputChannel.Setup(p => p.Send(It.Is(q => q == inputStat))) - .Verifiable(); - statsd.LogCount("some.stat"); - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void LogRaw_WithoutEpoch_Valid() - { - var statsd = new Statsd("localhost", 12000, prefix : "", outputChannel : _outputChannel.Object); - var inputStat = "my.raw.stat:12934|r"; - _outputChannel.Setup(p => p.Send(It.Is(q => q == inputStat))) - .Verifiable(); - statsd.LogRaw("my.raw.stat", 12934); - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void LogRaw_WithEpoch_Valid() - { - var statsd = new Statsd("localhost", 12000, prefix : "", outputChannel : _outputChannel.Object); - var almostAnEpoch = DateTime.Now.Ticks; - var inputStat = "my.raw.stat:12934|r|" + almostAnEpoch; - _outputChannel.Setup(p => p.Send(It.Is(q => q == inputStat))) - .Verifiable(); - statsd.LogRaw("my.raw.stat", 12934, almostAnEpoch); - _outputChannel.VerifyAll(); - } - - [TestMethod] - public void CreateClient_WithInvalidHostName_DoesNotError() - { - var statsd = new Statsd("nowhere.here.or.anywhere", 12000); - statsd.LogCount("test.stat"); - } - - [TestMethod] - public void CreateClient_WithIPAddress_DoesNotError() - { - var statsd = new Statsd("127.0.0.1", 12000); - statsd.LogCount("test.stat"); - } - - [TestMethod] - public void CreateClient_WithInvalidCharactersInHostName_DoesNotError() - { - var statsd = new Statsd("@%)(F(FSDLKDEQ423t0-vbdfb", 12000); - statsd.LogCount("test.foo"); - } - } -} diff --git a/StatsdClientTests/packages.config b/StatsdClientTests/packages.config deleted file mode 100644 index 507a0f8..0000000 --- a/StatsdClientTests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/nuget/StatsdClient.nuspec b/nuget/StatsdClient.nuspec deleted file mode 100644 index 1c9c6cc..0000000 --- a/nuget/StatsdClient.nuspec +++ /dev/null @@ -1,38 +0,0 @@ - - - - StatsdCsharpClient - 1.2.1.0 - Simple Statsd Client for .Net 3.5, 4.0 and 4.5 - Luke Venediger - Luke Venediger - https://github.com/lukevenediger/statsd-csharp-client/ - A simple c# client library for statsd and statsd.net - - The simple statsd client for .Net is a robust, easy-to-use way of feeding metrics into a statsd-compatible server. You can use it to log counts, timings and gauges. - - Features include: - * Log counts, timings, gauges, sets and raw metrics - * Has an additional API that uses dynamics to create and submit stats - * Fault-tolerant client that can be configured to fail silently (with a warning) if misconfigured - * IStatsdClient interface for easy mocking in unit tests - * Allows for customisation of every output stat to do things like screen metrics before sending - * Supports a user-defined prefix to prepend to every metric - * Outputs to UDP or TCP - - .Net 4.0 and 4.5 Users: - * Use the StatsdExtensions to define metrics without having to manipulate strings - * The dynamic stats builder interface provides a cleaner alternative to creating and logging metrics - - Licence: MIT - - - * Fixed a bug in the tcp output channel's retry logic - * Skip DNS resolution on the UDP client if already an IP Address - * Fall back to the Null Output Channel if the client is created with an empty host name. - - false - Copyright 2013 Luke Venediger - statsd statsd.net graphite etsy metrics - - \ No newline at end of file diff --git a/src/StatsdCore.Net.Tests/Properties/AssemblyInfo.cs b/src/StatsdCore.Net.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c844944 --- /dev/null +++ b/src/StatsdCore.Net.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +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: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("StatsdCore.Net.Tests")] +[assembly: AssemblyTrademark("")] + +// 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("92092ac3-65a9-44d4-a4b2-27502d139d22")] diff --git a/src/StatsdCore.Net.Tests/StatsdCore.Net.Tests.xproj b/src/StatsdCore.Net.Tests/StatsdCore.Net.Tests.xproj new file mode 100644 index 0000000..4fc7eca --- /dev/null +++ b/src/StatsdCore.Net.Tests/StatsdCore.Net.Tests.xproj @@ -0,0 +1,22 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 92092ac3-65a9-44d4-a4b2-27502d139d22 + StatsdCore.Net.Tests + .\obj + .\bin\ + v4.5.2 + + + 2.0 + + + + + + \ No newline at end of file diff --git a/src/StatsdCore.Net.Tests/StatsdExtensionsTests.cs b/src/StatsdCore.Net.Tests/StatsdExtensionsTests.cs new file mode 100644 index 0000000..aff3e1e --- /dev/null +++ b/src/StatsdCore.Net.Tests/StatsdExtensionsTests.cs @@ -0,0 +1,62 @@ +using Moq; +using StatsdClient; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace StatsdClientTests +{ + public class StatsdExtensionsTests + { + private Mock _outputChannel; + private Statsd _statsd; + private TestData _testData; + + public void Initialise() + { + _outputChannel = new Mock(); + _statsd = new Statsd("localhost", 12000, outputChannel: _outputChannel.Object); + _testData = new TestData(); + } + + [Fact] + public void count_SendToStatsd_Success() + { + Initialise(); + _outputChannel.Setup(p => p.SendAsync("foo.bar:1|c")).Verifiable(); + _statsd.count().foo.bar += 1; + _outputChannel.VerifyAll(); + } + + [Fact] + public void gauge_SendToStatsd_Success() + { + Initialise(); + _outputChannel.Setup(p => p.SendAsync("foo.bar:1|g")).Verifiable(); + _statsd.gauge().foo.bar += 1; + _outputChannel.VerifyAll(); + } + + [Fact] + public void timing_SendToStatsd_Success() + { + Initialise(); + _outputChannel.Setup(p => p.SendAsync("foo.bar:1|ms")).Verifiable(); + _statsd.timing().foo.bar += 1; + _outputChannel.VerifyAll(); + } + + [Fact] + public void count_AddNamePartAsString_Success() + { + Initialise(); + _outputChannel.Setup(p => p.SendAsync("foo.bar:1|ms")).Verifiable(); + _statsd.timing().foo._("bar")._ += 1; + _outputChannel.VerifyAll(); + } + } + +} diff --git a/src/StatsdCore.Net.Tests/StatsdTests.cs b/src/StatsdCore.Net.Tests/StatsdTests.cs new file mode 100644 index 0000000..70d907e --- /dev/null +++ b/src/StatsdCore.Net.Tests/StatsdTests.cs @@ -0,0 +1,195 @@ +using System; +using StatsdClient; +using Moq; +using Xunit; + +namespace StatsdClientTests +{ + + public class StatsdTests + { + private Mock _outputChannel; + private Statsd _statsd; + private TestData _testData; + + public StatsdTests() + { + _testData = new TestData(); + } + + public void Initialise() + { + _outputChannel = new Mock(); + _statsd = new Statsd("localhost", 12000, outputChannel: _outputChannel.Object); + } + + #region Parameter Checks + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void LogCount_NameIsNull_ExpectArgumentNullException() + //{ + // _statsd.LogCount(null); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void LogCount_ValueIsLessThanZero_ExpectArgumentOutOfRangeException() + //{ + // _statsd.LogCount("foo", -1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void LogGauge_NameIsNull_ExpectArgumentNullException() + //{ + // _statsd.LogGauge(null, _testData.NextInteger); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void LogGauge_ValueIsLessThanZero_ExpectArgumentOutOfRangeException() + //{ + // _statsd.LogGauge("foo", -1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void LogTiming_NameIsNull_ExpectArgumentNullException() + //{ + // _statsd.LogTiming(null, _testData.NextInteger); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void LogTiming_ValueIsLessThanZero_ExpectArgumentOutOfRangeException() + //{ + // _statsd.LogTiming("foo", -1); + //} + #endregion + + [Fact] + public void LogCount_ValidInput_Success() + { + Initialise(); + var stat = _testData.NextStatName; + var count = _testData.NextInteger; + _outputChannel.Setup(p => p.SendAsync(stat + ":" + count.ToString() + "|c")).Verifiable(); + + _statsd.LogCount(stat, count); + + _outputChannel.VerifyAll(); + } + + [Fact] + public void LogTiming_ValidInput_Success() + { + Initialise(); + var stat = _testData.NextStatName; + var count = _testData.NextInteger; + _outputChannel.Setup(p => p.SendAsync(stat + ":" + count.ToString() + "|ms")).Verifiable(); + + _statsd.LogTiming(stat, count); + + _outputChannel.VerifyAll(); + } + + [Fact] + public void LogGauge_ValidInput_Success() + { + Initialise(); + var stat = _testData.NextStatName; + var count = _testData.NextInteger; + _outputChannel.Setup(p => p.SendAsync(stat + ":" + count.ToString() + "|g")).Verifiable(); + + _statsd.LogGauge(stat, count); + + _outputChannel.VerifyAll(); + } + + [Fact] + public void Constructor_PrefixEndsInPeriod_RemovePeriod() + { + Initialise(); + var statsd = new Statsd("localhost", 12000, "foo.", outputChannel: _outputChannel.Object); + var stat = _testData.NextStatName; + var count = _testData.NextInteger; + _outputChannel.Setup(p => p.SendAsync("foo." + stat + ":" + count.ToString() + "|c")).Verifiable(); + + statsd.LogCount(stat, count); + + _outputChannel.VerifyAll(); + } + + [Fact] + public void LogCount_NullPrefix_DoesNotStartNameWithPeriod() + { + Initialise(); + var statsd = new Statsd("localhost", 12000, prefix: null, outputChannel: _outputChannel.Object); + var inputStat = "some.stat:1|c"; + _outputChannel.Setup(p => p.SendAsync(It.Is(q => q == inputStat))) + .Verifiable(); + statsd.LogCount("some.stat"); + _outputChannel.VerifyAll(); + } + + [Fact] + public void LogCount_EmptyStringPrefix_DoesNotStartNameWithPeriod() + { + Initialise(); + var statsd = new Statsd("localhost", 12000, prefix: "", outputChannel: _outputChannel.Object); + var inputStat = "some.stat:1|c"; + _outputChannel.Setup(p => p.SendAsync(It.Is(q => q == inputStat))) + .Verifiable(); + statsd.LogCount("some.stat"); + _outputChannel.VerifyAll(); + } + + [Fact] + public void LogRaw_WithoutEpoch_Valid() + { + Initialise(); + var statsd = new Statsd("localhost", 12000, prefix: "", outputChannel: _outputChannel.Object); + var inputStat = "my.raw.stat:12934|r"; + _outputChannel.Setup(p => p.SendAsync(It.Is(q => q == inputStat))) + .Verifiable(); + statsd.LogRaw("my.raw.stat", 12934); + _outputChannel.VerifyAll(); + } + + [Fact] + public void LogRaw_WithEpoch_Valid() + { + Initialise(); + var statsd = new Statsd("localhost", 12000, prefix: "", outputChannel: _outputChannel.Object); + var almostAnEpoch = DateTime.Now.Ticks; + var inputStat = "my.raw.stat:12934|r|" + almostAnEpoch; + _outputChannel.Setup(p => p.SendAsync(It.Is(q => q == inputStat))) + .Verifiable(); + statsd.LogRaw("my.raw.stat", 12934, almostAnEpoch); + _outputChannel.VerifyAll(); + } + + [Fact] + public void CreateClient_WithInvalidHostName_DoesNotError() + { + var statsd = new Statsd("nowhere.here.or.anywhere", 12000); + statsd.LogCount("test.stat"); + } + + [Fact] + public void CreateClient_WithIPAddress_DoesNotError() + { + Initialise(); + var statsd = new Statsd("127.0.0.1", 12000); + statsd.LogCount("test.stat"); + } + + [Fact] + public void CreateClient_WithInvalidCharactersInHostName_DoesNotError() + { + Initialise(); + var statsd = new Statsd("@%)(F(FSDLKDEQ423t0-vbdfb", 12000); + statsd.LogCount("test.foo"); + } + } +} diff --git a/StatsdClientTests/TestData.cs b/src/StatsdCore.Net.Tests/TestData.cs similarity index 100% rename from StatsdClientTests/TestData.cs rename to src/StatsdCore.Net.Tests/TestData.cs diff --git a/src/StatsdCore.Net.Tests/project.json b/src/StatsdCore.Net.Tests/project.json new file mode 100644 index 0000000..a501603 --- /dev/null +++ b/src/StatsdCore.Net.Tests/project.json @@ -0,0 +1,20 @@ +{ + "version": "1.0.0-*", + "testRunner": "xunit", + "dependencies": { + "xunit": "2.2.0-beta2-build3300", + "dotnet-test-xunit": "2.2.0-preview2-build1029", + "Moq": "4.6.38-alpha", + "StatsdCore.Net": "1.0.*" + }, + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + } + } + } + } +} \ No newline at end of file diff --git a/StatsdClient/AsyncLock.cs b/src/StatsdCore.Net/AsyncLock.cs similarity index 100% rename from StatsdClient/AsyncLock.cs rename to src/StatsdCore.Net/AsyncLock.cs diff --git a/StatsdClient/CalendargramRetentionPeriod.cs b/src/StatsdCore.Net/CalendargramRetentionPeriod.cs similarity index 100% rename from StatsdClient/CalendargramRetentionPeriod.cs rename to src/StatsdCore.Net/CalendargramRetentionPeriod.cs diff --git a/src/StatsdCore.Net/Class1.cs b/src/StatsdCore.Net/Class1.cs new file mode 100644 index 0000000..5334b02 --- /dev/null +++ b/src/StatsdCore.Net/Class1.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace StatsdCore.Net +{ + public class Class1 + { + public Class1() + { + } + } +} diff --git a/StatsdClient/ConnectionType.cs b/src/StatsdCore.Net/ConnectionType.cs similarity index 100% rename from StatsdClient/ConnectionType.cs rename to src/StatsdCore.Net/ConnectionType.cs diff --git a/StatsdClient/IOutputChannel.cs b/src/StatsdCore.Net/IOutputChannel.cs similarity index 74% rename from StatsdClient/IOutputChannel.cs rename to src/StatsdCore.Net/IOutputChannel.cs index 9d79586..ffdaf18 100644 --- a/StatsdClient/IOutputChannel.cs +++ b/src/StatsdCore.Net/IOutputChannel.cs @@ -1,11 +1,12 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; namespace StatsdClient { /// /// Contract for sending raw statds lines to the server /// - public interface IOutputChannel + public interface IOutputChannel: IDisposable { /// /// Sends a line of stats data to the server asynchronously. diff --git a/StatsdClient/IStatsd.cs b/src/StatsdCore.Net/IStatsd.cs similarity index 100% rename from StatsdClient/IStatsd.cs rename to src/StatsdCore.Net/IStatsd.cs diff --git a/StatsdClient/MetricType.cs b/src/StatsdCore.Net/MetricType.cs similarity index 100% rename from StatsdClient/MetricType.cs rename to src/StatsdCore.Net/MetricType.cs diff --git a/src/StatsdCore.Net/NullOutputChannel.cs b/src/StatsdCore.Net/NullOutputChannel.cs new file mode 100644 index 0000000..5028e34 --- /dev/null +++ b/src/StatsdCore.Net/NullOutputChannel.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading.Tasks; + +namespace StatsdClient +{ + internal sealed class NullOutputChannel : IOutputChannel + { + public void Dispose(){} + + public void Send(string line){} + + public async Task SendAsync(string line){} + } +} \ No newline at end of file diff --git a/src/StatsdCore.Net/Properties/AssemblyInfo.cs b/src/StatsdCore.Net/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6cf34d1 --- /dev/null +++ b/src/StatsdCore.Net/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +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: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("StatsdCore.Net")] +[assembly: AssemblyTrademark("")] + +// 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("4f80cf24-d107-44ce-b9f7-eef6c1e5b3a1")] diff --git a/StatsdClient/Statsd.cs b/src/StatsdCore.Net/Statsd.cs similarity index 78% rename from StatsdClient/Statsd.cs rename to src/StatsdCore.Net/Statsd.cs index cd74e85..97c7fe4 100644 --- a/StatsdClient/Statsd.cs +++ b/src/StatsdCore.Net/Statsd.cs @@ -81,13 +81,13 @@ namespace StatsdClient private void InitialiseInternal(Func createOutputChannel, string prefix, bool rethrowOnError) { _prefix = prefix; - if (_prefix != null && _prefix.EndsWith(".")) + if (_prefix != null && _prefix.EndsWith(".", StringComparison.Ordinal)) { _prefix = _prefix.Substring(0, _prefix.Length - 1); } try { - _outputChannel = createOutputChannel(); + _outputChannel = createOutputChannel?.Invoke(); } catch (Exception ex) { @@ -105,30 +105,24 @@ namespace StatsdClient /// /// The metric name. /// The counter value (defaults to 1). - public async Task LogCountAsync(string name, long count = 1) - { - await SendMetricAsync(MetricType.COUNT, name, _prefix, count); - } + public Task LogCountAsync(string name, long count = 1) => SendMetricAsync(MetricType.COUNT, name, _prefix, count); + /// /// Log a timing / latency /// /// The metric name. /// The duration, in milliseconds, for this metric. - public async Task LogTimingAsync(string name, long milliseconds) - { - await SendMetricAsync(MetricType.TIMING, name, _prefix, milliseconds); - } + public Task LogTimingAsync(string name, long milliseconds) => SendMetricAsync(MetricType.TIMING, name, _prefix, milliseconds); + /// /// Log a gauge. /// /// The metric name /// The value for this gauge - public async Task LogGaugeAsync(string name, long value) - { - await SendMetricAsync(MetricType.GAUGE, name, _prefix, value); - } + public Task LogGaugeAsync(string name, long value) => SendMetricAsync(MetricType.GAUGE, name, _prefix, value); + /// /// Log to a set @@ -139,10 +133,8 @@ namespace StatsdClient /// Logging to a set is about counting the number /// of occurrences of each event. /// - public async Task LogSetAsync(string name, long value) - { - await SendMetricAsync(MetricType.SET, name, _prefix, value); - } + public Task LogSetAsync(string name, long value) => SendMetricAsync(MetricType.SET, name, _prefix, value); + /// /// Log a raw metric that will not get aggregated on the server. @@ -150,10 +142,8 @@ namespace StatsdClient /// The metric name. /// The metric value. /// (optional) The epoch timestamp. Leave this blank to have the server assign an epoch for you. - public async Task LogRawAsync(string name, long value, long? epoch = null) - { - await SendMetricAsync(MetricType.RAW, name, String.Empty, value, epoch.HasValue ? epoch.ToString() : null); - } + public Task LogRawAsync(string name, long value, long? epoch = null) => SendMetricAsync(MetricType.RAW, name, String.Empty, value, epoch.HasValue ? epoch.ToString() : null); + /// /// Log a calendargram metric @@ -161,10 +151,8 @@ namespace StatsdClient /// The metric namespace /// The unique value to be counted in the time period /// The time period, can be one of h,d,dow,w,m - public async Task LogCalendargramAsync(string name, string value, string period) - { - await SendMetricAsync(MetricType.CALENDARGRAM, name, _prefix, value, period); - } + public Task LogCalendargramAsync(string name, string value, string period) => SendMetricAsync(MetricType.CALENDARGRAM, name, _prefix, value, period); + /// /// Log a calendargram metric @@ -172,28 +160,26 @@ namespace StatsdClient /// The metric namespace /// The unique value to be counted in the time period /// The time period, can be one of h,d,dow,w,m - public async Task LogCalendargramAsync(string name, long value, string period) - { - await SendMetricAsync(MetricType.CALENDARGRAM, name, _prefix, value, period); - } + public Task LogCalendargramAsync(string name, long value, string period) => SendMetricAsync(MetricType.CALENDARGRAM, name, _prefix, value, period); + - private async Task SendMetricAsync(string metricType, string name, string prefix, long value, string postFix = null) + private Task SendMetricAsync(string metricType, string name, string prefix, long value, string postFix = null) { if (value < 0) { Trace.TraceWarning("Metric value for {0} was less than zero: {1}. Not sending.", name, value); - return; + return Task.FromResult(0); } - await SendMetricAsync(metricType, name, prefix, value.ToString(), postFix); + return SendMetricAsync(metricType, name, prefix, value.ToString(), postFix); } - private async Task SendMetricAsync(string metricType, string name, string prefix, string value, string postFix = null) + private Task SendMetricAsync(string metricType, string name, string prefix, string value, string postFix = null) { - if (String.IsNullOrEmpty(name)) + if (string.IsNullOrEmpty(name)) { - throw new ArgumentNullException("name"); + throw new ArgumentNullException(nameof(name)); } - await _outputChannel.SendAsync(PrepareMetric(metricType, name, prefix, value, postFix)); + return _outputChannel.SendAsync(PrepareMetric(metricType, name, prefix, value, postFix)); } /// diff --git a/StatsdClient/StatsdClientExtensions.cs b/src/StatsdCore.Net/StatsdClientExtensions.cs similarity index 72% rename from StatsdClient/StatsdClientExtensions.cs rename to src/StatsdCore.Net/StatsdClientExtensions.cs index 542e21f..e296827 100644 --- a/StatsdClient/StatsdClientExtensions.cs +++ b/src/StatsdCore.Net/StatsdClientExtensions.cs @@ -12,9 +12,10 @@ namespace StatsdClient /// /// The metric name. /// The counter value (defaults to 1). + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogCount(this IStatsd client, string name, int count = 1) { - client.LogCountAsync(name, count).Wait(); + client.LogCountAsync(name, count)?.Wait(); } /// @@ -22,9 +23,10 @@ namespace StatsdClient /// /// The metric name. /// The duration, in milliseconds, for this metric. + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogTiming(this IStatsd client, string name, long milliseconds) { - client.LogTimingAsync(name, milliseconds).Wait(); + client.LogTimingAsync(name, milliseconds)?.Wait(); } /// @@ -32,9 +34,10 @@ namespace StatsdClient /// /// The metric name /// The value for this gauge + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogGauge(this IStatsd client, string name, int value) { - client.LogGaugeAsync(name, value).Wait(); + client.LogGaugeAsync(name, value)?.Wait(); } /// @@ -45,9 +48,10 @@ namespace StatsdClient /// /// Logging to a set is about counting the number of occurrences of each event. /// + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogSet(this IStatsd client, string name, int value) { - client.LogSetAsync(name, value).Wait(); + client.LogSetAsync(name, value)?.Wait(); } /// @@ -56,9 +60,10 @@ namespace StatsdClient /// The metric name. /// The metric value. /// (optional) The epoch timestamp. Leave this blank to have the server assign an epoch for you. + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogRaw(this IStatsd client, string name, int value, long? epoch = null) { - client.LogRawAsync(name, value, epoch).Wait(); + client.LogRawAsync(name, value, epoch)?.Wait(); } /// @@ -67,9 +72,10 @@ namespace StatsdClient /// The metric namespace /// The unique value to be counted in the time period /// The time period, can be one of h,d,dow,w,m + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogCalendargram(this IStatsd client, string name, string value, string period) { - client.LogCalendargramAsync(name, value, period).Wait(); + client.LogCalendargramAsync(name, value, period)?.Wait(); } /// @@ -78,9 +84,10 @@ namespace StatsdClient /// The metric namespace /// The unique value to be counted in the time period /// The time period, can be one of h,d,dow,w,m + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogCalendargram(this IStatsd client, string name, long value, string period) { - client.LogCalendargramAsync(name, value, period).Wait(); + client.LogCalendargramAsync(name, value, period)?.Wait(); } /// @@ -89,6 +96,7 @@ namespace StatsdClient /// The statsd client instance. /// The namespace of the timing metric. /// The duration to log (will be converted into milliseconds) + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static void LogTiming(this IStatsd client, string name, TimeSpan duration) { client.LogTiming(name, (long)duration.TotalMilliseconds); @@ -103,6 +111,7 @@ namespace StatsdClient /// /// Wrap the code you want to measure in a using() {} block. The TimingToken instance will log the duration when it is disposed. /// + [Obsolete("This will go away, if you want to call this in a sync fashion you should just call this with ?.Wait()", false)] public static TimingToken LogTiming(this IStatsd client, string name) { return new TimingToken(client, name); diff --git a/src/StatsdCore.Net/StatsdCore.Net.xproj b/src/StatsdCore.Net/StatsdCore.Net.xproj new file mode 100644 index 0000000..24cf1c8 --- /dev/null +++ b/src/StatsdCore.Net/StatsdCore.Net.xproj @@ -0,0 +1,21 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + 4f80cf24-d107-44ce-b9f7-eef6c1e5b3a1 + StatsdCore.Net + .\obj + .\bin\ + v4.5.2 + + + + 2.0 + + + diff --git a/StatsdClient/StatsdExtensions.cs b/src/StatsdCore.Net/StatsdExtensions.cs similarity index 100% rename from StatsdClient/StatsdExtensions.cs rename to src/StatsdCore.Net/StatsdExtensions.cs diff --git a/StatsdClient/TcpOutputChannel.cs b/src/StatsdCore.Net/TcpOutputChannel.cs similarity index 83% rename from StatsdClient/TcpOutputChannel.cs rename to src/StatsdCore.Net/TcpOutputChannel.cs index d211d93..701b7b1 100644 --- a/StatsdClient/TcpOutputChannel.cs +++ b/src/StatsdCore.Net/TcpOutputChannel.cs @@ -9,7 +9,7 @@ namespace StatsdClient { internal sealed class TcpOutputChannel : IOutputChannel { - private readonly TcpClient _tcpClient; + private TcpClient _tcpClient; private NetworkStream _stream; private readonly string _host; private readonly int _port; @@ -26,7 +26,6 @@ namespace StatsdClient _tcpClient = new TcpClient(); _asyncLock = new AsyncLock(); } - public async Task SendAsync(string line) { await SendWithRetryAsync(line, _reconnectEnabled ? _retryAttempts - 1 : 0); @@ -83,5 +82,27 @@ namespace StatsdClient } } } + + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if(!disposedValue) + { + if(disposing) + { + _tcpClient.Dispose(); + } + _tcpClient = null; + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + } + #endregion } } \ No newline at end of file diff --git a/StatsdClient/TimingToken.cs b/src/StatsdCore.Net/TimingToken.cs similarity index 91% rename from StatsdClient/TimingToken.cs rename to src/StatsdCore.Net/TimingToken.cs index 93fd681..6bb474b 100644 --- a/StatsdClient/TimingToken.cs +++ b/src/StatsdCore.Net/TimingToken.cs @@ -29,7 +29,7 @@ namespace StatsdClient public void Dispose() { _stopwatch.Stop(); - _client.LogTiming(_name, (int)_stopwatch.ElapsedMilliseconds); + _client.LogTimingAsync(_name, (int)_stopwatch.ElapsedMilliseconds); } } } diff --git a/src/StatsdCore.Net/UdpOutputChannel.cs b/src/StatsdCore.Net/UdpOutputChannel.cs new file mode 100644 index 0000000..f9443bf --- /dev/null +++ b/src/StatsdCore.Net/UdpOutputChannel.cs @@ -0,0 +1,90 @@ +using System; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace StatsdClient +{ + internal sealed class UdpOutputChannel : IOutputChannel + { + private readonly UdpClient _udpClient = new UdpClient(); + private IPEndPoint _ipEndpoint; + private string _hostOrIPAddress; + private int _port; + public Socket ClientSocket + { + get + { + return _udpClient.Client; + } + } + + public UdpOutputChannel(string hostOrIPAddress, int port) + { + _hostOrIPAddress = hostOrIPAddress; + _port = port; + } + + private async Task GetIpAddress() + { + if(_ipEndpoint != null) + { + return _ipEndpoint; + } + IPAddress ipAddress; + // Is this an IP address already? + if(!IPAddress.TryParse(_hostOrIPAddress, out ipAddress)) + { + try + { + ipAddress = (await Dns.GetHostAddressesAsync(_hostOrIPAddress).ConfigureAwait(false)).First(p => p.AddressFamily == AddressFamily.InterNetwork); + } + catch(Exception) + { + System.Diagnostics.Trace.TraceError("Failed to retrieve domain {0}", _hostOrIPAddress); + _ipEndpoint = null; + return null; + } + + // Convert to ipv4 address + + } + _ipEndpoint = new IPEndPoint(ipAddress, _port); + return _ipEndpoint; + + + } + + public async Task SendAsync(string line) + { + var endpoint = await GetIpAddress().ConfigureAwait(false); + if(endpoint == null) return; + var payload = Encoding.UTF8.GetBytes(line); + await _udpClient.SendAsync(payload, payload.Length, endpoint).ConfigureAwait(false); + } + + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if(!disposedValue) + { + if(disposing) + { + _udpClient.Dispose(); + } + disposedValue = true; + } + } + + // This code added to correctly implement the disposable pattern. + public void Dispose() + { + Dispose(true); + } + #endregion + } +} \ No newline at end of file diff --git a/src/StatsdCore.Net/project.json b/src/StatsdCore.Net/project.json new file mode 100644 index 0000000..e9e40be --- /dev/null +++ b/src/StatsdCore.Net/project.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0-*", + + "dependencies": { + "NETStandard.Library": "1.6.0", + "System.Diagnostics.TraceSource": "4.0.0", + "System.Dynamic.Runtime": "4.0.11", + "System.Net.NameResolution": "4.0.0" + }, + + "frameworks": { + "netstandard1.3": { + "imports": "dnxcore50" + } + } +}