3232
3333pytest .importorskip ("elasticsearch" ) # isort:skip
3434
35+ import json
3536import os
3637
3738from elasticsearch import VERSION as ES_VERSION
3839from elasticsearch import Elasticsearch
40+ from elasticsearch .serializer import JSONSerializer
3941
4042from elasticapm .conf .constants import TRANSACTION
43+ from elasticapm .utils import compat
4144
4245pytestmark = [pytest .mark .elasticsearch ]
4346
4851document_type = "_doc" if ES_VERSION [0 ] >= 6 else "doc"
4952
5053
54+ class NumberObj :
55+ def __init__ (self , value ):
56+ self .value = value
57+
58+
59+ class SpecialEncoder (JSONSerializer ):
60+ def default (self , obj ):
61+ if isinstance (obj , NumberObj ):
62+ return obj .value
63+ return JSONSerializer .default (self , obj )
64+
65+ def force_key_encoding (self , obj ):
66+ if isinstance (obj , dict ):
67+
68+ def yield_key_value (d ):
69+ for key , value in compat .iteritems (d ):
70+ try :
71+ yield self .default (key ), self .force_key_encoding (value )
72+ except TypeError :
73+ yield key , self .force_key_encoding (value )
74+
75+ return dict (yield_key_value (obj ))
76+ else :
77+ return obj
78+
79+ def dumps (self , obj ):
80+ return super (SpecialEncoder , self ).dumps (self .force_key_encoding (obj ))
81+
82+
5183@pytest .fixture
5284def elasticsearch (request ):
5385 """Elasticsearch client fixture."""
54- client = Elasticsearch (hosts = os .environ ["ES_URL" ])
86+ client = Elasticsearch (hosts = os .environ ["ES_URL" ], serializer = SpecialEncoder () )
5587 try :
5688 yield client
5789 finally :
@@ -338,9 +370,10 @@ def test_search_body(instrument, elasticapm_client, elasticsearch):
338370 assert span ["subtype" ] == "elasticsearch"
339371 assert span ["action" ] == "query"
340372 assert span ["context" ]["db" ]["type" ] == "elasticsearch"
341- assert (
342- span ["context" ]["db" ]["statement" ] == '{"sort": ["userid"], "query": {"term": {"user": "kimchy"}}}'
343- or span ["context" ]["db" ]["statement" ] == '{"query": {"term": {"user": "kimchy"}}, "sort": ["userid"]}'
373+ assert json .loads (span ["context" ]["db" ]["statement" ]) == json .loads (
374+ '{"sort": ["userid"], "query": {"term": {"user": "kimchy"}}}'
375+ ) or json .loads (span ["context" ]["db" ]["statement" ]) == json .loads (
376+ '{"query": {"term": {"user": "kimchy"}}, "sort": ["userid"]}'
344377 )
345378
346379
@@ -393,7 +426,7 @@ def test_search_both(instrument, elasticapm_client, elasticsearch):
393426 assert span ["subtype" ] == "elasticsearch"
394427 assert span ["action" ] == "query"
395428 assert span ["context" ]["db" ]["type" ] == "elasticsearch"
396- assert span ["context" ]["db" ]["statement" ] == 'q=text:hola\n \n {"query": {"term": {"user": "kimchy"}}}'
429+ assert span ["context" ]["db" ]["statement" ]. startswith ( 'q=text:hola\n \n {"query":' )
397430
398431
399432@pytest .mark .integrationtest
@@ -419,7 +452,7 @@ def test_count_body(instrument, elasticapm_client, elasticsearch):
419452 assert span ["subtype" ] == "elasticsearch"
420453 assert span ["action" ] == "query"
421454 assert span ["context" ]["db" ]["type" ] == "elasticsearch"
422- assert span ["context" ]["db" ]["statement" ] == '{"query": {"term": {"user": "kimchy"}}}'
455+ assert json . loads ( span ["context" ]["db" ]["statement" ]) == json . loads ( '{"query": {"term": {"user": "kimchy"}}}' )
423456
424457
425458@pytest .mark .integrationtest
@@ -486,7 +519,7 @@ def test_delete_by_query_body(instrument, elasticapm_client, elasticsearch):
486519 assert span ["subtype" ] == "elasticsearch"
487520 assert span ["action" ] == "query"
488521 assert span ["context" ]["db" ]["type" ] == "elasticsearch"
489- assert span ["context" ]["db" ]["statement" ] == '{"query": {"term": {"user": "kimchy"}}}'
522+ assert json . loads ( span ["context" ]["db" ]["statement" ]) == json . loads ( '{"query":{"term":{"user":"kimchy"}}}' )
490523
491524
492525@pytest .mark .integrationtest
@@ -528,3 +561,20 @@ def test_multiple_indexes_doctypes(instrument, elasticapm_client, elasticsearch)
528561 assert span ["subtype" ] == "elasticsearch"
529562 assert span ["action" ] == "query"
530563 assert span ["context" ]["db" ]["type" ] == "elasticsearch"
564+
565+
566+ @pytest .mark .integrationtest
567+ def test_custom_serializer (instrument , elasticapm_client , elasticsearch ):
568+ if ES_VERSION [0 ] < 7 :
569+ elasticsearch .index ("test-index" , document_type , {"2" : 1 })
570+ else :
571+ elasticsearch .index (index = "test-index" , body = {"2" : 1 })
572+ elasticapm_client .begin_transaction ("test" )
573+ search_query = {"query" : {"term" : {NumberObj (2 ): {"value" : 1 }}}}
574+ result = elasticsearch .search (index = "test-index" , body = search_query , params = None )
575+ elasticapm_client .end_transaction ("test" , "OK" )
576+
577+ transaction = elasticapm_client .events [TRANSACTION ][0 ]
578+ spans = elasticapm_client .spans_for_transaction (transaction )
579+ span = spans [0 ]
580+ assert json .loads (span ["context" ]["db" ]["statement" ]) == json .loads ('{"query":{"term":{"2":{"value":1}}}}' )
0 commit comments