Skip to content

Commit 3ef5f34

Browse files
authored
Merge pull request #304 from jimmyca15/user/jimmyca/appInsightsTelemetryExample
Add example for telemetry publishing.
2 parents 95492cc + 403d370 commit 3ef5f34

File tree

81 files changed

+74753
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+74753
-4
lines changed

Microsoft.FeatureManagement.sln

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{FB
1515
EndProject
1616
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.FeatureManagement.AspNetCore", "tests\Tests.FeatureManagement.AspNetCore\Tests.FeatureManagement.AspNetCore.csproj", "{FC0DC3E2-5646-4AEC-A7DB-2D6167BC3BB4}"
1717
EndProject
18-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "examples\ConsoleApp\ConsoleApp.csproj", "{7B98D293-F270-423E-A9A6-0D388E903AE9}"
18+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "examples\ConsoleApp\ConsoleApp.csproj", "{7B98D293-F270-423E-A9A6-0D388E903AE9}"
1919
EndProject
20-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorPages", "examples\RazorPages\RazorPages.csproj", "{36DBB413-D9CA-4C56-AE5B-EAEA4C344DB3}"
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPages", "examples\RazorPages\RazorPages.csproj", "{36DBB413-D9CA-4C56-AE5B-EAEA4C344DB3}"
2121
EndProject
22-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeatureFlagDemo", "examples\FeatureFlagDemo\FeatureFlagDemo.csproj", "{DACAB624-4611-42E8-844C-529F93A54980}"
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureFlagDemo", "examples\FeatureFlagDemo\FeatureFlagDemo.csproj", "{DACAB624-4611-42E8-844C-529F93A54980}"
2323
EndProject
24-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetingConsoleApp", "examples\TargetingConsoleApp\TargetingConsoleApp.csproj", "{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}"
24+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TargetingConsoleApp", "examples\TargetingConsoleApp\TargetingConsoleApp.csproj", "{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}"
25+
EndProject
26+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EvaluationDataToApplicationInsights", "examples\EvaluationDataToApplicationInsights\EvaluationDataToApplicationInsights.csproj", "{1502529E-47E9-4306-98C4-BF6CF7C7C275}"
27+
EndProject
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FeatureManagement.Telemetry.ApplicationInsights", "src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.csproj", "{3448BDE1-5145-49D4-936A-757B68387439}"
2529
EndProject
2630
Global
2731
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -61,6 +65,14 @@ Global
6165
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}.Debug|Any CPU.Build.0 = Debug|Any CPU
6266
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}.Release|Any CPU.ActiveCfg = Release|Any CPU
6367
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Debug|Any CPU.Build.0 = Debug|Any CPU
70+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.ActiveCfg = Release|Any CPU
71+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.Build.0 = Release|Any CPU
72+
{3448BDE1-5145-49D4-936A-757B68387439}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73+
{3448BDE1-5145-49D4-936A-757B68387439}.Debug|Any CPU.Build.0 = Debug|Any CPU
74+
{3448BDE1-5145-49D4-936A-757B68387439}.Release|Any CPU.ActiveCfg = Release|Any CPU
75+
{3448BDE1-5145-49D4-936A-757B68387439}.Release|Any CPU.Build.0 = Release|Any CPU
6476
EndGlobalSection
6577
GlobalSection(SolutionProperties) = preSolution
6678
HideSolutionNode = FALSE
@@ -72,6 +84,7 @@ Global
7284
{36DBB413-D9CA-4C56-AE5B-EAEA4C344DB3} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
7385
{DACAB624-4611-42E8-844C-529F93A54980} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
7486
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
87+
{1502529E-47E9-4306-98C4-BF6CF7C7C275} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
7588
EndGlobalSection
7689
GlobalSection(ExtensibilityGlobals) = postSolution
7790
SolutionGuid = {84DA6C54-F140-4518-A1B4-E4CF42117FBD}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.21.0" />
10+
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="6.1.1" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\..\src\Microsoft.FeatureManagement.AspNetCore\Microsoft.FeatureManagement.AspNetCore.csproj" />
15+
<ProjectReference Include="..\..\src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.csproj" />
16+
</ItemGroup>
17+
18+
</Project>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
//
4+
using Microsoft.FeatureManagement.FeatureFilters;
5+
6+
namespace EvaluationDataToApplicationInsights
7+
{
8+
/// <summary>
9+
/// Provides an implementation of <see cref="ITargetingContextAccessor"/> that creates a targeting context using info from the current HTTP request.
10+
/// </summary>
11+
public class HttpContextTargetingContextAccessor : ITargetingContextAccessor
12+
{
13+
private const string TargetingContextLookup = "HttpContextTargetingContextAccessor.TargetingContext";
14+
private readonly IHttpContextAccessor _httpContextAccessor;
15+
16+
public HttpContextTargetingContextAccessor(IHttpContextAccessor httpContextAccessor)
17+
{
18+
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
19+
}
20+
21+
public ValueTask<TargetingContext> GetContextAsync()
22+
{
23+
HttpContext httpContext = _httpContextAccessor.HttpContext;
24+
25+
//
26+
// Try cache lookup
27+
if (httpContext.Items.TryGetValue(TargetingContextLookup, out object value))
28+
{
29+
return new ValueTask<TargetingContext>((TargetingContext)value);
30+
}
31+
32+
string username = httpContext.Request.Cookies["username"];
33+
34+
var groups = new List<string>();
35+
36+
//
37+
// Build targeting context based on user info
38+
var targetingContext = new TargetingContext
39+
{
40+
UserId = username,
41+
Groups = groups
42+
};
43+
44+
//
45+
// Cache for subsequent lookup
46+
httpContext.Items[TargetingContextLookup] = targetingContext;
47+
48+
return new ValueTask<TargetingContext>(targetingContext);
49+
}
50+
}
51+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@page
2+
@model CheckoutModel
3+
@{
4+
ViewData["Title"] = "Checkout";
5+
}
6+
<h1>@ViewData["Title"]</h1>
7+
8+
<p>Click Below To Check Out!</p>
9+
10+
<button id="checkout" name="checkout" onclick="appInsights.trackEvent({ name: 'checkout', properties: { 'success' : 'yes' } }); appInsights.trackMetric({ name: 'checkoutAmount', average: Math.floor(Math.random() * 100) }); alert('Checked Out!');">
11+
Check Out
12+
</button>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Microsoft.AspNetCore.Mvc.RazorPages;
2+
3+
namespace EvaluationDataToApplicationInsights.Pages
4+
{
5+
public class CheckoutModel : PageModel
6+
{
7+
}
8+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@page
2+
@model ErrorModel
3+
@{
4+
ViewData["Title"] = "Error";
5+
}
6+
7+
<h1 class="text-danger">Error.</h1>
8+
<h2 class="text-danger">An error occurred while processing your request.</h2>
9+
10+
@if (Model.ShowRequestId)
11+
{
12+
<p>
13+
<strong>Request ID:</strong> <code>@Model.RequestId</code>
14+
</p>
15+
}
16+
17+
<h3>Development Mode</h3>
18+
<p>
19+
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
20+
</p>
21+
<p>
22+
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
23+
It can result in displaying sensitive information from exceptions to end users.
24+
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
25+
and restarting the app.
26+
</p>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.AspNetCore.Mvc.RazorPages;
3+
using System.Diagnostics;
4+
5+
namespace EvaluationDataToApplicationInsights.Pages
6+
{
7+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
8+
[IgnoreAntiforgeryToken]
9+
public class ErrorModel : PageModel
10+
{
11+
public string RequestId { get; set; }
12+
13+
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
14+
15+
private readonly ILogger<ErrorModel> _logger;
16+
17+
public ErrorModel(ILogger<ErrorModel> logger)
18+
{
19+
_logger = logger;
20+
}
21+
22+
public void OnGet()
23+
{
24+
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
25+
}
26+
}
27+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
@page
2+
@model IndexModel
3+
@{
4+
ViewData["Title"] = "Home page";
5+
}
6+
7+
<div class="text-center mb-40">
8+
<h1 class="display-4">Welcome, @Model.Username !</h1>
9+
</div>
10+
11+
<div class="text-center">
12+
<div style="display:inline-block;width:500px;">
13+
<img class="mb-40" src="@ViewData["ImageUri"]" />
14+
<div class="panel panel-primary">
15+
<div class="panel-heading">
16+
<h3 class="panel-title">
17+
<span class="glyphicon glyphicon-arrow-right"></span>Rate the image on a scale of 1 - 5 !<span class="glyphicon glyphicon-new-window"></span></a>
18+
</h3>
19+
</div>
20+
<form action="/" method="post">
21+
<div class="panel-body mb-5">
22+
<ul class="list-group">
23+
<li class="list-group-item">
24+
<div class="radio">
25+
<label>
26+
<input type="radio" name="imageScore" value="5">
27+
5
28+
</label>
29+
</div>
30+
</li>
31+
<li class="list-group-item">
32+
<div class="radio">
33+
<label>
34+
<input type="radio" name="imageScore" value="4">
35+
4
36+
</label>
37+
</div>
38+
</li>
39+
<li class="list-group-item">
40+
<div class="radio">
41+
<label>
42+
<input type="radio" name="imageScore" value="3">
43+
3
44+
</label>
45+
</div>
46+
</li>
47+
<li class="list-group-item">
48+
<div class="radio">
49+
<label>
50+
<input type="radio" name="imageScore" value="2">
51+
2
52+
</label>
53+
</div>
54+
</li>
55+
<li class="list-group-item">
56+
<div class="radio">
57+
<label>
58+
<input type="radio" name="imageScore" value="1">
59+
1
60+
</label>
61+
</div>
62+
</li>
63+
</ul>
64+
</div>
65+
@Html.AntiForgeryToken()
66+
<div class="panel-footer">
67+
<input type="submit" class="btn btn-primary btn-sm" value="Vote" />
68+
</div>
69+
</form>
70+
</div>
71+
</div>
72+
</div>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using Microsoft.ApplicationInsights;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.AspNetCore.Mvc.RazorPages;
4+
using Microsoft.FeatureManagement;
5+
6+
namespace EvaluationDataToApplicationInsights.Pages
7+
{
8+
public class IndexModel : PageModel
9+
{
10+
private readonly IVariantFeatureManager _featureManager;
11+
private readonly TelemetryClient _telemetry;
12+
13+
public string Username { get; set; }
14+
15+
public IndexModel(
16+
IVariantFeatureManager featureManager,
17+
TelemetryClient telemetry)
18+
{
19+
_featureManager = featureManager ?? throw new ArgumentNullException(nameof(featureManager));
20+
_telemetry = telemetry ?? throw new ArgumentNullException(nameof(telemetry));
21+
}
22+
23+
public async Task<IActionResult> OnGet()
24+
{
25+
Username = Request.Cookies["username"];
26+
27+
if (string.IsNullOrEmpty(Username))
28+
{
29+
return Redirect("/RandomizeUser");
30+
}
31+
32+
//
33+
// Use application's feature manager to get assigned variant for current user
34+
Variant variant = await _featureManager
35+
.GetVariantAsync("ImageRating", HttpContext.RequestAborted);
36+
37+
//
38+
// Set the page's display image based on the assigned variant.
39+
ViewData["ImageUri"] = variant.Configuration.Value;
40+
41+
return Page();
42+
}
43+
44+
public IActionResult OnPost()
45+
{
46+
if (Request.Form != null)
47+
{
48+
string val = Request.Form["imageScore"];
49+
50+
if (val != null &&
51+
int.TryParse(val, out int rating))
52+
{
53+
_telemetry.TrackEvent(
54+
"Vote",
55+
properties: null,
56+
metrics: new Dictionary<string, double>
57+
{
58+
{ "ImageRating", rating }
59+
});
60+
}
61+
}
62+
63+
return Redirect("/RandomizeUser");
64+
}
65+
}
66+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@page
2+
@model EvaluationDataToApplicationInsights.Pages.RandomizeUserModel
3+
@{
4+
}

0 commit comments

Comments
 (0)