2017-10-16 3 views
9

私はPythonコードからCassandraで実行されたすべてのクエリを記録する方法を見つけようとしています。具体的には、実行中のログは、次のコマンドを使用して実行します。BatchStatementcassandra-python-driverですべてのクエリをログに記録

これを記録するために使用できるフックまたはコールバックはありますか?

答えて

3

2オプション:

A)BoundStatement

  1. スティックソースコードから

    session.add_request_init_listenerhttps://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をトレースし、追加のコールバック/ errbacksを追加されたクエリの種類を検査するだけの方法ですhttps://datastax.github.io/python-driver/api/cassandra/cluster.html#cassandra.cluster.ResponseFuture.get_all_query_traces

    リクエストのトレースは、Session.execute_async()でtrace = Trueを設定することでオンにすることができます。

    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 
    

    それは次の出力を生成します。ここでは

は、オプション2を使用してトレース BatchStatementの例ですそして、将来にResponseFuture.get_query_trace()を待って結果を見ます
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' 
+0

私は 'BatchStatement'を使用しています。私は '_statements_and_parameters'にアクセスしようとしましたが、クエリと値はエン​​コードされています。 フックは、要求が開始されたときに呼び出され、クエリの実行が終了したときには呼び出されません。だから私はそれを使用すると実行に失敗したクエリを記録することがあります。 –

+0

また、トレースを試みました。 'BatchStatement'によって実行されたクエリの完全なログを返しません –

+0

コードサンプル – ffeast

1

executeまたはそれに相当するデコレータ(例:execute_concurrent)を使用して、お客様のステートメントまたはプリペアドステートメントに使用されるCQLクエリを記録することを検討しましたか?

これは、クエリが正常に実行された場合にのみCQLクエリが記録されるように書くことができます。

+0

クエリ文字列がバッチによって実行された後、そのクエリ文字列にアクセスする方法が見つかりません。 –

+0

execute_async()にコールバックを追加することができます:https://datastax.github.io/python-driver/api/cassandra/cluster.html#cassandra.cluster.ResponseFuture.add_callback –

+0

コールバックは 'ResultSet'を返します。実行されたquieresを含んでいない。 –

1

add_request_init_listener(fn, *args, **kwargs)

任意の要求が作成されたときに呼び出される引数を指定してコールバックを追加します。

これは、各クライアント要求が作成された後(response_future、* argsを、** kwargsから)FNとして呼び出されると、要求はあなたが簡単に行われたすべてのクエリをログに記録することができますコールバックを使用して*

を送信される前にそのセッションで

例:

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) 
+0

これは良いアプローチですが、このコールバックはクエリが実行される前に呼び出され、クエリオブジェクトではなくクエリオブジェクトを返します。 'Preparedstatement'と' BatchStatement'の場合、クエリとその値がエンコードされていて、デコードする方法が見つかりませんでした。 –

関連する問題