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:
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user