Skip to content

Commit 096991a

Browse files
V13: Add webhook information to detailed telemetry (#16060)
* Cleanup ReportSiteJob * Report on registered webhook event types * Report on custom header webhook count * Use constants instead of magic strings * Update tests * Update translation files
1 parent 2bb56f1 commit 096991a

File tree

7 files changed

+75
-16
lines changed

7 files changed

+75
-16
lines changed

src/Umbraco.Core/Constants-Telemetry.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@ public static class Telemetry
3232
public static string BackofficeExternalLoginProviderCount = "BackofficeExternalLoginProviderCount";
3333
public static string DeliverApiEnabled = "DeliverApiEnabled";
3434
public static string DeliveryApiPublicAccess = "DeliveryApiPublicAccess";
35+
public static string WebhookPrefix = "WebhookCount_";
36+
public static string WebhookTotal = $"{WebhookPrefix}Total";
37+
public static string WebhookCustomHeaders = $"{WebhookPrefix}CustomHeaders";
38+
public static string WebhookCustomEvent = $"{WebhookPrefix}CustomEvent";
3539
}
3640
}

src/Umbraco.Core/EmbeddedResources/Lang/en.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3077,7 +3077,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
30773077
<key alias="detailedLevelDescription"><![CDATA[We will send:
30783078
<ul>
30793079
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
3080-
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.</li>
3080+
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, and Property Editors in use.</li>
30813081
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
30823082
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>
30833083
</ul>

src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
20352035
<key alias="webhookKey">Webhook key</key>
20362036
<key alias="retryCount">Retry count</key>
20372037
<key alias="toggleDebug">Toggle debug mode for more information.</key>
2038-
<key alias="statusNotOk">Not OK status code</key>
2038+
<key alias="statusNotOk">Not OK status code</key>
20392039
<key alias="urlDescription">The url to call when the webhook is triggered.</key>
20402040
<key alias="eventDescription">The events for which the webhook should be triggered.</key>
20412041
<key alias="contentTypeDescription">Only trigger the webhook for a specific content type.</key>
@@ -3096,7 +3096,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
30963096
We will send:
30973097
<ul>
30983098
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
3099-
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.</li>
3099+
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, and Property Editors in use.</li>
31003100
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
31013101
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>
31023102
</ul>

src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ReportSiteJob.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,24 @@ namespace Umbraco.Cms.Infrastructure.BackgroundJobs.Jobs;
1717
public class ReportSiteJob : IRecurringBackgroundJob
1818
{
1919

20-
public TimeSpan Period { get => TimeSpan.FromDays(1); }
21-
public TimeSpan Delay { get => TimeSpan.FromMinutes(5); }
22-
public ServerRole[] ServerRoles { get => Enum.GetValues<ServerRole>(); }
20+
public TimeSpan Period => TimeSpan.FromDays(1);
2321

24-
// No-op event as the period never changes on this job
25-
public event EventHandler PeriodChanged { add { } remove { } }
22+
public TimeSpan Delay => TimeSpan.FromMinutes(5);
23+
24+
public ServerRole[] ServerRoles => Enum.GetValues<ServerRole>();
2625

26+
// No-op event as the period never changes on this job
27+
public event EventHandler PeriodChanged
28+
{
29+
add { } remove { }
30+
}
2731

2832
private static HttpClient _httpClient = new();
33+
2934
private readonly ILogger<ReportSiteJob> _logger;
35+
3036
private readonly ITelemetryService _telemetryService;
31-
37+
3238

3339
public ReportSiteJob(
3440
ILogger<ReportSiteJob> logger,
@@ -43,9 +49,8 @@ public ReportSiteJob(
4349
/// Runs the background task to send the anonymous ID
4450
/// to telemetry service
4551
/// </summary>
46-
public async Task RunJobAsync()
52+
public async Task RunJobAsync()
4753
{
48-
4954
if (_telemetryService.TryGetTelemetryReportData(out TelemetryReportData? telemetryReportData) is false)
5055
{
5156
_logger.LogWarning("No telemetry marker found");

src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.TelemetryProviders.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static IUmbracoBuilder AddTelemetryProviders(this IUmbracoBuilder builder
2020
builder.Services.AddTransient<IDetailedTelemetryProvider, UserTelemetryProvider>();
2121
builder.Services.AddTransient<IDetailedTelemetryProvider, SystemInformationTelemetryProvider>();
2222
builder.Services.AddTransient<IDetailedTelemetryProvider, DeliveryApiTelemetryProvider>();
23+
builder.Services.AddTransient<IDetailedTelemetryProvider, WebhookTelemetryProvider>();
2324
return builder;
2425
}
2526
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Umbraco.Cms.Core;
2+
using Umbraco.Cms.Core.Models;
3+
using Umbraco.Cms.Core.Services;
4+
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
5+
6+
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers;
7+
8+
public class WebhookTelemetryProvider : IDetailedTelemetryProvider
9+
{
10+
private readonly IWebhookService _webhookService;
11+
12+
public WebhookTelemetryProvider(IWebhookService webhookService) => _webhookService = webhookService;
13+
14+
private readonly string[] _defaultEventTypes =
15+
[
16+
"Umbraco.ContentDelete",
17+
"Umbraco.ContentPublish",
18+
"Umbraco.ContentUnpublish",
19+
"Umbraco.MediaDelete",
20+
"Umbraco.MediaSave"
21+
];
22+
23+
public IEnumerable<UsageInformation> GetInformation()
24+
{
25+
IWebhook[] allWebhooks = _webhookService.GetAllAsync(0, int.MaxValue).GetAwaiter().GetResult().Items.ToArray();
26+
27+
yield return new UsageInformation(Constants.Telemetry.WebhookTotal, allWebhooks.Length);
28+
29+
foreach (var eventType in _defaultEventTypes)
30+
{
31+
IWebhook[] webhooks = allWebhooks.Where(x => x.Events.Contains(eventType)).ToArray();
32+
yield return new UsageInformation($"{Constants.Telemetry.WebhookPrefix}{eventType}", webhooks.Length);
33+
}
34+
35+
IEnumerable<IWebhook> customWebhooks = allWebhooks.Where(x => x.Events.Except(_defaultEventTypes).Any());
36+
yield return new UsageInformation(Constants.Telemetry.WebhookCustomEvent, customWebhooks.Count());
37+
38+
IEnumerable<IWebhook> customHeaderWebhooks = allWebhooks.Where(x => x.Headers.Any());
39+
yield return new UsageInformation(Constants.Telemetry.WebhookCustomHeaders, customHeaderWebhooks.Count());
40+
}
41+
}

tests/Umbraco.Tests.Integration/Umbraco.Core/Telemetry/TelemetryServiceTests.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
using System.Linq;
21
using Microsoft.Extensions.DependencyInjection;
32
using NUnit.Framework;
43
using Umbraco.Cms.Core;
54
using Umbraco.Cms.Core.Configuration.Models;
6-
using Umbraco.Cms.Core.DependencyInjection;
75
using Umbraco.Cms.Core.Models;
86
using Umbraco.Cms.Core.Services;
97
using Umbraco.Cms.Core.Telemetry;
8+
using Umbraco.Cms.Core.Webhooks;
109
using Umbraco.Cms.Tests.Common.Testing;
1110
using Umbraco.Cms.Tests.Integration.Testing;
1211

@@ -20,12 +19,15 @@ protected override void CustomTestSetup(IUmbracoBuilder builder) =>
2019
builder.Services.Configure<GlobalSettings>(options => options.Id = Guid.NewGuid().ToString());
2120

2221
private ITelemetryService TelemetryService => GetRequiredService<ITelemetryService>();
22+
2323
private IMetricsConsentService MetricsConsentService => GetRequiredService<IMetricsConsentService>();
2424

25+
private WebhookEventCollection WebhookEventCollection => GetRequiredService<WebhookEventCollection>();
26+
2527
[Test]
2628
public void Expected_Detailed_Telemetry_Exists()
2729
{
28-
var expectedData = new[]
30+
var expectedData = new List<string>
2931
{
3032
Constants.Telemetry.RootCount,
3133
Constants.Telemetry.DomainCount,
@@ -52,9 +54,15 @@ public void Expected_Detailed_Telemetry_Exists()
5254
Constants.Telemetry.BackofficeExternalLoginProviderCount,
5355
Constants.Telemetry.RuntimeMode,
5456
Constants.Telemetry.DeliverApiEnabled,
55-
Constants.Telemetry.DeliveryApiPublicAccess
57+
Constants.Telemetry.DeliveryApiPublicAccess,
58+
Constants.Telemetry.WebhookTotal,
59+
Constants.Telemetry.WebhookCustomHeaders,
60+
Constants.Telemetry.WebhookCustomEvent,
5661
};
5762

63+
// Add the default webhook events.
64+
expectedData.AddRange(WebhookEventCollection.Select(eventInfo => $"{Constants.Telemetry.WebhookPrefix}{eventInfo.Alias}"));
65+
5866
MetricsConsentService.SetConsentLevel(TelemetryLevel.Detailed);
5967
var success = TelemetryService.TryGetTelemetryReportData(out var telemetryReportData);
6068
var detailed = telemetryReportData.Detailed.ToArray();
@@ -63,7 +71,7 @@ public void Expected_Detailed_Telemetry_Exists()
6371
Assert.Multiple(() =>
6472
{
6573
Assert.IsNotNull(detailed);
66-
Assert.AreEqual(expectedData.Length, detailed.Length);
74+
Assert.AreEqual(expectedData.Count, detailed.Length);
6775

6876
foreach (var expectedInfo in expectedData)
6977
{

0 commit comments

Comments
 (0)