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
This commit is contained in:
Mole
2024-04-16 14:36:02 +02:00
committed by GitHub
parent 2bb56f1b81
commit 096991ac79
7 changed files with 75 additions and 16 deletions

View File

@@ -32,5 +32,9 @@ public static partial class Constants
public static string BackofficeExternalLoginProviderCount = "BackofficeExternalLoginProviderCount";
public static string DeliverApiEnabled = "DeliverApiEnabled";
public static string DeliveryApiPublicAccess = "DeliveryApiPublicAccess";
public static string WebhookPrefix = "WebhookCount_";
public static string WebhookTotal = $"{WebhookPrefix}Total";
public static string WebhookCustomHeaders = $"{WebhookPrefix}CustomHeaders";
public static string WebhookCustomEvent = $"{WebhookPrefix}CustomEvent";
}
}

View File

@@ -3077,7 +3077,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
<key alias="detailedLevelDescription"><![CDATA[We will send:
<ul>
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
<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>
<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>
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
<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>
</ul>

View File

@@ -2035,7 +2035,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
<key alias="webhookKey">Webhook key</key>
<key alias="retryCount">Retry count</key>
<key alias="toggleDebug">Toggle debug mode for more information.</key>
<key alias="statusNotOk">Not OK status code</key>
<key alias="statusNotOk">Not OK status code</key>
<key alias="urlDescription">The url to call when the webhook is triggered.</key>
<key alias="eventDescription">The events for which the webhook should be triggered.</key>
<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
We will send:
<ul>
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
<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>
<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>
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
<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>
</ul>

View File

@@ -17,18 +17,24 @@ namespace Umbraco.Cms.Infrastructure.BackgroundJobs.Jobs;
public class ReportSiteJob : IRecurringBackgroundJob
{
public TimeSpan Period { get => TimeSpan.FromDays(1); }
public TimeSpan Delay { get => TimeSpan.FromMinutes(5); }
public ServerRole[] ServerRoles { get => Enum.GetValues<ServerRole>(); }
public TimeSpan Period => TimeSpan.FromDays(1);
public TimeSpan Delay => TimeSpan.FromMinutes(5);
public ServerRole[] ServerRoles => Enum.GetValues<ServerRole>();
// No-op event as the period never changes on this job
public event EventHandler PeriodChanged { add { } remove { } }
public event EventHandler PeriodChanged
{
add { } remove { }
}
private static HttpClient _httpClient = new();
private readonly ILogger<ReportSiteJob> _logger;
private readonly ITelemetryService _telemetryService;
public ReportSiteJob(
ILogger<ReportSiteJob> logger,
@@ -43,9 +49,8 @@ public class ReportSiteJob : IRecurringBackgroundJob
/// Runs the background task to send the anonymous ID
/// to telemetry service
/// </summary>
public async Task RunJobAsync()
public async Task RunJobAsync()
{
if (_telemetryService.TryGetTelemetryReportData(out TelemetryReportData? telemetryReportData) is false)
{
_logger.LogWarning("No telemetry marker found");

View File

@@ -20,6 +20,7 @@ public static class UmbracoBuilder_TelemetryProviders
builder.Services.AddTransient<IDetailedTelemetryProvider, UserTelemetryProvider>();
builder.Services.AddTransient<IDetailedTelemetryProvider, SystemInformationTelemetryProvider>();
builder.Services.AddTransient<IDetailedTelemetryProvider, DeliveryApiTelemetryProvider>();
builder.Services.AddTransient<IDetailedTelemetryProvider, WebhookTelemetryProvider>();
return builder;
}
}

View File

@@ -0,0 +1,41 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers;
public class WebhookTelemetryProvider : IDetailedTelemetryProvider
{
private readonly IWebhookService _webhookService;
public WebhookTelemetryProvider(IWebhookService webhookService) => _webhookService = webhookService;
private readonly string[] _defaultEventTypes =
[
"Umbraco.ContentDelete",
"Umbraco.ContentPublish",
"Umbraco.ContentUnpublish",
"Umbraco.MediaDelete",
"Umbraco.MediaSave"
];
public IEnumerable<UsageInformation> GetInformation()
{
IWebhook[] allWebhooks = _webhookService.GetAllAsync(0, int.MaxValue).GetAwaiter().GetResult().Items.ToArray();
yield return new UsageInformation(Constants.Telemetry.WebhookTotal, allWebhooks.Length);
foreach (var eventType in _defaultEventTypes)
{
IWebhook[] webhooks = allWebhooks.Where(x => x.Events.Contains(eventType)).ToArray();
yield return new UsageInformation($"{Constants.Telemetry.WebhookPrefix}{eventType}", webhooks.Length);
}
IEnumerable<IWebhook> customWebhooks = allWebhooks.Where(x => x.Events.Except(_defaultEventTypes).Any());
yield return new UsageInformation(Constants.Telemetry.WebhookCustomEvent, customWebhooks.Count());
IEnumerable<IWebhook> customHeaderWebhooks = allWebhooks.Where(x => x.Headers.Any());
yield return new UsageInformation(Constants.Telemetry.WebhookCustomHeaders, customHeaderWebhooks.Count());
}
}

View File

@@ -1,12 +1,11 @@
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Telemetry;
using Umbraco.Cms.Core.Webhooks;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
@@ -20,12 +19,15 @@ public class TelemetryServiceTests : UmbracoIntegrationTest
builder.Services.Configure<GlobalSettings>(options => options.Id = Guid.NewGuid().ToString());
private ITelemetryService TelemetryService => GetRequiredService<ITelemetryService>();
private IMetricsConsentService MetricsConsentService => GetRequiredService<IMetricsConsentService>();
private WebhookEventCollection WebhookEventCollection => GetRequiredService<WebhookEventCollection>();
[Test]
public void Expected_Detailed_Telemetry_Exists()
{
var expectedData = new[]
var expectedData = new List<string>
{
Constants.Telemetry.RootCount,
Constants.Telemetry.DomainCount,
@@ -52,9 +54,15 @@ public class TelemetryServiceTests : UmbracoIntegrationTest
Constants.Telemetry.BackofficeExternalLoginProviderCount,
Constants.Telemetry.RuntimeMode,
Constants.Telemetry.DeliverApiEnabled,
Constants.Telemetry.DeliveryApiPublicAccess
Constants.Telemetry.DeliveryApiPublicAccess,
Constants.Telemetry.WebhookTotal,
Constants.Telemetry.WebhookCustomHeaders,
Constants.Telemetry.WebhookCustomEvent,
};
// Add the default webhook events.
expectedData.AddRange(WebhookEventCollection.Select(eventInfo => $"{Constants.Telemetry.WebhookPrefix}{eventInfo.Alias}"));
MetricsConsentService.SetConsentLevel(TelemetryLevel.Detailed);
var success = TelemetryService.TryGetTelemetryReportData(out var telemetryReportData);
var detailed = telemetryReportData.Detailed.ToArray();
@@ -63,7 +71,7 @@ public class TelemetryServiceTests : UmbracoIntegrationTest
Assert.Multiple(() =>
{
Assert.IsNotNull(detailed);
Assert.AreEqual(expectedData.Length, detailed.Length);
Assert.AreEqual(expectedData.Count, detailed.Length);
foreach (var expectedInfo in expectedData)
{