diff --git a/samples/linecounter/Controllers/HomeController.cs b/samples/linecounter/Controllers/HomeController.cs index 4b6ebb1194815..e051a473dd34c 100644 --- a/samples/linecounter/Controllers/HomeController.cs +++ b/samples/linecounter/Controllers/HomeController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +using Azure.Messaging.EventGrid; using Azure.Messaging.EventHubs; using Azure.Messaging.EventHubs.Producer; using Azure.Storage.Blobs; @@ -18,12 +19,18 @@ public class HomeController : Controller private readonly ILogger _logger; private readonly BlobContainerClient _blobContainerClient; private readonly EventHubProducerClient _uploadsProducer; + private readonly EventGridPublisherClient _publisherClient; - public HomeController(ILogger logger, BlobServiceClient blobServiceClient, IAzureClientFactory clientFactory) + public HomeController( + ILogger logger, + BlobServiceClient blobServiceClient, + IAzureClientFactory clientFactory, + EventGridPublisherClient publisherClient) { _logger = logger; _blobContainerClient = blobServiceClient.GetBlobContainerClient("uploads"); _uploadsProducer = clientFactory.CreateClient("Uploads"); + _publisherClient = publisherClient; } public IActionResult Index() @@ -60,7 +67,7 @@ public async Task Status(string name) { var properties = await _blobContainerClient.GetBlobClient(name).GetPropertiesAsync(); properties.Value.Metadata.TryGetValue("whitespacecount", out var count); - + await _publisherClient.SendEventsAsync(new CloudEvent[] { new CloudEvent("https://www.contoso.com/LineCounter", "LineCounter.Status.Viewed", name) }); return count ?? "-1"; } } diff --git a/samples/linecounter/LineCounter.csproj b/samples/linecounter/LineCounter.csproj index f2039159e1e25..45fc5bc38b516 100644 --- a/samples/linecounter/LineCounter.csproj +++ b/samples/linecounter/LineCounter.csproj @@ -13,4 +13,7 @@ + + + \ No newline at end of file diff --git a/samples/linecounter/README.md b/samples/linecounter/README.md index b1e7342dd607a..13a733f9a86fd 100644 --- a/samples/linecounter/README.md +++ b/samples/linecounter/README.md @@ -6,15 +6,16 @@ products: - azure - azure-storage - azure-event-hubs +- azure-event-grid urlFragment: line-counter name: LineCounter -description: Sample that illustrates using Storage and Event Hubs clients along with ASP.NET Core integration, distributed tracing and hosted services. +description: Sample that illustrates using Storage, Event Hubs, and Event Grid clients along with ASP.NET Core integration, distributed tracing and hosted services. --- # LineCounter -This is a sample app that illustrates using Storage and Event Hubs clients along with ASP.NET Core integration, distributed tracing and hosted services. +This is a sample app that illustrates using Storage, Event Hubs, and Event Grid clients along with ASP.NET Core integration, distributed tracing and hosted services. It allows users to upload a file to a blob, which triggers an Event Hubs event containing the file name. -The Event Hubs Processor receives the event, and then the app downloads the blob and counts the number of lines in the file. +The Event Hubs Processor receives the event, and then the app downloads the blob and counts the number of lines in the file. The app displays a link to a page containing the line count. When the link is clicked, a CloudEvent containing the name of the file is published using Event Grid. # Configuration @@ -32,6 +33,11 @@ To run the sample set the following configuration properties using manage user s "Results": { "connectionString": "...", "eventHubName": "..." + }, + "Notification": { + "endpoint": "...", + "credential": { + "key": "..." } } ``` @@ -45,3 +51,7 @@ To light up App Insights, add the InstrumentationKey key and value to the Applic } } ``` + +# Azure Monitor +You can view an end-to-end transaction in the portal by going to your App. Click on the Search icon, and then click See all data. +After selecting a grouped result, you will be able to see a timeline of the grouped requests: ![Monitor](assets/monitor.PNG). diff --git a/samples/linecounter/Startup.cs b/samples/linecounter/Startup.cs index 49c6e681fe262..ecacd1aeca985 100644 --- a/samples/linecounter/Startup.cs +++ b/samples/linecounter/Startup.cs @@ -29,6 +29,7 @@ public void ConfigureServices(IServiceCollection services) builder.AddEventHubProducerClient(Configuration.GetSection("Uploads")).WithName("Uploads"); builder.AddEventHubProducerClient(Configuration.GetSection("Results")).WithName("Results"); + builder.AddEventGridPublisherClient(Configuration.GetSection("Notification")); }); services.AddApplicationInsightsTelemetry(); } diff --git a/samples/linecounter/assets/monitor.PNG b/samples/linecounter/assets/monitor.PNG new file mode 100644 index 0000000000000..4dc2535b5fe6f Binary files /dev/null and b/samples/linecounter/assets/monitor.PNG differ diff --git a/sdk/core/Azure.Core/samples/Diagnostics.md b/sdk/core/Azure.Core/samples/Diagnostics.md index 04ed8cd5b57b3..bcf130fb0f42e 100644 --- a/sdk/core/Azure.Core/samples/Diagnostics.md +++ b/sdk/core/Azure.Core/samples/Diagnostics.md @@ -102,6 +102,9 @@ To setup ApplicationInsights tracking for your application follow the [Start Mon Follow the [OpenTelemetry configuration guide](https://github.com/open-telemetry/opentelemetry-dotnet#configuration-with-microsoftextensionsdependencyinjection) to configure collecting distribute tracing event collection using the OpenTelemetry library. +### Sample +To see an example of distributed tracing in action, take a look at our [sample app](https://github.com/Azure/azure-sdk-for-net/blob/master/samples/linecounter/README.md) that combines several Azure SDKs. + ## Setting x-ms-client-request-id value sent with requests By default x-ms-client-request-id header gets a unique value per client method call. If you would like to use a specific value for a set of requests use the `HttpPipeline.CreateClientRequestIdScope` method. diff --git a/sdk/eventgrid/Azure.Messaging.EventGrid/README.md b/sdk/eventgrid/Azure.Messaging.EventGrid/README.md index 3df37982c09ba..04da5c295a78e 100644 --- a/sdk/eventgrid/Azure.Messaging.EventGrid/README.md +++ b/sdk/eventgrid/Azure.Messaging.EventGrid/README.md @@ -231,6 +231,9 @@ foreach (EventGridEvent egEvent in egEvents) ### Setting up console logging You can also easily [enable console logging](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/samples/Diagnostics.md#logging) if you want to dig deeper into the requests you're making against the service. +### Distributed Tracing +The Event Grid library supports distributing tracing out of the box. In order to adhere to the CloudEvents specification's [guidance](https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md) on distributing tracing, the library will set the `traceparent` and `tracestate` on the [ExtensionAttributes](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventgrid/Azure.Messaging.EventGrid/src/Customization/CloudEvent.cs#L126) of a `CloudEvent` when distributed tracing is enabled. To learn more about how to enable distributed tracing in your application, take a look at the Azure SDK [distributed tracing documentation](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/samples/Diagnostics.md#Distributed-tracing). + ## Next steps View more https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventgrid/Azure.Messaging.EventGrid/samples here for common usages of the Event Grid client library: [Event Grid Samples](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventgrid/Azure.Messaging.EventGrid/samples). diff --git a/sdk/eventgrid/Azure.Messaging.EventGrid/api/Azure.Messaging.EventGrid.netstandard2.0.cs b/sdk/eventgrid/Azure.Messaging.EventGrid/api/Azure.Messaging.EventGrid.netstandard2.0.cs index 037015ecc6b21..52dba42fda0a7 100644 --- a/sdk/eventgrid/Azure.Messaging.EventGrid/api/Azure.Messaging.EventGrid.netstandard2.0.cs +++ b/sdk/eventgrid/Azure.Messaging.EventGrid/api/Azure.Messaging.EventGrid.netstandard2.0.cs @@ -1341,3 +1341,12 @@ internal WebSlotSwapWithPreviewStartedEventData() { } public string Verb { get { throw null; } } } } +namespace Microsoft.Extensions.Azure +{ + public static partial class EventGridPublisherClientBuilderExtensions + { + public static Azure.Core.Extensions.IAzureClientBuilder AddEventGridPublisherClient(this TBuilder builder, System.Uri endpoint, Azure.AzureKeyCredential credential) where TBuilder : Azure.Core.Extensions.IAzureClientFactoryBuilder { throw null; } + public static Azure.Core.Extensions.IAzureClientBuilder AddEventGridPublisherClient(this TBuilder builder, System.Uri endpoint, Azure.Messaging.EventGrid.EventGridSharedAccessSignatureCredential credential) where TBuilder : Azure.Core.Extensions.IAzureClientFactoryBuilder { throw null; } + public static Azure.Core.Extensions.IAzureClientBuilder AddEventGridPublisherClient(this TBuilder builder, TConfiguration configuration) where TBuilder : Azure.Core.Extensions.IAzureClientFactoryBuilderWithConfiguration { throw null; } + } +} diff --git a/sdk/eventgrid/Azure.Messaging.EventGrid/src/Compatibility/EventGridPublisherClientBuilderExtensions.cs b/sdk/eventgrid/Azure.Messaging.EventGrid/src/Compatibility/EventGridPublisherClientBuilderExtensions.cs new file mode 100644 index 0000000000000..7896dfeaee51e --- /dev/null +++ b/sdk/eventgrid/Azure.Messaging.EventGrid/src/Compatibility/EventGridPublisherClientBuilderExtensions.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure; +using Azure.Core.Extensions; +using Azure.Messaging.EventGrid; + +namespace Microsoft.Extensions.Azure +{ + /// + /// The set of extensions to add the type to the clients builder. + /// + public static class EventGridPublisherClientBuilderExtensions + { + /// + /// Registers a instance with the provided and ./>. + /// + public static IAzureClientBuilder AddEventGridPublisherClient( + this TBuilder builder, + Uri endpoint, + AzureKeyCredential credential) + where TBuilder : IAzureClientFactoryBuilder => + builder.RegisterClientFactory(options => new EventGridPublisherClient(endpoint, credential, options)); + + /// + /// Registers a instance with the provided and ./>. + /// + public static IAzureClientBuilder AddEventGridPublisherClient( + this TBuilder builder, + Uri endpoint, + EventGridSharedAccessSignatureCredential credential) + where TBuilder : IAzureClientFactoryBuilder => + builder.RegisterClientFactory(options => new EventGridPublisherClient(endpoint, credential, options)); + + /// + /// Registers a instance with connection options loaded from the provided instance. + /// + public static IAzureClientBuilder AddEventGridPublisherClient( + this TBuilder builder, + TConfiguration configuration) + where TBuilder : IAzureClientFactoryBuilderWithConfiguration => + builder.RegisterClientFactory(configuration); + } +}