mirror of https://github.com/Squidex/squidex.git
14 changed files with 177 additions and 197 deletions
@ -1,67 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// 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.Log |
|
||||
{ |
|
||||
public static class Profile |
|
||||
{ |
|
||||
private static ILogProfilerSessionProvider sessionProvider; |
|
||||
|
|
||||
private sealed class Timer : IDisposable |
|
||||
{ |
|
||||
private readonly Stopwatch watch = Stopwatch.StartNew(); |
|
||||
private readonly ProfilerSession session; |
|
||||
private readonly string key; |
|
||||
|
|
||||
public Timer(ProfilerSession session, string key) |
|
||||
{ |
|
||||
this.session = session; |
|
||||
this.key = key; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
watch.Stop(); |
|
||||
|
|
||||
session.Measured(key, watch.ElapsedMilliseconds); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static void Init(ILogProfilerSessionProvider provider) |
|
||||
{ |
|
||||
sessionProvider = provider; |
|
||||
} |
|
||||
|
|
||||
public static IDisposable Method<T>([CallerMemberName] string memberName = null) |
|
||||
{ |
|
||||
return Key($"{typeof(T).Name}/{memberName}"); |
|
||||
} |
|
||||
|
|
||||
public static IDisposable Method(string objectName, [CallerMemberName] string memberName = null) |
|
||||
{ |
|
||||
return Key($"{objectName}/{memberName}"); |
|
||||
} |
|
||||
|
|
||||
public static IDisposable Key(string key) |
|
||||
{ |
|
||||
Guard.NotNull(key, nameof(key)); |
|
||||
|
|
||||
var session = sessionProvider?.GetSession(); |
|
||||
|
|
||||
if (session == null) |
|
||||
{ |
|
||||
return NoopDisposable.Instance; |
|
||||
} |
|
||||
|
|
||||
return new Timer(session, key); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,69 @@ |
|||||
|
// ==========================================================================
|
||||
|
// 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; |
||||
|
using System.Threading; |
||||
|
using Squidex.Infrastructure.Tasks; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Log |
||||
|
{ |
||||
|
public static class Profiler |
||||
|
{ |
||||
|
private static readonly AsyncLocal<ProfilerSession> LocalSession = new AsyncLocal<ProfilerSession>(); |
||||
|
private static readonly AsyncLocalCleaner<ProfilerSession> Cleaner; |
||||
|
|
||||
|
public static ProfilerSession Session |
||||
|
{ |
||||
|
get { return LocalSession.Value; } |
||||
|
} |
||||
|
|
||||
|
static Profiler() |
||||
|
{ |
||||
|
Cleaner = new AsyncLocalCleaner<ProfilerSession>(LocalSession); |
||||
|
} |
||||
|
|
||||
|
public static IDisposable StartSession() |
||||
|
{ |
||||
|
LocalSession.Value = new ProfilerSession(); |
||||
|
|
||||
|
return Cleaner; |
||||
|
} |
||||
|
|
||||
|
public static IDisposable TraceMethod<T>([CallerMemberName] string memberName = null) |
||||
|
{ |
||||
|
return Trace($"{typeof(T).Name}/{memberName}"); |
||||
|
} |
||||
|
|
||||
|
public static IDisposable TraceMethod(string objectName, [CallerMemberName] string memberName = null) |
||||
|
{ |
||||
|
return Trace($"{objectName}/{memberName}"); |
||||
|
} |
||||
|
|
||||
|
public static IDisposable Trace(string key) |
||||
|
{ |
||||
|
Guard.NotNull(key, nameof(key)); |
||||
|
|
||||
|
var session = LocalSession.Value; |
||||
|
|
||||
|
if (session == null) |
||||
|
{ |
||||
|
return NoopDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
var watch = Stopwatch.StartNew(); |
||||
|
|
||||
|
return new DelegateDisposable(() => |
||||
|
{ |
||||
|
watch.Stop(); |
||||
|
|
||||
|
session.Measured(key, watch.ElapsedMilliseconds); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Tasks |
||||
|
{ |
||||
|
public sealed class AsyncLocalCleaner<T> : IDisposable |
||||
|
{ |
||||
|
private readonly AsyncLocal<T> asyncLocal; |
||||
|
|
||||
|
public AsyncLocalCleaner(AsyncLocal<T> asyncLocal) |
||||
|
{ |
||||
|
Guard.NotNull(asyncLocal, nameof(asyncLocal)); |
||||
|
|
||||
|
this.asyncLocal = asyncLocal; |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
asyncLocal.Value = default(T); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,40 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.Log; |
|
||||
|
|
||||
namespace Squidex.Pipeline |
|
||||
{ |
|
||||
public sealed class RequestLogProfilerSessionProvider : ILogProfilerSessionProvider |
|
||||
{ |
|
||||
private const string ItemKey = "ProfilerSesison"; |
|
||||
private readonly IHttpContextAccessor httpContextAccessor; |
|
||||
|
|
||||
public RequestLogProfilerSessionProvider(IHttpContextAccessor httpContextAccessor) |
|
||||
{ |
|
||||
this.httpContextAccessor = httpContextAccessor; |
|
||||
|
|
||||
Profile.Init(this); |
|
||||
} |
|
||||
|
|
||||
public ProfilerSession GetSession() |
|
||||
{ |
|
||||
var context = httpContextAccessor?.HttpContext?.Items[ItemKey] as ProfilerSession; |
|
||||
|
|
||||
return context; |
|
||||
} |
|
||||
|
|
||||
public void Start(HttpContext httpContext, ProfilerSession session) |
|
||||
{ |
|
||||
Guard.NotNull(httpContext, nameof(httpContext)); |
|
||||
|
|
||||
httpContext.Items[ItemKey] = session; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue