Skip to content

Commit

Permalink
Simply scrapers to reduce duplicate code and make it easy to add… (#839)
Browse files Browse the repository at this point in the history
* Reduce duplicate code in scraper

Signed-off-by: Tom Kerkhove <[email protected]>

* Use correct instance name and refactor resource definition

Signed-off-by: Tom Kerkhove <[email protected]>
  • Loading branch information
tomkerkhove authored Jan 15, 2020
1 parent 3b5384a commit c2aa7c4
Show file tree
Hide file tree
Showing 45 changed files with 337 additions and 279 deletions.
63 changes: 63 additions & 0 deletions src/Promitor.Core.Scraping/AppServiceScraper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System.Collections.Generic;
using Promitor.Core.Scraping.Configuration.Model.Metrics;

// ReSharper disable All

namespace Promitor.Core.Scraping
{
/// <summary>
/// Azure Monitor Scraper
/// </summary>
/// <typeparam name="TResourceDefinition">Type of metric definition that is being used</typeparam>
public abstract class AppServiceScraper<TResourceDefinition> : AzureMonitorScraper<TResourceDefinition>
where TResourceDefinition : class, IAppServiceResourceDefinition
{
/// <summary>
/// Constructor
/// </summary>
protected AppServiceScraper(ScraperConfiguration scraperConfiguration) :
base(scraperConfiguration)
{
}

/// <summary>
/// Builds the URI without deployment slots of the App Service resource to scrape
/// </summary>
/// <param name="subscriptionId">Subscription id in which the resource lives</param>
/// <param name="scrapeDefinition">Contains all the information needed to scrape the resource.</param>
/// <param name="resource">Contains the resource cast to the specific resource type.</param>
/// <returns>Uri of Azure resource</returns>
protected abstract string BuildResourceUriWithoutDeploymentSlot(string subscriptionId, ScrapeDefinition<IAzureResourceDefinition> scrapeDefinition, TResourceDefinition resource);

/// <inheritdoc />
protected override string BuildResourceUri(string subscriptionId, ScrapeDefinition<IAzureResourceDefinition> scrapeDefinition, TResourceDefinition resource)
{
var slotName = DetermineSlotName(resource);
var resourceUri = BuildResourceUriWithoutDeploymentSlot(subscriptionId, scrapeDefinition, resource);

// Production slot should not be suffixed in resource URI
if (slotName != "production")
{
resourceUri += $"/slots/{slotName}";
}

return resourceUri;
}

/// <inheritdoc />
protected override Dictionary<string, string> DetermineMetricLabels(TResourceDefinition resourceDefinition)
{
var metricLabels = base.DetermineMetricLabels(resourceDefinition);

var slotName = DetermineSlotName(resourceDefinition);
metricLabels?.TryAdd("slot_name", slotName);

return metricLabels;
}

private static string DetermineSlotName(TResourceDefinition resource)
{
return string.IsNullOrWhiteSpace(resource.SlotName) ? "production" : resource.SlotName;
}
}
}
58 changes: 58 additions & 0 deletions src/Promitor.Core.Scraping/AzureMonitorScraper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.Management.Monitor.Fluent.Models;
using Promitor.Core.Scraping.Configuration.Model.Metrics;

namespace Promitor.Core.Scraping
{
/// <summary>
/// Azure Monitor Scraper
/// </summary>
/// <typeparam name="TResourceDefinition">Type of metric definition that is being used</typeparam>
public abstract class AzureMonitorScraper<TResourceDefinition> : Scraper<TResourceDefinition>
where TResourceDefinition : class, IAzureResourceDefinition
{
/// <summary>
/// Constructor
/// </summary>
protected AzureMonitorScraper(ScraperConfiguration scraperConfiguration) :
base(scraperConfiguration)
{
}

/// <inheritdoc />
protected override async Task<ScrapeResult> ScrapeResourceAsync(string subscriptionId, ScrapeDefinition<IAzureResourceDefinition> scrapeDefinition, TResourceDefinition resourceDefinition, AggregationType aggregationType, TimeSpan aggregationInterval)
{
var resourceUri = BuildResourceUri(AzureMetadata.SubscriptionId, scrapeDefinition, resourceDefinition);

var metricFilter = DetermineMetricFilter(resourceDefinition);
var metricName = scrapeDefinition.AzureMetricConfiguration.MetricName;
var dimensionName = scrapeDefinition.AzureMetricConfiguration.Dimension?.Name;
var foundMetricValue = await AzureMonitorClient.QueryMetricAsync(metricName, dimensionName, aggregationType, aggregationInterval, resourceUri, metricFilter);

var instanceName = resourceDefinition.GetResourceName();
var metricLabels = DetermineMetricLabels(resourceDefinition);

return new ScrapeResult(subscriptionId, scrapeDefinition.ResourceGroupName, instanceName, resourceUri, foundMetricValue, metricLabels);
}

/// <summary>
/// Determines the metric filter to use
/// </summary>
/// <param name="resourceDefinition">Contains the resource cast to the specific resource type.</param>
protected virtual string DetermineMetricFilter(TResourceDefinition resourceDefinition)
{
return null;
}

/// <summary>
/// Determines the metric labels to include in the reported metric
/// </summary>
/// <param name="resourceDefinition">Contains the resource cast to the specific resource type.</param>
protected virtual Dictionary<string, string> DetermineMetricLabels(TResourceDefinition resourceDefinition)
{
return new Dictionary<string, string>();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
namespace Promitor.Core.Scraping.Configuration.Model.Metrics
{
/// <summary>
/// Describes a resource in Azure that can be scraped. Inheriting classes can add whatever
/// additional information is required to scrape a particular Azure resource.
/// Describes a resource in Azure that can be scraped. Inheriting classes can add whatever
/// additional information is required to scrape a particular Azure resource.
/// </summary>
public abstract class AzureResourceDefinition
public abstract class AzureResourceDefinition : IAzureResourceDefinition
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="resourceType">Type of resource that is configured</param>
/// <param name="resourceGroupName">Specify a resource group to scrape that defers from the default resource group.</param>
protected AzureResourceDefinition(ResourceType resourceType, string resourceGroupName)
{
ResourceType = resourceType;
Expand All @@ -22,5 +27,8 @@ protected AzureResourceDefinition(ResourceType resourceType, string resourceGrou
/// This enables you to do multi-resource group scraping with one configuration file.
/// </summary>
public string ResourceGroupName { get; }

/// <inheritdoc />
public abstract string GetResourceName();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Promitor.Core.Scraping.Configuration.Model.Metrics
{
public interface IAppServiceResourceDefinition : IAzureResourceDefinition
{
public string SlotName { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Promitor.Core.Scraping.Configuration.Model.Metrics
{
/// <summary>
/// Describes a resource in Azure that can be scraped. Inheriting classes can add whatever
/// additional information is required to scrape a particular Azure resource.
/// </summary>
public interface IAzureResourceDefinition
{
/// <summary>
/// Type of resource that is configured
/// </summary>
public ResourceType ResourceType { get; }

/// <summary>
/// Specify a resource group to scrape that defers from the default resource group.
/// This enables you to do multi-resource group scraping with one configuration file.
/// </summary>
public string ResourceGroupName { get; }

/// <summary>
/// Gets the name of the resource
/// </summary>
/// <remarks>This should return the name of the main resource</remarks>
/// <example>
/// For an Azure SQL Database it should be the name of the DB, not the server
/// </example>
string GetResourceName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public MetricDefinition(PrometheusMetricDefinition prometheusMetricDefinition,
Scraping scraping,
AzureMetricConfiguration azureMetricConfiguration,
ResourceType resourceType,
List<AzureResourceDefinition> resources)
List<IAzureResourceDefinition> resources)
{
AzureMetricConfiguration = azureMetricConfiguration;
PrometheusMetricDefinition = prometheusMetricDefinition;
Expand Down Expand Up @@ -44,17 +44,17 @@ public MetricDefinition(PrometheusMetricDefinition prometheusMetricDefinition,
/// <summary>
/// Gets or sets the list of resources to scrape.
/// </summary>
public List<AzureResourceDefinition> Resources { get; set; }
public List<IAzureResourceDefinition> Resources { get; set; }

/// <summary>
/// Creates a <see cref="ScrapeDefinition{TResourceDefinition}"/> object for the specified resource.
/// </summary>
/// <param name="resource">The resource to scrape.</param>
/// <param name="azureMetadata">The Azure global metadata.</param>
/// <returns>The scrape definition.</returns>
public ScrapeDefinition<AzureResourceDefinition> CreateScrapeDefinition(AzureResourceDefinition resource, AzureMetadata azureMetadata)
public ScrapeDefinition<IAzureResourceDefinition> CreateScrapeDefinition(IAzureResourceDefinition resource, AzureMetadata azureMetadata)
{
return new ScrapeDefinition<AzureResourceDefinition>(
return new ScrapeDefinition<IAzureResourceDefinition>(
AzureMetricConfiguration,
PrometheusMetricDefinition,
Scraping,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ public AppPlanResourceDefinition(string resourceGroupName, string appPlanName)
/// The name of the Azure App Plan to get metrics for.
/// </summary>
public string AppPlanName { get; set; }

/// <inheritdoc />
public override string GetResourceName() => AppPlanName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public ContainerInstanceResourceDefinition(string resourceGroupName, string cont
}

public string ContainerGroup { get; }

/// <inheritdoc />
public override string GetResourceName() => ContainerGroup;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public ContainerRegistryResourceDefinition(string resourceGroupName, string regi
}

public string RegistryName { get; }

/// <inheritdoc />
public override string GetResourceName() => RegistryName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public CosmosDbResourceDefinition(string resourceGroupName, string dbName)
}

public string DbName { get; }

/// <inheritdoc />
public override string GetResourceName() => DbName;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes
{
public class FunctionAppResourceDefinition : AzureResourceDefinition
public class FunctionAppResourceDefinition : AzureResourceDefinition, IAppServiceResourceDefinition
{
public FunctionAppResourceDefinition(string resourceGroupName, string functionAppName)
: base(ResourceType.FunctionApp, resourceGroupName)
Expand All @@ -17,5 +17,8 @@ public FunctionAppResourceDefinition(string resourceGroupName, string functionAp
/// The name of the deployment slot.
/// </summary>
public string SlotName { get; set; }

/// <inheritdoc />
public override string GetResourceName() => FunctionAppName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public GenericAzureResourceDefinition(string resourceGroupName, string filter, s

public string Filter { get; }
public string ResourceUri { get; }

/// <inheritdoc />
public override string GetResourceName() => null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public NetworkInterfaceResourceDefinition(string resourceGroupName, string netwo
}

public string NetworkInterfaceName { get; }

/// <inheritdoc />
public override string GetResourceName() => NetworkInterfaceName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public PostgreSqlResourceDefinition(string resourceGroupName, string serverName)
}

public string ServerName { get; }

/// <inheritdoc />
public override string GetResourceName() => ServerName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public RedisCacheResourceDefinition(string resourceGroupName, string cacheName)
}

public string CacheName { get; }

/// <inheritdoc />
public override string GetResourceName() => CacheName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public ServiceBusQueueResourceDefinition(string resourceGroupName, string ns, st

public string Namespace { get; }
public string QueueName { get; }

/// <inheritdoc />
public override string GetResourceName() => QueueName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ public SqlDatabaseResourceDefinition(string resourceGroupName, string serverName
/// The name of the database.
/// </summary>
public string DatabaseName { get; }

/// <inheritdoc />
public override string GetResourceName() => DatabaseName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ public SqlManagedInstanceResourceDefinition(string resourceGroupName, string ins
/// The name of the Azure SQL Managed Instance resource.
/// </summary>
public string InstanceName { get; }

/// <inheritdoc />
public override string GetResourceName() => InstanceName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ public StorageQueueResourceDefinition(string resourceGroupName, string accountNa
public string AccountName { get; }
public string QueueName { get; }
public Secret SasToken { get; }

/// <inheritdoc />
public override string GetResourceName() => AccountName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public VirtualMachineResourceDefinition(string resourceGroupName, string virtual
}

public string VirtualMachineName { get; }

/// <inheritdoc />
public override string GetResourceName() => VirtualMachineName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ public VirtualMachineScaleSetResourceDefinition(string resourceGroupName, string
}

public string ScaleSetName { get; }

/// <inheritdoc />
public override string GetResourceName() => ScaleSetName;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes
{
public class WebAppResourceDefinition : AzureResourceDefinition
public class WebAppResourceDefinition : AzureResourceDefinition, IAppServiceResourceDefinition
{
public WebAppResourceDefinition(string resourceGroupName, string webAppName, string slotName)
: base(ResourceType.WebApp, resourceGroupName)
Expand All @@ -18,5 +18,8 @@ public WebAppResourceDefinition(string resourceGroupName, string webAppName, str
/// The name of the deployment slot.
/// </summary>
public string SlotName { get; set; }

/// <inheritdoc />
public override string GetResourceName() => WebAppName;
}
}
Loading

0 comments on commit c2aa7c4

Please sign in to comment.