我们有一个ASP.NET 4.5 webapi解决方案,它将数据写入Cassandra。我们遇到了删除操作不起作用的问题。我们想看看引擎盖下的C#驱动程序是怎么回事。我们已经将CassandraTraceSwitch设置为Verbose,但它不会提供太多有用的数据。我想看看它对Cassandra生成和执行的实际查询,以及它得到的响应。
没有办法输出生成的查询,但这是一个好主意。
我已经创建了一个票证,以便在跟踪级别为Verbose
时将生成的查询包含在输出中,您可以跟踪JIRA的进度或发送请求。
只是一个想法。它并不能完全回答最初的问题,但可能会有所帮助。您可以创建DispatchProxy
并拦截CQL查询。我这样做
using Cassandra;
using System;
using System.Reflection;
using Cassandra.Data.Linq;
using Wpfe.Logging;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace Wpfe.Storage {
public class QueryTracingProxy<T> : DispatchProxy where T : class {
private static readonly ILogger _logger = AppLogFactory.CreateLogger("Wpfe.StorageQuery");
static Lazy<PropertyInfo> cqlPropertyInfo = new Lazy<PropertyInfo>(
() => typeof(PreparedStatement).GetProperty("Cql", BindingFlags.NonPublic | BindingFlags.Instance));
public T Target { get; private set; }
public static T Decorate(T target) {
var proxy = Create<T, QueryTracingProxy<T>>() as QueryTracingProxy<T>;
proxy.Target = target;
return proxy as T;
}
[DebuggerStepThrough]
protected override object Invoke(MethodInfo targetMethod, object[] args) {
try {
if (targetMethod.Name.Equals(nameof(ISession.Execute))) {
if (args.Length > 0) {
var arg1 = args[0];
if (arg1 is string) {
var str = (string)arg1;
_logger.LogInformation(str);
}
else if (arg1 is CqlCommand) {
var cmd = (CqlCommand)arg1;
var values = string.Join("n", cmd.QueryValues);
_logger.LogInformation(string.Concat(cmd.QueryString, "n", values));
}
}
}
else if (targetMethod.Name.Equals(nameof(ISession.ExecuteAsync)) && args.Length == 1) {
var statement = args[0] as BoundStatement;
if (statement != null) {
var preparedStatement = statement.PreparedStatement;
if (preparedStatement != null) {
var cql = cqlPropertyInfo.Value.GetValue(preparedStatement);
var values = string.Join("n", statement.QueryValues);
_logger.LogInformation(string.Concat(cql, "n", values));
}
}
}
var result = targetMethod.Invoke(Target, args);
return result;
}
catch (TargetInvocationException exc) {
throw exc.InnerException;
}
}
}
public static class QueryTracer {
private static readonly ILogger _logger = AppLogFactory.CreateLogger("Wpfe.StorageQuery");
public static ISession HookUp(ISession session) {
if (_logger.IsEnabled(LogLevel.Information) || _logger.IsEnabled(LogLevel.Debug)) {
var proxy = QueryTracingProxy<ISession>.Decorate(session);
return proxy;
}
return session;
}
}
}
然后在代码中,我只是装饰ISession
实例,即
private static ISession createDefaultSession() {
var cluster = EntityManagerFactory.BuildCluster(StorageGlobalOptions.Value.DatabaseEffective);
var session = cluster.Connect();
return QueryTracer.HookUp(session);
}