mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
53 changed files with 916 additions and 1216 deletions
@ -1,100 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<RuleSet Name="Squidex Rules" Description="Squidex Rules" ToolsVersion="14.0"> |
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers"> |
|
||||
<Rule Id="SA1002" Action="Error" /> |
|
||||
<Rule Id="SA1003" Action="Error" /> |
|
||||
<Rule Id="SA1008" Action="None" /> |
|
||||
<Rule Id="SA1009" Action="None" /> |
|
||||
<Rule Id="SA1012" Action="Error" /> |
|
||||
<Rule Id="SA1013" Action="Error" /> |
|
||||
<Rule Id="SA1025" Action="Error" /> |
|
||||
<Rule Id="SA1026" Action="Error" /> |
|
||||
<Rule Id="SA1028" Action="Error" /> |
|
||||
<Rule Id="SA1000" Action="Error" /> |
|
||||
<Rule Id="SA1001" Action="Error" /> |
|
||||
<Rule Id="SA1101" Action="None" /> |
|
||||
<Rule Id="SA1004" Action="Error" /> |
|
||||
<Rule Id="SA1107" Action="None" /> |
|
||||
<Rule Id="SA1010" Action="Error" /> |
|
||||
<Rule Id="SA1111" Action="None" /> |
|
||||
<Rule Id="SA1116" Action="None" /> |
|
||||
<Rule Id="SA1117" Action="None" /> |
|
||||
<Rule Id="SA1118" Action="None" /> |
|
||||
<Rule Id="SA1119" Action="None" /> |
|
||||
<Rule Id="SA1122" Action="Error" /> |
|
||||
<Rule Id="SA1127" Action="None" /> |
|
||||
<Rule Id="SA1128" Action="Error" /> |
|
||||
<Rule Id="SA1129" Action="Error" /> |
|
||||
<Rule Id="SA1200" Action="None" /> |
|
||||
<Rule Id="SA1201" Action="None" /> |
|
||||
<Rule Id="SA1202" Action="None" /> |
|
||||
<Rule Id="SA1203" Action="Error" /> |
|
||||
<Rule Id="SA1204" Action="None" /> |
|
||||
<Rule Id="SA1208" Action="Error" /> |
|
||||
<Rule Id="SA1210" Action="Error" /> |
|
||||
<Rule Id="SA1214" Action="Error" /> |
|
||||
<Rule Id="SA1306" Action="Error" /> |
|
||||
<Rule Id="SA1311" Action="Error" /> |
|
||||
<Rule Id="SA1400" Action="Error" /> |
|
||||
<Rule Id="SA1401" Action="Error" /> |
|
||||
<Rule Id="SA1402" Action="None" /> |
|
||||
<Rule Id="SA1407" Action="Error" /> |
|
||||
<Rule Id="SA1408" Action="None" /> |
|
||||
<Rule Id="SA1502" Action="Error" /> |
|
||||
<Rule Id="SA1504" Action="Error" /> |
|
||||
<Rule Id="SA1505" Action="Error" /> |
|
||||
<Rule Id="SA1507" Action="Error" /> |
|
||||
<Rule Id="SA1508" Action="Error" /> |
|
||||
<Rule Id="SA1518" Action="Error" /> |
|
||||
<Rule Id="SA1512" Action="None" /> |
|
||||
<Rule Id="SA1513" Action="Error" /> |
|
||||
<Rule Id="SA1515" Action="None" /> |
|
||||
<Rule Id="SA1516" Action="None" /> |
|
||||
<Rule Id="SA1600" Action="None" /> |
|
||||
<Rule Id="SA1612" Action="None" /> |
|
||||
<Rule Id="SA1615" Action="None" /> |
|
||||
<Rule Id="SA1623" Action="None" /> |
|
||||
<Rule Id="SA1633" Action="Error" /> |
|
||||
<Rule Id="SA1649" Action="Error" /> |
|
||||
<Rule Id="SA1634" Action="None" /> |
|
||||
<Rule Id="SA1635" Action="None" /> |
|
||||
<Rule Id="SA1652" Action="None" /> |
|
||||
<Rule Id="SA1404" Action="None" /> |
|
||||
<Rule Id="SA1601" Action="None" /> |
|
||||
<Rule Id="SA1413" Action="None" /> |
|
||||
<Rule Id="SA0001" Action="None" /> |
|
||||
<Rule Id="SA1602" Action="None" /> |
|
||||
</Rules> |
|
||||
<Rules AnalyzerId="RefactoringEssentials" RuleNamespace="RefactoringEssentials"> |
|
||||
<Rule Id="RECS0061" Action="Error" /> |
|
||||
<Rule Id="RECS0017" Action="Error" /> |
|
||||
<Rule Id="RECS0060" Action="Error" /> |
|
||||
<Rule Id="RECS0062" Action="Error" /> |
|
||||
<Rule Id="RECS0063" Action="Error" /> |
|
||||
<Rule Id="RECS0064" Action="Error" /> |
|
||||
<Rule Id="RECS0133" Action="Error" /> |
|
||||
<Rule Id="REVB0145" Action="None" /> |
|
||||
<Rule Id="RECS0002" Action="Error" /> |
|
||||
<Rule Id="RECS0154" Action="None" /> |
|
||||
<Rule Id="RECS0146" Action="Error" /> |
|
||||
<Rule Id="RECS0026" Action="Error" /> |
|
||||
<Rule Id="RECS0145" Action="None" /> |
|
||||
<Rule Id="RECS0129" Action="None" /> |
|
||||
<Rule Id="RECS0070" Action="None" /> |
|
||||
</Rules> |
|
||||
<Rules AnalyzerId="Roslyn.Core" RuleNamespace="Roslyn.Core"> |
|
||||
<Rule Id="AD0001" Action="None" /> |
|
||||
</Rules> |
|
||||
<Rules AnalyzerId="Roslyn.Core" RuleNamespace="Microsoft.CodeAnalysis.Diagnostics"> |
|
||||
<Rule Id="IDE0070" Action="None" /> |
|
||||
<Rule Id="IDE0032" Action="None" /> |
|
||||
<Rule Id="IDE0042" Action="None" /> |
|
||||
<Rule Id="IDE0090" Action="None" /> |
|
||||
</Rules> |
|
||||
<Rules AnalyzerId="Microsoft.AspNetCore.Mvc.Api.Analyzers" RuleNamespace="Microsoft.AspNetCore.Mvc.Api.Analyzers"> |
|
||||
<Rule Id="API1000" Action="Error" /> |
|
||||
<Rule Id="API1001" Action="Error" /> |
|
||||
<Rule Id="API1002" Action="Error" /> |
|
||||
<Rule Id="API1003" Action="Error" /> |
|
||||
</Rules> |
|
||||
</RuleSet> |
|
||||
@ -1,36 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.ApplicationInsights.Channel; |
|
||||
using Microsoft.ApplicationInsights.Extensibility; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
|
|
||||
namespace Squidex.Extensions.APM.ApplicationInsights |
|
||||
{ |
|
||||
public sealed class RoleNameTelemetryInitializer : ITelemetryInitializer |
|
||||
{ |
|
||||
private readonly string roleName; |
|
||||
|
|
||||
public RoleNameTelemetryInitializer(IConfiguration configuration) |
|
||||
{ |
|
||||
roleName = configuration.GetValue<string>("logging:roleName"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(roleName)) |
|
||||
{ |
|
||||
roleName = "Squidex"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public void Initialize(ITelemetry telemetry) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName)) |
|
||||
{ |
|
||||
telemetry.Context.Cloud.RoleName = roleName; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,82 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Datadog.Trace; |
|
||||
using Datadog.Trace.Configuration; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Squidex.Infrastructure.Plugins; |
|
||||
using Squidex.Log; |
|
||||
|
|
||||
namespace Squidex.Extensions.APM.Datadog |
|
||||
{ |
|
||||
public sealed class DatadogPlugin : IPlugin, IStartupFilter |
|
||||
{ |
|
||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next) |
|
||||
{ |
|
||||
return builder => |
|
||||
{ |
|
||||
builder.Use(async (context, next) => |
|
||||
{ |
|
||||
using (var scope = Tracer.Instance.StartActive(context.Request.Path)) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
scope.Span.SetTag("http.method", context.Request.Method); |
|
||||
|
|
||||
await next(); |
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
scope.Span.SetException(ex); |
|
||||
throw; |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
scope.Span.SetTag("http.status_code", context.Response.StatusCode.ToString()); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
next(builder); |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
public void ConfigureServices(IServiceCollection services, IConfiguration config) |
|
||||
{ |
|
||||
var isEnabled = config.GetValue<bool>("logging:datadog"); |
|
||||
|
|
||||
if (isEnabled) |
|
||||
{ |
|
||||
services.AddSingleton<IStartupFilter>(this); |
|
||||
|
|
||||
SetupTracer(); |
|
||||
SetupProfiler(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void SetupProfiler() |
|
||||
{ |
|
||||
Profiler.SpanStarted += session => |
|
||||
{ |
|
||||
session.Listen(Tracer.Instance.StartActive(session.Key)); |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
private static void SetupTracer() |
|
||||
{ |
|
||||
var settings = TracerSettings.FromDefaultSources(); |
|
||||
|
|
||||
settings.ServiceName = "squidex"; |
|
||||
|
|
||||
Tracer.Instance = new Tracer(settings); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,35 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using OpenTelemetry.Trace; |
||||
|
using Squidex.Infrastructure.Plugins; |
||||
|
|
||||
|
namespace Squidex.Extensions.APM.Datadog |
||||
|
{ |
||||
|
public sealed class OtlpPlugin : IPlugin |
||||
|
{ |
||||
|
public void ConfigureServices(IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
services.AddOpenTelemetryTracing(builder => |
||||
|
{ |
||||
|
if (config.GetValue<bool>("logging:otlp:enabled")) |
||||
|
{ |
||||
|
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
|
||||
|
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); |
||||
|
|
||||
|
builder.AddOtlpExporter(options => |
||||
|
{ |
||||
|
config.GetSection("logging:otlp").Bind(options); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Google.Cloud.Diagnostics.AspNetCore; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Log; |
||||
|
|
||||
|
namespace Squidex.Extensions.APM.Stackdriver |
||||
|
{ |
||||
|
internal class StackdriverExceptionHandler : ILogAppender |
||||
|
{ |
||||
|
private readonly DefaultHttpContext fallbackContext = new DefaultHttpContext(); |
||||
|
private readonly IExceptionLogger logger; |
||||
|
private readonly IHttpContextAccessor httpContextAccessor; |
||||
|
|
||||
|
public StackdriverExceptionHandler(IExceptionLogger logger, IHttpContextAccessor httpContextAccessor) |
||||
|
{ |
||||
|
this.logger = logger; |
||||
|
|
||||
|
this.httpContextAccessor = httpContextAccessor; |
||||
|
} |
||||
|
|
||||
|
public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception exception) |
||||
|
{ |
||||
|
if (exception != null && exception is not DomainException) |
||||
|
{ |
||||
|
var httpContext = httpContextAccessor.HttpContext; |
||||
|
|
||||
|
logger.Log(exception, httpContext ?? fallbackContext); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using OpenTelemetry.Trace; |
||||
|
using Squidex.Infrastructure.Plugins; |
||||
|
using Squidex.Log; |
||||
|
|
||||
|
namespace Squidex.Extensions.APM.Stackdriver |
||||
|
{ |
||||
|
public sealed class StackdriverPlugin : IPlugin |
||||
|
{ |
||||
|
public void ConfigureServices(IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
services.AddOpenTelemetryTracing(builder => |
||||
|
{ |
||||
|
if (config.GetValue<bool>("logging:stackdriver:enabled")) |
||||
|
{ |
||||
|
var projectId = config.GetValue<string>("logging:stackdriver:projectId"); |
||||
|
|
||||
|
builder.UseStackdriverExporter(projectId); |
||||
|
|
||||
|
services.AddSingleton<ILogAppender, |
||||
|
StackdriverSeverityLogAppender>(); |
||||
|
|
||||
|
services.AddSingleton<ILogAppender, |
||||
|
StackdriverExceptionHandler>(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Squidex.Log; |
||||
|
|
||||
|
namespace Squidex.Extensions.APM.Stackdriver |
||||
|
{ |
||||
|
public sealed class StackdriverSeverityLogAppender : ILogAppender |
||||
|
{ |
||||
|
public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception exception) |
||||
|
{ |
||||
|
var severity = GetSeverity(logLevel); |
||||
|
|
||||
|
writer.WriteProperty(nameof(severity), severity); |
||||
|
} |
||||
|
|
||||
|
private static string GetSeverity(SemanticLogLevel logLevel) |
||||
|
{ |
||||
|
switch (logLevel) |
||||
|
{ |
||||
|
case SemanticLogLevel.Trace: |
||||
|
return "DEBUG"; |
||||
|
case SemanticLogLevel.Debug: |
||||
|
return "DEBUG"; |
||||
|
case SemanticLogLevel.Information: |
||||
|
return "INFO"; |
||||
|
case SemanticLogLevel.Warning: |
||||
|
return "WARNING"; |
||||
|
case SemanticLogLevel.Error: |
||||
|
return "ERROR"; |
||||
|
case SemanticLogLevel.Fatal: |
||||
|
return "CRITICAL"; |
||||
|
default: |
||||
|
return "DEFAULT"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Diagnostics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace Squidex.Infrastructure |
||||
|
{ |
||||
|
public static class Telemetry |
||||
|
{ |
||||
|
public static readonly ActivitySource Activities = new ActivitySource("Notifo"); |
||||
|
|
||||
|
public static Activity? StartMethod(this ActivitySource activity, Type type, [CallerMemberName] string? memberName = null) |
||||
|
{ |
||||
|
return activity.StartActivity($"{type.Name}/{memberName}"); |
||||
|
} |
||||
|
|
||||
|
public static Activity? StartMethod<T>(this ActivitySource activity, [CallerMemberName] string? memberName = null) |
||||
|
{ |
||||
|
return activity.StartActivity($"{typeof(T).Name}/{memberName}"); |
||||
|
} |
||||
|
|
||||
|
public static Activity? StartMethod(this ActivitySource activity, string objectName, [CallerMemberName] string? memberName = null) |
||||
|
{ |
||||
|
return activity.StartActivity($"{objectName}/{memberName}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using OpenTelemetry.Resources; |
||||
|
using OpenTelemetry.Trace; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class TelemetryServices |
||||
|
{ |
||||
|
public static void AddSquidexTelemetry(this IServiceCollection services) |
||||
|
{ |
||||
|
services.AddOpenTelemetryTracing(builder => |
||||
|
{ |
||||
|
builder.SetResourceBuilder( |
||||
|
ResourceBuilder.CreateDefault() |
||||
|
.AddService("Squidex", "Squidex", |
||||
|
typeof(TelemetryServices).Assembly.GetName().Version!.ToString())); |
||||
|
|
||||
|
builder.AddSource("Squidex"); |
||||
|
|
||||
|
builder.AddAspNetCoreInstrumentation(); |
||||
|
builder.AddHttpClientInstrumentation(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
Loading…
Reference in new issue