-
Notifications
You must be signed in to change notification settings - Fork 117
Updates to feature/egressExtension
Part 1
#2748
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
Changes from all commits
604cecf
757b878
419eb63
66dc367
3820f0b
581a517
8815f2a
e750d13
ab949f8
0007678
fd43014
b75675c
69d2db0
9781efe
ef898cd
ec05a23
198c44c
7a639cf
3ad0085
a863b3d
62dac41
b6e7ad5
13f2453
0b0b5e9
5ed4a85
78e4977
0c9c4a8
df9d4e9
2759067
55edfe0
b28a04f
b10da3f
c72e188
62806a5
15398f5
14761e8
f02916f
da9f8f4
54720a1
88d08f6
da71da9
8b7444c
719d8b1
70504eb
90dd40c
02251b5
17e8f87
113dd89
56e55c9
5527c81
ee05d54
9da2d8b
da0718a
e78601c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We aren't doing it yet, but in the future we'll be moving this to the new extensions repo |
||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.3.32819.101 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureBlobStorage", "AzureBlobStorage\AzureBlobStorage.csproj", "{5ED61A7B-F0AA-45F2-9E9A-8972FF7F7278}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{5ED61A7B-F0AA-45F2-9E9A-8972FF7F7278}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{5ED61A7B-F0AA-45F2-9E9A-8972FF7F7278}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{5ED61A7B-F0AA-45F2-9E9A-8972FF7F7278}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{5ED61A7B-F0AA-45F2-9E9A-8972FF7F7278}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {6679B669-CE81-4761-8452-D5218551CE0F} | ||
EndGlobalSection | ||
EndGlobal |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,36 +9,28 @@ | |
using Azure.Storage.Blobs.Models; | ||
using Azure.Storage.Blobs.Specialized; | ||
using Azure.Storage.Queues; | ||
using Microsoft.Extensions.Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Net; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Microsoft.Diagnostics.Tools.Monitor.Egress.AzureBlob | ||
namespace Microsoft.Diagnostics.Monitoring.AzureStorage.AzureBlob | ||
{ | ||
/// <summary> | ||
/// Egress provider for egressing stream data to an Azure blob storage account. | ||
/// </summary> | ||
/// <remarks> | ||
/// Blobs created through this provider will overwrite existing blobs if they have the same blob name. | ||
/// </remarks> | ||
internal partial class AzureBlobEgressProvider : | ||
EgressProvider<AzureBlobEgressProviderOptions> | ||
internal partial class AzureBlobEgressProvider | ||
{ | ||
private int BlobStorageBufferSize = 4 * 1024 * 1024; | ||
private readonly string AzureBlobStorage = "AzureBlobStorage"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be moved to some kind of shared constant because it is used in the same way both here and in the Program class. |
||
protected ILogger Logger { get; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a private field. |
||
|
||
public AzureBlobEgressProvider(ILogger<AzureBlobEgressProvider> logger) | ||
: base(logger) | ||
public AzureBlobEgressProvider(ILogger logger) | ||
{ | ||
Logger = logger; | ||
} | ||
|
||
public override async Task<string> EgressAsync( | ||
string providerType, | ||
string providerName, | ||
public async Task<string> EgressAsync( | ||
AzureBlobEgressProviderOptions options, | ||
Func<CancellationToken, Task<Stream>> action, | ||
EgressArtifactSettings artifactSettings, | ||
|
@@ -54,7 +46,7 @@ public override async Task<string> EgressAsync( | |
|
||
BlobClient blobClient = containerClient.GetBlobClient(blobName); | ||
|
||
Logger?.EgressProviderInvokeStreamAction(EgressProviderTypes.AzureBlobStorage); | ||
Logger.EgressProviderInvokeStreamAction(AzureBlobStorage); | ||
using var stream = await action(token); | ||
|
||
// Write blob content, headers, and metadata | ||
|
@@ -63,75 +55,7 @@ public override async Task<string> EgressAsync( | |
await SetBlobClientMetadata(blobClient, artifactSettings, token); | ||
|
||
string blobUriString = GetBlobUri(blobClient); | ||
Logger?.EgressProviderSavedStream(EgressProviderTypes.AzureBlobStorage, blobUriString); | ||
|
||
if (CheckQueueEgressOptions(options)) | ||
{ | ||
await EgressMessageToQueue(blobName, options, token); | ||
} | ||
|
||
return blobUriString; | ||
} | ||
catch (AggregateException ex) when (ex.InnerException is RequestFailedException innerException) | ||
{ | ||
throw CreateException(innerException); | ||
} | ||
catch (RequestFailedException ex) | ||
{ | ||
throw CreateException(ex); | ||
} | ||
catch (CredentialUnavailableException ex) | ||
{ | ||
throw CreateException(ex); | ||
} | ||
} | ||
|
||
public override async Task<string> EgressAsync( | ||
string providerType, | ||
string providerName, | ||
AzureBlobEgressProviderOptions options, | ||
Func<Stream, CancellationToken, Task> action, | ||
EgressArtifactSettings artifactSettings, | ||
CancellationToken token) | ||
{ | ||
try | ||
{ | ||
AddConfiguredMetadataAsync(options, artifactSettings); | ||
|
||
var containerClient = await GetBlobContainerClientAsync(options, token); | ||
|
||
string blobName = GetBlobName(options, artifactSettings); | ||
|
||
BlockBlobClient blobClient = containerClient.GetBlockBlobClient(blobName); | ||
|
||
// Write blob content | ||
|
||
var bloboptions = new BlockBlobOpenWriteOptions | ||
{ | ||
BufferSize = BlobStorageBufferSize, | ||
}; | ||
using (Stream blobStream = await blobClient.OpenWriteAsync(overwrite: true, options: bloboptions, cancellationToken: token)) | ||
using (AutoFlushStream flushStream = new AutoFlushStream(blobStream, BlobStorageBufferSize)) | ||
{ | ||
//Azure's stream from OpenWriteAsync will do the following | ||
//1. Write the data to a local buffer | ||
//2. Once that buffer is full, stage the data remotely (this data is not considered valid yet) | ||
//3. After 4Gi of data has been staged, the data will be commited. This can be forced earlier by flushing | ||
//the stream. | ||
// Since we want the data to be readily available, we automatically flush (and therefore commit) every time we fill up the buffer. | ||
Logger?.EgressProviderInvokeStreamAction(EgressProviderTypes.AzureBlobStorage); | ||
await action(flushStream, token); | ||
|
||
await flushStream.FlushAsync(token); | ||
} | ||
|
||
// Write blob headers | ||
await blobClient.SetHttpHeadersAsync(CreateHttpHeaders(artifactSettings), cancellationToken: token); | ||
|
||
await SetBlobClientMetadata(blobClient, artifactSettings, token); | ||
|
||
string blobUriString = GetBlobUri(blobClient); | ||
Logger?.EgressProviderSavedStream(EgressProviderTypes.AzureBlobStorage, blobUriString); | ||
Logger.EgressProviderSavedStream(AzureBlobStorage, blobUriString); | ||
|
||
if (CheckQueueEgressOptions(options)) | ||
{ | ||
|
@@ -395,7 +319,6 @@ private string GetBlobName(AzureBlobEgressProviderOptions options, EgressArtifac | |
private BlobHttpHeaders CreateHttpHeaders(EgressArtifactSettings artifactSettings) | ||
{ | ||
BlobHttpHeaders headers = new BlobHttpHeaders(); | ||
headers.ContentEncoding = artifactSettings.ContentEncoding; | ||
headers.ContentType = artifactSettings.ContentType; | ||
return headers; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace Microsoft.Diagnostics.Monitoring.AzureStorage | ||
{ | ||
/// <summary> | ||
/// Egress provider options for Azure blob storage. | ||
/// </summary> | ||
internal sealed partial class AzureBlobEgressProviderOptions | ||
{ | ||
[Required] | ||
public Uri AccountUri { get; set; } | ||
|
||
public string AccountKey { get; set; } | ||
|
||
public string AccountKeyName { get; set; } | ||
|
||
public string SharedAccessSignature { get; set; } | ||
|
||
public string SharedAccessSignatureName { get; set; } | ||
|
||
public string ManagedIdentityClientId { get; set; } | ||
|
||
[Required] | ||
public string ContainerName { get; set; } | ||
|
||
public string BlobPrefix { get; set; } | ||
|
||
public int? CopyBufferSize { get; set; } | ||
|
||
public string QueueName { get; set; } | ||
|
||
public Uri QueueAccountUri { get; set; } | ||
|
||
public string QueueSharedAccessSignature { get; set; } | ||
|
||
public string QueueSharedAccessSignatureName { get; set; } | ||
|
||
public IDictionary<string, string> Metadata { get; set; } | ||
= new Dictionary<string, string>(0); | ||
} | ||
} |
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.
Remove this and add the AzureBlobStorage project to the dotnet-monitor.sln file if it already doesn't exist.