Skip to content

Commit

Permalink
Merge pull request #38 from IvanJosipovic/dev2
Browse files Browse the repository at this point in the history
Reworked initialization to better support Blazor Server and Pre Rendering (thanks @HonzaBejvl)
Added note to disable the integrated ILoggerProvider with Blazor Server
  • Loading branch information
IvanJosipovic authored Dec 1, 2020
2 parents 4506ece + df3bf9b commit e03f280
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 79 deletions.
114 changes: 55 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Application Insights for Blazor web applications

# Install
## Install

- Add [BlazorApplicationInsights Nuget](https://www.nuget.org/packages/BlazorApplicationInsights)
- dotnet add package BlazorApplicationInsights
Expand All @@ -18,45 +18,47 @@ Application Insights for Blazor web applications
- Add Application Insights JS to head in index.html
- [Source](https://github.com/microsoft/ApplicationInsights-JS#snippet-setup-ignore-if-using-npm-setup)
- Set 'ld: -1' so that the page will be blocked until the JS is loaded and enter your instrumentationKey
- Example
```html
<script type="text/javascript">
!function(T,l,y){ // Removed for brevity...
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js",
ld: -1, // Set this to -1
crossOrigin: "anonymous",
cfg: {
instrumentationKey: "YOUR_INSTRUMENTATION_KEY_GOES_HERE"
}});
</script>
```
```html
<script type="text/javascript">
!function(T,l,y){ // Removed for brevity...
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js",
ld: -1, // Set this to -1
crossOrigin: "anonymous",
cfg: {
instrumentationKey: "YOUR_INSTRUMENTATION_KEY_GOES_HERE"
}});
</script>
```
- Add JS Interop to the bottom of body in index.html
```html
<script src="_content/BlazorApplicationInsights/JsInterop.js"></script>
```

## [Example Project](https://github.com/IvanJosipovic/BlazorApplicationInsights/tree/master/src/BlazorApplicationInsights.Sample)

# Features
- Automatically triggers Track Page View on route changes
- ILoggerProvider which sends all the logs to App Insights
- Supported [APIs](https://github.com/microsoft/ApplicationInsights-JS/blob/master/API-reference.md)
- AddTelemetryInitializer
- ClearAuthenticatedUserContext
- Flush
- SetAuthenticatedUserContext
- StartTrackPage
- StopTrackPage
- TrackDependencyData
- TrackEvent
- TrackException
- TrackMetric
- TrackPageView
- TrackPageViewPerformance
- TrackTrace


# TrackEvent
## Features
- Automatically triggers Track Page View on route changes
- ILoggerProvider which sends all the logs to App Insights
- Supported [APIs](https://github.com/microsoft/ApplicationInsights-JS/blob/master/API-reference.md)
- AddTelemetryInitializer
- ClearAuthenticatedUserContext
- Flush
- SetAuthenticatedUserContext
- StartTrackPage
- StopTrackPage
- TrackDependencyData
- TrackEvent
- TrackException
- TrackMetric
- TrackPageView
- TrackPageViewPerformance
- TrackTrace

## Blazor Server
- Disable the integrated ILoggerProvider otherwise all logs will be sent through to the browser!
- ```builder.Services.AddBlazorApplicationInsights(false);```

## TrackEvent

```csharp
@page "/"
Expand All @@ -73,7 +75,7 @@ Application Insights for Blazor web applications
}
```

# Set User Name
## Set User Name
- Edit Authentication.razor
```csharp
@page "/authentication/{action}"
Expand Down Expand Up @@ -101,37 +103,31 @@ Application Insights for Blazor web applications
}
```

# Set Role and Instance
## Set Role and Instance
- Edit Program.cs
```csharp
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");

builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddBlazorApplicationInsights();

var build = builder.Build();
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");

var applicationInsights = build.Services.GetRequiredService<IApplicationInsights>();
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

var telemetryItem = new TelemetryItem()
builder.Services.AddBlazorApplicationInsights(async applicationInsights =>
{
var telemetryItem = new TelemetryItem()
{
Tags = new Dictionary<string, object>()
{
Tags = new Dictionary<string, object>()
{
{ "ai.cloud.role", "SPA" },
{ "ai.cloud.roleInstance", "Blazor Wasm" },
}
};
{ "ai.cloud.role", "SPA" },
{ "ai.cloud.roleInstance", "Blazor Wasm" },
}
};

await applicationInsights.AddTelemetryInitializer(telemetryItem);
await applicationInsights.AddTelemetryInitializer(telemetryItem);
});

await build.RunAsync();
}
}
await builder.Build().RunAsync();
}

```
25 changes: 11 additions & 14 deletions src/BlazorApplicationInsights.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,21 @@ public static async Task Main(string[] args)

builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddBlazorApplicationInsights();

var build = builder.Build();

var applicationInsights = build.Services.GetRequiredService<IApplicationInsights>();

var telemetryItem = new TelemetryItem()
builder.Services.AddBlazorApplicationInsights(async applicationInsights =>
{
Tags = new Dictionary<string, object>()
var telemetryItem = new TelemetryItem()
{
{ "ai.cloud.role", "SPA" },
{ "ai.cloud.roleInstance", "Blazor Wasm" },
}
};
Tags = new Dictionary<string, object>()
{
{ "ai.cloud.role", "SPA" },
{ "ai.cloud.roleInstance", "Blazor Wasm" },
}
};

await applicationInsights.AddTelemetryInitializer(telemetryItem);
await applicationInsights.AddTelemetryInitializer(telemetryItem);
});

await build.RunAsync();
await builder.Build().RunAsync();
}
}
}
13 changes: 10 additions & 3 deletions src/BlazorApplicationInsights/ApplicationInsights.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ namespace BlazorApplicationInsights
{
public class ApplicationInsights : IApplicationInsights
{
private readonly IJSRuntime JSRuntime;
private IJSRuntime? JSRuntime { get; set; }
private Func<IApplicationInsights, Task> OnInsightsInitAction { get; }

public ApplicationInsights(IJSRuntime jsRuntime)
public ApplicationInsights(Func<IApplicationInsights, Task> onInsightsInitAction)
{
JSRuntime = jsRuntime;
OnInsightsInitAction = onInsightsInitAction;
}
public async Task InitBlazorApplicationInsightsAsync(IJSRuntime jSRuntime)
{
JSRuntime = jSRuntime;

await OnInsightsInitAction.Invoke(this);
}

public async Task TrackPageView(string? name = null, string? uri = null, string? refUri = null, string? pageType = null, bool? isLoggedIn = null, Dictionary<string, object>? properties = null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
using Microsoft.AspNetCore.Components;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.JSInterop;

namespace BlazorApplicationInsights
{
public partial class ApplicationInsightsComponent
{
[Inject] private IApplicationInsights ApplicationInsights { get; set; }
[Inject] private NavigationManager NavigationManager { get; set; }
[Inject] private IJSRuntime JSRuntime { get; set; }

protected override void OnInitialized()
{
NavigationManager.LocationChanged += NavigationManager_LocationChanged;
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await ApplicationInsights.InitBlazorApplicationInsightsAsync(JSRuntime);
}
}

private async void NavigationManager_LocationChanged(object sender, LocationChangedEventArgs e)
{
await ApplicationInsights.TrackPageView();
Expand Down
7 changes: 7 additions & 0 deletions src/BlazorApplicationInsights/IApplicationInsights.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.JSInterop;

namespace BlazorApplicationInsights
{
public interface IApplicationInsights
{
/// <summary>
/// Set IJSRuntime and run init action queue
/// </summary>
/// <param name="jSRuntime"></param>
Task InitBlazorApplicationInsightsAsync(IJSRuntime jSRuntime);

/// <summary>
/// Log a user action or other occurrence.
/// </summary>
Expand Down
29 changes: 27 additions & 2 deletions src/BlazorApplicationInsights/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace BlazorApplicationInsights
Expand All @@ -7,6 +9,24 @@ public static class IServiceCollectionExtensions
{
/// <summary>
/// Adds the BlazorApplicationInsights services.
/// Blazor Server, set addILoggerProvider to false
/// </summary>
/// <param name="services"></param>
/// <param name="addILoggerProvider"></param>
/// <returns></returns>
public static IServiceCollection AddBlazorApplicationInsights(this IServiceCollection services, Func<IApplicationInsights, Task> onInsightsInit, bool addILoggerProvider = true)
{
if (addILoggerProvider)
{
AddLoggerProvider(services);
}

return services.AddSingleton<IApplicationInsights>(factory => new ApplicationInsights(onInsightsInit));
}

/// <summary>
/// Adds the BlazorApplicationInsights services.
/// Blazor Server, set addILoggerProvider to false
/// </summary>
/// <param name="services"></param>
/// <param name="addILoggerProvider"></param>
Expand All @@ -15,10 +35,15 @@ public static IServiceCollection AddBlazorApplicationInsights(this IServiceColle
{
if (addILoggerProvider)
{
services.AddSingleton<ILoggerProvider, ApplicationInsightsLoggerProvider>();
AddLoggerProvider(services);
}

return services.AddSingleton<IApplicationInsights, ApplicationInsights>();
}

private static void AddLoggerProvider(IServiceCollection services)
{
services.AddSingleton<ILoggerProvider, ApplicationInsightsLoggerProvider>();
}
}
}

0 comments on commit e03f280

Please sign in to comment.