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 24, 2013
2 parents 60bb61e + 4ef8803 commit bb255d6
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 206 deletions.
70 changes: 20 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,56 +101,26 @@ In a new connection to each individual Azure SQL Database:

## Proxy Support ##

When the plugin is installed behind a proxy, there are a few configuration options.

**Default Proxy**

Assuming the proxy is configured at the system level (Internet Options in Control Panel), just uncomment the default configuration so that it reads as follows:

<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy usesystemdefault="True" bypassonlocal="True" />
</defaultProxy>
</system.net>

This configuration may be used with the username and password in the next section.

If you are upgrading from version 1.0.8 or earlier, you'll need to add that snippet to the config.

**Authenticated Proxy**

Ensure the above `defaultProxy` configuration is in place before setting the credentials. The New Relic .NET SDK requires that you uncomment the default configuration and set the username and password as below:

<appSettings>
<add key="proxyUsername" value="OFFICE\jdoe"/>
<add key="proxyPassword" value="p@ssw0rd"/>
</appSettings>

When specifying the username and password, you *must* configure the default proxy seen immediately above. The domain name before the user is optional.

If you are upgrading from version 1.0.8 or earlier, you'll need to add that snippet to the config.

**Authenticated Proxy with Proxy URL**

The authenticated proxy with specified URL is a bit of a mix of the previous two settings. It is also mutually exclusive to the previous proxy setting. First, ensure the `<appSettings>` contain the proxy URL, username, and password:

<appSettings>
<!-- The proxyAddress can be a url or an IP address. The port is required after the colon. -->
<add key="proxyAddress" value="http://www.urlOrIpAddress.com:5503"/>
<add key="proxyUsername" value="jdoe"/>
<add key="proxyPassword" value="p@ssw0rd"/>
</appSettings>

Then the proxy handler must be configured. This is *similar* to the previous proxy config above:

<system.net>
<defaultProxy enabled="true" useDefaultCredentials="false">
<module type="NewRelic.Platform.Binding.DotNET.Proxy, NewRelic.Platform.Binding.DotNET"/>
</defaultProxy>
</system.net>

If you have any questions regarding the expected look of the config file, please review the [latest source on GitHub](https://github.com/newrelic-platform/newrelic_microsoft_sqlserver_plugin/blob/develop/src/NewRelic.Microsoft.SqlServer.Plugin/app.config).

For installations behind a proxy, the details are set in the config file.

<!-- Proxy settings for connecting to the New Relic service. -->
<!-- If a proxy is used, the host attribute is required.

Attributes:
host - The proxy server host name.
port - The proxy server port (optional - defaults to 8080).
user - The username used to authenticate with the proxy server (optional).
password - The password used to authenticate with the proxy server (optional).
domain - The domain used to authenticate with the proxy server (optional).
useDefaultCredentials - 'true' or 'false. Uses the credentials of the account running the plugin (optional - defaults to false).
If specified, 'user' and 'password' are ignored.
-->

<!--
<proxy host="hostname" />
-->

If you are upgrading from version 1.0.9 or earlier, you'll need to replace the previous proxy settings with this new snippet in the config.

## Logging

Expand Down
2 changes: 1 addition & 1 deletion build/versions.targets
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<MajorVersion>1</MajorVersion>
<MinorVersion>0</MinorVersion>
<PatchVersion>9</PatchVersion>
<PatchVersion>10</PatchVersion>

<BuildQuality></BuildQuality>
</PropertyGroup>
Expand Down
Binary file modified lib/NewRelic.Platform.Binding.DotNET.dll
Binary file not shown.
Binary file removed lib/NewRelic.Platform.Binding.DotNET.pdb
Binary file not shown.
6 changes: 3 additions & 3 deletions src/Common/CommonAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.9")]
[assembly: AssemblyFileVersion("1.0.9")]
[assembly: AssemblyInformationalVersion("1.0.9")]
[assembly: AssemblyVersion("1.0.10")]
[assembly: AssemblyFileVersion("1.0.10")]
[assembly: AssemblyInformationalVersion("1.0.10")]
23 changes: 23 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin.Tests/SqlEndpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,29 @@ public IEnumerable<TestCaseData> ComponentGuidTestCases
}
}

//Tests fix for issue where Plugin gets 400's after server is unavailable for a time https://support.newrelic.com/tickets/55385
[Test]
[TestCase(1, TestName = "A Minute Since Success")]
[TestCase(5, TestName = "5 Minutes Since Success")]
[TestCase(30, TestName = "30 Minutes Since Success")]
[TestCase(60, TestName = "An Hour Since Success")]
[TestCase(120, TestName = "Two Hours Since Success")]
[TestCase(1440, TestName = "A Day Since Success")]
[TestCase(2880, TestName = "Two Days Since Success")]
public void Assert_duration_does_not_exceed_allowed_max(int minutesSinceLastSuccessful)
{
var endpoint = new SqlServerEndpoint("Foo",".",false);
endpoint.MetricReportSuccessful(DateTime.Now.AddMinutes(minutesSinceLastSuccessful * -1));

const int thirtyMinutesInSeconds = 30 * 60;
Assert.That(endpoint.Duration, Is.LessThanOrEqualTo(thirtyMinutesInSeconds), "Duration should never be longer than 30 minutes, regardless of last succssful reported time");

endpoint.MetricReportSuccessful(DateTime.Now.AddMinutes(-.5));
Assert.That(endpoint.Duration, Is.LessThanOrEqualTo(31), "Duration should reset to be around 30 seconds regardless of previous value");

}

[Test]
public void Assert_endpoint_appropriately_massages_duplicated_data()
{
var endpoint = Substitute.For<SqlEndpointBase>("", "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
{
internal class NewRelicConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("service")]
[ConfigurationProperty("service", IsRequired = true)]
public ServiceElement Service
{
get { return ((ServiceElement) (base["service"])); }
}

[ConfigurationProperty("proxy")]
public ProxyElement Proxy
{
get { return ((ProxyElement)(base["proxy"])); }
}

[ConfigurationProperty("sqlServers")]
public SqlServerCollection SqlServers
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Configuration;

namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
{
internal class ProxyElement : ConfigurationElement
{
/// <summary>
/// The proxy server host name. Required.
/// </summary>
[ConfigurationProperty("host", DefaultValue = "", IsKey = false, IsRequired = true)]
public string Host
{
get { return ((string)(base["host"])); }
set { base["host"] = value; }
}
/// <summary>
/// The proxy server port (optional - defaults to 8080).
/// </summary>
[ConfigurationProperty("port", DefaultValue = "8080", IsKey = false, IsRequired = false)]
public string Port
{
get { return ((string)(base["port"])); }
set { base["port"] = value; }
}
/// <summary>
/// The username used to authenticate with the proxy server (optional).
/// </summary>
[ConfigurationProperty("user", DefaultValue = "", IsKey = false, IsRequired = false)]
public string User
{
get { return ((string)(base["user"])); }
set { base["user"] = value; }
}
/// <summary>
/// The password used to authenticate with the proxy server (optional).
/// </summary>
[ConfigurationProperty("password", DefaultValue = "", IsKey = false, IsRequired = false)]
public string Password
{
get { return ((string)(base["password"])); }
set { base["password"] = value; }
}
/// <summary>
/// The domain used to authenticate with the proxy server (optional).
/// </summary>
[ConfigurationProperty("domain", DefaultValue = "", IsKey = false, IsRequired = false)]
public string Domain
{
get { return ((string)(base["domain"])); }
set { base["domain"] = value; }
}
/// <summary>
/// 'true' or 'false. Uses the credentials of the account running the plugin (optional - defaults to false).
/// </summary>
[ConfigurationProperty("useDefaultCredentials", DefaultValue = "false", IsKey = false, IsRequired = false)]
public string UseDefaultCredentials
{
get { return ((string)(base["useDefaultCredentials"])); }
set { base["useDefaultCredentials"] = value; }
}
}
}
71 changes: 71 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin/Configuration/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Principal;
using System.Text.RegularExpressions;
Expand All @@ -13,6 +14,7 @@ namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
public class Settings
{
private string _version;
private static string _ProxyDetails;

public Settings(ISqlEndpoint[] endpoints)
{
Expand Down Expand Up @@ -74,9 +76,72 @@ internal static Settings FromConfigurationSection(NewRelicConfigurationSection s
settings.ServiceName = service.ServiceName;
}

var webProxy = GetWebProxy(section, log);
if (webProxy != null)
{
WebRequest.DefaultWebProxy = webProxy;
}

return settings;
}

private static IWebProxy GetWebProxy(NewRelicConfigurationSection section, ILog log)
{
var proxyElement = section.Proxy;
if (proxyElement == null || !proxyElement.ElementInformation.IsPresent) return null;

Uri uri;
if (!Uri.TryCreate(proxyElement.Host, UriKind.RelativeOrAbsolute, out uri))
{
log.ErrorFormat("Proxy host '{0}' is not a valid URI, skipping proxy.", proxyElement.Host);
return null;
}

int port;
if (!int.TryParse(proxyElement.Port, out port))
{
log.ErrorFormat("Unable to parse proxy port from '{0}', skipping proxy. Expecting a number from 1-65535.", proxyElement.Port);
return null;
}

WebProxy webProxy;
try
{
webProxy = new WebProxy(proxyElement.Host, port);
}
catch (Exception e)
{
log.ErrorFormat("Proxy settings are invalid. {0}", e.Message);
return null;
}

if ("true".Equals(proxyElement.UseDefaultCredentials, StringComparison.InvariantCultureIgnoreCase))
{
webProxy.UseDefaultCredentials = true;
webProxy.Credentials = CredentialCache.DefaultCredentials;
_ProxyDetails = string.Format("Proxy Server: {0}:{1} with default credentials", proxyElement.Host, port);
}
else if (!string.IsNullOrEmpty(proxyElement.User))
{
if (string.IsNullOrEmpty(proxyElement.Domain))
{
webProxy.Credentials = new NetworkCredential(proxyElement.User, proxyElement.Password);
_ProxyDetails = string.Format("Proxy Server: {0}@{1}:{2}", proxyElement.User, proxyElement.Host, port);
}
else
{
webProxy.Credentials = new NetworkCredential(proxyElement.User, proxyElement.Password, proxyElement.Domain);
_ProxyDetails = string.Format("Proxy Server: {0}\\{1}@{2}:{3}", proxyElement.Domain, proxyElement.User, proxyElement.Host, port);
}
}
else
{
_ProxyDetails = string.Format("Proxy Server: {0}:{1}", proxyElement.Host, port);
}

return webProxy;
}

public void ToLog(ILog log)
{
// Pending review by New Relic before adding this information
Expand All @@ -87,6 +152,12 @@ public void ToLog(ILog log)
log.Info(" Windows Service: " + (Environment.UserInteractive ? "No" : "Yes"));
log.InfoFormat(@" User: {0}\{1}", Environment.UserDomainName, Environment.UserName);
log.Info(" Run as Administrator: " + (IsProcessElevated ? "Yes" : "No"));

if (_ProxyDetails != null)
{
log.Info(" " + _ProxyDetails);
}

log.Info(" Total Endpoints: " + Endpoints.Length);
log.Info(" Poll Interval Seconds: " + PollIntervalSeconds);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<Compile Include="Configuration\Database.cs" />
<Compile Include="Configuration\DatabaseCollection.cs" />
<Compile Include="Configuration\DatabaseElement.cs" />
<Compile Include="Configuration\ProxyElement.cs" />
<Compile Include="IMetricQuery.cs" />
<Compile Include="IQueryContext.cs" />
<Compile Include="ISqlEndpoint.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
-- Retrieves relevant data about each database
-- Assists support when a user reports a problem


SELECT
d.[name] AS DatabaseName,
SELECT d.[name] AS DatabaseName,
* -- Use * as differnt databases seem to have different columns. This isn't critical data so we must fail gracefully.
/*
d.[database_id],
d.[source_database_id],
d.[create_date],
Expand Down Expand Up @@ -70,5 +70,6 @@ SELECT
d.[containment],
d.[containment_desc],
d.[target_recovery_time_in_seconds]
*/
FROM sys.databases d
/*{WHERE}*/
Loading

0 comments on commit bb255d6

Please sign in to comment.