使用cassandra python驱动程序记录所有查询

使用cassandra python驱动程序记录所有查询,python,cassandra,cassandra-python-driver,Python,Cassandra,Cassandra Python Driver,我正试图找到一种方法,从python代码中记录在Cassandra上完成的所有查询。在使用BatchStatement 是否有任何钩子或回调可用于记录此操作?您是否考虑过为您的execute或等效工具(例如execute\u concurrent)创建一个装饰器,用于记录用于语句或准备语句的CQL查询 您可以这样编写:只有在查询成功执行时,才会记录CQL查询。 添加一个回调,其中包含创建任何请求时要调用的参数 在创建每个客户端请求之后,在发送请求之前,它将作为fn(response_future

我正试图找到一种方法,从python代码中记录在Cassandra上完成的所有查询。在使用
BatchStatement


是否有任何钩子或回调可用于记录此操作?

您是否考虑过为您的
execute
或等效工具(例如
execute\u concurrent
)创建一个装饰器,用于记录用于语句或准备语句的CQL查询

您可以这样编写:只有在查询成功执行时,才会记录CQL查询。

添加一个回调,其中包含创建任何请求时要调用的参数

在创建每个客户端请求之后,在发送请求之前,它将作为fn(response_future,*args,**kwargs)调用*

使用回调,您可以轻松地记录该会话进行的所有查询

例如:

from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider


class RequestHandler:

    def on_request(self, rf):
        # This callback is invoked each time a request is created, on the thread creating the request.
        # We can use this to count events, or add callbacks
        print(rf.query)


auth_provider = PlainTextAuthProvider(
    username='cassandra',
    password='cassandra'
)

cluster = Cluster(['192.168.65.199'],auth_provider=auth_provider)
session = cluster.connect('test')

handler = RequestHandler()
# each instance will be registered with a session, and receive a callback for each request generated
session.add_request_init_listener(handler.on_request)

from time import sleep

for count in range(1, 10):
    print(count)
    for row in session.execute("select * from kv WHERE key = %s", ["ed1e49e0-266f-11e7-9d76-fd55504093c1"]):
        print row
    sleep(1)
2种选择:

  • 坚持会话。添加请求初始化侦听器

    从源代码:

    a)
    BoundStatement

    传递的值存储在原始值中,您可以尝试提取它

    b)
    BatchStatement

    它将用于构造此对象的所有语句和参数存储在
    \u statements\u和\u parameters
    中。 虽然它不是公共财产,但似乎可以取回

    c) 只有这个钩子被称为,我没有找到任何其他钩子

    但它与查询的实际执行无关——它只是一种检查已构造的查询类型的方法,可能还会添加其他回调/错误回调

  • 从不同的角度接近它,并使用痕迹

    通过在Session.execute\u async()中设置trace=True,可以为任何请求打开请求跟踪。通过等待将来查看结果,然后是ResponseFuture.get\u query\u trace()

  • 下面是使用选项2进行跟踪的
    BatchStatement
    示例:

    bs = BatchStatement()                                                        
    bs.add_all(['insert into test.test(test_type, test_desc) values (%s, %s)',   
                'insert into test.test(test_type, test_desc) values (%s, %s)',   
                'delete from test.test where test_type=%s',
                'update test.test set test_desc=%s where test_type=%s'],
               [['hello1', 'hello1'],                                            
                ['hello2', 'hello2'],                                            
                ['hello2'],
                ['hello100', 'hello1']])     
    res = session.execute(bs, trace=True)                                        
    trace = res.get_query_trace()                                                
    for event in trace.events:                                                   
        if event.description.startswith('Parsing'):                              
            print event.description 
    
    它产生以下输出:

    Parsing insert into test.test(test_type, test_desc) values ('hello1', 'hello1')
    Parsing insert into test.test(test_type, test_desc) values ('hello2', 'hello2')
    Parsing delete from test.test where test_type='hello2'
    Parsing update test.test set test_desc='hello100' where test_type='hello1'
    

    批处理执行查询字符串后,我找不到如何访问该字符串。您可以添加回调以执行_async():回调返回一个
    ResultSet
    ,其中不包含已执行的quieres。这是一种很好的方法,但在执行查询之前调用此回调,它返回语句对象,而不是查询字符串。对于
    Preparedstatement
    BatchStatement
    查询及其值和编码,我找不到解码它们的方法。我正在使用
    BatchStatement
    。我尝试访问
    \u语句和\u参数
    ,但查询和值都已编码。钩子是在请求启动时调用的,而不是在查询执行完毕时调用的。因此,如果我使用它,我可能会记录无法执行的查询。还尝试了跟踪。不会返回由
    BatchStatement
    执行的查询的完整日志,它的工作方式与您所说的相同。但是当批处理像这样创建时,它不起作用
    bs.add(session.prepare('insert-into-test.test(test\u-type,test\u-desc))值(?,,,['hello1','hello1'))