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

Improve resource discovery & Prometheus setup #1235

Merged
merged 3 commits into from
Aug 20, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public GraphQueryBuilder LimitTo(int limit)

public string Build()
{
return _queryBuilder.ToString();
return _queryBuilder.ToString().Trim();
}

private void FilterByField(string fieldName, List<string> allowedValues)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Promitor.Agents.ResourceDiscovery.Graph.ResourceTypes
public abstract class AppServiceResourceDiscoveryQuery : ResourceDiscoveryQuery
{
public override string[] ResourceTypes => new[] { "microsoft.web/sites", "microsoft.web/sites/slots" };
public override string[] ProjectedFieldNames => new[] { "subscriptionId", "resourceGroup", "type", "name", "id" };
public override string[] ProjectedFieldNames => new[] { "subscriptionId", "resourceGroup", "type", "name", "id", "kind" };

public (string AppName, string SlotName) DetermineAppDetails(string resourceName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public ResourceDiscoveryClient(HttpClient httpClient, IOptionsMonitor<ResourceDi

public async Task<List<AzureResourceDefinition>> GetAsync(string resourceDiscoveryGroupName)
{
var uri = $"/api/v1/resources/groups/{resourceDiscoveryGroupName}/discover";
var uri = $"api/v1/resources/groups/{resourceDiscoveryGroupName}/discover";
var rawResponse = await SendGetRequestAsync(uri);

var foundResources = JsonConvert.DeserializeObject<List<AzureResourceDefinition>>(rawResponse, _serializerSettings);
Expand All @@ -45,14 +45,15 @@ public async Task<List<AzureResourceDefinition>> GetAsync(string resourceDiscove

public async Task<HealthReport> GetHealthAsync()
{
var rawResponse = await SendGetRequestAsync("/api/v1/health");
var rawResponse = await SendGetRequestAsync("api/v1/health");
var healthReport = JsonConvert.DeserializeObject<HealthReport>(rawResponse, new HealthReportEntryConverter());
return healthReport;
}

private async Task<string> SendGetRequestAsync(string uri)
private async Task<string> SendGetRequestAsync(string uriPath)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
var url = ComposeUrl(uriPath);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);

var response = await SendRequestToApiAsync(request);
response.EnsureSuccessStatusCode();
Expand All @@ -68,7 +69,6 @@ private async Task<HttpResponseMessage> SendRequestToApiAsync(HttpRequestMessage
HttpResponseMessage response = null;
try
{
_httpClient.BaseAddress = new Uri($"http://{_configuration.CurrentValue.Host}:{_configuration.CurrentValue.Port}");
response = await _httpClient.SendAsync(request);
_logger.LogRequest(request, response, dependencyMeasurement.Elapsed);

Expand All @@ -88,5 +88,10 @@ private async Task<HttpResponseMessage> SendRequestToApiAsync(HttpRequestMessage
}
}
}

private Uri ComposeUrl(string uriPath)
{
return new Uri($"http://{_configuration.CurrentValue.Host}:{_configuration.CurrentValue.Port}/{uriPath}");
}
}
}
15 changes: 15 additions & 0 deletions src/Promitor.Agents.Scraper/Docs/Open-Api.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using JustEat.StatsD;
using GuardNet;
using JustEat.StatsD;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Prometheus.Client;
using Prometheus.Client.Abstractions;
using Prometheus.Client.DependencyInjection;
using Promitor.Agents.Core.Configuration.Server;
using Promitor.Agents.Core.Configuration.Telemetry;
using Promitor.Agents.Core.Configuration.Telemetry.Sinks;
Expand All @@ -13,17 +13,18 @@
using Promitor.Agents.Scraper.Configuration;
using Promitor.Agents.Scraper.Configuration.Sinks;
using Promitor.Agents.Scraper.Discovery;
using Promitor.Agents.Scraper.Validation.Steps;
using Promitor.Agents.Scraper.Validation.Steps.Sinks;
using Promitor.Core;
using Promitor.Core.Metrics;
using Promitor.Core.Metrics.Sinks;
using Promitor.Core.Scraping.Configuration.Providers;
using Promitor.Core.Scraping.Configuration.Providers.Interfaces;
using Promitor.Core.Scraping.Configuration.Runtime;
using Promitor.Core.Scraping.Configuration.Serialization;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Core;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Model;
using Promitor.Core.Scraping.Factories;
using Promitor.Agents.Scraper.Validation.Steps;
using Promitor.Agents.Scraper.Validation.Steps.Sinks;
using Promitor.Core.Metrics;
using Promitor.Core.Metrics.Sinks;
using Promitor.Core.Scraping.Configuration.Runtime;
using Promitor.Integrations.AzureMonitor.Configuration;
using Promitor.Integrations.Sinks.Atlassian.Statuspage;
using Promitor.Integrations.Sinks.Atlassian.Statuspage.Configuration;
Expand All @@ -38,13 +39,57 @@ namespace Microsoft.Extensions.DependencyInjection
// ReSharper disable once InconsistentNaming
public static class IServiceCollectionExtensions
{
/// <summary>
/// Add the Promitor Resource Discovery client
/// </summary>
/// <param name="services">Collections of services in application</param>
/// <param name="promitorUserAgent">User agent for Promitor</param>
public static IServiceCollection AddResourceDiscoveryClient(this IServiceCollection services, string promitorUserAgent)
{
Guard.NotNull(services, nameof(services));

services.AddHttpClient<ResourceDiscoveryClient>(client =>
{
// Provide Promitor User-Agent
client.DefaultRequestHeaders.UserAgent.TryParseAdd(promitorUserAgent);
});
services.AddTransient<ResourceDiscoveryRepository>();

return services;
}

/// <summary>
/// Add the Atlassian Statuspage client
/// </summary>
/// <param name="services">Collections of services in application</param>
/// <param name="promitorUserAgent">User agent for Promitor</param>
/// <param name="configuration">Configuration of the agent</param>
public static IServiceCollection AddAtlassianStatuspageClient(this IServiceCollection services, string promitorUserAgent, IConfiguration configuration)
{
Guard.NotNull(services, nameof(services));

services.AddHttpClient<IAtlassianStatuspageClient, AtlassianStatuspageClient>(client =>
{
// Provide Promitor User-Agent
client.DefaultRequestHeaders.UserAgent.TryParseAdd(promitorUserAgent);

// Auth all requests
var apiKey = configuration[EnvironmentVariables.Integrations.AtlassianStatuspage.ApiKey];
client.DefaultRequestHeaders.Add("Authorization", $"OAuth {apiKey}");
});
services.AddTransient<ResourceDiscoveryRepository>();

return services;
}

/// <summary>
/// Defines the dependencies that Promitor requires
/// </summary>
/// <param name="services">Collections of services in application</param>
public static IServiceCollection DefineDependencies(this IServiceCollection services)
{
services.AddTransient<ResourceDiscoveryRepository>();
Guard.NotNull(services, nameof(services));

services.AddTransient<IMetricsDeclarationProvider, MetricsDeclarationProvider>();
services.AddTransient<IRuntimeMetricsCollector, RuntimeMetricsCollector>();
services.AddTransient<MetricScraperFactory>();
Expand All @@ -66,6 +111,7 @@ public static IServiceCollection DefineDependencies(this IServiceCollection serv

return services;
}

/// <summary>
/// Defines the validation for when Promitor starts up
/// </summary>
Expand Down Expand Up @@ -114,7 +160,7 @@ public static IServiceCollection UseMetricSinks(this IServiceCollection services

private static void AddPrometheusMetricSink(IServiceCollection services)
{
services.AddSingleton<IMetricFactory, MetricFactory>(serviceProvider => new MetricFactory(Metrics.DefaultCollectorRegistry));
services.AddMetricFactory();
services.AddTransient<IMetricSink, PrometheusScrapingEndpointMetricSink>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
<PackageReference Include="AutoMapper" Version="10.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.0.1" />
<PackageReference Include="CronScheduler.AspNetCore" Version="3.0.0" />
<PackageReference Include="Prometheus.Client.AspNetCore" Version="4.0.0" />
<PackageReference Include="Prometheus.Client.AspNetCore" Version="4.1.0" />
<PackageReference Include="Prometheus.Client.DependencyInjection" Version="0.1.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="YamlDotNet" Version="8.1.2" />
</ItemGroup>
Expand Down
21 changes: 4 additions & 17 deletions src/Promitor.Agents.Scraper/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
using Promitor.Agents.Core;
using Promitor.Agents.Scraper.Configuration;
using Promitor.Agents.Scraper.Configuration.Sinks;
using Promitor.Agents.Scraper.Discovery;
using Promitor.Agents.Scraper.Extensions;
using Promitor.Core;
using Promitor.Core.Scraping.Configuration.Serialization.v1.Mapping;
using Promitor.Integrations.AzureMonitor.Logging;
using Promitor.Integrations.Sinks.Atlassian.Statuspage;
using Serilog;
using Version = Promitor.Core.Version;

Expand All @@ -33,24 +31,13 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
string agentVersion = Version.Get();
var promitorUserAgent=UserAgent.Generate("Scraper", agentVersion);
string openApiDescription = BuildOpenApiDescription(Configuration);
services.AddHttpClient<ResourceDiscoveryClient>(client =>
{
// Provide Promitor User-Agent
client.DefaultRequestHeaders.UserAgent.TryParseAdd(promitorUserAgent);
});
services.AddHttpClient<IAtlassianStatuspageClient, AtlassianStatuspageClient>(client =>
{
// Provide Promitor User-Agent
client.DefaultRequestHeaders.UserAgent.TryParseAdd(promitorUserAgent);

// Auth all requests
var apiKey = Configuration[EnvironmentVariables.Integrations.AtlassianStatuspage.ApiKey];
client.DefaultRequestHeaders.Add("Authorization", $"OAuth {apiKey}");
});
var promitorUserAgent = UserAgent.Generate("Scraper", agentVersion);
string openApiDescription = BuildOpenApiDescription(Configuration);

services.UseWebApi()
.AddResourceDiscoveryClient(promitorUserAgent)
.AddAtlassianStatuspageClient(promitorUserAgent, Configuration)
.AddHttpCorrelation()
.AddAutoMapper(typeof(V1MappingProfile).Assembly)
.DefineDependencies()
Expand Down