-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
#3349) * Reapply "track total content length and files indexed (#3318)" (#3346) This reverts commit 8a0247d. * add FunctionsPreservedDependencies so openTelemetry can be used / DiagnosticSource loaded as needed by functions host
- Loading branch information
Showing
27 changed files
with
7,165 additions
and
3 deletions.
There are no files selected for viewing
38 changes: 38 additions & 0 deletions
38
src/Microsoft.Health.Dicom.Core/Features/Common/IndexedFileProperties.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// ------------------------------------------------------------------------------------------------- | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. | ||
// ------------------------------------------------------------------------------------------------- | ||
|
||
using System; | ||
|
||
namespace Microsoft.Health.Dicom.Core.Features.Common; | ||
|
||
/// <summary> | ||
/// Metadata on FileProperty table in database | ||
/// </summary> | ||
public readonly struct IndexedFileProperties : IEquatable<IndexedFileProperties> | ||
{ | ||
/// <summary> | ||
/// Total indexed FileProperty in database | ||
/// </summary> | ||
public long TotalIndexed { get; init; } | ||
|
||
/// <summary> | ||
/// Total sum of all ContentLength rows in FileProperty table | ||
/// </summary> | ||
public long TotalSum { get; init; } | ||
|
||
public override bool Equals(object obj) => obj is IndexedFileProperties other && Equals(other); | ||
|
||
public bool Equals(IndexedFileProperties other) | ||
=> TotalIndexed == other.TotalIndexed && TotalSum == other.TotalSum; | ||
|
||
public override int GetHashCode() | ||
=> HashCode.Combine(TotalIndexed, TotalSum); | ||
|
||
public static bool operator ==(IndexedFileProperties left, IndexedFileProperties right) | ||
=> left.Equals(right); | ||
|
||
public static bool operator !=(IndexedFileProperties left, IndexedFileProperties right) | ||
=> !(left == right); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/Microsoft.Health.Dicom.Core/Features/Telemetry/MetricPointExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// ------------------------------------------------------------------------------------------------- | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. | ||
// ------------------------------------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using OpenTelemetry.Metrics; | ||
|
||
namespace Microsoft.Health.Dicom.Core.Features.Telemetry; | ||
|
||
/// <summary> | ||
/// Since only enumerators are exposed publicly for working with tags or getting the collection of | ||
/// metrics, these extension facilitate getting both. | ||
/// </summary> | ||
public static class MetricPointExtensions | ||
{ | ||
/// <summary> | ||
/// Get tags key value pairs from metric point. | ||
/// </summary> | ||
public static Dictionary<string, object> GetTags(this MetricPoint metricPoint) | ||
{ | ||
var tags = new Dictionary<string, object>(); | ||
foreach (var pair in metricPoint.Tags) | ||
{ | ||
tags.Add(pair.Key, pair.Value); | ||
} | ||
|
||
return tags; | ||
} | ||
|
||
/// <summary> | ||
/// Get all metrics emitted after flushing. | ||
/// </summary> | ||
[SuppressMessage("Performance", "CA1859: Use concrete types when possible for improved performance", Justification = "Result should be read-only.")] | ||
public static IReadOnlyList<MetricPoint> GetMetricPoints(this ICollection<Metric> exportedItems, string metricName) | ||
{ | ||
MetricPointsAccessor accessor = exportedItems | ||
.Single(item => item.Name.Equals(metricName, StringComparison.Ordinal)) | ||
.GetMetricPoints(); | ||
var metrics = new List<MetricPoint>(); | ||
foreach (MetricPoint metricPoint in accessor) | ||
{ | ||
metrics.Add(metricPoint); | ||
} | ||
|
||
return metrics; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...h.Dicom.Functions.UnitTests/IndexMetricsCollection/IndexMetricsCollectionFunctionTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// ------------------------------------------------------------------------------------------------- | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. | ||
// ------------------------------------------------------------------------------------------------- | ||
|
||
using System.Threading.Tasks; | ||
using Microsoft.Azure.WebJobs; | ||
using Microsoft.Extensions.Logging.Abstractions; | ||
using Microsoft.Extensions.Options; | ||
using Microsoft.Health.Dicom.Core.Configs; | ||
using Microsoft.Health.Dicom.Core.Features.Common; | ||
using Microsoft.Health.Dicom.Core.Features.Store; | ||
using Microsoft.Health.Dicom.Functions.MetricsCollection; | ||
using NSubstitute; | ||
using Xunit; | ||
|
||
namespace Microsoft.Health.Dicom.Functions.UnitTests.IndexMetricsCollection; | ||
|
||
public class IndexMetricsCollectionFunctionTests | ||
{ | ||
private readonly IndexMetricsCollectionFunction _collectionFunction; | ||
private readonly IIndexDataStore _indexStore; | ||
private readonly TimerInfo _timer; | ||
|
||
public IndexMetricsCollectionFunctionTests() | ||
{ | ||
_indexStore = Substitute.For<IIndexDataStore>(); | ||
_collectionFunction = new IndexMetricsCollectionFunction( | ||
_indexStore, | ||
Options.Create(new FeatureConfiguration { EnableExternalStore = true, })); | ||
_timer = Substitute.For<TimerInfo>(default, default, default); | ||
} | ||
|
||
[Fact] | ||
public async Task GivenIndexMetricsCollectionFunction_WhenRun_CollectionExecutedWhenExternalStoreEnabled() | ||
{ | ||
_indexStore.GetIndexedFileMetricsAsync().ReturnsForAnyArgs(new IndexedFileProperties()); | ||
|
||
await _collectionFunction.Run(_timer, NullLogger.Instance); | ||
|
||
await _indexStore.ReceivedWithAnyArgs(1).GetIndexedFileMetricsAsync(); | ||
} | ||
|
||
[Fact] | ||
public async Task GivenIndexMetricsCollectionFunction_WhenRun_CollectionNotExecutedWhenExternalStoreNotEnabled() | ||
{ | ||
_indexStore.GetIndexedFileMetricsAsync().ReturnsForAnyArgs(new IndexedFileProperties()); | ||
var collectionFunctionWihtoutExternalStore = new IndexMetricsCollectionFunction( | ||
_indexStore, | ||
Options.Create(new FeatureConfiguration { EnableExternalStore = false, })); | ||
|
||
await collectionFunctionWihtoutExternalStore.Run(_timer, NullLogger.Instance); | ||
|
||
await _indexStore.DidNotReceiveWithAnyArgs().GetIndexedFileMetricsAsync(); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
src/Microsoft.Health.Dicom.Functions/MetricsCollection/IndexMetricsCollectionFunction.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// ------------------------------------------------------------------------------------------------- | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. | ||
// ------------------------------------------------------------------------------------------------- | ||
|
||
using System.Threading.Tasks; | ||
using EnsureThat; | ||
using Microsoft.Azure.WebJobs; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
using Microsoft.Health.Dicom.Core.Configs; | ||
using Microsoft.Health.Dicom.Core.Features.Common; | ||
using Microsoft.Health.Dicom.Core.Features.Store; | ||
using Microsoft.Health.Functions.Extensions; | ||
|
||
namespace Microsoft.Health.Dicom.Functions.MetricsCollection; | ||
|
||
/// <summary> | ||
/// A function for collecting index metrics | ||
/// </summary> | ||
public class IndexMetricsCollectionFunction | ||
{ | ||
private readonly IIndexDataStore _indexDataStore; | ||
private readonly bool _externalStoreEnabled; | ||
private readonly bool _enableDataPartitions; | ||
private const string RunFrequencyVariable = $"%{AzureFunctionsJobHost.RootSectionName}:DicomFunctions:{IndexMetricsCollectionOptions.SectionName}:{nameof(IndexMetricsCollectionOptions.Frequency)}%"; | ||
|
||
public IndexMetricsCollectionFunction( | ||
IIndexDataStore indexDataStore, | ||
IOptions<FeatureConfiguration> featureConfiguration) | ||
{ | ||
EnsureArg.IsNotNull(featureConfiguration, nameof(featureConfiguration)); | ||
_indexDataStore = EnsureArg.IsNotNull(indexDataStore, nameof(indexDataStore)); | ||
_externalStoreEnabled = featureConfiguration.Value.EnableExternalStore; | ||
_enableDataPartitions = featureConfiguration.Value.EnableDataPartitions; | ||
} | ||
|
||
/// <summary> | ||
/// Asynchronously collects index metrics. | ||
/// </summary> | ||
/// <param name="invocationTimer">The timer which tracks the invocation schedule.</param> | ||
/// <param name="log">A diagnostic logger.</param> | ||
/// <returns>A task that represents the asynchronous metrics collection operation.</returns> | ||
[FunctionName(nameof(IndexMetricsCollectionFunction))] | ||
public async Task Run( | ||
[TimerTrigger(RunFrequencyVariable)] TimerInfo invocationTimer, | ||
ILogger log) | ||
{ | ||
EnsureArg.IsNotNull(invocationTimer, nameof(invocationTimer)); | ||
EnsureArg.IsNotNull(log, nameof(log)); | ||
if (!_externalStoreEnabled) | ||
{ | ||
log.LogInformation("External store is not enabled. Skipping index metrics collection."); | ||
return; | ||
} | ||
|
||
if (invocationTimer.IsPastDue) | ||
{ | ||
log.LogWarning("Current function invocation is running late."); | ||
} | ||
IndexedFileProperties indexedFileProperties = await _indexDataStore.GetIndexedFileMetricsAsync(); | ||
|
||
log.LogInformation( | ||
"DICOM telemetry - TotalFilesIndexed: {TotalFilesIndexed} , TotalByesIndexed: {TotalContentLengthIndexed} , with ExternalStoreEnabled: {ExternalStoreEnabled} and DataPartitionsEnabled: {PartitionsEnabled}", | ||
indexedFileProperties.TotalIndexed, | ||
indexedFileProperties.TotalSum, | ||
_externalStoreEnabled, | ||
_enableDataPartitions); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/Microsoft.Health.Dicom.Functions/MetricsCollection/IndexMetricsCollectionOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// ------------------------------------------------------------------------------------------------- | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. | ||
// ------------------------------------------------------------------------------------------------- | ||
|
||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace Microsoft.Health.Dicom.Functions.MetricsCollection; | ||
|
||
/// <summary> | ||
/// Options on collecting indexing metrics | ||
/// </summary> | ||
public class IndexMetricsCollectionOptions | ||
{ | ||
/// <summary> | ||
/// The default section name for <see cref="IndexMetricsCollectionOptions"/> in a configuration. | ||
/// </summary> | ||
public const string SectionName = "IndexMetricsCollection"; | ||
|
||
/// <summary> | ||
/// Gets or sets the cron expression that indicates how frequently to run the index metrics collection function. | ||
/// </summary> | ||
/// <value>A value cron expression</value> | ||
[Required] | ||
public string Frequency { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
src/Microsoft.Health.Dicom.SqlServer/Features/Schema/Migrations/57.diff.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
SET XACT_ABORT ON | ||
|
||
BEGIN TRANSACTION | ||
GO | ||
CREATE OR ALTER PROCEDURE dbo.GetIndexedFileMetrics | ||
AS | ||
BEGIN | ||
SET NOCOUNT ON; | ||
SET XACT_ABORT ON; | ||
SELECT TotalIndexedFileCount=COUNT_BIG(*), | ||
TotalIndexedBytes=SUM(ContentLength) | ||
FROM dbo.FileProperty; | ||
END | ||
GO | ||
|
||
COMMIT TRANSACTION | ||
|
||
IF NOT EXISTS | ||
( | ||
SELECT * | ||
FROM sys.indexes | ||
WHERE NAME = 'IXC_FileProperty_ContentLength' | ||
AND Object_id = OBJECT_ID('dbo.FileProperty') | ||
) | ||
BEGIN | ||
CREATE NONCLUSTERED INDEX IXC_FileProperty_ContentLength ON dbo.FileProperty | ||
( | ||
ContentLength | ||
) WITH (DATA_COMPRESSION = PAGE, ONLINE = ON) | ||
END | ||
GO |
Oops, something went wrong.