Exemple #1
0
 def create_span(operation_name, app_info={}, span_tags=None):
     try:
         tracer = ThundraTracer().get_instance()
         execution_context = ExecutionContextManager.get()
         parent_transaction_id = execution_context.transaction_id if execution_context.transaction_id else None
         trace_id = execution_context.trace_id if execution_context.trace_id else utils.create_uuid4()
         transaction_id = parent_transaction_id or utils.create_uuid4()
         scope =  tracer.start_active_span(
             span_id=utils.create_uuid4(),
             operation_name=operation_name,
             trace_id=trace_id,
             transaction_id=transaction_id,
             start_time=utils.current_milli_time(),
             execution_context = execution_context
         )
         span = scope.span
         span.domain_name = app_info.get("applicationDomainName")
         span.class_name = app_info.get("applicationClassName")
         span.service_name = app_info.get("applicationName")
         if span_tags:
             for key in span_tags.keys():
                 span.set_tag(key, span_tags[key])
         return scope
     except Exception as e:
         logger.error("Handler_utils create_span error: {}".format(e))
         pass
     return None
Exemple #2
0
def test_whitelist():
    config = {
        'block':
        True,
        "whitelist": [{
            "className": "HTTP",
            "tags": {
                "http.host": ["www.google.com", "www.yahoo.com"],
                "operation.type": ["*"]
            }
        }, {
            "className": "AWS-DynamoDB",
            "tags": {
                "aws.dynamodb.table.name": ["Users"],
                "operation.type":
                ["List", "Read", "Write", "Tagging", "PermissionsManagement"]
            }
        }]
    }

    sasl = SecurityAwareSpanListener.from_config(config)
    error_thrown = None

    # Test whitelisted
    tracer = ThundraTracer.get_instance()
    span = tracer.create_span(operation_name='test')
    span.set_tag("http.host", "www.google.com")
    span.set_tag(constants.SpanTags['TOPOLOGY_VERTEX'], True)
    span.set_tag(constants.SpanTags['OPERATION_TYPE'], "GET")
    span.class_name = "HTTP"
    try:
        sasl.on_span_started(span)
    except Exception as e:
        error_thrown = e

    assert error_thrown == None
    assert span.get_tag(constants.SecurityTags["VIOLATED"]) == None
    assert span.get_tag(constants.SecurityTags["BLOCKED"]) == None

    # Test span out of whitelist
    tracer = ThundraTracer.get_instance()
    span = tracer.create_span(operation_name='test')
    span.set_tag("http.host", "www.test.com")
    span.set_tag(constants.SpanTags['TOPOLOGY_VERTEX'], True)
    span.set_tag(constants.SpanTags['OPERATION_TYPE'], "GET")
    span.class_name = "HTTP"
    try:
        sasl.on_span_started(span)
    except Exception as e:
        error_thrown = e

    assert str(
        error_thrown) == "Operation was blocked due to security configuration"
    assert span.get_tag(constants.SecurityTags["VIOLATED"]) == True
    assert span.get_tag(constants.SecurityTags["BLOCKED"]) == True
Exemple #3
0
def test_postgre_integration_callproc():
    connection = psycopg2.connect(user='******',
                                  host='localhost',
                                  password='******',
                                  dbname='db')

    try:
        cursor = connection.cursor()
        cursor.callproc('multiply', (3, 5))
    except PostgreError:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        postgre_span = tracer.get_spans()[1]

        assert postgre_span.domain_name == constants.DomainNames['DB']
        assert postgre_span.class_name == constants.ClassNames['POSTGRESQL']
        assert postgre_span.operation_name == 'db'
        assert postgre_span.get_tag(constants.SpanTags['OPERATION_TYPE']) is ''
        assert postgre_span.get_tag(constants.SpanTags['DB_INSTANCE']) == 'db'
        assert postgre_span.get_tag(
            constants.SpanTags['DB_HOST']) == 'localhost'
        assert postgre_span.get_tag(
            constants.SpanTags['DB_STATEMENT']) == 'multiply'
        assert postgre_span.get_tag(
            constants.SpanTags['DB_STATEMENT_TYPE']) == 'MULTIPLY'

        tracer.clear()
        connection.close()
Exemple #4
0
def test_trace_return_values(trace_return_val):
    tracer = ThundraTracer.get_instance()
    nodes = tracer.get_spans()
    count = 0
    for key in nodes:
        if key.operation_name == 'func_return_val':
            count += 1

    assert count == 0

    traceable_trace_return_val, func_return_val = trace_return_val
    response = func_return_val()

    active_span = None
    nodes = tracer.get_spans()
    for key in nodes:
        if key.operation_name == 'func_return_val':
            count += 1
            active_span = key

    args = active_span.get_tag('method.args')
    assert args is None

    return_value = active_span.get_tag('method.return_value')
    assert return_value['type'] == type(response).__name__
    assert return_value['value'] == response

    error = active_span.get_tag('error')
    assert error is None

    assert count == 1
    assert traceable_trace_return_val.trace_args is False
    assert traceable_trace_return_val.trace_return_value is True
    assert traceable_trace_return_val.trace_error is True
Exemple #5
0
def test_athena_list_query_executions(mock_actual_call, mock_athena_list_query_executions_response):
    mock_actual_call.return_value = mock_athena_list_query_executions_response
    try:
        client = boto3.client('athena', region_name='us-west-2')
        client.list_query_executions(
            NextToken='string',
            MaxResults=123,
            WorkGroup='string'
        )
    except Exception as e:
        print(e)
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Athena'
        assert span.domain_name == 'DB'
        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'LIST'
        assert span.get_tag(constants.AwsSDKTags['REQUEST_NAME']) == 'ListQueryExecutions'
        assert span.get_tag(constants.SpanTags['DB_INSTANCE']) is None
        assert span.get_tag(constants.AthenaTags['S3_OUTPUT_LOCATION']) is None
        assert span.get_tag(constants.AthenaTags['REQUEST_QUERY_EXECUTION_IDS']) is None
        assert span.get_tag(constants.AthenaTags['RESPONSE_QUERY_EXECUTION_IDS']) == [
            '98765432-1111-1111-1111-12345678910']
        assert span.get_tag(constants.AthenaTags['REQUEST_NAMED_QUERY_IDS']) is None
        assert span.get_tag(constants.AthenaTags['RESPONSE_NAMED_QUERY_IDS']) is None
        assert span.get_tag(constants.DBTags['DB_STATEMENT']) is None
Exemple #6
0
def test_athena_statement_masked():
    ConfigProvider.set(config_names.THUNDRA_TRACE_INTEGRATIONS_AWS_ATHENA_STATEMENT_MASK, 'true')

    database = "test"
    table = "persons"
    query = "SELECT * FROM %s.%s where age = 10;" % (database, table)
    s3_output = 's3://athena-test-bucket/results/'

    try:
        client = boto3.client('athena', region_name='us-west-2')
        client.start_query_execution(
            QueryString=query,
            QueryExecutionContext={
                'Database': database
            },
            ResultConfiguration={
                'OutputLocation': s3_output,
            }
        )
    except:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Athena'
        assert span.domain_name == 'DB'
        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'WRITE'
        assert span.get_tag(constants.AwsSDKTags['REQUEST_NAME']) == 'StartQueryExecution'
        assert span.get_tag(constants.SpanTags['DB_INSTANCE']) == database
        assert span.get_tag(constants.AthenaTags['S3_OUTPUT_LOCATION']) == s3_output
        assert span.get_tag(constants.AthenaTags['REQUEST_QUERY_EXECUTION_IDS']) is None
        assert span.get_tag(constants.DBTags['DB_STATEMENT']) is None
Exemple #7
0
def test_firehose(mock_actual_call, mock_firehose_response):
    mock_actual_call.return_value = mock_firehose_response
    region = 'us-west-2'
    timestamp = 1553695200
    md5 = "098f6bcd4621d373cade4e832627b4f6"
    links = [
        region + ":" + "test-stream" + ":" + str(timestamp) + ":" + md5,
        region + ":" + "test-stream" + ":" + str(timestamp + 1) + ":" + md5,
        region + ":" + "test-stream" + ":" + str(timestamp + 2) + ":" + md5
    ]
    try:
        firehose = boto3.client('firehose', region_name=region)
        firehose.put_record(
            DeliveryStreamName='test-stream',
            Record={
                'Data': 'test'
            }
        )
    except botocore_errors:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Firehose'
        assert span.domain_name == 'Stream'
        assert span.get_tag('operation.type') == 'WRITE'
        assert span.get_tag('aws.firehose.stream.name') == 'test-stream'
        assert span.get_tag('aws.request.name') == 'PutRecord'
        assert sorted(span.get_tag(constants.SpanTags['TRACE_LINKS'])) == sorted(links)
Exemple #8
0
def test_lambda_payload_masked(mock_actual_call, mock_lambda_response, wrap_handler_with_thundra, mock_event,
                               mock_context):
    mock_actual_call.return_value = mock_lambda_response
    ConfigProvider.set(config_names.THUNDRA_TRACE_INTEGRATIONS_AWS_LAMBDA_PAYLOAD_MASK, 'true')

    def handler(event, context):
        lambda_func = boto3.client('lambda', region_name='us-west-2')
        lambda_func.invoke(
            FunctionName='Test',
            InvocationType='RequestResponse',
            Payload=b"{\"name\": \"thundra\"}"
        )

    with mock.patch('thundra.opentracing.recorder.ThundraRecorder.clear'):
        thundra, wrapped_handler = wrap_handler_with_thundra(handler)
        try:
            wrapped_handler(mock_event, mock_context)
        except:
            pass

        # Check span tags
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Lambda'
        assert span.domain_name == 'API'
        assert span.get_tag('aws.lambda.name') == 'Test'
        assert span.get_tag('aws.lambda.qualifier') is None
        assert span.get_tag('aws.lambda.invocation.payload') is None
        assert span.get_tag('aws.request.name') == 'Invoke'
        assert span.get_tag('aws.lambda.invocation.type') == 'RequestResponse'
Exemple #9
0
def test_refresh():
    ConfigProvider.set(
        config_names.THUNDRA_TRACE_INTEGRATIONS_ELASTICSEARCH_PATH_DEPTH, '2')
    try:
        es = Elasticsearch([{'host': 'test', 'port': 3737}], max_retries=0)
        res = es.indices.refresh(index='test-index')
        print(res)
    except ElasticsearchException as e:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.operation_name == '/test-index/_refresh'
        assert span.class_name == constants.ClassNames['ELASTICSEARCH']
        assert span.domain_name == constants.DomainNames['DB']

        assert span.get_tag(
            constants.ESTags['ES_HOSTS']) == ['http://test:3737']
        assert span.get_tag(
            constants.ESTags['ES_URI']) == '/test-index/_refresh'
        assert span.get_tag(constants.ESTags['ES_BODY']) == {}

        assert span.get_tag(constants.DBTags['DB_TYPE']) == 'elasticsearch'

        assert span.get_tag(constants.SpanTags['TOPOLOGY_VERTEX'])
Exemple #10
0
def test_get_doc():
    ConfigProvider.set(
        config_names.THUNDRA_TRACE_INTEGRATIONS_ELASTICSEARCH_PATH_DEPTH, '3')
    try:
        es = Elasticsearch(['one_host', 'another_host'], max_retries=0)
        es.get(index='test-index', doc_type='tweet', id=1)
    except ElasticsearchException as e:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        hosts = span.get_tag(constants.ESTags['ES_HOSTS'])

        assert span.operation_name == '/test-index/tweet/1'
        assert span.class_name == constants.ClassNames['ELASTICSEARCH']
        assert span.domain_name == constants.DomainNames['DB']

        assert len(hosts) == 2
        assert 'http://one_host:9200' in hosts
        assert 'http://another_host:9200' in hosts
        assert span.get_tag(constants.ESTags['ES_METHOD']) == 'GET'
        assert span.get_tag(
            constants.ESTags['ES_URI']) == '/test-index/tweet/1'
        assert span.get_tag(constants.ESTags['ES_BODY']) == {}

        assert span.get_tag(constants.DBTags['DB_TYPE']) == 'elasticsearch'

        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'GET'
        assert span.get_tag(constants.SpanTags['TOPOLOGY_VERTEX'])
Exemple #11
0
def test_via_threadpool():
    numbers = [1, 2, 3, 4, 5]
    squared_numbers = calculate_parallel(numbers, 4)
    expected_result = [1, 4, 9, 16, 25]

    assert squared_numbers == expected_result

    tracer = ThundraTracer.get_instance()
    nodes = tracer.get_spans()
    active_span = None
    for key in nodes:
        if key.operation_name == 'calculate_parallel':
            active_span = key

    args = active_span.get_tag('method.args')
    assert args[0]['name'] == 'arg-0'
    assert args[0]['value'] == numbers
    assert args[0]['type'] == 'list'
    assert args[1]['name'] == 'arg-1'
    assert args[1]['value'] == 4
    assert args[1]['type'] == 'int'

    return_value = active_span.get_tag('method.return_value')
    assert return_value['value'] == squared_numbers
    assert return_value['type'] == 'list'

    error = active_span.get_tag('thrownError')
    assert error is None
Exemple #12
0
def test_via_threading():
    numbers = [1, 2, 3, 4, 5]
    expected_result = [1, 4, 9, 16, 25]

    wrapper = TraceAwareWrapper()
    thread = Thread(target=wrapper(calculate_in_parallel), args=(numbers, ))
    thread.start()
    thread.join()

    tracer = ThundraTracer.get_instance()
    nodes = tracer.get_spans()
    active_span = None
    for key in nodes:
        if key.operation_name == 'calculate_in_parallel':
            active_span = key

    assert active_span is not None
    args = active_span.get_tag('method.args')
    assert args[0]['name'] == 'arg-0'
    assert args[0]['value'] == numbers
    assert args[0]['type'] == 'list'

    return_value = active_span.get_tag('method.return_value')
    assert return_value['value'] == expected_result
    assert return_value['type'] == 'list'

    error = active_span.get_tag('error')
    assert error is None
Exemple #13
0
def test_postgre_integration():
    query = "select 1 + 1 AS solution"

    connection = psycopg2.connect(user='******',
                                  host='localhost',
                                  password='******',
                                  dbname='db')

    try:
        cursor = connection.cursor()
        cursor.execute(query)
        for table in cursor.fetchall():
            print(table)

    finally:
        tracer = ThundraTracer.get_instance()
        postgre_span = tracer.get_spans()[1]

        assert postgre_span.domain_name == constants.DomainNames['DB']
        assert postgre_span.class_name == constants.ClassNames['POSTGRESQL']
        assert postgre_span.operation_name == 'db'
        assert postgre_span.get_tag(
            constants.SpanTags['OPERATION_TYPE']) == 'READ'
        assert postgre_span.get_tag(constants.SpanTags['DB_INSTANCE']) == 'db'
        assert postgre_span.get_tag(
            constants.SpanTags['DB_HOST']) == 'localhost'
        assert postgre_span.get_tag(
            constants.SpanTags['DB_STATEMENT']) == query
        assert postgre_span.get_tag(
            constants.SpanTags['DB_STATEMENT_TYPE']) == 'SELECT'

        connection.close()
Exemple #14
0
def test_postgre_integration_with_empty_query():
    connection = psycopg2.connect(user='******',
                                  host='localhost',
                                  password='******',
                                  dbname='db')

    try:
        cursor = connection.cursor()
        cursor.execute('')
        for table in cursor.fetchall():
            print(table)
    except PostgreError:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        postgre_span = tracer.get_spans()[1]

        assert postgre_span.domain_name == constants.DomainNames['DB']
        assert postgre_span.class_name == constants.ClassNames['POSTGRESQL']
        assert postgre_span.operation_name == 'db'
        assert postgre_span.get_tag(constants.SpanTags['OPERATION_TYPE']) is ''
        assert postgre_span.get_tag(constants.SpanTags['DB_INSTANCE']) == 'db'
        assert postgre_span.get_tag(
            constants.SpanTags['DB_HOST']) == 'localhost'
        assert postgre_span.get_tag(constants.SpanTags['DB_STATEMENT']) == ''
        assert postgre_span.get_tag(
            constants.SpanTags['DB_STATEMENT_TYPE']) == ''

        connection.close()
Exemple #15
0
    def test_command_failed():
        client = MongoClient('localhost', 27017)
        db = client.test

        try:
            for x in db.posts.find({}, {"field1": 1, "field2": 0}):
                print(x)
        except:
            pass

        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.operation_name == 'test'
        assert span.class_name == constants.ClassNames['MONGODB']
        assert span.domain_name == constants.DomainNames['DB']

        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'READ'
        assert span.get_tag(constants.DBTags['DB_HOST']) == 'localhost'
        assert span.get_tag(constants.DBTags['DB_PORT']) == 27017
        assert span.get_tag(constants.DBTags['DB_INSTANCE']) == 'test'
        assert span.get_tag(
            constants.MongoDBTags['MONGODB_COMMAND_NAME']) == 'FIND'

        assert span.get_tag(constants.SpanTags['TOPOLOGY_VERTEX'])

        assert span.get_tag('error') is True

        tracer.clear()
Exemple #16
0
def test_create_index():
    ConfigProvider.set(
        config_names.THUNDRA_TRACE_INTEGRATIONS_ELASTICSEARCH_PATH_DEPTH, '3')
    author1 = {"name": "Sidney Sheldon", "novels_count": 18}
    try:
        es = Elasticsearch([{'host': 'test', 'port': 3737}], max_retries=0)
        es.index(index='authors', doc_type='authors', body=author1, id=1)
    except ElasticsearchException as e:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.operation_name == '/authors/authors/1'
        assert span.class_name == constants.ClassNames['ELASTICSEARCH']
        assert span.domain_name == constants.DomainNames['DB']

        assert span.get_tag(
            constants.ESTags['ES_HOSTS']) == ['http://test:3737']
        assert span.get_tag(constants.ESTags['ES_URI']) == '/authors/authors/1'
        assert span.get_tag(constants.ESTags['ES_BODY']) == author1

        assert span.get_tag(constants.DBTags['DB_TYPE']) == 'elasticsearch'

        assert span.get_tag(constants.SpanTags['TOPOLOGY_VERTEX'])
Exemple #17
0
def test_dynamodb_put_item_resource():
    ConfigProvider.set(config_names.THUNDRA_TRACE_INTEGRATIONS_AWS_DYNAMODB_TRACEINJECTION_ENABLE, 'true')
    item = {
        'id': '3',
        'text': 'test'
    }
    try:
        dynamodb = boto3.resource('dynamodb', region_name='eu-west-2')
        table = dynamodb.Table('test-table')
        table.put_item(
            TableName="test-table",
            Item=item,
        )
    except botocore_errors:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-DynamoDB'
        assert span.domain_name == 'DB'
        assert span.operation_name == 'test-table'
        assert span.get_tag("operation.type") == 'WRITE'
        assert span.get_tag("db.instance") == 'dynamodb.eu-west-2.amazonaws.com'
        assert span.get_tag('db.statement') == item
        assert span.get_tag('db.statement.type') == 'WRITE'
        assert span.get_tag('db.type') == 'aws-dynamodb'
        assert span.get_tag('aws.dynamodb.table.name') == 'test-table'

        assert span.get_tag(constants.SpanTags['TRACE_LINKS']) == ["SAVE:" + span.span_id]
Exemple #18
0
    def __init__(self,
                 trace_args=None, trace_return_value=None, trace_error=True,
                 trace_line_by_line=False, trace_lines_with_source=None, trace_local_variables=None):
        self._trace_args = trace_args
        if trace_args is None:
            self._trace_args = False

        self._trace_return_value = trace_return_value
        if trace_return_value is None:
            self._trace_return_value = False

        self._trace_lines_with_source = trace_lines_with_source
        if trace_lines_with_source is None:
            self._trace_lines_with_source = False

        self._trace_local_variables = trace_local_variables
        if trace_local_variables is None:
            self._trace_local_variables = False

        self._trace_error = trace_error
        self._trace_line_by_line = trace_line_by_line

        if trace_line_by_line:
            if trace_lines_with_source is None:
                self._trace_lines_with_source = True
            if trace_return_value is None:
                self._trace_return_value = True
            if trace_local_variables is None:
                self._trace_local_variables = True
            if trace_args is None:
                self._trace_args = True

        self._tracing = False
        self._tracer = ThundraTracer.get_instance()
Exemple #19
0
def test_kinesis(mock_actual_call, mock_kinesis_response):
    mock_actual_call.return_value = mock_kinesis_response

    region = 'us-west-2'
    shard_id = 'shardId--000000000000'
    sequence_number = '49568167373333333333333333333333333333333333333333333333'

    try:
        kinesis = boto3.client('kinesis', region_name=region)
        kinesis.put_record(
            Data='STRING_VALUE',
            PartitionKey='STRING_VALUE',
            StreamName='STRING_VALUE',
            ExplicitHashKey='STRING_VALUE',
            SequenceNumberForOrdering='STRING_VALUE'
        )
    except botocore_errors:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Kinesis'
        assert span.domain_name == 'Stream'
        assert span.get_tag('operation.type') == 'WRITE'
        assert span.get_tag('aws.kinesis.stream.name') == 'STRING_VALUE'
        assert span.get_tag('aws.request.name') == 'PutRecord'
        assert span.get_tag(constants.SpanTags['TRACE_LINKS']) == [
            region + ':' + 'STRING_VALUE:' + shard_id + ':' + sequence_number]
Exemple #20
0
def test_sqlalchemy_session_pqsql():
    engine = set_up_engine_and_table(
        'postgresql://*****:*****@localhost:5432/db')

    # create a configured "Session" class
    Session = sessionmaker(bind=engine)

    # create a Session
    session = Session()

    # create Movies
    pulp_fiction = Movie("Pulp Fiction", date(1995, 4, 14))

    session.add(pulp_fiction)
    session.commit()
    session.close()

    tracer = ThundraTracer.get_instance()
    span = tracer.get_spans()[0]

    statement = "INSERT INTO movies (title, release_date) VALUES (%(title)s, %(release_date)s) RETURNING movies.id"

    assert span.domain_name == constants.DomainNames['DB']
    assert span.class_name == constants.ClassNames['POSTGRESQL']
    assert span.operation_name == 'db'
    assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'WRITE'
    assert span.get_tag(constants.SpanTags['DB_INSTANCE']) == 'db'
    assert span.get_tag(constants.SpanTags['DB_TYPE']) == "postgresql"
    assert span.get_tag(constants.SpanTags['DB_HOST']) == 'localhost'
    assert span.get_tag(constants.SpanTags['DB_STATEMENT']) == statement
    assert span.get_tag(constants.SpanTags['DB_STATEMENT_TYPE']) == 'INSERT'
Exemple #21
0
def test_athena_start_query_execution(mock_actual_call, mock_athena_start_query_exec_response):
    mock_actual_call.return_value = mock_athena_start_query_exec_response

    database = "test"
    table = "persons"
    query = "SELECT * FROM %s.%s where age = 10;" % (database, table)
    s3_output = 's3://athena-test-bucket/results/'

    try:
        client = boto3.client('athena', region_name='us-west-2')
        client.start_query_execution(
            QueryString=query,
            QueryExecutionContext={
                'Database': database
            },
            ResultConfiguration={
                'OutputLocation': s3_output,
            }
        )
    except:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Athena'
        assert span.domain_name == 'DB'
        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'WRITE'
        assert span.get_tag(constants.AwsSDKTags['REQUEST_NAME']) == 'StartQueryExecution'
        assert span.get_tag(constants.SpanTags['DB_INSTANCE']) == database
        assert span.get_tag(constants.AthenaTags['S3_OUTPUT_LOCATION']) == s3_output
        assert span.get_tag(constants.AthenaTags['REQUEST_QUERY_EXECUTION_IDS']) is None
        assert span.get_tag(constants.AthenaTags['RESPONSE_QUERY_EXECUTION_IDS']) == [
            "98765432-1111-1111-1111-12345678910"]
        assert span.get_tag(constants.DBTags['DB_STATEMENT']) == query
Exemple #22
0
    def _before_cursor_execute(self, conn, cursor, statement, parameters,
                               context, executemany):
        if not context:
            return
        tracer = ThundraTracer.get_instance()

        if not tracer.get_active_span():
            return
        scope = tracer.start_active_span(
            operation_name=self.get_operation_name(conn),
            finish_on_close=False)

        context.scope = scope

        # Inject before span tags
        try:
            self.before_call(scope, conn, statement)
        except Exception as instrumentation_exception:
            e = {
                'type': str(type(instrumentation_exception)),
                'message': str(instrumentation_exception),
                'traceback': traceback.format_exc(),
                'time': time.time()
            }
            scope.span.set_tag('instrumentation_error', e)

        try:
            # Inform span that initialization completed
            scope.span.on_started()
        except Exception as e:
            logger.error(e)
Exemple #23
0
def test_athena_create_named_query(mock_actual_call, mock_athena_create_named_query_response):
    mock_actual_call.return_value = mock_athena_create_named_query_response
    query = "SELECT * FROM persons where age = 10;"

    try:
        client = boto3.client('athena', region_name='us-west-2')
        client.create_named_query(
            QueryString=query,
            Database="test",
            Name="test",
        )
    except Exception as e:
        print(e)
    finally:
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.class_name == 'AWS-Athena'
        assert span.domain_name == 'DB'
        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'WRITE'
        assert span.get_tag(constants.AwsSDKTags['REQUEST_NAME']) == 'CreateNamedQuery'
        assert span.get_tag(constants.SpanTags['DB_INSTANCE']) is None
        assert span.get_tag(constants.AthenaTags['S3_OUTPUT_LOCATION']) is None
        assert span.get_tag(constants.AthenaTags['REQUEST_QUERY_EXECUTION_IDS']) is None
        assert span.get_tag(constants.AthenaTags['RESPONSE_QUERY_EXECUTION_IDS']) is None
        assert span.get_tag(constants.AthenaTags['REQUEST_NAMED_QUERY_IDS']) is None
        assert span.get_tag(constants.AthenaTags['RESPONSE_NAMED_QUERY_IDS']) == ["98765432-1111-1111-1111-12345678910"]
        assert span.get_tag(constants.DBTags['DB_STATEMENT']) == query
Exemple #24
0
def test_mysql_integration_callproc():
    connection = mysql.connector.connect(user='******',
                                         host='localhost',
                                         password='******',
                                         database='db',
                                         auth_plugin='mysql_native_password')

    try:
        cursor = connection.cursor()
        cursor.callproc('multiply')
    except MySQLError:
        pass
    finally:
        tracer = ThundraTracer.get_instance()
        mysql_span = tracer.get_spans()[1]

        assert mysql_span.domain_name == constants.DomainNames['DB']
        assert mysql_span.class_name == constants.ClassNames['MYSQL']
        assert mysql_span.operation_name == 'db'
        assert mysql_span.get_tag(constants.SpanTags['OPERATION_TYPE']) == ''
        assert mysql_span.get_tag(constants.SpanTags['DB_INSTANCE']) == 'db'
        assert mysql_span.get_tag(constants.SpanTags['DB_HOST']) == 'localhost'
        assert mysql_span.get_tag(
            constants.SpanTags['DB_STATEMENT']) == 'multiply'
        assert mysql_span.get_tag(
            constants.SpanTags['DB_STATEMENT_TYPE']) == 'MULTIPLY'

        connection.close()
Exemple #25
0
def test_trace_with_default_configs(trace):
    tracer = ThundraTracer.get_instance()
    nodes = tracer.get_spans()
    count = 0
    for key in nodes:
        if key.operation_name == 'func':
            count += 1

    assert count == 0

    traceable, func = trace
    func(arg='test')

    active_span = None
    nodes = tracer.get_spans()
    for key in nodes:
        if key.operation_name == 'func':
            count += 1
            active_span = key

    args = active_span.get_tag('method.args')
    assert args is None

    return_value = active_span.get_tag('method.return_value')
    assert return_value is None

    error = active_span.get_tag('error')
    assert error is None

    assert count == 1
    assert traceable.trace_args is False
    assert traceable.trace_return_value is False
    assert traceable.trace_error is True
Exemple #26
0
def test_mysql_integration():
    query = "SELECT 1 + 1 AS solution"
    connection = mysql.connector.connect(user='******',
                                         host='localhost',
                                         password='******',
                                         database='db',
                                         auth_plugin='mysql_native_password')

    try:
        cursor = connection.cursor()
        cursor.execute(query)
        for table in cursor.fetchall():
            print(table)

    finally:
        tracer = ThundraTracer.get_instance()
        mysql_span = tracer.get_spans()[1]

        assert mysql_span.domain_name == constants.DomainNames['DB']
        assert mysql_span.class_name == constants.ClassNames['MYSQL']
        assert mysql_span.operation_name == 'db'
        assert mysql_span.get_tag(
            constants.SpanTags['OPERATION_TYPE']) == 'READ'
        assert mysql_span.get_tag(constants.SpanTags['DB_INSTANCE']) == 'db'
        assert mysql_span.get_tag(constants.SpanTags['DB_HOST']) == 'localhost'
        assert mysql_span.get_tag(constants.SpanTags['DB_STATEMENT']) == query
        assert mysql_span.get_tag(
            constants.SpanTags['DB_STATEMENT_TYPE']) == 'SELECT'

        connection.close()
Exemple #27
0
def test_trace_error(trace_error):
    tracer = ThundraTracer.get_instance()
    nodes = tracer.get_spans()
    count = 0
    for key in nodes:
        if key.operation_name == 'func_with_error':
            count += 1

    assert count == 0

    traceable, func_with_error = trace_error
    try:
        func_with_error()
    except:
        active_span = None
        nodes = tracer.get_spans()
        for key in nodes:
            if key.operation_name == 'func_with_error':
                count += 1
                active_span = key

        args = active_span.get_tag('method.args')
        assert args is None

        return_value = active_span.get_tag('method.return_value')
        assert return_value is None

        thrown_error = active_span.get_tag('error.kind')
        assert thrown_error == 'Exception'

        assert count == 1
        assert traceable.trace_args is False
        assert traceable.trace_return_value is False
        assert traceable.trace_error is True
Exemple #28
0
    def test_command_insert():
        client = MongoClient('localhost', 27017)
        db = client.test

        post = {
            "author": "Mike",
            "text": "My first blog post!",
            "tags": ["mongodb", "python", "pymongo"]
        }

        db.posts.insert_one(post)
        tracer = ThundraTracer.get_instance()
        span = tracer.get_spans()[1]

        assert span.operation_name == 'test'
        assert span.class_name == constants.ClassNames['MONGODB']
        assert span.domain_name == constants.DomainNames['DB']

        assert span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'WRITE'
        assert span.get_tag(constants.DBTags['DB_HOST']) == 'localhost'
        assert span.get_tag(constants.DBTags['DB_PORT']) == 27017
        assert span.get_tag(constants.DBTags['DB_INSTANCE']) == 'test'
        assert span.get_tag(
            constants.MongoDBTags['MONGODB_COMMAND_NAME']) == 'INSERT'

        assert span.get_tag(constants.SpanTags['TOPOLOGY_VERTEX'])

        mongo_command = loads(
            span.get_tag(constants.MongoDBTags['MONGODB_COMMAND']))
        assert mongo_command.get('documents')[0].get(
            'text') == "My first blog post!"
Exemple #29
0
def test_operation_name():
    config = {
        'block':
        False,
        "blacklist": [{
            "className": "HTTP",
            "operationName": ["www.google.com/test"],
            "tags": {
                "http.host": ["www.google.com"],
                "operation.type": [
                    "GET",
                    "POST",
                    "PUT",
                ]
            }
        }]
    }

    sasl = SecurityAwareSpanListener.from_config(config)
    error_thrown = None

    tracer = ThundraTracer.get_instance()
    span = tracer.create_span(operation_name='www.google.com/test')
    span.set_tag("http.host", "www.google.com")
    span.set_tag(constants.SpanTags['TOPOLOGY_VERTEX'], True)
    span.set_tag(constants.SpanTags['OPERATION_TYPE'], "GET")
    span.class_name = "HTTP"

    try:
        sasl.on_span_started(span)
    except Exception as e:
        error_thrown = e

    assert error_thrown == None
    assert span.get_tag(constants.SecurityTags["VIOLATED"]) == True
Exemple #30
0
def test_http_put_body_masked():
    try:
        ConfigProvider.set(
            config_names.THUNDRA_TRACE_INTEGRATIONS_HTTP_BODY_MASK, 'true')
        url = 'https://jsonplaceholder.typicode.com/users/3'
        parsed_url = urlparse(url)
        path = parsed_url.path
        normalized_path = "/users"
        query = parsed_url.query
        host = parsed_url.netloc

        requests.put(url, data={"message": "test"})
        tracer = ThundraTracer.get_instance()
        http_span = tracer.get_spans()[1]

        assert http_span.operation_name == host + normalized_path
        assert http_span.domain_name == constants.DomainNames['API']
        assert http_span.class_name == constants.ClassNames['HTTP']

        assert http_span.get_tag(constants.SpanTags['OPERATION_TYPE']) == 'PUT'
        assert http_span.get_tag(constants.HttpTags['HTTP_METHOD']) == 'PUT'
        assert http_span.get_tag(constants.HttpTags['HTTP_URL']) == host + path
        assert http_span.get_tag(constants.HttpTags['HTTP_HOST']) == host
        assert http_span.get_tag(constants.HttpTags['HTTP_PATH']) == path
        assert http_span.get_tag(constants.HttpTags['QUERY_PARAMS']) == query
        assert http_span.get_tag(constants.HttpTags['BODY']) is None
    except Exception:
        raise
    finally:
        tracer.clear()