【问题标题】:Logging all queries with cassandra-python-driver使用 cassandra-python-driver 记录所有查询
【发布时间】:2018-03-28 03:56:10
【问题描述】:

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

特别记录他们完成执行

我可以使用任何挂钩或回调来记录这个吗?

【问题讨论】:

    标签: python cassandra cassandra-python-driver


    【解决方案1】:

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

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

    【讨论】:

    【解决方案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)
    

    【讨论】:

    • 这是一个很好的方法,但是这个回调是在查询执行之前调用的,它返回的是语句对象而不是查询字符串。在PreparedstatementBatchStatement 的情况下,查询及其值和编码,我找不到解码它们的方法。
    【解决方案3】:

    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()

    这是使用选项 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'
    

    【讨论】:

    • 我正在使用BatchStatement 。我尝试访问_statements_and_parameters ,但查询和值已编码。在发起请求时调用钩子,而不是在执行完查询时调用。因此,如果我使用它,我可能会记录无法执行的查询。
    • 也尝试过追踪。不返回由BatchStatement执行的查询的完整日志
    • 按你说的方式工作。但是当像这样创建批处理时它不起作用bs.add(session.prepare('insert into test.test(test_type, test_desc) values (?, ?)'), ['hello1', 'hello1'])
    猜你喜欢
    • 2020-12-16
    • 2021-12-24
    • 1970-01-01
    • 2020-08-12
    • 2014-08-01
    • 2021-11-21
    • 2018-04-27
    • 2013-02-18
    • 2015-02-02
    相关资源
    最近更新 更多