/
Telemetry.cs
168 lines (140 loc) · 6.2 KB
/
Telemetry.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
using System.Diagnostics.Metrics;
namespace IdentityServerHost.Pages;
#pragma warning disable CA1034 // Nested types should not be visible
#pragma warning disable CA1724 // Type names should not match namespaces
/// <summary>
/// Telemetry helpers for the UI
/// </summary>
public static class Telemetry
{
private static readonly string ServiceVersion = typeof(Telemetry).Assembly.GetName().Version!.ToString();
/// <summary>
/// Service name for telemetry.
/// </summary>
public static readonly string ServiceName = typeof(Telemetry).Assembly.GetName().Name!;
/// <summary>
/// Metrics configuration
/// </summary>
public static class Metrics
{
/// <summary>
/// Name of Counters
/// </summary>
public static class Counters
{
/// <summary>
/// consent_granted
/// </summary>
public const string ConsentGranted = "consent_granted";
/// <summary>
/// consent_denied
/// </summary>
public const string ConsentDenied = "consent_denied";
/// <summary>
/// grants_revoked
/// </summary>
public const string GrantsRevoked = "grants_revoked";
/// <summary>
/// user_login
/// </summary>
public const string UserLogin = "user_login";
/// <summary>
/// user_login_failure
/// </summary>
public const string UserLoginFailure = "user_login_failure";
/// <summary>
/// user_logout
/// </summary>
public const string UserLogout = "user_logout";
}
/// <summary>
/// Name of tags
/// </summary>
public static class Tags
{
/// <summary>
/// client
/// </summary>
public const string Client = "client";
/// <summary>
/// error
/// </summary>
public const string Error = "error";
/// <summary>
/// idp
/// </summary>
public const string Idp = "idp";
/// <summary>
/// remember
/// </summary>
public const string Remember = "remember";
/// <summary>
/// scope
/// </summary>
public const string Scope = "scope";
}
/// <summary>
/// Meter for the IdentityServer host project
/// </summary>
private static readonly Meter Meter = new Meter(ServiceName, ServiceVersion);
private static Counter<long> ConsentGrantedCounter = Meter.CreateCounter<long>(Counters.ConsentGranted);
/// <summary>
/// Helper method to increase <see cref="Counters.ConsentGranted"/> counter. The scopes
/// are expanded and called one by one to not cause a combinatory explosion of scopes.
/// </summary>
/// <param name="clientId">Client id</param>
/// <param name="scopes">Scope names. Each element is added on it's own to the counter</param>
public static void ConsentGranted(string clientId, IEnumerable<string> scopes, bool remember)
{
ArgumentNullException.ThrowIfNull(scopes);
foreach(var scope in scopes)
{
ConsentGrantedCounter.Add(1, new(Tags.Client, clientId), new(Tags.Scope, scope), new(Tags.Remember, remember));
}
}
private static Counter<long> ConsentDeniedCounter = Meter.CreateCounter<long>(Counters.ConsentDenied);
/// <summary>
/// Helper method to increase <see cref="Counters.ConsentDenied"/> counter. The scopes
/// are expanded and called one by one to not cause a combinatory explosion of scopes.
/// </summary>
/// <param name="clientId">Client id</param>
/// <param name="scopes">Scope names. Each element is added on it's own to the counter</param>
public static void ConsentDenied(string clientId, IEnumerable<string> scopes)
{
ArgumentNullException.ThrowIfNull(scopes);
foreach (var scope in scopes)
{
ConsentDeniedCounter.Add(1, new(Tags.Client, clientId), new(Tags.Scope, scope));
}
}
private static Counter<long> GrantsRevokedCounter = Meter.CreateCounter<long>(Counters.GrantsRevoked);
/// <summary>
/// Helper method to increase the <see cref="Counters.GrantsRevoked"/> counter.
/// </summary>
/// <param name="clientId">Client id to revoke for, or null for all.</param>
public static void GrantsRevoked(string? clientId)
=> GrantsRevokedCounter.Add(1, tag: new(Tags.Client, clientId));
private static Counter<long> UserLoginCounter = Meter.CreateCounter<long>(Counters.UserLogin);
/// <summary>
/// Helper method to increase <see cref="Counters.UserLogin"/> counter.
/// </summary>
/// <param name="clientId">Client Id, if available</param>
public static void UserLogin(string? clientId, string idp)
=> UserLoginCounter.Add(1, new(Tags.Client, clientId), new(Tags.Idp, idp));
private static Counter<long> UserLoginFailureCounter = Meter.CreateCounter<long>(Counters.UserLoginFailure);
/// <summary>
/// Helper method to increase <see cref="Counters.UserLoginFailure" counter.
/// </summary>
/// <param name="clientId">Client Id, if available</param>
/// <param name="error">Error message</param>
public static void UserLoginFailure(string? clientId, string idp, string error)
=> UserLoginFailureCounter.Add(1, new(Tags.Client, clientId), new(Tags.Idp, idp), new(Tags.Error, error));
private static Counter<long> UserLogoutCounter = Meter.CreateCounter<long>(Counters.UserLogout);
/// <summary>
/// Helper method to increase the <see cref="Counters.UserLogout"/> counter.
/// </summary>
/// <param name="idp">Idp/authentication scheme for external authentication, or "local" for built in.</param>
public static void UserLogout(string? idp)
=> UserLogoutCounter.Add(1, tag: new(Tags.Idp, idp));
}
}