Exemple #1
0
    def test_render(self):
        # render
        t = Template("Hello ${name}!")
        self.assertEqual(t.render(name="mako"), "Hello mako!")

        spans = self.pop_spans()
        self.assertEqual(len(spans), 1)

        assert_is_measured(spans[0])
        self.assertEqual(spans[0].service, "mako")
        self.assertEqual(spans[0].span_type, "template")
        self.assertEqual(spans[0].get_tag("mako.template_name"),
                         DEFAULT_TEMPLATE_NAME)
        self.assertEqual(spans[0].name, "mako.template.render")
        self.assertEqual(spans[0].resource, DEFAULT_TEMPLATE_NAME)

        # render_unicode
        t = Template("Hello ${name}!")
        self.assertEqual(t.render_unicode(name="mako"),
                         to_unicode("Hello mako!"))
        spans = self.pop_spans()
        self.assertEqual(len(spans), 1)
        assert_is_measured(spans[0])
        self.assertEqual(spans[0].service, "mako")
        self.assertEqual(spans[0].span_type, "template")
        self.assertEqual(spans[0].get_tag("mako.template_name"),
                         DEFAULT_TEMPLATE_NAME)
        self.assertEqual(spans[0].name, "mako.template.render_unicode")
        self.assertEqual(spans[0].resource, DEFAULT_TEMPLATE_NAME)

        # render_context
        t = Template("Hello ${name}!")
        buf = StringIO()
        c = Context(buf, name="mako")
        t.render_context(c)
        self.assertEqual(buf.getvalue(), "Hello mako!")
        spans = self.pop_spans()
        self.assertEqual(len(spans), 1)
        assert_is_measured(spans[0])
        self.assertEqual(spans[0].service, "mako")
        self.assertEqual(spans[0].span_type, "template")
        self.assertEqual(spans[0].get_tag("mako.template_name"),
                         DEFAULT_TEMPLATE_NAME)
        self.assertEqual(spans[0].name, "mako.template.render_context")
        self.assertEqual(spans[0].resource, DEFAULT_TEMPLATE_NAME)
Exemple #2
0
 def test_sqs_send_message_trace_injection_with_message_attributes(self):
     sqs = self.session.create_client("sqs",
                                      region_name="us-east-1",
                                      endpoint_url="http://localhost:4566")
     queue = sqs.create_queue(QueueName="test")
     Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sqs)
     message_attributes = {
         "one": {
             "DataType": "String",
             "StringValue": "one"
         },
         "two": {
             "DataType": "String",
             "StringValue": "two"
         },
         "three": {
             "DataType": "String",
             "StringValue": "three"
         },
         "four": {
             "DataType": "String",
             "StringValue": "four"
         },
         "five": {
             "DataType": "String",
             "StringValue": "five"
         },
         "six": {
             "DataType": "String",
             "StringValue": "six"
         },
         "seven": {
             "DataType": "String",
             "StringValue": "seven"
         },
         "eight": {
             "DataType": "String",
             "StringValue": "eight"
         },
         "nine": {
             "DataType": "String",
             "StringValue": "nine"
         },
     }
     sqs.send_message(QueueUrl=queue["QueueUrl"],
                      MessageBody="world",
                      MessageAttributes=message_attributes)
     spans = self.get_spans()
     assert spans
     span = spans[0]
     self.assertEqual(len(spans), 1)
     self.assertEqual(span.get_tag("aws.region"), "us-east-1")
     self.assertEqual(span.get_tag("aws.operation"), "SendMessage")
     assert_is_measured(span)
     assert_span_http_status_code(span, 200)
     self.assertEqual(span.service, "test-botocore-tracing.sqs")
     self.assertEqual(span.resource, "sqs.sendmessage")
     trace_json = span.get_tag(
         "params.MessageAttributes._datadog.StringValue")
     trace_data_injected = json.loads(trace_json)
     self.assertEqual(trace_data_injected[HTTP_HEADER_TRACE_ID],
                      str(span.trace_id))
     self.assertEqual(trace_data_injected[HTTP_HEADER_PARENT_ID],
                      str(span.span_id))
     response = sqs.receive_message(QueueUrl=queue["QueueUrl"],
                                    MessageAttributeNames=["_datadog"])
     self.assertEqual(len(response["Messages"]), 1)
     trace_json_message = response["Messages"][0]["MessageAttributes"][
         "_datadog"]["StringValue"]
     trace_data_in_message = json.loads(trace_json_message)
     self.assertEqual(trace_data_in_message[HTTP_HEADER_TRACE_ID],
                      str(span.trace_id))
     self.assertEqual(trace_data_in_message[HTTP_HEADER_PARENT_ID],
                      str(span.span_id))
     sqs.delete_queue(QueueUrl=queue["QueueUrl"])
Exemple #3
0
    def test_request_error_handler(self):
        """
        When making a request
            When the requested endpoint raises an exception
                We create the expected spans
        """
        @self.app.errorhandler(500)
        def error_handler(e):
            return "Whoops", 500

        @self.app.route("/500")
        def fivehundred():
            raise Exception("500 error")

        res = self.client.get("/500")
        self.assertEqual(res.status_code, 500)
        self.assertEqual(res.data, b"Whoops")

        spans = self.get_spans()

        if flask_version >= (0, 12):
            self.assertEqual(len(spans), 11)

            # Assert the order of the spans created
            self.assertListEqual(
                [
                    "flask.request",
                    "flask.try_trigger_before_first_request_functions",
                    "flask.preprocess_request",
                    "flask.dispatch_request",
                    "tests.contrib.flask.test_request.fivehundred",
                    "flask.handle_user_exception",
                    "flask.handle_exception",
                    "tests.contrib.flask.test_request.error_handler",
                    "flask.process_response",
                    "flask.do_teardown_request",
                    "flask.do_teardown_appcontext",
                ],
                [s.name for s in spans],
            )
        else:
            self.assertEqual(len(spans), 10)
            # Assert the order of the spans created
            self.assertListEqual(
                [
                    "flask.request",
                    "flask.try_trigger_before_first_request_functions",
                    "flask.preprocess_request",
                    "flask.dispatch_request",
                    "tests.contrib.flask.test_request.fivehundred",
                    "flask.handle_user_exception",
                    "flask.handle_exception",
                    "tests.contrib.flask.test_request.error_handler",
                    "flask.do_teardown_request",
                    "flask.do_teardown_appcontext",
                ],
                [s.name for s in spans],
            )

        # Assert span services
        for span in spans:
            self.assertEqual(span.service, "flask")

        # Root request span
        req_span = spans[0]
        assert_is_measured(req_span)
        self.assertEqual(req_span.service, "flask")
        self.assertEqual(req_span.name, "flask.request")
        self.assertEqual(req_span.resource, "GET /500")
        self.assertEqual(req_span.span_type, "web")
        self.assertEqual(req_span.error, 1)
        self.assertIsNone(req_span.parent_id)

        # Request tags
        self.assertEqual(req_span.get_tag("http.method"), "GET")
        self.assertEqual(req_span.get_tag(http.URL), "http://localhost/500")
        assert_span_http_status_code(req_span, 500)
        self.assertEqual(req_span.get_tag("flask.endpoint"), "fivehundred")
        self.assertEqual(req_span.get_tag("flask.url_rule"), "/500")

        # Dispatch span
        dispatch_span = spans[3]
        self.assertEqual(dispatch_span.service, "flask")
        self.assertEqual(dispatch_span.name, "flask.dispatch_request")
        self.assertEqual(dispatch_span.resource, "flask.dispatch_request")
        self.assertEqual(dispatch_span.error, 1)
        self.assertTrue(
            dispatch_span.get_tag("error.msg").startswith("500 error"))
        self.assertTrue(
            dispatch_span.get_tag("error.stack").startswith("Traceback"))
        self.assertEqual(dispatch_span.get_tag("error.type"),
                         base_exception_name)

        # Handler span
        handler_span = spans[4]
        self.assertEqual(handler_span.service, "flask")
        self.assertEqual(handler_span.name,
                         "tests.contrib.flask.test_request.fivehundred")
        self.assertEqual(handler_span.resource, "/500")
        self.assertEqual(handler_span.error, 1)
        self.assertTrue(
            handler_span.get_tag("error.msg").startswith("500 error"))
        self.assertTrue(
            handler_span.get_tag("error.stack").startswith("Traceback"))
        self.assertEqual(handler_span.get_tag("error.type"),
                         base_exception_name)

        # User exception span
        user_ex_span = spans[5]
        self.assertEqual(user_ex_span.service, "flask")
        self.assertEqual(user_ex_span.name, "flask.handle_user_exception")
        self.assertEqual(user_ex_span.resource, "flask.handle_user_exception")
        self.assertEqual(user_ex_span.error, 1)
        self.assertTrue(
            user_ex_span.get_tag("error.msg").startswith("500 error"))
        self.assertTrue(
            user_ex_span.get_tag("error.stack").startswith("Traceback"))
        self.assertEqual(user_ex_span.get_tag("error.type"),
                         base_exception_name)
Exemple #4
0
    def test_request_501(self):
        """
        When making a request
            When the requested endpoint calls `abort(501)`
                We create the expected spans
        """
        @self.app.route("/501")
        def fivehundredone():
            abort(501)

        res = self.client.get("/501")
        self.assertEqual(res.status_code, 501)

        spans = self.get_spans()
        self.assertEqual(len(spans), 10)

        # Assert the order of the spans created
        self.assertListEqual(
            [
                "flask.request",
                "flask.try_trigger_before_first_request_functions",
                "flask.preprocess_request",
                "flask.dispatch_request",
                "tests.contrib.flask.test_request.fivehundredone",
                "flask.handle_user_exception",
                "flask.handle_http_exception",
                "flask.process_response",
                "flask.do_teardown_request",
                "flask.do_teardown_appcontext",
            ],
            [s.name for s in spans],
        )

        # Assert span services
        for span in spans:
            self.assertEqual(span.service, "flask")

        # Root request span
        req_span = spans[0]
        assert_is_measured(req_span)
        self.assertEqual(req_span.service, "flask")
        self.assertEqual(req_span.name, "flask.request")
        self.assertEqual(req_span.resource, "GET /501")
        self.assertEqual(req_span.span_type, "web")
        self.assertEqual(req_span.error, 1)
        self.assertIsNone(req_span.parent_id)

        # Request tags
        self.assertEqual(req_span.get_tag("http.method"), "GET")
        self.assertEqual(req_span.get_tag(http.URL), "http://localhost/501")
        assert_span_http_status_code(req_span, 501)
        self.assertEqual(req_span.get_tag("flask.endpoint"), "fivehundredone")
        self.assertEqual(req_span.get_tag("flask.url_rule"), "/501")

        # Dispatch span
        dispatch_span = spans[3]
        self.assertEqual(dispatch_span.service, "flask")
        self.assertEqual(dispatch_span.name, "flask.dispatch_request")
        self.assertEqual(dispatch_span.resource, "flask.dispatch_request")
        self.assertEqual(dispatch_span.error, 1)
        self.assertTrue(
            dispatch_span.get_tag("error.msg").startswith(
                "501 Not Implemented"))
        self.assertTrue(
            dispatch_span.get_tag("error.stack").startswith("Traceback"))
        self.assertEqual(dispatch_span.get_tag("error.type"),
                         "werkzeug.exceptions.NotImplemented")

        # Handler span
        handler_span = spans[4]
        self.assertEqual(handler_span.service, "flask")
        self.assertEqual(handler_span.name,
                         "tests.contrib.flask.test_request.fivehundredone")
        self.assertEqual(handler_span.resource, "/501")
        self.assertEqual(handler_span.error, 1)
        self.assertTrue(
            handler_span.get_tag("error.msg").startswith(
                "501 Not Implemented"))
        self.assertTrue(
            handler_span.get_tag("error.stack").startswith("Traceback"))
        self.assertEqual(handler_span.get_tag("error.type"),
                         "werkzeug.exceptions.NotImplemented")

        # User exception span
        user_ex_span = spans[5]
        self.assertEqual(user_ex_span.service, "flask")
        self.assertEqual(user_ex_span.name, "flask.handle_user_exception")
        self.assertEqual(user_ex_span.resource, "flask.handle_user_exception")
        self.assertEqual(user_ex_span.error, 0)
Exemple #5
0
    def test_request_query_string(self):
        """
        When making a request
            When the request contains a query string
                We create the expected spans
        """
        @self.app.route("/")
        def index():
            return "Hello Flask", 200

        res = self.client.get("/", query_string=dict(hello="flask"))
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.data, b"Hello Flask")

        spans = self.get_spans()
        self.assertEqual(len(spans), 8)

        # Assert the order of the spans created
        self.assertListEqual(
            [
                "flask.request",
                "flask.try_trigger_before_first_request_functions",
                "flask.preprocess_request",
                "flask.dispatch_request",
                "tests.contrib.flask.test_request.index",
                "flask.process_response",
                "flask.do_teardown_request",
                "flask.do_teardown_appcontext",
            ],
            [s.name for s in spans],
        )

        # Assert span services
        for span in spans:
            self.assertEqual(span.service, "flask")

        # Root request span
        req_span = spans[0]

        assert_is_measured(req_span)
        self.assertEqual(req_span.service, "flask")
        self.assertEqual(req_span.name, "flask.request")
        # Note: contains no query string
        self.assertEqual(req_span.resource, "GET /")
        self.assertEqual(req_span.span_type, "web")
        self.assertEqual(req_span.error, 0)
        self.assertIsNone(req_span.parent_id)

        # Request tags
        self.assertEqual(req_span.get_tag("flask.endpoint"), "index")
        # Note: contains no query string
        self.assertEqual(req_span.get_tag("flask.url_rule"), "/")
        self.assertEqual(req_span.get_tag("http.method"), "GET")
        # Note: contains no query string
        self.assertEqual(req_span.get_tag(http.URL), "http://localhost/")
        assert_span_http_status_code(req_span, 200)

        # Handler span
        handler_span = spans[4]
        self.assertEqual(handler_span.service, "flask")
        self.assertEqual(handler_span.name,
                         "tests.contrib.flask.test_request.index")
        # Note: contains no query string
        self.assertEqual(handler_span.resource, "/")
        self.assertEqual(req_span.error, 0)
Exemple #6
0
    def assert_conn_is_traced(self, db, service):

        # ensure the trace pscyopg client doesn't add non-standard
        # methods
        try:
            db.execute("""select 'foobar'""")
        except AttributeError:
            pass

        # Ensure we can run a query and it's correctly traced
        q = """select 'foobarblah'"""

        start = time.time()
        cursor = db.cursor()
        res = cursor.execute(q)
        self.assertIsNone(res)
        rows = cursor.fetchall()
        end = time.time()

        self.assertEquals(rows, [("foobarblah", )])

        self.assert_structure(
            dict(name="postgres.query",
                 resource=q,
                 service=service,
                 error=0,
                 span_type="sql"), )
        root = self.get_root_span()
        self.assertIsNone(root.get_tag("sql.query"))
        assert start <= root.start <= end
        assert root.duration <= end - start
        # confirm analytics disabled by default
        self.reset()

        # run a query with an error and ensure all is well
        q = """select * from some_non_existant_table"""
        cur = db.cursor()
        try:
            cur.execute(q)
        except Exception:
            pass
        else:
            assert 0, "should have an error"

        self.assert_structure(
            dict(
                name="postgres.query",
                resource=q,
                service=service,
                error=1,
                span_type="sql",
                meta={
                    "out.host": "127.0.0.1",
                },
                metrics={
                    "out.port": TEST_PORT,
                },
            ), )
        root = self.get_root_span()
        assert_is_measured(root)
        self.assertIsNone(root.get_tag("sql.query"))
        self.reset()
    def test_request(self):
        """
        When using ddtrace-run
            When making a request to flask app
                We generate the expected spans
        """
        @self.app.route("/")
        def index():
            return "Hello Flask", 200

        res = self.client.get("/")
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.data, b"Hello Flask")

        spans = self.pop_spans()
        self.assertEqual(len(spans), 8)

        self.assertListEqual(
            [
                "flask.request",
                "flask.try_trigger_before_first_request_functions",
                "flask.preprocess_request",
                "flask.dispatch_request",
                "tests.contrib.flask_autopatch.test_flask_autopatch.index",
                "flask.process_response",
                "flask.do_teardown_request",
                "flask.do_teardown_appcontext",
            ],
            [s.name for s in spans],
        )

        # Assert span services
        for span in spans:
            self.assertEqual(span.service, "test-flask")

        # Root request span
        req_span = spans[0]
        assert_is_measured(req_span)
        self.assertEqual(req_span.service, "test-flask")
        self.assertEqual(req_span.name, "flask.request")
        self.assertEqual(req_span.resource, "GET /")
        self.assertEqual(req_span.span_type, "web")
        self.assertEqual(req_span.error, 0)
        self.assertIsNone(req_span.parent_id)

        # Request tags
        for tag in [
                "flask.version", "http.url", "http.method", "http.status_code",
                "flask.endpoint", "flask.url_rule"
        ]:
            assert tag in req_span.meta

        self.assertEqual(req_span.get_tag("flask.endpoint"), "index")
        self.assertEqual(req_span.get_tag("flask.url_rule"), "/")
        self.assertEqual(req_span.get_tag("http.method"), "GET")
        self.assertEqual(req_span.get_tag(http.URL), "http://localhost/")
        assert_span_http_status_code(req_span, 200)

        # Handler span
        handler_span = spans[4]
        self.assertEqual(handler_span.service, "test-flask")
        self.assertEqual(
            handler_span.name,
            "tests.contrib.flask_autopatch.test_flask_autopatch.index")
        self.assertEqual(handler_span.resource, "/")
        self.assertEqual(req_span.error, 0)
Exemple #8
0
    def test_insert_find(self):
        tracer, client = self.get_tracer_and_client()

        start = time.time()
        db = client.testdb
        db.drop_collection('teams')
        teams = [{
            'name': 'Toronto Maple Leafs',
            'established': 1917,
        }, {
            'name': 'Montreal Canadiens',
            'established': 1910,
        }, {
            'name': 'New York Rangers',
            'established': 1926,
        }]

        # create some data (exercising both ways of inserting)

        db.teams.insert_one(teams[0])
        db.teams.insert_many(teams[1:])

        # wildcard query (using the [] syntax)
        cursor = db['teams'].find()
        count = 0
        for row in cursor:
            count += 1
        assert count == len(teams)

        # scoped query (using the getattr syntax)
        q = {'name': 'Toronto Maple Leafs'}
        queried = list(db.teams.find(q))
        end = time.time()
        assert len(queried) == 1
        assert queried[0]['name'] == 'Toronto Maple Leafs'
        assert queried[0]['established'] == 1917

        spans = tracer.pop()
        for span in spans:
            # ensure all the of the common metadata is set
            assert_is_measured(span)
            assert span.service == self.TEST_SERVICE
            assert span.span_type == 'mongodb'
            assert span.meta.get('mongodb.collection') == 'teams'
            assert span.meta.get('mongodb.db') == 'testdb'
            assert span.meta.get('out.host'), span.pprint()
            assert span.metrics.get('out.port'), span.pprint()
            assert span.start > start
            assert span.duration < end - start

        expected_resources = [
            'drop teams',
            'insert teams',
            'insert teams',
        ]

        # query names should be used in >3.1
        name = 'find' if pymongo.version_tuple >= (3, 1, 0) else 'query'

        expected_resources.extend([
            '{} teams'.format(name),
            '{} teams {{"name": "?"}}'.format(name),
        ])

        assert expected_resources == list(s.resource for s in spans)

        # confirm query tag for find all
        assert spans[-2].get_tag('mongodb.query') is None

        # confirm query tag find with query criteria on name
        assert spans[-1].get_tag('mongodb.query') == '{\'name\': \'?\'}'
Exemple #9
0
    def assert_conn_is_traced(self, tracer, db, service):

        # ensure the trace aiopg client doesn't add non-standard
        # methods
        try:
            yield from db.execute('select \'foobar\'')
        except AttributeError:
            pass

        # Ensure we can run a query and it's correctly traced
        q = 'select \'foobarblah\''
        start = time.time()
        cursor = yield from db.cursor()
        yield from cursor.execute(q)
        rows = yield from cursor.fetchall()
        end = time.time()
        assert rows == [('foobarblah', )]
        assert rows
        spans = self.pop_spans()
        assert spans
        assert len(spans) == 1
        span = spans[0]
        assert_is_measured(span)
        assert span.name == 'postgres.query'
        assert span.resource == q
        assert span.service == service
        assert span.meta['sql.query'] == q
        assert span.error == 0
        assert span.span_type == 'sql'
        assert start <= span.start <= end
        assert span.duration <= end - start

        # Ensure OpenTracing compatibility
        ot_tracer = init_tracer('aiopg_svc', tracer)
        with ot_tracer.start_active_span('aiopg_op'):
            cursor = yield from db.cursor()
            yield from cursor.execute(q)
            rows = yield from cursor.fetchall()
            assert rows == [('foobarblah', )]
        spans = self.pop_spans()
        assert len(spans) == 2
        ot_span, dd_span = spans
        # confirm the parenting
        assert ot_span.parent_id is None
        assert dd_span.parent_id == ot_span.span_id
        assert ot_span.name == 'aiopg_op'
        assert ot_span.service == 'aiopg_svc'
        assert dd_span.name == 'postgres.query'
        assert dd_span.resource == q
        assert dd_span.service == service
        assert dd_span.meta['sql.query'] == q
        assert dd_span.error == 0
        assert dd_span.span_type == 'sql'

        # run a query with an error and ensure all is well
        q = 'select * from some_non_existant_table'
        cur = yield from db.cursor()
        try:
            yield from cur.execute(q)
        except Exception:
            pass
        else:
            assert 0, 'should have an error'
        spans = self.pop_spans()
        assert spans, spans
        assert len(spans) == 1
        span = spans[0]
        assert span.name == 'postgres.query'
        assert span.resource == q
        assert span.service == service
        assert span.meta['sql.query'] == q
        assert span.error == 1
        # assert span.meta['out.host'] == 'localhost'
        assert span.metrics['out.port'] == TEST_PORT
        assert span.span_type == 'sql'
Exemple #10
0
    def test_update_ot(self):
        """OpenTracing version of test_update."""
        tracer, client = self.get_tracer_and_client()
        ot_tracer = init_tracer("mongo_svc", tracer)

        with ot_tracer.start_active_span("mongo_op"):
            db = client["testdb"]
            db.drop_collection("songs")
            input_songs = [
                {
                    "name": "Powderfinger",
                    "artist": "Neil"
                },
                {
                    "name": "Harvest",
                    "artist": "Neil"
                },
                {
                    "name": "Suzanne",
                    "artist": "Leonard"
                },
                {
                    "name": "Partisan",
                    "artist": "Leonard"
                },
            ]
            db.songs.insert_many(input_songs)
            result = db.songs.update_many(
                {"artist": "Neil"},
                {"$set": {
                    "artist": "Shakey"
                }},
            )

            assert result.matched_count == 2
            assert result.modified_count == 2

        # ensure all is traced.
        spans = tracer.pop()
        assert spans, spans
        assert len(spans) == 4

        ot_span = spans[0]
        assert ot_span.parent_id is None
        assert ot_span.name == "mongo_op"
        assert ot_span.service == "mongo_svc"

        for span in spans[1:]:
            # ensure the parenting
            assert span.parent_id == ot_span.span_id
            # ensure all the of the common metadata is set
            assert_is_measured(span)
            assert span.service == self.TEST_SERVICE
            assert span.span_type == "mongodb"
            assert span.meta.get("mongodb.collection") == "songs"
            assert span.meta.get("mongodb.db") == "testdb"
            assert span.meta.get("out.host")
            assert span.metrics.get("out.port")

        expected_resources = set([
            "drop songs",
            'update songs {"artist": "?"}',
            "insert songs",
        ])

        assert expected_resources == {s.resource for s in spans[1:]}
Exemple #11
0
    def test_insert_find(self):
        tracer, client = self.get_tracer_and_client()

        start = time.time()
        db = client.testdb
        db.drop_collection("teams")
        teams = [
            {
                "name": "Toronto Maple Leafs",
                "established": 1917,
            },
            {
                "name": "Montreal Canadiens",
                "established": 1910,
            },
            {
                "name": "New York Rangers",
                "established": 1926,
            },
        ]

        # create some data (exercising both ways of inserting)

        db.teams.insert_one(teams[0])
        db.teams.insert_many(teams[1:])

        # wildcard query (using the [] syntax)
        cursor = db["teams"].find()
        count = 0
        for row in cursor:
            count += 1
        assert count == len(teams)

        # scoped query (using the getattr syntax)
        q = {"name": "Toronto Maple Leafs"}
        queried = list(db.teams.find(q))
        end = time.time()
        assert len(queried) == 1
        assert queried[0]["name"] == "Toronto Maple Leafs"
        assert queried[0]["established"] == 1917

        spans = tracer.pop()
        for span in spans:
            # ensure all the of the common metadata is set
            assert_is_measured(span)
            assert span.service == self.TEST_SERVICE
            assert span.span_type == "mongodb"
            assert span.meta.get("mongodb.collection") == "teams"
            assert span.meta.get("mongodb.db") == "testdb"
            assert span.meta.get("out.host"), span.pprint()
            assert span.metrics.get("out.port"), span.pprint()
            assert span.start > start
            assert span.duration < end - start

        expected_resources = [
            "drop teams",
            "insert teams",
            "insert teams",
        ]

        # query names should be used in >3.1
        name = "find" if pymongo.version_tuple >= (3, 1, 0) else "query"

        expected_resources.extend([
            "{} teams".format(name),
            '{} teams {{"name": "?"}}'.format(name),
        ])

        assert expected_resources == list(s.resource for s in spans)

        # confirm query tag for find all
        assert spans[-2].get_tag("mongodb.query") is None

        # confirm query tag find with query criteria on name
        assert spans[-1].get_tag("mongodb.query") == "{'name': '?'}"
Exemple #12
0
    def test_delete(self):
        # ensure we trace deletes
        tracer, client = self.get_tracer_and_client()

        db = client["testdb"]
        collection_name = "here.are.songs"
        db.drop_collection(collection_name)
        input_songs = [
            {
                "name": "Powderfinger",
                "artist": "Neil"
            },
            {
                "name": "Harvest",
                "artist": "Neil"
            },
            {
                "name": "Suzanne",
                "artist": "Leonard"
            },
            {
                "name": "Partisan",
                "artist": "Leonard"
            },
        ]

        songs = db[collection_name]
        songs.insert_many(input_songs)

        # test delete one
        af = {"artist": "Neil"}
        assert songs.count(af) == 2
        songs.delete_one(af)
        assert songs.count(af) == 1

        # test delete many
        af = {"artist": "Leonard"}
        assert songs.count(af) == 2
        songs.delete_many(af)
        assert songs.count(af) == 0

        # ensure all is traced.
        spans = tracer.pop()
        assert spans, spans
        for span in spans:
            # ensure all the of the common metadata is set
            assert_is_measured(span)
            assert span.service == self.TEST_SERVICE
            assert span.span_type == "mongodb"
            assert span.meta.get("mongodb.collection") == collection_name
            assert span.meta.get("mongodb.db") == "testdb"
            assert span.meta.get("out.host")
            assert span.metrics.get("out.port")

        expected_resources = [
            "drop here.are.songs",
            "count here.are.songs",
            "count here.are.songs",
            "count here.are.songs",
            "count here.are.songs",
            'delete here.are.songs {"artist": "?"}',
            'delete here.are.songs {"artist": "?"}',
            "insert here.are.songs",
        ]

        assert sorted(expected_resources) == sorted(s.resource for s in spans)
Exemple #13
0
def test_set_tag_measured_no_value():
    s = Span(tracer=None, name="test.span")
    s.set_tag(SPAN_MEASURED_KEY)
    assert_is_measured(s)
Exemple #14
0
    def test_update_ot(self):
        """OpenTracing version of test_update."""
        tracer, client = self.get_tracer_and_client()
        ot_tracer = init_tracer('mongo_svc', tracer)

        with ot_tracer.start_active_span('mongo_op'):
            db = client['testdb']
            db.drop_collection('songs')
            input_songs = [
                {
                    'name': 'Powderfinger',
                    'artist': 'Neil'
                },
                {
                    'name': 'Harvest',
                    'artist': 'Neil'
                },
                {
                    'name': 'Suzanne',
                    'artist': 'Leonard'
                },
                {
                    'name': 'Partisan',
                    'artist': 'Leonard'
                },
            ]
            db.songs.insert_many(input_songs)
            result = db.songs.update_many(
                {'artist': 'Neil'},
                {'$set': {
                    'artist': 'Shakey'
                }},
            )

            assert result.matched_count == 2
            assert result.modified_count == 2

        # ensure all is traced.
        spans = tracer.pop()
        assert spans, spans
        assert len(spans) == 4

        ot_span = spans[0]
        assert ot_span.parent_id is None
        assert ot_span.name == 'mongo_op'
        assert ot_span.service == 'mongo_svc'

        for span in spans[1:]:
            # ensure the parenting
            assert span.parent_id == ot_span.span_id
            # ensure all the of the common metadata is set
            assert_is_measured(span)
            assert span.service == self.TEST_SERVICE
            assert span.span_type == 'mongodb'
            assert span.meta.get('mongodb.collection') == 'songs'
            assert span.meta.get('mongodb.db') == 'testdb'
            assert span.meta.get('out.host')
            assert span.metrics.get('out.port')

        expected_resources = set([
            'drop songs',
            'update songs {"artist": "?"}',
            'insert songs',
        ])

        assert expected_resources == {s.resource for s in spans[1:]}
Exemple #15
0
    def test_sqs_send_message_batch_trace_injection_with_max_message_attributes(
            self):
        sqs = self.session.create_client("sqs",
                                         region_name="us-east-1",
                                         endpoint_url="http://localhost:4566")
        queue = sqs.create_queue(QueueName="test")
        Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sqs)
        entries = [{
            "Id": "1",
            "MessageBody": "ironmaiden",
            "MessageAttributes": {
                "one": {
                    "DataType": "String",
                    "StringValue": "one"
                },
                "two": {
                    "DataType": "String",
                    "StringValue": "two"
                },
                "three": {
                    "DataType": "String",
                    "StringValue": "three"
                },
                "four": {
                    "DataType": "String",
                    "StringValue": "four"
                },
                "five": {
                    "DataType": "String",
                    "StringValue": "five"
                },
                "six": {
                    "DataType": "String",
                    "StringValue": "six"
                },
                "seven": {
                    "DataType": "String",
                    "StringValue": "seven"
                },
                "eight": {
                    "DataType": "String",
                    "StringValue": "eight"
                },
                "nine": {
                    "DataType": "String",
                    "StringValue": "nine"
                },
                "ten": {
                    "DataType": "String",
                    "StringValue": "ten"
                },
            },
        }]

        sqs.send_message_batch(QueueUrl=queue["QueueUrl"], Entries=entries)
        spans = self.get_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 1)
        self.assertEqual(span.get_tag("aws.region"), "us-east-1")
        self.assertEqual(span.get_tag("aws.operation"), "SendMessageBatch")
        assert_is_measured(span)
        assert_span_http_status_code(span, 200)
        self.assertEqual(span.service, "test-botocore-tracing.sqs")
        self.assertEqual(span.resource, "sqs.sendmessagebatch")
        response = sqs.receive_message(QueueUrl=queue["QueueUrl"],
                                       MessageAttributeNames=["_datadog"])
        self.assertEqual(len(response["Messages"]), 1)
        trace_in_message = "MessageAttributes" in response["Messages"][0]
        self.assertEqual(trace_in_message, False)
        sqs.delete_queue(QueueUrl=queue["QueueUrl"])
Exemple #16
0
    def test_insert_update_delete_query(self):
        tracer = self.get_tracer_and_connect()

        start = time.time()
        Artist.drop_collection()
        end = time.time()

        # ensure we get a drop collection span
        spans = tracer.pop()
        assert len(spans) == 1
        span = spans[0]

        assert_is_measured(span)
        assert span.resource == "drop artist"
        assert span.span_type == "mongodb"
        assert span.service == self.TEST_SERVICE
        _assert_timing(span, start, end)

        start = end
        joni = Artist()
        joni.first_name = "Joni"
        joni.last_name = "Mitchell"
        joni.save()
        end = time.time()

        # ensure we get an insert span
        spans = tracer.pop()
        assert len(spans) == 1
        span = spans[0]
        assert_is_measured(span)
        assert span.resource == "insert artist"
        assert span.span_type == "mongodb"
        assert span.service == self.TEST_SERVICE
        _assert_timing(span, start, end)

        # ensure full scans work
        start = time.time()
        artists = [a for a in Artist.objects]
        end = time.time()
        assert len(artists) == 1
        assert artists[0].first_name == "Joni"
        assert artists[0].last_name == "Mitchell"

        # query names should be used in pymongo>3.1
        name = "find" if pymongo.version_tuple >= (3, 1, 0) else "query"

        spans = tracer.pop()
        assert len(spans) == 1
        span = spans[0]
        assert_is_measured(span)
        assert span.resource == "{} artist".format(name)
        assert span.span_type == "mongodb"
        assert span.service == self.TEST_SERVICE
        _assert_timing(span, start, end)

        # ensure filtered queries work
        start = time.time()
        artists = [a for a in Artist.objects(first_name="Joni")]
        end = time.time()
        assert len(artists) == 1
        joni = artists[0]
        assert artists[0].first_name == "Joni"
        assert artists[0].last_name == "Mitchell"

        spans = tracer.pop()
        assert len(spans) == 1
        span = spans[0]
        assert_is_measured(span)
        assert span.resource == '{} artist {{"first_name": "?"}}'.format(name)
        assert span.span_type == "mongodb"
        assert span.service == self.TEST_SERVICE
        _assert_timing(span, start, end)

        # ensure updates work
        start = time.time()
        joni.last_name = "From Saskatoon"
        joni.save()
        end = time.time()

        spans = tracer.pop()
        assert len(spans) == 1
        span = spans[0]
        assert_is_measured(span)
        assert span.resource == 'update artist {"_id": "?"}'
        assert span.span_type == "mongodb"
        assert span.service == self.TEST_SERVICE
        _assert_timing(span, start, end)

        # ensure deletes
        start = time.time()
        joni.delete()
        end = time.time()

        spans = tracer.pop()
        assert len(spans) == 1
        span = spans[0]
        assert_is_measured(span)
        assert span.resource == 'delete artist {"_id": "?"}'
        assert span.span_type == "mongodb"
        assert span.service == self.TEST_SERVICE
        _assert_timing(span, start, end)
Exemple #17
0
    def test_delete(self):
        # ensure we trace deletes
        tracer, client = self.get_tracer_and_client()

        db = client['testdb']
        collection_name = 'here.are.songs'
        db.drop_collection(collection_name)
        input_songs = [
            {
                'name': 'Powderfinger',
                'artist': 'Neil'
            },
            {
                'name': 'Harvest',
                'artist': 'Neil'
            },
            {
                'name': 'Suzanne',
                'artist': 'Leonard'
            },
            {
                'name': 'Partisan',
                'artist': 'Leonard'
            },
        ]

        songs = db[collection_name]
        songs.insert_many(input_songs)

        # test delete one
        af = {'artist': 'Neil'}
        assert songs.count(af) == 2
        songs.delete_one(af)
        assert songs.count(af) == 1

        # test delete many
        af = {'artist': 'Leonard'}
        assert songs.count(af) == 2
        songs.delete_many(af)
        assert songs.count(af) == 0

        # ensure all is traced.
        spans = tracer.pop()
        assert spans, spans
        for span in spans:
            # ensure all the of the common metadata is set
            assert_is_measured(span)
            assert span.service == self.TEST_SERVICE
            assert span.span_type == 'mongodb'
            assert span.meta.get('mongodb.collection') == collection_name
            assert span.meta.get('mongodb.db') == 'testdb'
            assert span.meta.get('out.host')
            assert span.metrics.get('out.port')

        expected_resources = [
            'drop here.are.songs',
            'count here.are.songs',
            'count here.are.songs',
            'count here.are.songs',
            'count here.are.songs',
            'delete here.are.songs {"artist": "?"}',
            'delete here.are.songs {"artist": "?"}',
            'insert here.are.songs',
        ]

        assert sorted(expected_resources) == sorted(s.resource for s in spans)