Browse Source

Tracking for graphql.

pull/968/head
Sebastian 3 years ago
parent
commit
6ea95a6c66
  1. 44
      backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs
  2. 16
      backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs
  3. 31
      backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryService.cs
  4. 29
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Resolvers.cs
  5. 10
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs
  6. 16
      backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs
  7. 9
      backend/src/Squidex.Domain.Apps.Entities/Teams/Indexes/TeamsIndex.cs
  8. 4
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs
  9. 10
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs
  10. 7
      backend/src/Squidex/appsettings.json

44
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<AppDomainObject>(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<AppDomainObject>(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);
}
}
}

16
backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs

@ -61,8 +61,10 @@ public sealed class AppsIndex : IAppsIndex, ICommandMiddleware, IInitializable
public async Task<List<IAppEntity>> 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<List<IAppEntity>> 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<IAppEntity?> 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<IAppEntity?> 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)

31
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<IReadOnlyList<IAssetFolderEntity>> 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<IAssetFolderEntity>();
while (id != DomainId.Empty)
@ -65,8 +68,10 @@ public sealed class AssetQueryService : IAssetQueryService
public async Task<IResultList<IAssetFolderEntity>> 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<IResultList<IAssetFolderEntity>> 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)

29
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<TSource, T>(Func<TSource, T> resolver)
{
return new FuncFieldResolver<TSource, T>(x => resolver(x.Source));
return new FuncFieldResolver<TSource, T>(c => resolver(c.Source));
}
public static IFieldResolver Sync<TSource, T>(Func<TSource, IResolveFieldContext, GraphQLExecutionContext, T> resolver)
{
return new FuncFieldResolver<TSource, T>(x => resolver(x.Source, x, (GraphQLExecutionContext)x.UserContext));
return new FuncFieldResolver<TSource, T>(c => resolver(c.Source, c, (GraphQLExecutionContext)c.UserContext));
}
public static IFieldResolver Async<TSource, T>(Func<TSource, ValueTask<T?>> resolver)
{
return new FuncFieldResolver<TSource, T>(x => resolver(x.Source));
return new FuncFieldResolver<TSource, T>(c => resolver(c.Source));
}
public static IFieldResolver Async<TSource, T>(Func<TSource, IResolveFieldContext, GraphQLExecutionContext, ValueTask<T?>> resolver)
{
return new FuncFieldResolver<TSource, T>(x => resolver(x.Source, x, (GraphQLExecutionContext)x.UserContext));
return new FuncFieldResolver<TSource, T>(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<IResolveFieldContext, ICommand> action)

10
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<IEnrichedContentEntity>();

16
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<List<ISchemaEntity>> 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<ISchemaEntity?> 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<ISchemaEntity?> 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)

9
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<ITeamEntity?> 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<List<ITeamEntity>> 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();

4
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
{

10
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
{

7
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": {

Loading…
Cancel
Save