Browse Source

More extensibility for logging and profiling.

pull/403/head
Sebastian Stehle 6 years ago
parent
commit
a2cbb9d82a
  1. 7
      extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs
  2. 2
      src/Squidex.Infrastructure/Log/ApplicationInfoLogAppender.cs
  3. 2
      src/Squidex.Infrastructure/Log/ConstantsLogWriter.cs
  4. 2
      src/Squidex.Infrastructure/Log/ILogAppender.cs
  5. 13
      src/Squidex.Infrastructure/Log/Profiler.cs
  6. 66
      src/Squidex.Infrastructure/Log/ProfilerSpan.cs
  7. 2
      src/Squidex.Infrastructure/Log/SemanticLog.cs
  8. 2
      src/Squidex.Infrastructure/Log/TimestampLogAppender.cs
  9. 4
      src/Squidex.Infrastructure/Plugins/IWebPlugin.cs
  10. 14
      src/Squidex.Infrastructure/Plugins/PluginManager.cs
  11. 2
      src/Squidex.Web/Pipeline/ActionContextLogAppender.cs
  12. 15
      src/Squidex/Pipeline/Plugins/PluginExtensions.cs
  13. 3
      src/Squidex/WebStartup.cs

7
extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs

@ -69,15 +69,16 @@ namespace Squidex.Extensions.Actions.Discourse
{ {
using (var httpClient = httpClientFactory.CreateClient()) using (var httpClient = httpClientFactory.CreateClient())
{ {
var request = new HttpRequestMessage(HttpMethod.Post, job.RequestUrl) using (var request = new HttpRequestMessage(HttpMethod.Post, job.RequestUrl)
{ {
Content = new StringContent(job.RequestBody, Encoding.UTF8, "application/json") Content = new StringContent(job.RequestBody, Encoding.UTF8, "application/json")
}; })
{
return await httpClient.OneWayRequestAsync(request, job.RequestBody, ct); return await httpClient.OneWayRequestAsync(request, job.RequestBody, ct);
} }
} }
} }
}
public sealed class DiscourseJob public sealed class DiscourseJob
{ {

2
src/Squidex.Infrastructure/Log/ApplicationInfoLogAppender.cs

@ -30,7 +30,7 @@ namespace Squidex.Infrastructure.Log
applicationSessionId = applicationSession.ToString(); applicationSessionId = applicationSession.ToString();
} }
public void Append(IObjectWriter writer) public void Append(IObjectWriter writer, SemanticLogLevel logLevel)
{ {
writer.WriteObject("app", w => w writer.WriteObject("app", w => w
.WriteProperty("name", applicationName) .WriteProperty("name", applicationName)

2
src/Squidex.Infrastructure/Log/ConstantsLogWriter.cs

@ -20,7 +20,7 @@ namespace Squidex.Infrastructure.Log
this.objectWriter = objectWriter; this.objectWriter = objectWriter;
} }
public void Append(IObjectWriter writer) public void Append(IObjectWriter writer, SemanticLogLevel logLevel)
{ {
objectWriter(writer); objectWriter(writer);
} }

2
src/Squidex.Infrastructure/Log/ILogAppender.cs

@ -9,6 +9,6 @@ namespace Squidex.Infrastructure.Log
{ {
public interface ILogAppender public interface ILogAppender
{ {
void Append(IObjectWriter writer); void Append(IObjectWriter writer, SemanticLogLevel logLevel);
} }
} }

13
src/Squidex.Infrastructure/Log/Profiler.cs

@ -12,6 +12,8 @@ using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.Log namespace Squidex.Infrastructure.Log
{ {
public delegate void ProfilerStarted(ProfilerSpan span);
public static class Profiler public static class Profiler
{ {
private static readonly AsyncLocal<ProfilerSession> LocalSession = new AsyncLocal<ProfilerSession>(); private static readonly AsyncLocal<ProfilerSession> LocalSession = new AsyncLocal<ProfilerSession>();
@ -22,6 +24,8 @@ namespace Squidex.Infrastructure.Log
get { return LocalSession.Value; } get { return LocalSession.Value; }
} }
public static event ProfilerStarted SpanStarted;
static Profiler() static Profiler()
{ {
Cleaner = new AsyncLocalCleaner<ProfilerSession>(LocalSession); Cleaner = new AsyncLocalCleaner<ProfilerSession>(LocalSession);
@ -60,14 +64,11 @@ namespace Squidex.Infrastructure.Log
return NoopDisposable.Instance; return NoopDisposable.Instance;
} }
var watch = ValueStopwatch.StartNew(); var span = new ProfilerSpan(session, key);
return new DelegateDisposable(() => SpanStarted?.Invoke(span);
{
var elapsedMs = watch.Stop();
session.Measured(key, elapsedMs); return span;
});
} }
} }
} }

66
src/Squidex.Infrastructure/Log/ProfilerSpan.cs

@ -0,0 +1,66 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
namespace Squidex.Infrastructure.Log
{
public sealed class ProfilerSpan : IDisposable
{
private readonly ValueStopwatch watch = ValueStopwatch.StartNew();
private readonly ProfilerSession session;
private readonly string key;
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;
}
}
}
}
}
}

2
src/Squidex.Infrastructure/Log/SemanticLog.cs

@ -79,7 +79,7 @@ namespace Squidex.Infrastructure.Log
for (var i = 0; i < appenders.Length; i++) for (var i = 0; i < appenders.Length; i++)
{ {
appenders[i].Append(writer); appenders[i].Append(writer, logLevel);
} }
return writer.ToString(); return writer.ToString();

2
src/Squidex.Infrastructure/Log/TimestampLogAppender.cs

@ -18,7 +18,7 @@ namespace Squidex.Infrastructure.Log
this.clock = clock ?? SystemClock.Instance; this.clock = clock ?? SystemClock.Instance;
} }
public void Append(IObjectWriter writer) public void Append(IObjectWriter writer, SemanticLogLevel logLevel)
{ {
writer.WriteProperty("timestamp", clock.GetCurrentInstant()); writer.WriteProperty("timestamp", clock.GetCurrentInstant());
} }

4
src/Squidex.Infrastructure/Plugins/IWebPlugin.cs

@ -11,6 +11,8 @@ namespace Squidex.Infrastructure.Plugins
{ {
public interface IWebPlugin : IPlugin public interface IWebPlugin : IPlugin
{ {
void Configure(IApplicationBuilder app); void ConfigureBefore(IApplicationBuilder app);
void ConfigureAfter(IApplicationBuilder app);
} }
} }

14
src/Squidex.Infrastructure/Plugins/PluginManager.cs

@ -70,13 +70,23 @@ namespace Squidex.Infrastructure.Plugins
} }
} }
public void Configure(IApplicationBuilder app) public void ConfigureBefore(IApplicationBuilder app)
{ {
Guard.NotNull(app, nameof(app)); Guard.NotNull(app, nameof(app));
foreach (var plugin in loadedPlugins.OfType<IWebPlugin>()) foreach (var plugin in loadedPlugins.OfType<IWebPlugin>())
{ {
plugin.Configure(app); plugin.ConfigureBefore(app);
}
}
public void ConfigureAfter(IApplicationBuilder app)
{
Guard.NotNull(app, nameof(app));
foreach (var plugin in loadedPlugins.OfType<IWebPlugin>())
{
plugin.ConfigureAfter(app);
} }
} }

2
src/Squidex.Web/Pipeline/ActionContextLogAppender.cs

@ -23,7 +23,7 @@ namespace Squidex.Web.Pipeline
this.httpContextAccessor = httpContextAccessor; this.httpContextAccessor = httpContextAccessor;
} }
public void Append(IObjectWriter writer) public void Append(IObjectWriter writer, SemanticLogLevel logLevel)
{ {
var httpContext = httpContextAccessor.HttpContext; var httpContext = httpContextAccessor.HttpContext;

15
src/Squidex/Pipeline/Plugins/PluginExtensions.cs

@ -57,11 +57,24 @@ namespace Squidex.Pipeline.Plugins
return mvcBuilder; return mvcBuilder;
} }
public static void UsePluginsBefore(this IApplicationBuilder app)
{
var pluginManager = app.ApplicationServices.GetRequiredService<PluginManager>();
pluginManager.ConfigureBefore(app);
}
public static void UsePluginsAfter(this IApplicationBuilder app)
{
var pluginManager = app.ApplicationServices.GetRequiredService<PluginManager>();
pluginManager.ConfigureAfter(app);
}
public static void UsePlugins(this IApplicationBuilder app) public static void UsePlugins(this IApplicationBuilder app)
{ {
var pluginManager = app.ApplicationServices.GetRequiredService<PluginManager>(); var pluginManager = app.ApplicationServices.GetRequiredService<PluginManager>();
pluginManager.Configure(app);
pluginManager.Log(app.ApplicationServices.GetService<ISemanticLog>()); pluginManager.Log(app.ApplicationServices.GetService<ISemanticLog>());
} }
} }

3
src/Squidex/WebStartup.cs

@ -125,6 +125,8 @@ namespace Squidex
{ {
app.ApplicationServices.LogConfiguration(); app.ApplicationServices.LogConfiguration();
app.UsePluginsBefore();
app.UseMyHealthCheck(); app.UseMyHealthCheck();
app.UseMyRobotsTxt(); app.UseMyRobotsTxt();
app.UseMyTracking(); app.UseMyTracking();
@ -138,6 +140,7 @@ namespace Squidex
app.ConfigureIdentityServer(); app.ConfigureIdentityServer();
app.ConfigureFrontend(); app.ConfigureFrontend();
app.UsePluginsAfter();
app.UsePlugins(); app.UsePlugins();
} }
} }

Loading…
Cancel
Save