使用cassandra-python-driver记录所有查询

时间:2017-10-16 15:12:34

标签: python cassandra cassandra-python-driver

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

完成日志记录

我可以使用任何钩子或回调来记录它吗?

3 个答案:

答案 0 :(得分:5)

2个选项:

  1. 坚持session.add_request_init_listener

    来自源代码:

    a)BoundStatement

    https://github.com/datastax/python-driver/blob/3.11.0/cassandra/query.py#L560

    传递的值存储在raw_values中,您可以尝试将其解压缩

    b)BatchStatement

    https://github.com/datastax/python-driver/blob/3.11.0/cassandra/query.py#L676

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

    c)只调用此钩子,我没有设法找到任何其他钩子 https://github.com/datastax/python-driver/blob/master/cassandra/cluster.py#L2097

    但它与查询实际执行无关 - 它只是一种检查已构造的查询类型的方法,并且可能添加额外的回调/错误

  2. 从不同的角度接近它并使用痕迹

    https://datastax.github.io/python-driver/faq.html#how-do-i-trace-a-request https://datastax.github.io/python-driver/api/cassandra/cluster.html#cassandra.cluster.ResponseFuture.get_all_query_traces

      

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

  3. 以下是使用选项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'
    

答案 1 :(得分:2)

<强> add_request_init_listener(fn, *args, **kwargs)

  

添加带有参数的回调,以便在创建任何请求时调用。

     

在创建每个客户端请求之后,在发送请求之前,它将被调用为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 :(得分:1)

您是否考虑为execute或等效文件(例如execute_concurrent)创建一个装饰器,用于记录用于语句或预准备语句的CQL查询?

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