Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.
/ NuGet.Jobs Public archive

Commit

Permalink
Add telemetry around report generation in Search.GenerateAuxiliaryData (
Browse files Browse the repository at this point in the history
  • Loading branch information
joelverhagen committed Mar 29, 2019
1 parent e8101f6 commit f9f08ff
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 11 deletions.
6 changes: 3 additions & 3 deletions src/Search.GenerateAuxiliaryData/BlobStorageExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ public BlobStorageExporter(ILogger<Exporter> logger, CloudBlobContainer sourceCo

public override async Task ExportAsync()
{
_logger.LogInformation("Copying {ReportName} report from {ConnectionString}/{SourceName}", _name, _sourceContainer.Uri, _sourceName);
_logger.LogInformation("Copying {ReportName} report from {ConnectionString}/{SourceName}", Name, _sourceContainer.Uri, _sourceName);

await _destinationContainer.CreateIfNotExistsAsync();

var sourceCloudBlob = _sourceContainer.GetBlockBlobReference(_sourceName);
var destinationCloudBlob = _destinationContainer.GetBlockBlobReference(_name);
var destinationCloudBlob = _destinationContainer.GetBlockBlobReference(Name);


await destinationCloudBlob.StartCopyAsync(sourceCloudBlob);
Expand All @@ -57,7 +57,7 @@ public override async Task ExportAsync()
throw new StorageException($"The blob copy operation had copy status {destinationCloudBlob.CopyState.Status} ({destinationCloudBlob.CopyState.StatusDescription}).");
}

_logger.LogInformation("Copy of {ReportName} completed. Took: {Seconds} seconds.", _name, stopwatch.Elapsed.TotalSeconds);
_logger.LogInformation("Copy of {ReportName} completed. Took: {Seconds} seconds.", Name, stopwatch.Elapsed.TotalSeconds);
}
}
}
8 changes: 4 additions & 4 deletions src/Search.GenerateAuxiliaryData/Exporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ namespace Search.GenerateAuxiliaryData
// Public only to facilitate testing.
public abstract class Exporter
{
protected ILogger<Exporter> _logger;
protected CloudBlobContainer _destinationContainer;
protected readonly ILogger<Exporter> _logger;
protected readonly CloudBlobContainer _destinationContainer;

protected string _name { get; }
public string Name { get; }

public Exporter(ILogger<Exporter> logger, CloudBlobContainer defaultDestinationContainer, string defaultName)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_destinationContainer = defaultDestinationContainer ?? throw new ArgumentNullException(nameof(defaultDestinationContainer));

_name = defaultName;
Name = defaultName;
}

public abstract Task ExportAsync();
Expand Down
16 changes: 15 additions & 1 deletion src/Search.GenerateAuxiliaryData/Job.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Autofac;
Expand All @@ -14,6 +15,7 @@
using Microsoft.WindowsAzure.Storage;
using NuGet.Jobs;
using NuGet.Jobs.Configuration;
using Search.GenerateAuxiliaryData.Telemetry;

namespace Search.GenerateAuxiliaryData
{
Expand All @@ -37,12 +39,14 @@ public class Job : JsonConfigurationJob
private List<Exporter> _exportersToRun;

private InitializationConfiguration Configuration { get; set; }
public ITelemetryService TelemetryService { get; private set; }

public override void Init(IServiceContainer serviceContainer, IDictionary<string, string> jobArgsDictionary)
{
base.Init(serviceContainer, jobArgsDictionary);

Configuration = _serviceProvider.GetRequiredService<IOptionsSnapshot<InitializationConfiguration>>().Value;
TelemetryService = _serviceProvider.GetRequiredService<ITelemetryService>();

var destinationContainer = CloudStorageAccount.Parse(Configuration.PrimaryDestination)
.CreateCloudBlobClient()
Expand Down Expand Up @@ -94,16 +98,24 @@ public override async Task Run()

foreach (Exporter exporter in _exportersToRun)
{
var exporterName = exporter.GetType().Name;
var reportName = exporter.Name;
var stopwatch = Stopwatch.StartNew();
var success = false;
try
{
await exporter.ExportAsync();
success = true;
}
catch (Exception e)
{
var exporterName = exporter.GetType().Name;
Logger.LogError("SQL exporter '{ExporterName}' failed: {Exception}", exporterName, e);
failedExporters.Add(exporterName);
}
finally
{
TelemetryService.TrackExporterDuration(exporterName, reportName, stopwatch.Elapsed, success);
}
}

if (failedExporters.Any())
Expand All @@ -119,6 +131,8 @@ protected override void ConfigureAutofacServices(ContainerBuilder containerBuild
protected override void ConfigureJobServices(IServiceCollection services, IConfigurationRoot configurationRoot)
{
ConfigureInitializationSection<InitializationConfiguration>(services, configurationRoot);

services.AddTransient<ITelemetryService, TelemetryService>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RankingsExporter.cs" />
<Compile Include="SqlExporter.cs" />
<Compile Include="Telemetry\ITelemetryService.cs" />
<Compile Include="Telemetry\TelemetryService.cs" />
<Compile Include="VerifiedPackagesExporter.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
5 changes: 2 additions & 3 deletions src/Search.GenerateAuxiliaryData/SqlExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public SqlExporter(
TimeSpan commandTimeout)
: base(logger, defaultDestinationContainer, defaultName)
{
_logger = logger;
OpenSqlConnectionAsync = openSqlConnectionAsync;
_commandTimeout = commandTimeout;
}
Expand All @@ -60,12 +59,12 @@ public override async Task ExportAsync()
using (var connection = await OpenSqlConnectionAsync())
{
_logger.LogInformation("Generating {ReportName} report from {DataSource}/{InitialCatalog}.",
_name, connection.DataSource, connection.Database);
Name, connection.DataSource, connection.Database);

result = GetResultOfQuery(connection);
}

await WriteToBlobAsync(_logger, _destinationContainer, result.ToString(Formatting.None), _name);
await WriteToBlobAsync(_logger, _destinationContainer, result.ToString(Formatting.None), Name);
}

protected abstract JContainer GetResultOfQuery(SqlConnection connection);
Expand Down
12 changes: 12 additions & 0 deletions src/Search.GenerateAuxiliaryData/Telemetry/ITelemetryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace Search.GenerateAuxiliaryData.Telemetry
{
public interface ITelemetryService
{
void TrackExporterDuration(string exporter, string report, TimeSpan duration, bool success);
}
}
34 changes: 34 additions & 0 deletions src/Search.GenerateAuxiliaryData/Telemetry/TelemetryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using NuGet.Services.Logging;

namespace Search.GenerateAuxiliaryData.Telemetry
{
public class TelemetryService : ITelemetryService
{
private const string Prefix = "Search.GenerateAuxiliaryData.";

private readonly ITelemetryClient _telemetryClient;

public TelemetryService(ITelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}

public void TrackExporterDuration(string exporter, string report, TimeSpan duration, bool success)
{
_telemetryClient.TrackMetric(
Prefix + "ExporterDurationMs",
duration.TotalMilliseconds,
new Dictionary<string, string>
{
{ "Exporter", exporter },
{ "Report", report },
{ "Success", success.ToString() },
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Moq;
using NuGet.Services.Logging;
using Search.GenerateAuxiliaryData.Telemetry;
using Xunit;

namespace Tests.Search.GenerateAuxiliaryData.Telemetry
{
public class TelemetryServiceFacts
{
public class TrackExporterDuration : BaseFacts
{
[Fact]
public void EmitsExpectedMetric()
{
Target.TrackExporterDuration(
"TheExporter",
"TheReport",
TimeSpan.FromMilliseconds(1234),
success: true);

TelemetryClient.Verify(
x => x.TrackMetric(
"Search.GenerateAuxiliaryData.ExporterDurationMs",
1234,
It.IsAny<IDictionary<string, string>>()),
Times.Once);

var properties = Assert.Single(Properties);
Assert.Equal(new[] { "Exporter", "Report", "Success" }, properties.Keys.OrderBy(x => x).ToArray());
Assert.Equal("TheExporter", properties["Exporter"]);
Assert.Equal("TheReport", properties["Report"]);
Assert.Equal("True", properties["Success"]);
}
}

public abstract class BaseFacts
{
public BaseFacts()
{
TelemetryClient = new Mock<ITelemetryClient>();
Properties = new ConcurrentQueue<IDictionary<string, string>>();

TelemetryClient
.Setup(x => x.TrackMetric(It.IsAny<string>(), It.IsAny<double>(), It.IsAny<IDictionary<string, string>>()))
.Callback<string, double, IDictionary<string, string>>((_, __, p) => Properties.Enqueue(p));

Target = new TelemetryService(TelemetryClient.Object);
}

public Mock<ITelemetryClient> TelemetryClient { get; }
public ConcurrentQueue<IDictionary<string, string>> Properties { get; }
public TelemetryService Target { get; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="RankingsExporterTests.cs" />
<Compile Include="Telemetry\TelemetryServiceFacts.cs" />
<Compile Include="VerifiedPackagesExporterTests.cs" />
</ItemGroup>
<ItemGroup>
Expand Down

0 comments on commit f9f08ff

Please sign in to comment.