Beispiel #1
0
    def test_marshal_trace_context(self):
        trace_id = "123456"
        parent_id = "654321"
        trace_fields = {"i": "like", "to": "trace"}

        trace_context = marshal_trace_context(trace_id, parent_id, trace_fields)

        trace_id_u, parent_id_u, trace_fields_u = unmarshal_trace_context(trace_context)
        self.assertEqual(trace_id_u, trace_id, "unmarshaled trace id should match original")
        self.assertEqual(parent_id_u, parent_id, "unmarshaled parent id should match original")
        self.assertDictEqual(trace_fields_u, trace_fields, "unmarshaled trace fields should match original")
Beispiel #2
0
def _get_trace_data_from_message_attributes(attributes):
    ''' Look for the trace data from SNS/SQS Messsage Atrributes
    '''
    trace_id, parent_id, context = None, None, None

    if isinstance(attributes, dict):
        keymap = {k.lower(): k for k in attributes.keys()}
        if 'x-honeycomb-trace' in keymap:
            if 'Value' in attributes[keymap['x-honeycomb-trace']]:
                # SNS
                trace_id, parent_id, context = unmarshal_trace_context(
                    attributes[keymap['x-honeycomb-trace']]['Value']
                )
            elif 'stringValue' in attributes[keymap['x-honeycomb-trace']]:
                # SQS
                trace_id, parent_id, context = unmarshal_trace_context(
                    attributes[keymap['x-honeycomb-trace']]['stringValue']
                )

    return trace_id, parent_id, context
Beispiel #3
0
def _get_trace_context(request):
    trace_context = request.META.get('HTTP_X_HONEYCOMB_TRACE')
    beeline.internal.log("got trace context: %s", trace_context)
    if trace_context:
        try:
            return unmarshal_trace_context(trace_context)
        except Exception as e:
            beeline.internal.log(
                'error attempting to extract trace context: %s', str(e))

    return None, None, None
    def test_marshal_trace_context_empty_context(self):
        trace_id = "123456"
        parent_id = "654321"
        trace_context = "{};trace_id={},parent_id={}".format(
            1, trace_id, parent_id)

        trace_id_u, parent_id_u, trace_fields_u = unmarshal_trace_context(
            trace_context)
        self.assertEqual(trace_id_u, trace_id,
                         "unmarshaled trace id should match original")
        self.assertEqual(parent_id_u, parent_id,
                         "unmarshaled parent id should match original")
        self.assertDictEqual(trace_fields_u, {},
                             "unmarshaled trace fields should match original")
Beispiel #5
0
def _get_trace_context(environ):
    ''' returns trace_id, parent_id, context '''
    # http://werkzeug.pocoo.org/docs/0.14/wrappers/#base-wrappers
    req = Request(environ, shallow=True)

    trace_context = req.headers.get('x-honeycomb-trace')
    beeline.internal.log("got trace context: %s", trace_context)
    if trace_context:
        try:
            return unmarshal_trace_context(trace_context)
        except Exception as e:
            beeline.internal.log('error attempting to extract trace context: %s', beeline.internal.stringify_exception(e))

    return None, None, None
Beispiel #6
0
def _get_trace_data(event):
    ''' Extract trace/parent ids and context object that are threaded through
    in various ways from other beelines'''
    trace_id, parent_id, context = None, None, None

    # If API gateway is triggering the Lambda, the event will have headers
    # and we can look for our trace headers
    if isinstance(event, dict):
        if 'headers' in event:
            if isinstance(event['headers'], dict):
                # deal with possible case issues
                keymap = {k.lower(): k for k in event['headers'].keys()}
                if 'x-honeycomb-trace' in keymap:
                    trace_id, parent_id, context = unmarshal_trace_context(
                        event['headers'][keymap['x-honeycomb-trace']])

    return trace_id, parent_id, context
Beispiel #7
0
def _get_trace_data(event):
    ''' Extract trace/parent ids and context object that are threaded through
    in various ways from other beelines'''
    trace_id, parent_id, context = None, None, None

    # Look for trace headers in common places
    if isinstance(event, dict):
        # If API gateway is triggering the Lambda, the event will have headers
        # and we can look for our trace headers
        # https://docs.aws.amazon.com/lambda/latest/dg/with-on-demand-https.html
        if 'headers' in event:
            if isinstance(event['headers'], dict):
                # deal with possible case issues
                keymap = {k.lower(): k  for k in event['headers'].keys()}
                if 'x-honeycomb-trace' in keymap:
                    trace_id, parent_id, context = unmarshal_trace_context(
                        event['headers'][keymap['x-honeycomb-trace']]
                    )

        # If a message source is triggering the Lambda, the event may have
        # our trace data in the message attributes
        elif 'Records' in event:
            # Only process batches of exactly 1
            #  Higher batch sizes would have multiple messages thus
            #  generating multiple traces and requiring manual instrumentation
            if len(event['Records']) == 1:
                # If SNS is triggering the Lambda
                # https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html
                if 'EventSource' in event['Records'][0]:
                    if event['Records'][0]['EventSource'] == 'aws:sns':
                        trace_id, parent_id, context = _get_trace_data_from_message_attributes(
                            event['Records'][0]['Sns']['MessageAttributes']
                        )

                # If SQS is triggering the Lambda
                # https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html
                elif 'eventSource' in event['Records'][0]:
                    if event['Records'][0]['eventSource'] == 'aws:sqs':
                        trace_id, parent_id, context = _get_trace_data_from_message_attributes(
                            event['Records'][0]['messageAttributes']
                        )

    return trace_id, parent_id, context
    def test_marshal_trace_context_dataset_included(self):
        """ ensures unmarshalling still works if there's a dataset context field """
        trace_id = "123456"
        parent_id = "654321"
        dataset_id = "foo"
        trace_fields = {"i": "like", "to": "trace"}
        fields_string = base64.b64encode(
            json.dumps(trace_fields).encode()).decode()
        trace_context = "{};trace_id={},parent_id={},dataset_id={},context={}".format(
            1, trace_id, parent_id, dataset_id, fields_string)

        trace_id_u, parent_id_u, trace_fields_u = unmarshal_trace_context(
            trace_context)
        self.assertEqual(trace_id_u, trace_id,
                         "unmarshaled trace id should match original")
        self.assertEqual(parent_id_u, parent_id,
                         "unmarshaled parent id should match original")
        self.assertDictEqual(trace_fields_u, trace_fields,
                             "unmarshaled trace fields should match original")