-
-
Notifications
You must be signed in to change notification settings - Fork 90
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 support for batch scraping #2459
base: master
Are you sure you want to change the base?
Conversation
Thank you for your contribution! 🙏 We will review it as soon as possible. |
|
||
public TimeSpan AggregationInterval{ get; } | ||
|
||
public override int GetHashCode() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this is a sane way to implement HashCode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need one? If not, let's remove it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea I have is to use hash code computation to enforce batch restrictions. This part should be sane.
How I'm choosing to implement hash code is hashing a unique string representation of ScrapeDefinitionBatch
. Curious what you think/can think of something better?
Thanks! Is it safe to say that the top of the diagram is current and bottom shows these changes? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start, added a few remarks but no concerns!
Logger.LogInformation("Batch scraping Azure Metric {AzureMetricName} for resource type {ResourceType}.", azureMetricName, resourceType); | ||
await ScheduleLimitedConcurrencyAsyncTask(tasks, () => ScrapeMetricBatched(batchScrapeDefinition), cancellationToken); | ||
} | ||
} | ||
|
||
foreach (var scrapeDefinition in scrapeDefinitions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need it if batch is enabled?
/// 1. Definitions in a batch must target the same resource type | ||
/// 2. Definitions in a batch must target the same Azure metric with identical dimensions | ||
/// 3. Definitions in a batch must have the same time granularity | ||
/// 4. Batch size cannot exceed configured maximum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add link to docs here for future reference
@@ -45,5 +45,20 @@ public class AzureMetricConfiguration | |||
} | |||
return Dimensions?.Any(dimension => dimension.Name.Equals(dimensionName, StringComparison.InvariantCultureIgnoreCase)); | |||
} | |||
|
|||
// A unique string to represent this Azure metric and its configured dimensions | |||
public string ToUniqueStringRepresentation() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this to identify unique groups?
Let's make sure we have proper unit tests for this before merging later on
{ | ||
public class MetricBatchScrapeConfig | ||
{ | ||
public bool Enabled { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's be explicit
public bool Enabled { get; set; } | |
public bool Enabled { get; set; } = false; |
Guard.NotNull(groupedScrapeDefinitions, nameof(groupedScrapeDefinitions)); | ||
Guard.NotNull(groupedScrapeDefinitions, nameof(scrapeDefinitionBatchProperties)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's guard for things that have no entries
Guard.NotNull(groupedScrapeDefinitions, nameof(groupedScrapeDefinitions)); | ||
Guard.NotNull(groupedScrapeDefinitions, nameof(scrapeDefinitionBatchProperties)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard.NotNull(groupedScrapeDefinitions, nameof(groupedScrapeDefinitions)); | |
Guard.NotNull(groupedScrapeDefinitions, nameof(scrapeDefinitionBatchProperties)); | |
Guard.NotNull(groupedScrapeDefinitions, nameof(groupedScrapeDefinitions)); | |
Guard.NotNull(scrapeDefinitionBatchProperties, nameof(scrapeDefinitionBatchProperties)); |
@@ -94,5 +94,14 @@ public class ScrapeDefinition<TResourceDefinition> where TResourceDefinition : c | |||
} | |||
return AzureMetricConfiguration?.Aggregation?.Interval; | |||
} | |||
|
|||
public ScrapeDefinitionBatchProperties buildPropertiesForBatch() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Massive nit
public ScrapeDefinitionBatchProperties buildPropertiesForBatch() { | |
public ScrapeDefinitionBatchProperties BuildScrapingBatchInfo() { |
|
||
public TimeSpan AggregationInterval{ get; } | ||
|
||
public override int GetHashCode() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need one? If not, let's remove it
/// <summary> | ||
/// Equality comparison override in case of hash collision | ||
/// </summary> | ||
public override bool Equals(object obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, let's remove if we don't need it
foreach (int i in Enumerable.Range(0, scrapedMetricResult.Count)) | ||
{ | ||
var scrapedMetricResult = scrapedMetricResult[i]; | ||
var scrapeDefinition = scrapeDefinitions[i]; | ||
LogMeasuredMetrics(scrapeDefinition, scrapedMetricResult, aggregationInterval); | ||
|
||
await _metricSinkWriter.ReportMetricAsync(scrapeDefinition.PrometheusMetricDefinition.Name, scrapeDefinition.PrometheusMetricDefinition.Description, scrapedMetricResult); | ||
|
||
await ReportScrapingOutcomeAsync(scrapeDefinition, isSuccessful: true, isBatchJob: true) ; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to fan this out to running tasks in parallel for every result, but can do that in a later update
Hey I'm revisiting this PR now since SDK migration is almost across the finish line. Do you know if the batch scraping API is available in sovereign clouds and what URLs we should use? We are particularly interested in the US Gov cloud. I can't find any information online(Azure doesn't really mentioned the existence of sovereign clouds to begin with) |
I do not know, sorry! What is the URL for public cloud? |
|
Awesome! How did you find this out? |
I reached out to the team :D |
@hkfgo Do you know if you'll have time to finalize this PR next week? I'd like to cut a release next week. |
We should plan for batch scraping to be on the release after this coming one. There are still a decent amount of work left and I'm not able to work on this full time. I do have time to get SDK migration done though. In that case we should have something major-ish to release :) |
That's OK - Thank you! |
Hey Tom, hope all is well! I worked on a PR to support batch scraping, got reasonably far, but sadly got blocked due to Promitor's current deprecated SDK. I think what I've written so far is enough to get some feedback though. Would love to know if you like this overall approach, w.r.t how batch scraping is configured, how scrape definitions are batched, the definition of the batch scrape job, etc. I've attached this diagram to illustrate my proposed change.
Meanwhile, I would love some input on SDK migration. I will comment separately on that issue. I think we need to migrate over to the new SDK and make sure all existing scraper features still work, before merging in changes to support batch scraping.
Implements #2284