Skip to content
Permalink
Browse files

Simplifying diagnostic code

  • Loading branch information...
Turnerj committed Jun 8, 2019
1 parent 94de91b commit fc0d4824493bc9f74fa6f19d38bc63154c80d44d
@@ -6,7 +6,6 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using MongoFramework.Infrastructure;
using MongoFramework.Infrastructure.Diagnostics;
using StackExchange.Profiling;

@@ -27,36 +26,41 @@ public void OnNext(DiagnosticCommand value)
return;
}

if (value is ReadDiagnosticCommand readCommand)
if (value.CommandState == CommandState.Start)
{
if (readCommand.CommandState == CommandState.Start)
if (value is ReadDiagnosticCommand readCommand)
{
Commands[value.CommandId] = StackExchange.Profiling.MiniProfiler.Current.CustomTiming("mongoframework", readCommand.Queryable.ToQuery(), readCommand.Source);
OnNextReadCommand(readCommand);
}
else if (Commands.TryRemove(value.CommandId, out var current))
else if (value is WriteDiagnosticCommandBase writeCommandBase)
{
if (readCommand.CommandState == CommandState.FirstResult)
{
Commands[value.CommandId] = current;
current.FirstFetchCompleted();
}
else
{
current.Errored = readCommand.CommandState == CommandState.Error;
current.Stop();
}
OnNextWriteCommand(writeCommandBase);
}
else if (value is IndexDiagnosticCommandBase indexCommandBase)
{
OnNextIndexCommand(indexCommandBase);
}
}
else if (value is WriteDiagnosticCommandBase writeCommandBase)
{
OnNextWriteCommand(writeCommandBase);
}
else if (value is IndexDiagnosticCommandBase indexCommandBase)
else if (Commands.TryRemove(value.CommandId, out var current))
{
OnNextIndexCommand(indexCommandBase);
if (value.CommandState == CommandState.FirstResult)
{
Commands[value.CommandId] = current;
current.FirstFetchCompleted();
}
else
{
current.Errored = value.CommandState == CommandState.Error;
current.Stop();
}
}
}

private void OnNextReadCommand(ReadDiagnosticCommand command)
{
Commands[command.CommandId] = StackExchange.Profiling.MiniProfiler.Current.CustomTiming("mongodb", command.Query, "Read");
}

private void OnNextWriteCommand(WriteDiagnosticCommandBase commandBase)
{
var onNextWriteCommand = GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)
@@ -66,18 +70,10 @@ private void OnNextWriteCommand(WriteDiagnosticCommandBase commandBase)
#pragma warning disable CRR0026 // Unused member
private void OnNextWriteCommand<TEntity>(WriteDiagnosticCommand<TEntity> command)
{
if (command.CommandState == CommandState.Start)
{
var queryList = command.WriteModel.GroupBy(w => w.ModelType)
var queryList = command.WriteModel.GroupBy(w => w.ModelType)
.Select(g => g.Key.ToString() + "\n" + string.Join("\n", g.Select(w => GetWriteModelAsString(w))));
var writeModelString = string.Join("; ", queryList);
Commands[command.CommandId] = StackExchange.Profiling.MiniProfiler.Current.CustomTiming("mongoframework", writeModelString, command.Source);
}
else if (Commands.TryRemove(command.CommandId, out var current))
{
current.Errored = command.CommandState == CommandState.Error;
current.Stop();
}
var writeModelString = string.Join("; ", queryList);
Commands[command.CommandId] = StackExchange.Profiling.MiniProfiler.Current.CustomTiming("mongodb", writeModelString, "Write");
}
#pragma warning restore CRR0026 // Unused member
private string GetWriteModelAsString<TEntity>(WriteModel<TEntity> writeModel)
@@ -121,18 +117,10 @@ private void OnNextIndexCommand(IndexDiagnosticCommandBase commandBase)
#pragma warning disable CRR0026 // Unused member
private void OnNextIndexCommand<TEntity>(IndexDiagnosticCommand<TEntity> command)
{
if (command.CommandState == CommandState.Start)
{
var queryList = command.IndexModel.GroupBy(w => w.Options.Name)
var queryList = command.IndexModel.GroupBy(w => w.Options.Name)
.Select(g => g.Key.ToString() + "\n" + string.Join("\n", g.Select(w => GetIndexModelAsString(w))));
var indexModelString = string.Join("; ", queryList);
Commands[command.CommandId] = StackExchange.Profiling.MiniProfiler.Current.CustomTiming("mongoframework", indexModelString, command.Source);
}
else if (Commands.TryRemove(command.CommandId, out var current))
{
current.Errored = command.CommandState == CommandState.Error;
current.Stop();
}
var indexModelString = string.Join("; ", queryList);
Commands[command.CommandId] = StackExchange.Profiling.MiniProfiler.Current.CustomTiming("mongodb", indexModelString, "Index");
}
#pragma warning restore CRR0026 // Unused member
private string GetIndexModelAsString<TEntity>(CreateIndexModel<TEntity> indexModel)
@@ -1,6 +1,7 @@
using System;
using MongoDB.Driver;
using MongoFramework.Infrastructure;
using MongoFramework.Infrastructure.Diagnostics;

namespace MongoFramework
{
@@ -34,40 +34,17 @@ public void Write(IEnumerable<IWriteCommand<TEntity>> writeCommands)

if (writeModel.Any())
{
var commandId = Guid.NewGuid();
try
using (var diagnostics = DiagnosticRunner.Start(Connection, writeModel))
{
Connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
try
{
CommandId = commandId,
Source = $"{nameof(CommandWriter<TEntity>)}.{nameof(Write)}",
CommandState = CommandState.Start,
EntityType = typeof(TEntity),
WriteModel = writeModel
});
GetCollection().BulkWrite(writeModel);
Connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
GetCollection().BulkWrite(writeModel);
}
catch (Exception exception)
{
CommandId = commandId,
Source = $"{nameof(CommandWriter<TEntity>)}.{nameof(Write)}",
CommandState = CommandState.End,
EntityType = typeof(TEntity),
WriteModel = writeModel
});
}
catch (Exception ex)
{
Connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
{
CommandId = commandId,
Source = $"{nameof(CommandWriter<TEntity>)}.{nameof(Write)}",
CommandState = CommandState.Error,
EntityType = typeof(TEntity),
WriteModel = writeModel
});
Connection.DiagnosticListener.OnError(ex);

throw;
diagnostics.Error(exception);
throw;
}
}
}
}
@@ -80,40 +57,17 @@ public async Task WriteAsync(IEnumerable<IWriteCommand<TEntity>> writeCommands,

if (writeModel.Any())
{
var commandId = Guid.NewGuid();
try
using (var diagnostics = DiagnosticRunner.Start(Connection, writeModel))
{
Connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
try
{
CommandId = commandId,
Source = $"{nameof(CommandWriter<TEntity>)}.{nameof(WriteAsync)}",
CommandState = CommandState.Start,
EntityType = typeof(TEntity),
WriteModel = writeModel
});
await GetCollection().BulkWriteAsync(writeModel, null, cancellationToken).ConfigureAwait(false);
Connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
await GetCollection().BulkWriteAsync(writeModel, null, cancellationToken).ConfigureAwait(false);
}
catch (Exception exception)
{
CommandId = commandId,
Source = $"{nameof(CommandWriter<TEntity>)}.{nameof(WriteAsync)}",
CommandState = CommandState.End,
EntityType = typeof(TEntity),
WriteModel = writeModel
});
}
catch (Exception ex)
{
Connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
{
CommandId = commandId,
Source = $"{nameof(CommandWriter<TEntity>)}.{nameof(WriteAsync)}",
CommandState = CommandState.Error,
EntityType = typeof(TEntity),
WriteModel = writeModel
});
Connection.DiagnosticListener.OnError(ex);

throw;
diagnostics.Error(exception);
throw;
}
}
}
}
@@ -5,10 +5,9 @@

namespace MongoFramework.Infrastructure.Diagnostics
{
public abstract class DiagnosticCommand
public class DiagnosticCommand
{
public Guid CommandId { get; set; }
public string Source { get; set; }
public CommandState CommandState { get; set; }
public Type EntityType { get; set; }
}
@@ -23,7 +22,7 @@ public enum CommandState

public class ReadDiagnosticCommand : DiagnosticCommand
{
public IMongoFrameworkQueryable Queryable { get; set; }
public string Query { get; set; }
}

public abstract class WriteDiagnosticCommandBase : DiagnosticCommand { }
@@ -0,0 +1,95 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoFramework.Infrastructure.Linq;

namespace MongoFramework.Infrastructure.Diagnostics
{
public class DiagnosticRunner : IDisposable
{
public Guid CommandId { get; } = Guid.NewGuid();
public IMongoDbConnection Connection { get; }
public bool HasErrored { get; private set; } = false;

private DiagnosticRunner(IMongoDbConnection connection)
{
Connection = connection;
}
public static DiagnosticRunner Start<TEntity, TOutput>(IMongoDbConnection connection, IMongoFrameworkQueryProvider<TEntity, TOutput> provider) where TEntity : class
{
var runner = new DiagnosticRunner(connection);
connection.DiagnosticListener.OnNext(new ReadDiagnosticCommand
{
CommandId = runner.CommandId,
CommandState = CommandState.Start,
EntityType = typeof(TOutput),
Query = provider.ToQuery()
});
return runner;
}
public static DiagnosticRunner Start<TEntity>(IMongoDbConnection connection, IEnumerable<WriteModel<TEntity>> model) where TEntity : class
{
var runner = new DiagnosticRunner(connection);
connection.DiagnosticListener.OnNext(new WriteDiagnosticCommand<TEntity>
{
CommandId = runner.CommandId,
CommandState = CommandState.Start,
EntityType = typeof(TEntity),
WriteModel = model
});
return runner;
}
public static DiagnosticRunner Start<TEntity>(IMongoDbConnection connection, IEnumerable<CreateIndexModel<TEntity>> model) where TEntity : class
{
var runner = new DiagnosticRunner(connection);
connection.DiagnosticListener.OnNext(new IndexDiagnosticCommand<TEntity>
{
CommandId = runner.CommandId,
CommandState = CommandState.Start,
EntityType = typeof(TEntity),
IndexModel = model
});
return runner;
}

public void FirstReadResult<TOutput>()
{
Connection.DiagnosticListener.OnNext(new ReadDiagnosticCommand
{
CommandId = CommandId,
CommandState = CommandState.FirstResult,
EntityType = typeof(TOutput)
});
}

public void Error(Exception exception = null)
{
HasErrored = true;
Connection.DiagnosticListener.OnNext(new DiagnosticCommand
{
CommandId = CommandId,
CommandState = CommandState.Error
});

if (exception != null)
{
Connection.DiagnosticListener.OnError(exception);
}
}

public void Dispose()
{
if (!HasErrored)
{
Connection.DiagnosticListener.OnNext(new DiagnosticCommand
{
CommandId = CommandId,
CommandState = CommandState.End
});
}
}
}
}
@@ -1,7 +1,7 @@
using MongoFramework.Infrastructure.Diagnostics;
using System;

namespace MongoFramework.Infrastructure
namespace MongoFramework.Infrastructure.Diagnostics
{
public interface IDiagnosticListener : IObserver<DiagnosticCommand>
{

0 comments on commit fc0d482

Please sign in to comment.
You can’t perform that action at this time.