Esempio n. 1
0
 def handle_error(self, context):
     beeline.add_context_field(
         "db.error",
         beeline.internal.stringify_exception(context.original_exception))
     if self.state.span:
         beeline.finish_span(self.state.span)
     self.state.span = None
def lambda_handler(event, context):

    trace_context = None
    input = None
    parent_trace = None
    output = {}

    logging.debug(f"event: {json.dumps(event)}")
    init_beeline()

    # Attempt to get trace_context(s) from the input
    input = event.get("Input", None)
    if input:
        trace_context = input.get("trace_context", None)

    # Start trace if it isn't already, otherwise resume
    if trace_context:
        trace_id, parent_id, context = beeline.trace.unmarshal_trace_context(
            trace_context)
        logging.info(f"Resuming trace: {trace_id}")
        trace = beeline.start_trace(trace_id=trace_id,
                                    parent_span_id=parent_id,
                                    context=context)
        # add a field to test context propogation
        beeline.add_trace_field(
            event.get("Path", "UnknownPath").lower(), uuid.uuid4())
        beeline.add_context(
            {"name": event.get("Path", "Missing Path Information")})
        beeline.add_context(
            {"function_name": event.get("Path", "Missing Path Information")})

        random_sleep()
        beeline.finish_span(trace)
    else:
        trace = start_trace()
        beeline.add_trace_field("c3po", "r2d2")
        logging.info(f"Starting Trace")
        with beeline.tracer(
                name=event.get("Path", "Missing Path Information")):
            random_sleep()
        trace_context = beeline.get_beeline(
        ).tracer_impl.marshal_trace_context()

    # If final step close the parent trace
    if event.get("Path") == "Step4":
        # 2019-03-26T20:14:13.192Z
        parent_trace_id, parent_parent_id, parent_context_data = beeline.trace.unmarshal_trace_context(
            trace_context)
        start_time = datetime.strptime(event.get("start_time"),
                                       "%Y-%m-%dT%H:%M:%S.%fZ")
        close_final_trace(parent_trace_id, parent_parent_id,
                          parent_context_data, start_time)

    # Close only (send pending)
    beeline.close()

    # Return the trace_context to the SFN
    output["trace_context"] = trace_context
    return output
Esempio n. 3
0
def _render_template(fn, instance, args, kwargs):
    span = beeline.start_span(context={
        "name": "jinja2_render_template",
        "template.name": instance.name or "[string]",
    })

    try:
        return fn(*args, **kwargs)
    finally:
        beeline.finish_span(span)
Esempio n. 4
0
def request(_request, instance, args, kwargs):
    span = beeline.start_span(context={"meta.type": "http_client"})

    b = beeline.get_beeline()
    if b and b.http_trace_propagation_hook is not None:
        new_headers = beeline.http_trace_propagation_hook()
        if new_headers:
            b.log(
                "requests lib - adding trace context to outbound request: %s",
                new_headers)
            instance.headers.update(new_headers)
        else:
            b.log("requests lib - no trace context found")

    try:
        resp = None

        # Required as Python treats the `or` keyword differently in string
        # interpolation vs. when assigning a variable.
        method = kwargs.get('method') or args[0]

        beeline.add_context({
            "name": "requests_%s" % method,
            "request.method": method,
            "request.url": kwargs.get('url') or args[1],
        })
        resp = _request(*args, **kwargs)
        return resp
    except Exception as e:
        beeline.add_context({
            "request.error_type":
            str(type(e)),
            "request.error":
            beeline.internal.stringify_exception(e),
        })
        raise
    finally:
        if resp is not None:
            content_type = resp.headers.get('content-type')
            if content_type:
                beeline.add_context_field("response.content_type",
                                          content_type)
            content_length = resp.headers.get('content-length')
            if content_length:
                beeline.add_context_field("response.content_length",
                                          content_length)
            if hasattr(resp, 'status_code'):
                beeline.add_context_field("response.status_code",
                                          resp.status_code)
        beeline.finish_span(span)
Esempio n. 5
0
    def after_cursor_execute(self, conn, cursor, statement, parameters, context, executemany):
        if not current_app:
            return

        query_duration = datetime.datetime.now() - self.query_start_time

        beeline.add_context({
            "db.duration": query_duration.total_seconds() * 1000,
            "db.last_insert_id": getattr(cursor, 'lastrowid', None),
            "db.rows_affected": cursor.rowcount,
        })
        if self.state.span:
            beeline.finish_span(self.state.span)
        self.state.span = None
Esempio n. 6
0
def request(_request, instance, args, kwargs):
    span = beeline.start_span(context={"meta.type": "http_client"})

    b = beeline.get_beeline()
    if b:
        context = b.tracer_impl.marshal_trace_context()
        if context:
            b.log(
                "requests lib - adding trace context to outbound request: %s",
                context)
            instance.headers['X-Honeycomb-Trace'] = context
        else:
            b.log("requests lib - no trace context found")

    try:
        resp = None
        beeline.add_context({
            "name":
            "requests_%s" % kwargs.get('method') or args[0],
            "request.method":
            kwargs.get('method') or args[0],
            "request.url":
            kwargs.get('url') or args[1],
        })
        resp = _request(*args, **kwargs)
        return resp
    except Exception as e:
        beeline.add_context({
            "request.error_type":
            str(type(e)),
            "request.error":
            beeline.internal.stringify_exception(e),
        })
        raise
    finally:
        if resp:
            content_type = resp.headers.get('content-type')
            if content_type:
                beeline.add_context_field("response.content_type",
                                          content_type)
            content_length = resp.headers.get('content-length')
            if content_length:
                beeline.add_context_field("response.content_length",
                                          content_length)
            if hasattr(resp, 'status_code'):
                beeline.add_context_field("response.status_code",
                                          resp.status_code)
        beeline.finish_span(span)
Esempio n. 7
0
def _urllibopen(_urlopen, instance, args, kwargs):
    # urlopen accepts either a string URL or a Request object as its first arg
    # It's easier to process the info contained in the request and modify it
    # by converting the URL string into a Request
    if type(args[0]) != urllib.request.Request:
        args = (urllib.request.Request(args[0]), ) + tuple(args[1:])

    span = beeline.start_span(context={"meta.type": "http_client"})

    b = beeline.get_beeline()
    if b and b.http_trace_propagation_hook is not None:
        new_headers = beeline.http_trace_propagation_hook()
        if new_headers:
            # Merge the new headers into the existing headers for the outbound request
            b.log("urllib lib - adding trace context to outbound request: %s",
                  new_headers)
            args[0].headers.update(new_headers)

    try:
        resp = None
        beeline.add_context({
            "name": "urllib_%s" % args[0].get_method(),
            "request.method": args[0].get_method(),
            "request.uri": args[0].full_url
        })
        resp = _urlopen(*args, **kwargs)
        return resp
    except Exception as e:
        beeline.add_context({
            "request.error_type":
            str(type(e)),
            "request.error":
            beeline.internal.stringify_exception(e),
        })
        raise
    finally:
        if resp:
            beeline.add_context_field("response.status_code", resp.status)
            content_type = resp.getheader('content-type')
            if content_type:
                beeline.add_context_field("response.content_type",
                                          content_type)
            content_length = resp.getheader('content-length')
            if content_length:
                beeline.add_context_field("response.content_length",
                                          content_length)

        beeline.finish_span(span)
Esempio n. 8
0
def _urllibopen(_urlopen, instance, args, kwargs):
    if type(args[0]) != urllib.request.Request:
        args[0] = urllib.request.Request(args[0])

    span = beeline.start_span(context={"meta.type": "http_client"})

    b = beeline.get_beeline()
    if b:
        context = b.tracer_impl.marshal_trace_context()
        if context:
            b.log("urllib lib - adding trace context to outbound request: %s",
                  context)
            args[0].headers['X-Honeycomb-Trace'] = context
        else:
            b.log("urllib lib - no trace context found")

    try:
        resp = None
        beeline.add_context({
            "name": "urllib_%s" % args[0].get_method(),
            "request.method": args[0].get_method(),
            "request.uri": args[0].full_url
        })
        resp = _urlopen(*args, **kwargs)
        return resp
    except Exception as e:
        beeline.add_context({
            "request.error_type":
            str(type(e)),
            "request.error":
            beeline.internal.stringify_exception(e),
        })
        raise
    finally:
        if resp:
            beeline.add_context_field("response.status_code", resp.status)
            content_type = resp.getheader('content-type')
            if content_type:
                beeline.add_context_field("response.content_type",
                                          content_type)
            content_length = resp.getheader('content-length')
            if content_length:
                beeline.add_context_field("response.content_length",
                                          content_length)

        beeline.finish_span(span)
def random_sleep():
    logging.info("Generating a span")
    span = beeline.start_span(context={"name": "do_assorted_data_processing"})
    time.sleep(random.randint(1, 10))
    beeline.finish_span(span)
Esempio n. 10
0
def hello_world():
    span = beeline.start_span(context={"name": "Preparing to greet the world"})
    message = "Hello World"
    beeline.add_trace_field('message', message)
    beeline.finish_span(span)
    return message