Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Provide scraper for Azure Monitor Autoscale #1624

Merged
merged 3 commits into from
May 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/content/experimental/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ version:

#### Scraper

- {{% tag added %}} Provide scraper for Azure Monitor Autoscale ([docs](https://promitor.io/configuration/v2.x/metrics/monitor-autoscale)
| [#1593](https://github.com/tomkerkhove/promitor/issues/1593))
- {{% tag added %}} Provide capability to transform metric labels in Prometheus ([docs](https://promitor.io/configuration/v2.x/runtime/scraper#prometheus-scraping-endpoint)
- {{% tag added %}} Provide capability to limit the amount of resources to query when using filters/dimensions ([docs](https://promitor.io/configuration/v2.x/metrics)
| [#1596](https://github.com/tomkerkhove/promitor/issues/1596))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ resourceDiscoveryGroups:
type: IoTHub
- name: key-vaults
type: KeyVault
- name: autoscaling-rules
type: MonitorAutoscale
- name: network-interfaces
type: NetworkInterface
- name: postgres-databases
Expand Down
25 changes: 25 additions & 0 deletions config/promitor/scraper/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,31 @@ metricDefaults:
# Every minute
schedule: "0 * * ? * *"
metrics:
- name: promitor_demo_appplan_autoscale_instances_current_discovered
description: "Average amount of current instances for an Azure App Plan with Azure Monitor Autoscale"
resourceType: MonitorAutoscale
labels:
app: promitor
azureMetricConfiguration:
metricName: ObservedCapacity
aggregation:
type: Average
resourceDiscoveryGroups:
- name: autoscaling-rules
- name: promitor_demo_appplan_autoscale_observed_capacity
description: "Average amount of current instances for an Azure App Plan with Azure Monitor Autoscale"
resourceType: MonitorAutoscale
labels:
app: promitor
azureMetricConfiguration:
metricName: MetricThreshold
dimension:
name: MetricTriggerRule
aggregation:
type: Average
resources:
- autoscaleSettingsName: app-service-autoscaling-rules
resourceGroupName: demo
- name: promitor_demo_appplan_percentage_cpu
description: "Average percentage of memory usage on an Azure App Plan"
resourceType: AppPlan
Expand Down
1 change: 1 addition & 0 deletions docs/configuration/v2.x/metrics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ We also provide a simplified way to scrape the following Azure resources:
- [Azure Key Vault](key-vault)
- [Azure Kubernetes Service](kubernetes)
- [Azure Logic Apps](logic-apps)
- [Azure Monitor Autoscale](monitor-autoscale)
- [Azure Network Gateway](network-gateway)
- [Azure Network Interface](network-interface)
- [Azure Service Bus Namespace](service-bus-namespace)
Expand Down
40 changes: 40 additions & 0 deletions docs/configuration/v2.x/metrics/monitor-autoscale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
layout: default
title: Azure Monitor Autoscale Declaration
---

## Azure Monitor Autoscale

![Availability Badge](https://img.shields.io/badge/Available%20Starting-v2.3-green.svg)![Resource Discovery Support Badge](https://img.shields.io/badge/Support%20for%20Resource%20Discovery-Yes-green.svg)

You can declare to scrape an Azure Monitor Autoscale via the `MonitorAutoscale`
resource type.

When using declared resources, the following fields need to be provided:

- `autoscaleSettingsName` - The name of the Azure Monitor Autoscale settings

All supported metrics are documented in the official [Azure Monitor documentation](https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/metrics-supported#microsoftinsightsautoscalesettings).

Example:

```yaml
- name: promitor_demo_appplan_autoscale_observed_capacity
description: "Average amount of current instances for an Azure App Plan with Azure Monitor Autoscale"
resourceType: MonitorAutoscale
labels:
app: promitor
azureMetricConfiguration:
metricName: ObservedCapacity
aggregation:
type: Average
resources: # Optional, required when no resource discovery is configured
- autoscaleSettingsName: app-service-autoscaling-rules
resourceDiscoveryGroups: # Optional, requires Promitor Resource Discovery agent (https://promitor.io/concepts/how-it-works#using-resource-discovery)
- name: autoscaling-rules
```

<!-- markdownlint-disable MD033 -->
[&larr; back to metrics declarations](/configuration/v2.x/metrics)<br />
[&larr; back to introduction](/)
<!-- markdownlint-enable -->
1 change: 1 addition & 0 deletions docs/configuration/v2.x/resource-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ Dynamic resource discovery is supported for the following scrapers:
- [Azure Key Vault](metrics/key-vault)
- [Azure Kubernetes Service](metrics/kubernetes)
- [Azure Logic Apps](metrics/logic-apps)
- [Azure Monitor Autoscale](metrics/monitor-autoscale)
- [Azure Network Gateway](metrics/network-gateway)
- [Azure Network Interface](metrics/network-interface)
- [Azure Service Bus Namespace](metrics/service-bus-namespace)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public static ResourceDiscoveryQuery UseResourceDiscoveryFor(ResourceType resour
return new KubernetesServiceDiscoveryQuery();
case ResourceType.LogicApp:
return new LogicAppDiscoveryQuery();
case ResourceType.MonitorAutoscale:
return new MonitorAutoscaleDiscoveryQuery();
case ResourceType.NetworkGateway:
return new NetworkGatewayDiscoveryQuery();
case ResourceType.NetworkInterface:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using GuardNet;
using Newtonsoft.Json.Linq;
using Promitor.Core.Contracts;
using Promitor.Core.Contracts.ResourceTypes;

namespace Promitor.Agents.ResourceDiscovery.Graph.ResourceTypes
{
public class MonitorAutoscaleDiscoveryQuery : ResourceDiscoveryQuery
{
public override string[] ResourceTypes => new[] { "microsoft.insights/autoscalesettings" };
public override string[] ProjectedFieldNames => new[] { "subscriptionId", "resourceGroup", "type", "name" };

public override AzureResourceDefinition ParseResults(JToken resultRowEntry)
{
Guard.NotNull(resultRowEntry, nameof(resultRowEntry));

var autoscaleSettingsName = resultRowEntry[3]?.ToString();

var resource = new MonitorAutoscaleResourceDefinition(resultRowEntry[0]?.ToString(), resultRowEntry[1]?.ToString(), autoscaleSettingsName);
return resource;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ internal static IMetricValidator GetValidatorFor(ResourceType resourceType)
return new KubernetesServiceMetricValidator();
case ResourceType.LogicApp:
return new LogicAppMetricValidator();
case ResourceType.MonitorAutoscale:
return new MonitorAutoscaleMetricValidator();
case ResourceType.NetworkGateway:
return new NetworkGatewayMetricValidator();
case ResourceType.NetworkInterface:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using GuardNet;
using Promitor.Core.Scraping.Configuration.Model.Metrics;
using Promitor.Agents.Scraper.Validation.MetricDefinitions.Interfaces;
using Promitor.Core.Contracts.ResourceTypes;

namespace Promitor.Agents.Scraper.Validation.MetricDefinitions.ResourceTypes
{
internal class MonitorAutoscaleMetricValidator : IMetricValidator
{
public IEnumerable<string> Validate(MetricDefinition metricDefinition)
{
Guard.NotNull(metricDefinition, nameof(metricDefinition));

foreach (var resourceDefinition in metricDefinition.Resources.Cast<MonitorAutoscaleResourceDefinition>())
{
if (string.IsNullOrWhiteSpace(resourceDefinition.AutoscaleSettingsName))
{
yield return "No Azure Monitor Autoscale settings name is configured";
}
}
}
}
}
3 changes: 2 additions & 1 deletion src/Promitor.Core.Contracts/ResourceType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public enum ResourceType
SqlElasticPool = 33,
SynapseApacheSparkPool = 34,
SynapseSqlPool = 35,
SynapseWorkspace = 36
SynapseWorkspace = 36,
MonitorAutoscale = 37
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Promitor.Core.Contracts.ResourceTypes
{
public class MonitorAutoscaleResourceDefinition : AzureResourceDefinition
{
public MonitorAutoscaleResourceDefinition(string subscriptionId, string resourceGroupName, string autoscaleSettingsName)
: base(ResourceType.MonitorAutoscale, subscriptionId, resourceGroupName, autoscaleSettingsName)
{
AutoscaleSettingsName = autoscaleSettingsName;
}

public string AutoscaleSettingsName { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public IDeserializer<AzureResourceDefinitionV1> GetDeserializerFor(ResourceType
case ResourceType.LogicApp:
var logicAppLogger = _loggerFactory.CreateLogger<LogicAppDeserializer>();
return new LogicAppDeserializer(logicAppLogger);
case ResourceType.MonitorAutoscale:
var monitorAutoscaleLogger = _loggerFactory.CreateLogger<MonitorAutoscaleDeserializer>();
return new MonitorAutoscaleDeserializer(monitorAutoscaleLogger);
case ResourceType.NetworkGateway:
var networkGatewayLogger = _loggerFactory.CreateLogger<NetworkGatewayDeserializer>();
return new NetworkGatewayDeserializer(networkGatewayLogger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public V1MappingProfile()
CreateMap<KeyVaultResourceV1, KeyVaultResourceDefinition>();
CreateMap<KubernetesServiceResourceV1, KubernetesServiceResourceDefinition>();
CreateMap<LogicAppResourceV1, LogicAppResourceDefinition>();
CreateMap<MonitorAutoscaleResourceV1, MonitorAutoscaleResourceDefinition>();
CreateMap<NetworkGatewayResourceV1, NetworkGatewayResourceDefinition>();
CreateMap<NetworkInterfaceResourceV1, NetworkInterfaceResourceDefinition>();
CreateMap<PostgreSqlResourceV1, PostgreSqlResourceDefinition>();
Expand Down Expand Up @@ -85,6 +86,7 @@ public V1MappingProfile()
.Include<KeyVaultResourceV1, KeyVaultResourceDefinition>()
.Include<KubernetesServiceResourceV1, KubernetesServiceResourceDefinition>()
.Include<LogicAppResourceV1, LogicAppResourceDefinition>()
.Include<MonitorAutoscaleResourceV1, MonitorAutoscaleResourceDefinition>()
.Include<NetworkGatewayResourceV1, NetworkGatewayResourceDefinition>()
.Include<NetworkInterfaceResourceV1, NetworkInterfaceResourceDefinition>()
.Include<PostgreSqlResourceV1, PostgreSqlResourceDefinition>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes
{
/// <summary>
/// Contains the configuration required to scrape an Azure Monitor Autoscale settings.
/// </summary>
public class MonitorAutoscaleResourceV1 : AzureResourceDefinitionV1
{
/// <summary>
/// The name of the Azure Monitor Autoscale settings to get metrics for.
/// </summary>
public string AutoscaleSettingsName { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Microsoft.Extensions.Logging;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes;

namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers
{
public class MonitorAutoscaleDeserializer : ResourceDeserializer<MonitorAutoscaleResourceV1>
{
public MonitorAutoscaleDeserializer(ILogger<MonitorAutoscaleDeserializer> logger) : base(logger)
{
Map(resource => resource.AutoscaleSettingsName)
.IsRequired();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ public IScraper<IAzureResourceDefinition> CreateScraper(ResourceType metricDefin
return new KeyVaultScraper(scraperConfiguration);
case ResourceType.KubernetesService:
return new KubernetesServiceScraper(scraperConfiguration);
case ResourceType.LogicApp:
return new LogicAppScraper(scraperConfiguration);
case ResourceType.MonitorAutoscale:
return new MonitorAutoscaleScraper(scraperConfiguration);
case ResourceType.NetworkGateway:
return new NetworkGatewayScraper(scraperConfiguration);
case ResourceType.NetworkInterface:
return new NetworkInterfaceScraper(scraperConfiguration);
case ResourceType.LogicApp:
return new LogicAppScraper(scraperConfiguration);
case ResourceType.PostgreSql:
return new PostgreSqlScraper(scraperConfiguration);
case ResourceType.RedisCache:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Promitor.Core.Contracts;
using Promitor.Core.Contracts.ResourceTypes;
using Promitor.Core.Scraping.Configuration.Model.Metrics;

namespace Promitor.Core.Scraping.ResourceTypes
{
internal class MonitorAutoscaleScraper : AzureMonitorScraper<MonitorAutoscaleResourceDefinition>
{
private const string ResourceUriTemplate = "subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Insights/autoscalesettings/{2}";

public MonitorAutoscaleScraper(ScraperConfiguration scraperConfiguration)
: base(scraperConfiguration)
{
}

protected override string BuildResourceUri(string subscriptionId, ScrapeDefinition<IAzureResourceDefinition> scrapeDefinition, MonitorAutoscaleResourceDefinition resource)
{
return string.Format(ResourceUriTemplate, subscriptionId, scrapeDefinition.ResourceGroupName, resource.AutoscaleSettingsName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,24 @@ public MetricsDeclarationBuilder WithLogicAppMetric(string metricName = "promito
return this;
}

public MetricsDeclarationBuilder WithMonitorAutoscaleMetric(string metricName = "promitor-autoscale",
string metricDescription = "Description for a metric",
string autoscaleSettingsName = "promitor-autoscale-rules",
string azureMetricName = "ObservedCapacity",
string resourceDiscoveryGroupName = "",
int? azureMetricLimit = null,
bool omitResource = false)
{
var resource = new MonitorAutoscaleResourceV1
{
AutoscaleSettingsName = autoscaleSettingsName
};

CreateAndAddMetricDefinition(ResourceType.MonitorAutoscale, metricName, metricDescription, resourceDiscoveryGroupName, omitResource, azureMetricName, azureMetricLimit, resource);

return this;
}

public MetricsDeclarationBuilder WithCosmosDbMetric(string metricName = "promitor-cosmosdb",
string metricDescription = "Description for a metric",
string dbName = "promitor-cosmosdb",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.ComponentModel;
using Promitor.Core.Scraping.Configuration.Serialization;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Model;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers;
using Xunit;

namespace Promitor.Tests.Unit.Serialization.v1.Providers
{
[Category("Unit")]
public class MonitorAutoscaleDeserializerTests : ResourceDeserializerTest<MonitorAutoscaleDeserializer>
{
private readonly MonitorAutoscaleDeserializer _deserializer;

public MonitorAutoscaleDeserializerTests()
{
_deserializer = new MonitorAutoscaleDeserializer(Logger);
}

[Fact]
public void Deserialize_AutoscaleSettingsNameSupplied_SetsName()
{
YamlAssert.PropertySet<MonitorAutoscaleResourceV1, AzureResourceDefinitionV1, string>(
_deserializer,
"autoscaleSettingsName: promitor-application-gateway",
"promitor-application-gateway",
r => r.AutoscaleSettingsName);
}

[Fact]
public void Deserialize_AutoscaleSettingsNameNotSupplied_Null()
{
YamlAssert.PropertyNull<MonitorAutoscaleResourceV1, AzureResourceDefinitionV1>(
_deserializer,
"resourceGroupName: promitor-group",
r => r.AutoscaleSettingsName);
}

[Fact]
public void Deserialize_AutoscaleSettingsNameNotSupplied_ReportsError()
{
// Arrange
var node = YamlUtils.CreateYamlNode("resourceGroupName: promitor-group");

// Act / Assert
YamlAssert.ReportsErrorForProperty(
_deserializer,
node,
"autoscaleSettingsName");
}

protected override IDeserializer<AzureResourceDefinitionV1> CreateDeserializer()
{
return new MonitorAutoscaleDeserializer(Logger);
}
}
}
Loading