-
Notifications
You must be signed in to change notification settings - Fork 300
ServiceControl Integration added additional events #5289
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
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
5015d12
Update contracts.md
seanfarmar 4edfaa7
app insights integration sample
tmasternak e13a866
adding event
tmasternak f77ee23
Update contracts.md
seanfarmar f4ea629
app insights integration sample
tmasternak bde71dd
Added app insights text
seanfarmar 874a12c
cleanup
seanfarmar 43683fe
integration events pushed to App Insights
tmasternak 2e55199
Merge remote-tracking branch 'origin/exposing-additional-events' into…
tmasternak 7dbad0f
moving to the new folder
tmasternak 5fcd275
changing names
tmasternak 8ca01c1
text review
tmasternak b082354
typo
tmasternak 3000cbd
Apply suggestions from code review
seanfarmar 4116bea
Apply suggestions from code review
seanfarmar e65a9bb
Update samples/servicecontrol/azure-monitor-events/sample.md
seanfarmar c4b285f
added app-insights-integration.md
seanfarmar 3334726
note on SC support for integration events
tmasternak c139bbf
servicecontrol app insights integration page
tmasternak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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
14 changes: 14 additions & 0 deletions
14
...re-monitor-events/ServiceControlContracts_3/EndpointsMonitor/AzureMonitorConnector.csproj
This file contains hidden or 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,14 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <TargetFrameworks>netcoreapp3.1;netcoreapp2.1;net48</TargetFrameworks> | ||
| <OutputType>Exe</OutputType> | ||
| <LangVersion>7.3</LangVersion> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <PackageReference Include="Newtonsoft.Json" Version="13.*" /> | ||
| <PackageReference Include="NServiceBus" Version="7.*" /> | ||
| <PackageReference Include="NServiceBus.Newtonsoft.Json" Version="2.*" /> | ||
| <PackageReference Include="ServiceControl.Contracts" Version="3.*" /> | ||
| <PackageReference Include="Microsoft.ApplicationInsights" Version="2.14.*" /> | ||
| </ItemGroup> | ||
| </Project> |
119 changes: 119 additions & 0 deletions
119
...ol/azure-monitor-events/ServiceControlContracts_3/EndpointsMonitor/CustomEventsHandler.cs
This file contains hidden or 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,119 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.ApplicationInsights; | ||
| using Microsoft.ApplicationInsights.DataContracts; | ||
| using NServiceBus; | ||
| using NServiceBus.Logging; | ||
| using ServiceControl.Contracts; | ||
|
|
||
| #region AzureMonitorConnectorEventsHandler | ||
|
|
||
| public class MessageFailedHandler : | ||
| IHandleMessages<MessageFailed> | ||
| { | ||
| readonly TelemetryClient telemetryClient; | ||
| static ILog log = LogManager.GetLogger<CustomEventsHandler>(); | ||
|
|
||
| public MessageFailedHandler(TelemetryClient telemetryClient) | ||
| { | ||
| this.telemetryClient = telemetryClient; | ||
| } | ||
|
|
||
| public Task Handle(MessageFailed message, IMessageHandlerContext context) | ||
| { | ||
|
|
||
| telemetryClient.TrackEvent("Message Failed", new Dictionary<string, string> | ||
| { | ||
| {"MessageId", message.FailedMessageId}, | ||
| }); | ||
|
|
||
| log.Error($"Received ServiceControl 'MessageFailed' event for a {message.MessageType} with ID {message.FailedMessageId}."); | ||
| return Task.CompletedTask; | ||
| } | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| public class CustomEventsHandler : | ||
| IHandleMessages<HeartbeatStopped>, | ||
| IHandleMessages<HeartbeatRestored>, | ||
| IHandleMessages<FailedMessagesArchived>, | ||
| IHandleMessages<FailedMessagesUnArchived>, | ||
| IHandleMessages<MessageFailureResolvedByRetry>, | ||
| IHandleMessages<MessageFailureResolvedManually> | ||
| { | ||
| readonly TelemetryClient telemetryClient; | ||
| static ILog log = LogManager.GetLogger<CustomEventsHandler>(); | ||
|
|
||
| public CustomEventsHandler(TelemetryClient telemetryClient) | ||
| { | ||
| this.telemetryClient = telemetryClient; | ||
| } | ||
|
|
||
| public Task Handle(HeartbeatStopped message, IMessageHandlerContext context) | ||
| { | ||
| telemetryClient.TrackEvent("Heartbeat Stopped", new Dictionary<string, string> | ||
| { | ||
| {"EndpointName", message.EndpointName}, | ||
| }); | ||
|
|
||
| log.Warn($"Heartbeats from {message.EndpointName} have stopped."); | ||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
| public Task Handle(HeartbeatRestored message, IMessageHandlerContext context) | ||
| { | ||
| telemetryClient.TrackEvent("Heartbeat Restored", new Dictionary<string, string> | ||
| { | ||
| {"EndpointName", message.EndpointName}, | ||
| }); | ||
|
|
||
| log.Info($"Heartbeats from {message.EndpointName} have been restored."); | ||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
| public Task Handle(FailedMessagesArchived message, IMessageHandlerContext context) | ||
| { | ||
| telemetryClient.TrackEvent("Failed Messages Archived", new Dictionary<string, string> | ||
| { | ||
| {"MessagesIds", string.Join(",", message.FailedMessagesIds)}, | ||
| }); | ||
|
|
||
| log.Error($"Received ServiceControl 'FailedMessageArchived' with ID {message.FailedMessagesIds.FirstOrDefault()}."); | ||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
| public Task Handle(FailedMessagesUnArchived message, IMessageHandlerContext context) | ||
| { | ||
| telemetryClient.TrackEvent("Failed Messages Unarchived", new Dictionary<string, string> | ||
| { | ||
| {"MessagesIds", string.Join(",", message.FailedMessagesIds)}, | ||
| }); | ||
|
|
||
| log.Error($"Received ServiceControl 'FailedMessagesUnArchived' MessagesCount: {message.FailedMessagesIds.Length}."); | ||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
| public Task Handle(MessageFailureResolvedByRetry message, IMessageHandlerContext context) | ||
| { | ||
| telemetryClient.TrackEvent("Message Failure Resolved By Retry", new Dictionary<string, string> | ||
| { | ||
| {"MessageId", message.FailedMessageId}, | ||
| }); | ||
|
|
||
| log.Error($"Received ServiceControl 'MessageFailureResolvedByRetry' with ID {message.FailedMessageId}."); | ||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
| public Task Handle(MessageFailureResolvedManually message, IMessageHandlerContext context) | ||
| { | ||
| telemetryClient.TrackEvent("Message Failure Resolved Manually", new Dictionary<string, string> | ||
| { | ||
| {"MessageId", message.FailedMessageId}, | ||
| }); | ||
|
|
||
| log.Error($"Received ServiceControl 'MessageFailureResolvedManually' with ID {message.FailedMessageId}."); | ||
| return Task.CompletedTask; | ||
| } | ||
| } | ||
57 changes: 57 additions & 0 deletions
57
...servicecontrol/azure-monitor-events/ServiceControlContracts_3/EndpointsMonitor/Program.cs
This file contains hidden or 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,57 @@ | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.ApplicationInsights; | ||
| using Microsoft.ApplicationInsights.Extensibility; | ||
| using NServiceBus; | ||
|
|
||
| class Program | ||
| { | ||
| static async Task Main() | ||
| { | ||
| Console.Title = "AzureMonitorConnector"; | ||
| var endpointConfiguration = new EndpointConfiguration("AzureMonitorConnector"); | ||
| endpointConfiguration.UseSerialization<NewtonsoftSerializer>(); | ||
| endpointConfiguration.EnableInstallers(); | ||
| endpointConfiguration.UsePersistence<InMemoryPersistence>(); | ||
| endpointConfiguration.SendFailedMessagesTo("error"); | ||
|
|
||
| var transport = endpointConfiguration.UseTransport<LearningTransport>(); | ||
|
|
||
| var conventions = endpointConfiguration.Conventions(); | ||
| conventions.DefiningEventsAs( | ||
| type => | ||
| { | ||
| return typeof(IEvent).IsAssignableFrom(type) || | ||
| // include ServiceControl events | ||
| type.Namespace != null && | ||
| type.Namespace.StartsWith("ServiceControl.Contracts"); | ||
| }); | ||
|
|
||
| #region AppInsightsSdkSetup | ||
|
|
||
| var envInstrumentationKey = "ApplicationInsightKey"; | ||
| var instrumentationKey = Environment.GetEnvironmentVariable(envInstrumentationKey); | ||
|
|
||
| if (string.IsNullOrEmpty(instrumentationKey)) | ||
| { | ||
| throw new Exception($"Environment variable '{envInstrumentationKey}' required."); | ||
| } | ||
|
|
||
| Console.WriteLine("Using application insights application key: {0}", instrumentationKey); | ||
|
|
||
|
|
||
| var telemetryConfiguration = new TelemetryConfiguration(instrumentationKey); | ||
| var telemetryClient = new TelemetryClient(telemetryConfiguration); | ||
|
|
||
| endpointConfiguration.RegisterComponents(cc => cc.RegisterSingleton(telemetryClient)); | ||
|
|
||
| #endregion | ||
|
|
||
| var endpointInstance = await Endpoint.Start(endpointConfiguration) | ||
| .ConfigureAwait(false); | ||
| Console.WriteLine("Press any key to finish."); | ||
| Console.ReadKey(); | ||
| await endpointInstance.Stop() | ||
| .ConfigureAwait(false); | ||
| } | ||
| } |
3 changes: 3 additions & 0 deletions
3
...ol/azure-monitor-events/ServiceControlContracts_3/EndpointsMonitoring.StartupProjects.txt
This file contains hidden or 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,3 @@ | ||
| EndpointsMonitor\AzureMonitorConnector.csproj | ||
| NServiceBusEndpoint\NServiceBusEndpoint.csproj | ||
| PlatformLauncher\PlatformLauncher.csproj |
29 changes: 29 additions & 0 deletions
29
...les/servicecontrol/azure-monitor-events/ServiceControlContracts_3/EndpointsMonitoring.sln
This file contains hidden or 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,29 @@ | ||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| # Visual Studio Version 16 | ||
| VisualStudioVersion = 16.0.29728.190 | ||
| MinimumVisualStudioVersion = 15.0.26730.12 | ||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBusEndpoint", "NServiceBusEndpoint\NServiceBusEndpoint.csproj", "{814CEA2E-C5F5-4315-8FC3-8517B09C5931}" | ||
| EndProject | ||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureMonitorConnector", "EndpointsMonitor\AzureMonitorConnector.csproj", "{7A1C1662-35D1-4720-9F9F-4D23E9A57CE1}" | ||
| EndProject | ||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformLauncher", "PlatformLauncher\PlatformLauncher.csproj", "{EED01887-FC83-4920-901E-2B52AFFDCBE6}" | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|Any CPU = Debug|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {814CEA2E-C5F5-4315-8FC3-8517B09C5931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {814CEA2E-C5F5-4315-8FC3-8517B09C5931}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {7A1C1662-35D1-4720-9F9F-4D23E9A57CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {7A1C1662-35D1-4720-9F9F-4D23E9A57CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {EED01887-FC83-4920-901E-2B52AFFDCBE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {EED01887-FC83-4920-901E-2B52AFFDCBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ExtensibilityGlobals) = postSolution | ||
| SolutionGuid = {E4ACEBE4-E83E-4146-9EFF-9E61728BD574} | ||
| EndGlobalSection | ||
| EndGlobal |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or 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,99 @@ | ||
| --- | ||
| title: Monitor with ServiceControl events with Azure Application Insights | ||
| summary: A sample showing how to monitor events published by ServiceControl with Azure Application Insights | ||
| component: ServiceControlContracts | ||
| reviewed: 2021-04-16 | ||
| related: | ||
| - servicecontrol | ||
| - servicecontrol/contracts | ||
| - servicecontrol/plugins | ||
| - samples/servicecontrol/monitoring3rdparty | ||
| --- | ||
|
|
||
| This sample shows how to monitor a running NServiceBus system with ServiceControl and ServicePulse, as well as how to integrate with existing monitoring solutions. The sample uses the [Learning Transport](/transports/learning/) and a portable version of the Particular Service Platform tools. Installing ServiceControl is **not** required. | ||
|
|
||
| include: platformlauncher-windows-required | ||
|
|
||
| downloadbutton | ||
|
|
||
|
|
||
| ## Running the project | ||
|
|
||
| Running the project will result in 3 console windows: | ||
|
|
||
| 1. **NServiceBusEndpoint**: The endpoint that represents the system being monitored. | ||
| 1. **AzureMonitorConnector**: The endpoint that subscribes to ServiceControl notification events and pushes them to Application Insights as custom telemetry events. | ||
| 1. **PlatformLauncher**: Runs an in-process version of ServiceControl and ServicePulse. When the ServiceControl instance is ready, a browser window will be launched displaying the ServicePulse Dashboard. | ||
|
|
||
| The samples enables triggering two types of events: | ||
|
|
||
| ### Message Failures | ||
|
|
||
| A `MessageFailed` event is emitted when processing a message fails and the message is moved to the error queue. | ||
|
|
||
| To observe this in action, press <kbd>Enter</kbd> in the `NServiceBusEndpoint`console window. It will cause generate new `SimpleMessage` event that causes failure when processed. | ||
|
|
||
| NOTE: The exception will cause the debugger to enter a breakpoint. It may be preferable to detach the debugger in order to better observe what's going on. | ||
|
|
||
| When a `MessageFailed` event is received, the `AzureMonitorConnector` prints the following message in its console window: | ||
|
|
||
| ``` | ||
| > Received ServiceControl 'MessageFailed' event for a SimpleMessage with ID 42f25e40-a673-61f3-a505-c8dee6d16f8a | ||
| ``` | ||
|
|
||
| The failed message can also be viewed in the ServicePulse browser window. Navigating to the failed message allows viewing more details about the message failure. | ||
|
|
||
|
|
||
| ### Heartbeat statuses | ||
|
|
||
| The `HeartbeatStopped` event is published whenever an endpoint fails to send a control message within the expected interval. The `HeartbeatRestored` event is published whenever the endpoint successfully sends a control message again. | ||
|
|
||
| Note: The monitor must receive at least one control message before it can observe that the endpoint stopped responding. | ||
|
|
||
| To observe this in action, stop the `NServiceBusEndpoint` process and wait up to 30 seconds. When a `HeartbeatStopped` event is received, the `AzureMonitorConnector` prints the following message to the console window: | ||
|
|
||
| > `Heartbeat from NServiceBusEndpoint stopped.` | ||
|
|
||
| Next, restart the `NServiceBusEndpoint` application and wait up to 30 seconds. When a `HeartbeatRestored` event is received, the `AzureMonitorConnector` prints the following message in its console window: | ||
|
|
||
| > `Heartbeat from EndpointsMonitoring.NServiceBusEndpoint restored.` | ||
|
|
||
|
|
||
| ## Code walk-through | ||
|
|
||
|
|
||
| ### NServiceBusEndpoint | ||
|
|
||
| Retries are disabled in the sample for simplicity; messages are immediately moved to the error queue after a processing failure: | ||
|
|
||
| snippet: DisableRetries | ||
|
|
||
| The `MessageFailed` event is published whenever ServiceControl detects a new message in the error queue. | ||
|
|
||
| In order to receive `HeartbeatStopped` and `HeartbeatRestored` events, the endpoint must use the [heartbeats plugin](/monitoring/heartbeats). | ||
|
|
||
| NOTE: Heartbeat control messages are sent [every 30 seconds by default](/monitoring/heartbeats/legacy#configuration-time-to-live-ttl) so there will be up to a 30 second delay before ServiceControl realizes that it lost or restored connection with the endpoint. | ||
|
|
||
| ## Connect to Application Insights Azure Monitor | ||
|
|
||
| To connect the sample code to Application Insights, the instrumentation key must be provided. The key gets loaded from `ApplicationInsightKey` environment variable. | ||
|
|
||
| The instrumentation key can be retrieved from the Azure Portal by locating the Application Insights instance, and then navigating to the Properties view. | ||
|
|
||
| snippet: AppInsightsSdkSetup | ||
|
|
||
| ### AzureMonitorConnector | ||
|
|
||
| In order to get notifications when the exposed ServiceControl events occur, create an NServiceBus endpoint. Next, reference the `ServiceControl.Contracts` NuGet package and implement a handler which handles specific ServiceControl events: | ||
|
|
||
| snippet: AzureMonitorConnectorEventsHandler | ||
|
|
||
| The handler creates a custom telemetry event and pushes it to Application Insights. | ||
|
|
||
| ## Notes on other transports | ||
|
|
||
| This sample uses the [Learning Transport](/transports/learning/) in order to be portable with no transport dependencies. | ||
|
|
||
| If adjusting this sample to use the [Azure Service Bus transport](/transports/azure-service-bus/legacy/), note that the subscribing endpoint must also use the same name shortening strategy as ServiceControl. See the [configuration settings](/transports/azure-service-bus/configuration.md#entity-creation), or if using the [legacy Azure Service Bus transport](), see its [sanitization strategy documentation](/transports/azure-service-bus/legacy/sanitization.md). | ||
|
|
||
| Same applies to [Azure Storage Queues](/transports/azure-storage-queues) name [sanitization strategy](/transports/azure-storage-queues/sanitization.md#backward-compatibility-with-versions-7-and-below) |
34 changes: 0 additions & 34 deletions
34
...rol/events-subscription/ServiceControlContracts_1/EndpointsMonitor/CustomEventsHandler.cs
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 to show the whole handler with all the other noise or could we just scope it to the handle method ? Or is it because we consider the part of
IHandleMessages<>important?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 wanted to show the whole handler including the telemetry client injection and the message name. To make it smaller we moved all other supported messaged to a
CustomEventsHandler.