Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
edchapel committed Sep 1, 2013
2 parents 84f3b11 + fa1a85a commit 79204df
Show file tree
Hide file tree
Showing 32 changed files with 859 additions and 347 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,4 @@ This will stop and remove the service. The binaries and config files will still
and log files are not deleted. If you wish to remove these, it must be done manually.

## Credits
The New Relic Microsoft SQL Server plugin was originally authored by https://github.com/edchapel, https://github.com/jstromwick, and Mike Merrill. Subsequent updates and support are provided by [New Relic](http://newrelic.com/platform).
The New Relic Microsoft SQL Server plugin was originally authored by [Ed Chapel](https://github.com/edchapel), [Jesse Stromwick](https://github.com/jstromwick), and [Mike Merrill](https://github.com/infoone). Subsequent updates and support are provided by [New Relic](http://newrelic.com/platform).
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
using NewRelic.Microsoft.SqlServer.Plugin.Core;
using NewRelic.Microsoft.SqlServer.Plugin.Core.Extensions;
using NewRelic.Microsoft.SqlServer.Plugin.Properties;
using NewRelic.Microsoft.SqlServer.Plugin.QueryTypes;

namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
{
[TestFixture]
public class SqlServerTests
public class SqlServerEndpointTests
{
public IEnumerable<TestCaseData> QueryHistoryTestData
{
Expand Down Expand Up @@ -258,7 +259,7 @@ public string[] Assert_that_query_history_updated_appropriately(string[][] query
}

[Test]
public void AssertComplextIncludeSystemDatabasesWorks()
public void Assert_complex_include_system_databases_works()
{
var includeDbNames = new[] {"FooDb", "BarDb"};
IEnumerable<Database> includedDbs = includeDbNames.Select(x => new Database {Name = x,});
Expand All @@ -271,7 +272,7 @@ public void AssertComplextIncludeSystemDatabasesWorks()
}

[Test]
public void AssertIncludeExcludeListsBuiltAppropriately()
public void Assert_include_exclude_lists_built_appropriately()
{
IEnumerable<Database> includedDbs = new[] {"FooDb", "BarDb"}.Select(x => new Database {Name = x,});
var sqlServerToMonitor = new SqlServerEndpoint("FooServer", ".", false, includedDbs, new[] {"Baz"});
Expand All @@ -280,7 +281,7 @@ public void AssertIncludeExcludeListsBuiltAppropriately()
}

[Test]
public void AssertIncludeSystemDatabasesWorks()
public void Assert_include_system_databases_works()
{
var sqlServerToMonitor = new SqlServerEndpoint("FooServer", ".", false);
Assert.That(sqlServerToMonitor.IncludedDatabaseNames.Length, Is.EqualTo(0));
Expand All @@ -300,5 +301,42 @@ public void Assert_that_duration_is_reported_correctly()
Thread.Sleep(1000);
Assert.That(sqlServerToMonitor.Duration, Is.EqualTo(1), "Expected 1 second Duration after Thread.Sleep(1000)");
}

[Test]
public void Assert_that_max_recompile_summary_ignores_other_metrics()
{
object[] metrics = {new SqlCpuUsage()};
var results = new SqlServerEndpoint(null, null, false).GetMaxRecompileSummaryMetric(metrics);
Assert.That(results, Is.Null, "Implementation should have ignored bad data.");
}

[Test]
public void Assert_that_max_recompile_summary_ignores_empty_metric_array()
{
object[] metrics = {};
var results = new SqlServerEndpoint(null, null, false).GetMaxRecompileSummaryMetric(metrics);
Assert.That(results, Is.Null, "Implementation should have ignored empty data.");
}

[Test]
public void Assert_that_max_recompile_summary_is_reported()
{
object[] metrics =
{
new RecompileSummary { DatabaseName = "A", SingleUseObjects = 100, SingleUsePercent = 0, MultipleUseObjects = 1, },
new RecompileSummary { DatabaseName = "B", SingleUseObjects = 1, SingleUsePercent = 80, MultipleUseObjects = 1, },
new RecompileSummary { DatabaseName = "C", SingleUseObjects = 1, SingleUsePercent = 0, MultipleUseObjects = 50, },
};
var queryContext = new SqlServerEndpoint(null, null, false).GetMaxRecompileSummaryMetric(metrics);
var results = queryContext.Results.ToArray();

Assert.That(queryContext, Is.Not.SameAs(metrics), "Expected a new Array");

var max = results.OfType<RecompileMaximums>().SingleOrDefault();
Assert.That(max, Is.Not.Null, "Expected a new metric in the results");
Assert.That(max.SingleUseObjects, Is.EqualTo(100), "Wrong SingleUseObjects value");
Assert.That(max.SingleUsePercent, Is.EqualTo(80m), "Wrong SingleUsePercent value");
Assert.That(max.MultipleUseObjects, Is.EqualTo(50), "Wrong MultipleUseObjects value");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<Compile Include="Configuration\ComponentDataRetrieverTests.cs" />
<Compile Include="Configuration\ConfigurationParserTests.cs" />
<Compile Include="Configuration\Log4NetTests.cs" />
<Compile Include="Configuration\SqlServerTests.cs" />
<Compile Include="Configuration\SqlServerEndpointTests.cs" />
<Compile Include="Core\ExtensionsForAssemblyTests.cs" />
<Compile Include="MetricMapperTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

using NUnit.Framework;

using NewRelic.Microsoft.SqlServer.Plugin.Configuration;
using NewRelic.Microsoft.SqlServer.Plugin.Core;
using NewRelic.Microsoft.SqlServer.Plugin.Core.Extensions;
using NewRelic.Microsoft.SqlServer.Plugin.QueryTypes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,24 @@ public void Assert_buffer_cache_hit_ratio_stays_between_0_and_100()
memoryView.BufferCacheHitRatio = -5m;
Assert.That(memoryView.BufferCacheHitRatio, Is.EqualTo(0m), "Hit ratio of -5m");
}

[Test]
public void Assert_page_threat_stays_between_0_and_100()
{
var memoryView = new MemoryView {PageLife = 0};
Assert.That(memoryView.PageLifeThreat, Is.EqualTo(100m), "0 page life maxes at 100%");

// Try the default
memoryView.PageLife = 300;
Assert.That(memoryView.PageLifeThreat, Is.EqualTo(100m), "300 page life maxes at 100%");

// Just above the default
memoryView.PageLife = 301;
Assert.That(memoryView.PageLifeThreat, Is.LessThan(100m), "301 page life is slightly less than 100%");

// Just above the default
memoryView.PageLife = long.MaxValue;
Assert.That(memoryView.PageLifeThreat, Is.EqualTo(0m), "Max page life should effectively report 0%");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public IEnumerable<TestCaseData> ComponentGuidTestCases
}
}

public void AssertEndpointAppropriatelyMassagesDuplicatedData()
public void Assert_endpoint_appropriately_massages_duplicated_data()
{
var endpoint = Substitute.For<SqlEndpointBase>("", "");

Expand Down Expand Up @@ -88,14 +88,14 @@ public void AssertEndpointAppropriatelyMassagesDuplicatedData()

[Test]
[TestCaseSource("ComponentGuidTestCases")]
public string AssertCorrectComponentGuidSuppliedToQueryContext(SqlEndpointBase endpoint)
public string Assert_correct_component_guid_supplied_to_query_context(SqlEndpointBase endpoint)
{
QueryContext queryContext = endpoint.CreateQueryContext(Substitute.For<ISqlQuery>(), new object[0]);
return queryContext.ComponentData.Guid;
}

[Test]
public void AssertEndpointAppropriatelyMassagesData()
public void Assert_endpoint_appropriately_massages_data()
{
var endpoint = Substitute.For<SqlEndpointBase>("", "");

Expand Down Expand Up @@ -203,7 +203,7 @@ public void AssertEndpointAppropriatelyMassagesData()
}

[Test]
public void AssertSqlDMLActvityDataTakesCreateTimeMsIntoAccount()
public void Assert_sql_dml_actvity_data_takes_create_time_ms_into_account()
{
var endpoint = Substitute.For<SqlEndpointBase>("", "");
var d1 = new DateTime(2013, 06, 20, 8, 28, 10, 100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public override IEnumerable<IQueryContext> ExecuteQueries(ILog log)
/// <returns></returns>
internal IEnumerable<IQueryContext> PerformThrottlingQuery(ILog log)
{
SqlQuery[] queries = new QueryLocator(new DapperWrapper()).PrepareQueries(new[] {typeof (AzureServiceInterruptionEvents)}, false).ToArray();
var queries = new QueryLocator(new DapperWrapper()).PrepareQueries(new[] {typeof (AzureServiceInterruptionEvents)}, false).ToArray();
return ExecuteQueries(queries, _masterConnectionString, log);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public void ToLog(ILog log)
{
endpoint.ToLog(log);
}
log.Info(string.Empty);
}
else
{
Expand All @@ -114,6 +115,7 @@ public void ToLog(ILog log)
{
endpoint.ToLog(log);
}
log.Info(string.Empty);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public InstallController(string serviceName, bool isProcessElevated)
public void Install()
{
Install(true);
StartService();
}

public void Uninstall()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public sealed class ServiceProcessInstaller : System.ServiceProcess.ServiceProce
{
public ServiceProcessInstaller()
{
//Installs using local Service, this will need to be updated with the proper credentials after install
Account = ServiceAccount.LocalService;
//Installs using Local System. This may need to be updated with the proper credentials after install.
Account = ServiceAccount.LocalSystem;
}
}
}
16 changes: 16 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin/IMetricQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

using NewRelic.Microsoft.SqlServer.Plugin.Core;

namespace NewRelic.Microsoft.SqlServer.Plugin
{
public interface IMetricQuery
{
MetricTransformEnum MetricTransformEnum { get; }
string QueryName { get; }
Type QueryType { get; }
string MetricPattern { get; }
string ResultTypeName { get; }
void AddMetrics(QueryContext context);
}
}
25 changes: 25 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin/IQueryContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;

using NewRelic.Microsoft.SqlServer.Plugin.Core;
using NewRelic.Platform.Binding.DotNET;

namespace NewRelic.Microsoft.SqlServer.Plugin
{
public interface IQueryContext
{
string QueryName { get; }
Type QueryType { get; }
IEnumerable<object> Results { get; set; }
ComponentData ComponentData { get; set; }
int MetricsRecorded { get; }
bool DataSent { get; set; }
MetricTransformEnum MetricTransformEnum { get; }

string FormatMetricKey(object queryResult, string metricName, string metricUnits);
void AddAllMetrics();
void AddMetric(string name, int value);
void AddMetric(string name, decimal value);
void AddMetric(string name, MinMaxMetricValue value);
}
}
23 changes: 23 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin/ISqlQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Data;

using NewRelic.Microsoft.SqlServer.Plugin.Core;

namespace NewRelic.Microsoft.SqlServer.Plugin
{
public interface ISqlQuery : IMetricQuery
{
string ResourceName { get; }
string CommandText { get; }

/// <summary>
/// Queries data from the database and returns the results.
/// </summary>
/// <param name="dbConnection">Open connection to the database.</param>
/// <param name="endpoint">Settings for the endpoint that is queried.</param>
/// <returns>
/// An enumeration of a the type where the <see cref="SqlServerQueryAttribute" /> for this query object was found during initialization.
/// </returns>
IEnumerable<object> Query(IDbConnection dbConnection, ISqlEndpoint endpoint);
}
}
55 changes: 55 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin/MetricQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Linq;
using System.Reflection;

using NewRelic.Microsoft.SqlServer.Plugin.Core;
using NewRelic.Microsoft.SqlServer.Plugin.Core.Extensions;

namespace NewRelic.Microsoft.SqlServer.Plugin
{
public class MetricQuery : IMetricQuery
{
private readonly MetricMapper[] _metricMappers;

public MetricQuery(Type queryType, string queryName, string resultTypeName)
{
QueryType = queryType;
QueryName = queryName;
ResultTypeName = resultTypeName;
_metricMappers = GetMappers(QueryType);
MetricPattern = string.Format("Component/{0}", QueryType.Name);
}

public Type QueryType { get; private set; }

public string QueryName { get; private set; }

public MetricTransformEnum MetricTransformEnum { get; set; }

public string MetricPattern { get; protected set; }

public string ResultTypeName { get; private set; }

public void AddMetrics(QueryContext context)
{
context.Results.ForEach(r => _metricMappers.ForEach(m => m.AddMetric(context, r)));
}

/// <summary>
/// Sets up the mappers that take the values on the query result and records each one as a metric.
/// </summary>
/// <param name="type">
/// <em>QueryType</em> to look for metric properties
/// </param>
/// <returns>
/// An array of mappers capable of creating metrics for a <em>QueryType</em>
/// </returns>
internal static MetricMapper[] GetMappers(Type type)
{
return type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(MetricMapper.TryCreate)
.Where(m => m != null)
.ToArray();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,19 @@
<Compile Include="Configuration\Database.cs" />
<Compile Include="Configuration\DatabaseCollection.cs" />
<Compile Include="Configuration\DatabaseElement.cs" />
<Compile Include="IMetricQuery.cs" />
<Compile Include="IQueryContext.cs" />
<Compile Include="ISqlEndpoint.cs" />
<Compile Include="Configuration\NewRelicConfigurationSection.cs" />
<Compile Include="Configuration\ServiceElement.cs" />
<Compile Include="Configuration\Settings.cs" />
<Compile Include="ISqlQuery.cs" />
<Compile Include="MetricQuery.cs" />
<Compile Include="QueryTypes\AzureServiceInterruptionEvents.cs" />
<Compile Include="QueryTypes\AzureSqlDatabaseSummary.cs" />
<Compile Include="QueryTypes\SqlServerDetails.cs" />
<Compile Include="QueryTypes\DatabaseDetails.cs" />
<Compile Include="QueryTypes\RecompileMaximums.cs" />
<Compile Include="QueryTypes\SqlDmlActivity.cs" />
<Compile Include="QueryTypes\MemoryViewNuma.cs" />
<Compile Include="SqlEndpointBase.cs" />
Expand Down Expand Up @@ -176,6 +183,12 @@
<ItemGroup>
<EmbeddedResource Include="Queries\SqlDMLActivity.SqlServerAndAzureSQL.sql" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Queries\ServerDetails.SqlServer.sql" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Queries\DatabaseDetails.SqlServer.sql" />
</ItemGroup>
<Import Project="..\Common\NewRelic.Microsoft.SqlServer.Plugin.targets" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
-- All Databases on instance Azure
-- Must connect to master. If you connect to non master, you get master and that DB only

select
Name,
Database_id
from sys.databases

select * from sys.dm_exec_requests
SELECT
Name,
Database_id
FROM sys.databases
Loading

0 comments on commit 79204df

Please sign in to comment.