Reputation: 2732
We have a ASP.NET 4.5 webapi solution, which writes data to Cassandra. We are having an issue with a delete operation not working. We'd like to see what is going on with the C# driver under the hood. We've set the CassandraTraceSwitch to Verbose, but it doesn't give much useful data. I'd like to see the actual queries it's generating and executing against Cassandra, as well as the response it gets back.
Upvotes: 2
Views: 663
Reputation: 6287
Just as an idea. It does not fully answer original question but might help. You can create DispatchProxy
and intercept CQL queries. I do it this way
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;
}
}
}
Then in code I just decorate ISession
instance, i.e.
private static ISession createDefaultSession() {
var cluster = EntityManagerFactory.BuildCluster(StorageGlobalOptions.Value.DatabaseEffective);
var session = cluster.Connect();
return QueryTracer.HookUp(session);
}
Upvotes: 1
Reputation: 6600
There is no way to output the query generated, but it is a good idea.
I've created a ticket to include the generated query in the output when the trace level is Verbose
, you can follow the progress on JIRA or send a pull request for it.
Upvotes: 4