mirror of https://github.com/Squidex/squidex.git
5 changed files with 165 additions and 8 deletions
@ -0,0 +1,82 @@ |
|||||
|
// ==========================================================================
|
||||
|
// 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.Log; |
||||
|
using Squidex.Infrastructure.Plugins; |
||||
|
|
||||
|
namespace Squidex.Extensions.APM.Datadoq |
||||
|
{ |
||||
|
public sealed class DatadogPlugin : IPlugin, IStartupFilter |
||||
|
{ |
||||
|
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> nextBuilder) |
||||
|
{ |
||||
|
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()); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
nextBuilder(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,69 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
#pragma warning disable IDE0044 // Add readonly modifier
|
||||
|
#pragma warning disable RECS0092 // Convert field to readonly
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Log |
||||
|
{ |
||||
|
public sealed class ProfilerSpan : IDisposable |
||||
|
{ |
||||
|
private readonly ProfilerSession session; |
||||
|
private readonly string key; |
||||
|
private ValueStopwatch watch = ValueStopwatch.StartNew(); |
||||
|
private List<IDisposable> hooks; |
||||
|
|
||||
|
public string Key |
||||
|
{ |
||||
|
get { return key; } |
||||
|
} |
||||
|
|
||||
|
public ProfilerSpan(ProfilerSession session, string key) |
||||
|
{ |
||||
|
this.session = session; |
||||
|
|
||||
|
this.key = key; |
||||
|
} |
||||
|
|
||||
|
public void Listen(IDisposable hook) |
||||
|
{ |
||||
|
Guard.NotNull(hook, nameof(hook)); |
||||
|
|
||||
|
if (hooks == null) |
||||
|
{ |
||||
|
hooks = new List<IDisposable>(1); |
||||
|
} |
||||
|
|
||||
|
hooks.Add(hook); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
var elapsedMs = watch.Stop(); |
||||
|
|
||||
|
session.Measured(key, elapsedMs); |
||||
|
|
||||
|
if (hooks != null) |
||||
|
{ |
||||
|
for (var i = 0; i < hooks.Count; i++) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
hooks[i].Dispose(); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue