From 6ea95a6c664b5ad38dc0ae089a32e82d2a92f01b Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 24 Jan 2023 18:26:24 +0100 Subject: [PATCH] Tracking for graphql. --- .../Apps/AppPermanentDeleter.cs | 44 +++++++++---------- .../Apps/Indexes/AppsIndex.cs | 16 +++++-- .../Assets/Queries/AssetQueryService.cs | 31 ++++++++++--- .../Contents/GraphQL/Types/Resolvers.cs | 29 ++++++++++-- .../Contents/Queries/ContentQueryService.cs | 10 ++++- .../Schemas/Indexes/SchemasIndex.cs | 16 +++++-- .../Teams/Indexes/TeamsIndex.cs | 9 +++- .../Controllers/Apps/AppImageController.cs | 4 +- .../Assets/AssetContentController.cs | 10 ++--- backend/src/Squidex/appsettings.json | 7 ++- 10 files changed, 123 insertions(+), 53 deletions(-) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs index 7a2b689e7..8c1857763 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs @@ -68,41 +68,39 @@ public sealed class AppPermanentDeleter : IEventConsumer private async Task OnAppContributorRemoved(AppContributorRemoved appContributorRemoved) { - using (Telemetry.Activities.StartActivity("RemoveContributorFromSystem")) - { - var appId = appContributorRemoved.AppId.Id; + using var activity = Telemetry.Activities.StartActivity("RemoveContributorFromSystem"); + + var appId = appContributorRemoved.AppId.Id; - foreach (var deleter in deleters) + foreach (var deleter in deleters) + { + using (Telemetry.Activities.StartActivity(deleter.GetType().Name)) { - using (Telemetry.Activities.StartActivity(deleter.GetType().Name)) - { - await deleter.DeleteContributorAsync(appId, appContributorRemoved.ContributorId, default); - } + await deleter.DeleteContributorAsync(appId, appContributorRemoved.ContributorId, default); } } } private async Task OnArchiveAsync(AppDeleted appArchived) { - using (Telemetry.Activities.StartActivity("RemoveAppFromSystem")) - { - // Bypass our normal app resolve process, so that we can also retrieve the deleted app. - var app = factory.Create(appArchived.AppId.Id); + using var activity = Telemetry.Activities.StartActivity("RemoveAppFromSystem"); - await app.EnsureLoadedAsync(); + // Bypass our normal app resolve process, so that we can also retrieve the deleted app. + var app = factory.Create(appArchived.AppId.Id); - // If the app does not exist, the version is lower than zero. - if (app.Version < 0) - { - return; - } + await app.EnsureLoadedAsync(); - foreach (var deleter in deleters) + // If the app does not exist, the version is lower than zero. + if (app.Version < 0) + { + return; + } + + foreach (var deleter in deleters) + { + using (Telemetry.Activities.StartActivity(deleter.GetType().Name)) { - using (Telemetry.Activities.StartActivity(deleter.GetType().Name)) - { - await deleter.DeleteAppAsync(app.Snapshot, default); - } + await deleter.DeleteAppAsync(app.Snapshot, default); } } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs index 61e95a4c4..221e0a333 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs @@ -61,8 +61,10 @@ public sealed class AppsIndex : IAppsIndex, ICommandMiddleware, IInitializable public async Task> GetAppsForUserAsync(string userId, PermissionSet permissions, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AppsIndex/GetAppsForUserAsync")) + using (var activity = Telemetry.Activities.StartActivity("AppsIndex/GetAppsForUserAsync")) { + activity?.SetTag("userId", userId); + var apps = await appRepository.QueryAllAsync(userId, permissions.ToAppNames(), ct); foreach (var app in apps.Where(IsValid)) @@ -77,8 +79,10 @@ public sealed class AppsIndex : IAppsIndex, ICommandMiddleware, IInitializable public async Task> GetAppsForTeamAsync(DomainId teamId, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AppsIndex/GetAppsForTeamAsync")) + using (var activity = Telemetry.Activities.StartActivity("AppsIndex/GetAppsForTeamAsync")) { + activity?.SetTag("teamId", teamId); + var apps = await appRepository.QueryAllAsync(teamId, ct); foreach (var app in apps.Where(IsValid)) @@ -93,8 +97,10 @@ public sealed class AppsIndex : IAppsIndex, ICommandMiddleware, IInitializable public async Task GetAppAsync(string name, bool canCache = false, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AppsIndex/GetAppByNameAsync")) + using (var activity = Telemetry.Activities.StartActivity("AppsIndex/GetAppByNameAsync")) { + activity?.SetTag("appName", name); + if (canCache) { if (appCache.TryGetValue(GetCacheKey(name), out var v) && v is IAppEntity cacheApp) @@ -122,8 +128,10 @@ public sealed class AppsIndex : IAppsIndex, ICommandMiddleware, IInitializable public async Task GetAppAsync(DomainId appId, bool canCache = false, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AppsIndex/GetAppAsync")) + using (var activity = Telemetry.Activities.StartActivity("AppsIndex/GetAppAsync")) { + activity?.SetTag("appId", appId); + if (canCache) { if (appCache.TryGetValue(GetCacheKey(appId), out var cached) && cached is IAppEntity cachedApp) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs index a394d0baa..fe553b9c0 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Options; using Squidex.Domain.Apps.Entities.Assets.Repositories; using Squidex.Infrastructure; +using System.Diagnostics; namespace Squidex.Domain.Apps.Entities.Assets.Queries; @@ -39,8 +40,10 @@ public sealed class AssetQueryService : IAssetQueryService public async Task> FindAssetFolderAsync(DomainId appId, DomainId id, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AssetQueryService/FindAssetFolderAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/FindAssetFolderAsync")) { + activity?.SetTag("assetId", id); + var result = new List(); while (id != DomainId.Empty) @@ -65,8 +68,10 @@ public sealed class AssetQueryService : IAssetQueryService public async Task> QueryAssetFoldersAsync(DomainId appId, DomainId parentId, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AssetQueryService/QueryAssetFoldersAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/QueryAssetFoldersAsync")) { + activity?.SetTag("folderId", parentId); + var assetFolders = await QueryFoldersCoreAsync(appId, parentId, ct); return assetFolders; @@ -76,8 +81,10 @@ public sealed class AssetQueryService : IAssetQueryService public async Task> QueryAssetFoldersAsync(Context context, DomainId parentId, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("AssetQueryService/QueryAssetFoldersAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/QueryAssetFoldersAsync")) { + activity?.SetTag("folderId", parentId); + var assetFolders = await QueryFoldersCoreAsync(context, parentId, ct); return assetFolders; @@ -89,8 +96,12 @@ public sealed class AssetQueryService : IAssetQueryService { Guard.NotNull(context); - using (Telemetry.Activities.StartActivity("AssetQueryService/FindByHashAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/FindByHashAsync")) { + activity?.SetTag("fileHash", hash); + activity?.SetTag("fileName", fileName); + activity?.SetTag("fileSize", fileSize); + var asset = await FindByHashCoreAsync(context, hash, fileName, fileSize, ct); if (asset == null) @@ -107,8 +118,10 @@ public sealed class AssetQueryService : IAssetQueryService { Guard.NotNull(context); - using (Telemetry.Activities.StartActivity("AssetQueryService/FindBySlugAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/FindBySlugAsync")) { + activity?.SetTag("slug", slug); + var asset = await FindBySlugCoreAsync(context, slug, ct); if (asset == null) @@ -125,8 +138,10 @@ public sealed class AssetQueryService : IAssetQueryService { Guard.NotNull(context); - using (Telemetry.Activities.StartActivity("AssetQueryService/FindGlobalAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/FindGlobalAsync")) { + activity?.SetTag("assetId", id); + var asset = await FindCoreAsync(id, ct); if (asset == null) @@ -143,8 +158,10 @@ public sealed class AssetQueryService : IAssetQueryService { Guard.NotNull(context); - using (Telemetry.Activities.StartActivity("AssetQueryService/FindAsync")) + using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/FindAsync")) { + activity?.SetTag("assetId", id); + IAssetEntity? asset; if (version > EtagVersion.Empty) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Resolvers.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Resolvers.cs index 8373469c4..7d837c058 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Resolvers.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Resolvers.cs @@ -6,6 +6,7 @@ // ========================================================================== using GraphQL; +using GraphQL.Execution; using GraphQL.Resolvers; using Squidex.Domain.Apps.Core.Subscriptions; using Squidex.Infrastructure; @@ -21,22 +22,42 @@ public static class Resolvers { public static IFieldResolver Sync(Func resolver) { - return new FuncFieldResolver(x => resolver(x.Source)); + return new FuncFieldResolver(c => resolver(c.Source)); } public static IFieldResolver Sync(Func resolver) { - return new FuncFieldResolver(x => resolver(x.Source, x, (GraphQLExecutionContext)x.UserContext)); + return new FuncFieldResolver(c => resolver(c.Source, c, (GraphQLExecutionContext)c.UserContext)); } public static IFieldResolver Async(Func> resolver) { - return new FuncFieldResolver(x => resolver(x.Source)); + return new FuncFieldResolver(c => resolver(c.Source)); } public static IFieldResolver Async(Func> resolver) { - return new FuncFieldResolver(x => resolver(x.Source, x, (GraphQLExecutionContext)x.UserContext)); + return new FuncFieldResolver(async c => + { + using (var activity = Telemetry.Activities.StartActivity($"gql/{c.FieldDefinition.Name}")) + { + activity?.SetTag("/gql/fieldName", c.FieldDefinition.Name); + activity?.SetTag("/gql/fieldType", c.FieldDefinition.ResolvedType?.ToString()); + + if (activity != null && c.Arguments != null) + { + foreach (var (key, value) in c.Arguments) + { + if (value.Source == ArgumentSource.Literal) + { + activity.SetTag($"arg/{key}", value); + } + } + } + + return await resolver(c.Source, c, (GraphQLExecutionContext)c.UserContext); + } + }); } public static IFieldResolver Command(string permissionId, Func action) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs index fae4b4af0..6d5ecc876 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System.Diagnostics; using Microsoft.Extensions.Options; using Squidex.Domain.Apps.Entities.Contents.Repositories; using Squidex.Domain.Apps.Entities.Schemas; @@ -46,8 +47,11 @@ public sealed class ContentQueryService : IContentQueryService { Guard.NotNull(context); - using (Telemetry.Activities.StartActivity("ContentQueryService/FindAsync")) + using (var activity = Telemetry.Activities.StartActivity("ContentQueryService/FindAsync")) { + activity?.SetTag("schemaName", schemaIdOrName); + activity?.SetTag("contentId", id); + var schema = await GetSchemaOrThrowAsync(context, schemaIdOrName, ct); IContentEntity? content; @@ -80,8 +84,10 @@ public sealed class ContentQueryService : IContentQueryService { Guard.NotNull(context); - using (Telemetry.Activities.StartActivity("ContentQueryService/QueryAsync")) + using (var activity = Telemetry.Activities.StartActivity("ContentQueryService/QueryAsync")) { + activity?.SetTag("schemaName", schemaIdOrName); + if (q == null) { return ResultList.Empty(); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs index ebc866a07..14436db6c 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs @@ -13,6 +13,8 @@ using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.States; using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Validation; +using System.Diagnostics; +using System.Xml.Linq; namespace Squidex.Domain.Apps.Entities.Schemas.Indexes; @@ -34,8 +36,10 @@ public sealed class SchemasIndex : ICommandMiddleware, ISchemasIndex public async Task> GetSchemasAsync(DomainId appId, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("SchemasIndex/GetSchemasAsync")) + using (var activity = Telemetry.Activities.StartActivity("SchemasIndex/GetSchemasAsync")) { + activity?.SetTag("appId", appId); + var schemas = await schemaRepository.QueryAllAsync(appId, ct); foreach (var schema in schemas.Where(IsValid)) @@ -50,8 +54,11 @@ public sealed class SchemasIndex : ICommandMiddleware, ISchemasIndex public async Task GetSchemaAsync(DomainId appId, string name, bool canCache, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("SchemasIndex/GetSchemaByNameAsync")) + using (var activity = Telemetry.Activities.StartActivity("SchemasIndex/GetSchemaByNameAsync")) { + activity?.SetTag("appId", appId); + activity?.SetTag("schemaName", name); + var cacheKey = GetCacheKey(appId, name); if (canCache) @@ -81,8 +88,11 @@ public sealed class SchemasIndex : ICommandMiddleware, ISchemasIndex public async Task GetSchemaAsync(DomainId appId, DomainId id, bool canCache, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("SchemasIndex/GetSchemaAsync")) + using (var activity = Telemetry.Activities.StartActivity("SchemasIndex/GetSchemaAsync")) { + activity?.SetTag("appId", appId); + activity?.SetTag("schemaId", id); + var cacheKey = GetCacheKey(appId, id); if (canCache) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Teams/Indexes/TeamsIndex.cs b/backend/src/Squidex.Domain.Apps.Entities/Teams/Indexes/TeamsIndex.cs index ea5823362..f7ab34137 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Teams/Indexes/TeamsIndex.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Teams/Indexes/TeamsIndex.cs @@ -7,6 +7,7 @@ using Squidex.Domain.Apps.Entities.Teams.Repositories; using Squidex.Infrastructure; +using System.Diagnostics; namespace Squidex.Domain.Apps.Entities.Teams.Indexes; @@ -22,8 +23,10 @@ public sealed class TeamsIndex : ITeamsIndex public async Task GetTeamAsync(DomainId id, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("TeamsIndex/GetTeamAsync")) + using (var activity = Telemetry.Activities.StartActivity("TeamsIndex/GetTeamAsync")) { + activity?.SetTag("teamId", id); + var team = await teamRepository.FindAsync(id, ct); return IsValid(team) ? team : null; @@ -33,8 +36,10 @@ public sealed class TeamsIndex : ITeamsIndex public async Task> GetTeamsAsync(string userId, CancellationToken ct = default) { - using (Telemetry.Activities.StartActivity("TeamsIndex/GetTeamsAsync")) + using (var activity = Telemetry.Activities.StartActivity("TeamsIndex/GetTeamsAsync")) { + activity?.SetTag("userId", userId); + var teams = await teamRepository.QueryAllAsync(userId, ct); return teams.Where(IsValid).ToList(); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs index 96b3fedc9..0781b7192 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs @@ -85,6 +85,8 @@ public sealed class AppImageController : ApiController #pragma warning disable MA0040 // Flow the cancellation token using var activity = Telemetry.Activities.StartActivity("Resize"); + activity?.SetTag("fileType", mimeType); + await using var assetOriginal = new TempAssetFile(resizedAsset, mimeType, 0); await using var assetResized = new TempAssetFile(resizedAsset, mimeType, 0); @@ -102,7 +104,7 @@ public sealed class AppImageController : ApiController } } - using (Telemetry.Activities.StartActivity("Resize")) + using (Telemetry.Activities.StartActivity("Compute")) { try { diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs index f11176e92..3f8eb004e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs @@ -154,10 +154,7 @@ public sealed class AssetContentController : ApiController if (request.Force) { - using (Telemetry.Activities.StartActivity("Resize")) - { - await ResizeAsync(asset, suffix, body, resizeOptions, true, ct); - } + await ResizeAsync(asset, suffix, body, resizeOptions, true, ct); } else { @@ -205,6 +202,9 @@ public sealed class AssetContentController : ApiController #pragma warning disable MA0040 // Flow the cancellation token using var activity = Telemetry.Activities.StartActivity("Resize"); + activity?.SetTag("fileType", asset.MimeType); + activity?.SetTag("fileSize", asset.FileSize); + await using var assetOriginal = new TempAssetFile(asset.FileName, asset.MimeType, 0); await using var assetResized = new TempAssetFile(asset.FileName, asset.MimeType, 0); @@ -216,7 +216,7 @@ public sealed class AssetContentController : ApiController } } - using (Telemetry.Activities.StartActivity("Resize")) + using (Telemetry.Activities.StartActivity("Compute")) { try { diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index 6e162ea7f..89633af36 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -339,8 +339,11 @@ "storeRetentionInDays": 90, "stackdriver": { - // True, to enable stackdriver integration. - "enabled": false + // True, to enable stackdriver integration. + "enabled": false, + + // The ID of your Google Cloud project. + "projectId": "" }, "otlp": {