Browse Source

Tracking for graphql.

pull/968/head
Sebastian 4 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) private async Task OnAppContributorRemoved(AppContributorRemoved appContributorRemoved)
{ {
using (Telemetry.Activities.StartActivity("RemoveContributorFromSystem")) using var activity = Telemetry.Activities.StartActivity("RemoveContributorFromSystem");
{
var appId = appContributorRemoved.AppId.Id; 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) private async Task OnArchiveAsync(AppDeleted appArchived)
{ {
using (Telemetry.Activities.StartActivity("RemoveAppFromSystem")) using var activity = 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);
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. await app.EnsureLoadedAsync();
if (app.Version < 0)
{
return;
}
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, public async Task<List<IAppEntity>> GetAppsForUserAsync(string userId, PermissionSet permissions,
CancellationToken ct = default) 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); var apps = await appRepository.QueryAllAsync(userId, permissions.ToAppNames(), ct);
foreach (var app in apps.Where(IsValid)) 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, public async Task<List<IAppEntity>> GetAppsForTeamAsync(DomainId teamId,
CancellationToken ct = default) 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); var apps = await appRepository.QueryAllAsync(teamId, ct);
foreach (var app in apps.Where(IsValid)) 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, public async Task<IAppEntity?> GetAppAsync(string name, bool canCache = false,
CancellationToken ct = default) CancellationToken ct = default)
{ {
using (Telemetry.Activities.StartActivity("AppsIndex/GetAppByNameAsync")) using (var activity = Telemetry.Activities.StartActivity("AppsIndex/GetAppByNameAsync"))
{ {
activity?.SetTag("appName", name);
if (canCache) if (canCache)
{ {
if (appCache.TryGetValue(GetCacheKey(name), out var v) && v is IAppEntity cacheApp) 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, public async Task<IAppEntity?> GetAppAsync(DomainId appId, bool canCache = false,
CancellationToken ct = default) CancellationToken ct = default)
{ {
using (Telemetry.Activities.StartActivity("AppsIndex/GetAppAsync")) using (var activity = Telemetry.Activities.StartActivity("AppsIndex/GetAppAsync"))
{ {
activity?.SetTag("appId", appId);
if (canCache) if (canCache)
{ {
if (appCache.TryGetValue(GetCacheKey(appId), out var cached) && cached is IAppEntity cachedApp) 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 Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Entities.Assets.Repositories; using Squidex.Domain.Apps.Entities.Assets.Repositories;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using System.Diagnostics;
namespace Squidex.Domain.Apps.Entities.Assets.Queries; 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, public async Task<IReadOnlyList<IAssetFolderEntity>> FindAssetFolderAsync(DomainId appId, DomainId id,
CancellationToken ct = default) 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>(); var result = new List<IAssetFolderEntity>();
while (id != DomainId.Empty) while (id != DomainId.Empty)
@ -65,8 +68,10 @@ public sealed class AssetQueryService : IAssetQueryService
public async Task<IResultList<IAssetFolderEntity>> QueryAssetFoldersAsync(DomainId appId, DomainId parentId, public async Task<IResultList<IAssetFolderEntity>> QueryAssetFoldersAsync(DomainId appId, DomainId parentId,
CancellationToken ct = default) 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); var assetFolders = await QueryFoldersCoreAsync(appId, parentId, ct);
return assetFolders; return assetFolders;
@ -76,8 +81,10 @@ public sealed class AssetQueryService : IAssetQueryService
public async Task<IResultList<IAssetFolderEntity>> QueryAssetFoldersAsync(Context context, DomainId parentId, public async Task<IResultList<IAssetFolderEntity>> QueryAssetFoldersAsync(Context context, DomainId parentId,
CancellationToken ct = default) 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); var assetFolders = await QueryFoldersCoreAsync(context, parentId, ct);
return assetFolders; return assetFolders;
@ -89,8 +96,12 @@ public sealed class AssetQueryService : IAssetQueryService
{ {
Guard.NotNull(context); 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); var asset = await FindByHashCoreAsync(context, hash, fileName, fileSize, ct);
if (asset == null) if (asset == null)
@ -107,8 +118,10 @@ public sealed class AssetQueryService : IAssetQueryService
{ {
Guard.NotNull(context); 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); var asset = await FindBySlugCoreAsync(context, slug, ct);
if (asset == null) if (asset == null)
@ -125,8 +138,10 @@ public sealed class AssetQueryService : IAssetQueryService
{ {
Guard.NotNull(context); 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); var asset = await FindCoreAsync(id, ct);
if (asset == null) if (asset == null)
@ -143,8 +158,10 @@ public sealed class AssetQueryService : IAssetQueryService
{ {
Guard.NotNull(context); Guard.NotNull(context);
using (Telemetry.Activities.StartActivity("AssetQueryService/FindAsync")) using (var activity = Telemetry.Activities.StartActivity("AssetQueryService/FindAsync"))
{ {
activity?.SetTag("assetId", id);
IAssetEntity? asset; IAssetEntity? asset;
if (version > EtagVersion.Empty) if (version > EtagVersion.Empty)

29
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Resolvers.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using GraphQL; using GraphQL;
using GraphQL.Execution;
using GraphQL.Resolvers; using GraphQL.Resolvers;
using Squidex.Domain.Apps.Core.Subscriptions; using Squidex.Domain.Apps.Core.Subscriptions;
using Squidex.Infrastructure; using Squidex.Infrastructure;
@ -21,22 +22,42 @@ public static class Resolvers
{ {
public static IFieldResolver Sync<TSource, T>(Func<TSource, T> resolver) 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) 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) 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) 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) 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. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System.Diagnostics;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Entities.Contents.Repositories; using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas;
@ -46,8 +47,11 @@ public sealed class ContentQueryService : IContentQueryService
{ {
Guard.NotNull(context); 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); var schema = await GetSchemaOrThrowAsync(context, schemaIdOrName, ct);
IContentEntity? content; IContentEntity? content;
@ -80,8 +84,10 @@ public sealed class ContentQueryService : IContentQueryService
{ {
Guard.NotNull(context); Guard.NotNull(context);
using (Telemetry.Activities.StartActivity("ContentQueryService/QueryAsync")) using (var activity = Telemetry.Activities.StartActivity("ContentQueryService/QueryAsync"))
{ {
activity?.SetTag("schemaName", schemaIdOrName);
if (q == null) if (q == null)
{ {
return ResultList.Empty<IEnrichedContentEntity>(); 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.States;
using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation; using Squidex.Infrastructure.Validation;
using System.Diagnostics;
using System.Xml.Linq;
namespace Squidex.Domain.Apps.Entities.Schemas.Indexes; 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, public async Task<List<ISchemaEntity>> GetSchemasAsync(DomainId appId,
CancellationToken ct = default) 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); var schemas = await schemaRepository.QueryAllAsync(appId, ct);
foreach (var schema in schemas.Where(IsValid)) 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, public async Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, string name, bool canCache,
CancellationToken ct = default) 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); var cacheKey = GetCacheKey(appId, name);
if (canCache) if (canCache)
@ -81,8 +88,11 @@ public sealed class SchemasIndex : ICommandMiddleware, ISchemasIndex
public async Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, DomainId id, bool canCache, public async Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, DomainId id, bool canCache,
CancellationToken ct = default) 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); var cacheKey = GetCacheKey(appId, id);
if (canCache) 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.Domain.Apps.Entities.Teams.Repositories;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using System.Diagnostics;
namespace Squidex.Domain.Apps.Entities.Teams.Indexes; namespace Squidex.Domain.Apps.Entities.Teams.Indexes;
@ -22,8 +23,10 @@ public sealed class TeamsIndex : ITeamsIndex
public async Task<ITeamEntity?> GetTeamAsync(DomainId id, public async Task<ITeamEntity?> GetTeamAsync(DomainId id,
CancellationToken ct = default) 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); var team = await teamRepository.FindAsync(id, ct);
return IsValid(team) ? team : null; return IsValid(team) ? team : null;
@ -33,8 +36,10 @@ public sealed class TeamsIndex : ITeamsIndex
public async Task<List<ITeamEntity>> GetTeamsAsync(string userId, public async Task<List<ITeamEntity>> GetTeamsAsync(string userId,
CancellationToken ct = default) 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); var teams = await teamRepository.QueryAllAsync(userId, ct);
return teams.Where(IsValid).ToList(); 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 #pragma warning disable MA0040 // Flow the cancellation token
using var activity = Telemetry.Activities.StartActivity("Resize"); using var activity = Telemetry.Activities.StartActivity("Resize");
activity?.SetTag("fileType", mimeType);
await using var assetOriginal = new TempAssetFile(resizedAsset, mimeType, 0); await using var assetOriginal = new TempAssetFile(resizedAsset, mimeType, 0);
await using var assetResized = 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 try
{ {

10
backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs

@ -154,10 +154,7 @@ public sealed class AssetContentController : ApiController
if (request.Force) 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 else
{ {
@ -205,6 +202,9 @@ public sealed class AssetContentController : ApiController
#pragma warning disable MA0040 // Flow the cancellation token #pragma warning disable MA0040 // Flow the cancellation token
using var activity = Telemetry.Activities.StartActivity("Resize"); 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 assetOriginal = new TempAssetFile(asset.FileName, asset.MimeType, 0);
await using var assetResized = 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 try
{ {

7
backend/src/Squidex/appsettings.json

@ -339,8 +339,11 @@
"storeRetentionInDays": 90, "storeRetentionInDays": 90,
"stackdriver": { "stackdriver": {
// True, to enable stackdriver integration. // True, to enable stackdriver integration.
"enabled": false "enabled": false,
// The ID of your Google Cloud project.
"projectId": ""
}, },
"otlp": { "otlp": {

Loading…
Cancel
Save