From 0d36c0c0fb01ed4df89e1d1698bf37cd6b4b3f4f Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:30:51 +0100 Subject: [PATCH 01/25] Manually update init keys to avoid overwriting via update --- instana/span.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/instana/span.py b/instana/span.py index af14b3ba..83222aee 100644 --- a/instana/span.py +++ b/instana/span.py @@ -8,11 +8,12 @@ class InstanaSpan(object): n = None f = None ec = 0 - error = False + error = None data = None def __init__(self, **kwds): - self.__dict__.update(kwds) + for key in kwds: + self.__dict__[key] = kwds[key] class Data(object): From 8df3cec32da08d77fca3489df68ef0b1719618ab Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:31:07 +0100 Subject: [PATCH 02/25] Add urllib3 as a registered span --- instana/recorder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instana/recorder.py b/instana/recorder.py index a48b26a9..ca120ded 100644 --- a/instana/recorder.py +++ b/instana/recorder.py @@ -16,7 +16,7 @@ class InstanaRecorder(SpanRecorder): sensor = None - registered_spans = ("django", "memcache", "rpc-client", "rpc-server", "wsgi") + registered_spans = ("django", "memcache", "rpc-client", "rpc-server", "urllib3", "wsgi") entry_kind = ["entry", "server", "consumer"] exit_kind = ["exit", "client", "producer"] queue = queue.Queue() From 0884e7c5260e2c9bc0ca46ee6a03a3eb172fbdbf Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:32:07 +0100 Subject: [PATCH 03/25] Boot background flask app to test against. --- tests/__init__.py | 14 ++++++++++++++ tests/apps/__init__.py | 0 tests/apps/flaskalino.py | 15 +++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 tests/apps/__init__.py create mode 100644 tests/apps/flaskalino.py diff --git a/tests/__init__.py b/tests/__init__.py index e95723bf..87d192cf 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,6 +1,20 @@ +from __future__ import absolute_import import os +import time +import threading import opentracing import instana.tracer +from .apps.flaskalino import app as flaskalino os.environ["INSTANA_TEST"] = "true" opentracing.global_tracer = instana.tracer.InstanaTracer() + +# Spawn our background Flask app that the tests will throw +# requests at. Don't continue until the test app is fully +# up and running. +timer = threading.Thread(target=flaskalino.run) +timer.daemon = True +timer.name = "Test Flask app" +print("Starting background test app") +timer.start() +time.sleep(1) diff --git a/tests/apps/__init__.py b/tests/apps/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/apps/flaskalino.py b/tests/apps/flaskalino.py new file mode 100644 index 00000000..0bc37dd2 --- /dev/null +++ b/tests/apps/flaskalino.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from flask import Flask +app = Flask(__name__) +app.debug = False +app.use_reloader = False + + +@app.route("/") +def hello(): + return "

🐍 Hello Stan! 🦄

" + + +if __name__ == '__main__': + app.run() From e8aa850b13724501faae8c9453f56e70edbaf1de Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:32:31 +0100 Subject: [PATCH 04/25] Add nosetests json file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c3e3ec75..a8dcd608 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ htmlcov/ .coverage.* .cache nosetests.xml +nosetests.json coverage.xml *,cover .hypothesis/ From c0df08b6e4f45a8cf3eea54024971d9d6b1e1f2c Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:34:30 +0100 Subject: [PATCH 05/25] Add instrumentation dir with urllib3 instrumentation --- instana/instrumentation/__init__.py | 0 instana/instrumentation/urllib3.py | 30 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 instana/instrumentation/__init__.py create mode 100644 instana/instrumentation/urllib3.py diff --git a/instana/instrumentation/__init__.py b/instana/instrumentation/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/instana/instrumentation/urllib3.py b/instana/instrumentation/urllib3.py new file mode 100644 index 00000000..9c872f68 --- /dev/null +++ b/instana/instrumentation/urllib3.py @@ -0,0 +1,30 @@ +import opentracing.ext.tags as ext +import opentracing +import wrapt + + +@wrapt.patch_function_wrapper('urllib3', 'PoolManager.urlopen') +def urlopen_with_instana(wrapped, instance, args, kwargs): + try: + span = opentracing.global_tracer.start_span("urllib3") + span.set_tag(ext.HTTP_URL, args[1]) + span.set_tag(ext.HTTP_METHOD, args[0]) + + opentracing.global_tracer.inject(span.context, opentracing.Format.HTTP_HEADERS, kwargs["headers"]) + + rv = wrapped(*args, **kwargs) + span.set_tag(ext.HTTP_STATUS_CODE, rv.status) + if 500 <= rv.status <= 511: + span.set_tag("error", True) + ec = span.tags.get('ec', 0) + span.set_tag("ec", ec+1) + + except Exception as e: + print("found error:", e) + span.set_tag("error", True) + ec = span.tags.get('ec', 0) + span.set_tag("ec", ec+1) + raise + else: + span.finish() + return rv From 7bf23a7d23f5e3ba14be93cbcc7b3aac8ae38e5c Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:35:02 +0100 Subject: [PATCH 06/25] Urllib3 instrumentation tests --- tests/test_urllib3.py | 62 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 tests/test_urllib3.py diff --git a/tests/test_urllib3.py b/tests/test_urllib3.py new file mode 100644 index 00000000..72d7d733 --- /dev/null +++ b/tests/test_urllib3.py @@ -0,0 +1,62 @@ +from __future__ import absolute_import +from nose.tools import assert_equals +import opentracing +import instana.instrumentation.urllib3 +import urllib3 + + +class TestUrllib3: + def setUp(self): + """ Clear all spans before a test run """ + self.http = urllib3.PoolManager() + self.recorder = opentracing.global_tracer.recorder + self.recorder.clear_spans() + + def tearDown(self): + """ Do nothing for now """ + return None + + def test_vanilla_requests(self): + r = self.http.request('GET', 'http://127.0.0.1:5000/') + assert_equals(r.status, 200) + + def test_get_request(self): + span = opentracing.global_tracer.start_span("test") + r = self.http.request('GET', 'http://127.0.0.1:5000/') + span.finish() + + spans = self.recorder.queued_spans() + first_span = spans[1] + second_span = spans[0] + + assert(r) + assert_equals(200, r.status) + assert_equals(2, len(spans)) + assert_equals("test", first_span.data.sdk.name) + assert_equals("urllib3", second_span.n) + assert_equals(200, second_span.data.http.status) + assert_equals("http://127.0.0.1:5000/", second_span.data.http.url) + assert_equals("GET", second_span.data.http.method) + + assert_equals(None, second_span.error) + assert_equals(None, second_span.ec) + + def test_put_request(self): + span = opentracing.global_tracer.start_span("test") + r = self.http.request('PUT', 'http://127.0.0.1:5000/notfound') + span.finish() + + spans = self.recorder.queued_spans() + first_span = spans[1] + second_span = spans[0] + + assert(r) + assert_equals(404, r.status) + assert_equals(2, len(spans)) + assert_equals("test", first_span.data.sdk.name) + assert_equals("urllib3", second_span.n) + assert_equals(404, second_span.data.http.status) + assert_equals("http://127.0.0.1:5000/notfound", second_span.data.http.url) + assert_equals("PUT", second_span.data.http.method) + assert_equals(None, second_span.error) + assert_equals(None, second_span.ec) From fbe7f0c20131bde66a38007457976191afeb5730 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:43:18 +0100 Subject: [PATCH 07/25] Add Flask as a dependency --- requirements.txt | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 184d47f4..5ac57bc5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ fysom>=2.1.2 opentracing>=1.2.1 basictracer>=2.2.0 autowrapt>=1.0 +flask>=0.12.2 diff --git a/setup.py b/setup.py index 8e81250e..e256cad5 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ packages=find_packages(exclude=['tests', 'examples']), long_description="The instana package provides Python metrics and traces for Instana.", zip_safe=False, - setup_requires=['nose>=1.0'], + setup_requires=['nose>=1.0', 'flask>=0.12.2'], install_requires=['autowrapt>=1.0', 'fysom>=2.1.2', 'opentracing>=1.2.1,<1.3', From 7643103a581c81e0418deb522ae5d39731d3dba4 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 18:58:26 +0100 Subject: [PATCH 08/25] Separate out test requirements from production --- .travis.yml | 2 +- requirements.txt | 2 -- test_requirements.txt | 7 +++++++ 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 test_requirements.txt diff --git a/.travis.yml b/.travis.yml index a15ec293..ae6c37a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,5 @@ python: - "3.4" - "3.5" - "3.6" -install: "pip install -r requirements.txt" +install: "pip install -r test_requirements.txt" script: nosetests -v diff --git a/requirements.txt b/requirements.txt index 5ac57bc5..56514551 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,4 @@ -nose>=1.0 fysom>=2.1.2 opentracing>=1.2.1 basictracer>=2.2.0 autowrapt>=1.0 -flask>=0.12.2 diff --git a/test_requirements.txt b/test_requirements.txt new file mode 100644 index 00000000..ddef682d --- /dev/null +++ b/test_requirements.txt @@ -0,0 +1,7 @@ +nose>=1.0 +fysom>=2.1.2 +opentracing>=1.2.1 +basictracer>=2.2.0 +autowrapt>=1.0 +flask>=0.12.2 +urllib3>=1.9 From ee6012f0568a903e532ce76e6dce6858bf88e412 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 23:17:59 +0100 Subject: [PATCH 09/25] Updated package initialization; automatic tracer instantiation --- instana/__init__.py | 43 +++++++++++++++++++++++++++++++++++++++---- instana/tracer.py | 14 ++------------ tests/__init__.py | 4 ---- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/instana/__init__.py b/instana/__init__.py index 266ecf86..6ce3cdec 100644 --- a/instana/__init__.py +++ b/instana/__init__.py @@ -1,8 +1,17 @@ +from __future__ import absolute_import +import opentracing +from .sensor import Sensor +from .tracer import InstanaTracer +from .options import Options + """ -Instana sensor and tracer. It consists of two modules that can be used as entry points: +The Instana package has two core components: the sensor and the tracer. + +The sensor is individual to each python process and handles process metric +collection and reporting. -- sensor: activates the meter to collect and transmit all kind of built-in metrics -- tracer: OpenTracing tracer implementation. It implicitly activates the meter +The tracer upholds the OpenTracing API and is responsible for reporting +span data to Instana. """ __author__ = 'Instana Inc.' @@ -13,4 +22,30 @@ __maintainer__ = 'Peter Giacomo Lombardo' __email__ = 'peter.lombardo@instana.com' -__all__ = ['sensor', 'tracer'] +# For any given Python process, we only want one sensor as multiple would +# collect/report metrics in duplicate, triplicate etc.. +# +# Usage example: +# +# import instana +# instana.global_sensor +# +global_sensor = Sensor(Options()) + +# The global OpenTracing compatible tracer used internally by +# this package. +# +# Usage example: +# +# import instana +# instana.internal_tracer.start_span(...) +# +internal_tracer = InstanaTracer() + +# Set ourselves as the tracer. +opentracing.tracer = internal_tracer + + +def load_instrumentation(): + # Import & initialize instrumentation + from .instrumentation import urllib3 diff --git a/instana/tracer.py b/instana/tracer.py index ab5650be..a8f96ca2 100644 --- a/instana/tracer.py +++ b/instana/tracer.py @@ -2,8 +2,8 @@ from basictracer import BasicTracer import instana.recorder as r import opentracing as ot +import instana import instana.options as o -import instana.sensor as s from basictracer.context import SpanContext from basictracer.span import BasicSpan @@ -11,22 +11,12 @@ from instana.text_propagator import TextPropagator from instana.util import generate_id -# In case a user or app creates multiple tracers, we limit to just -# one sensor per process otherwise metrics collection is duplicated, -# triplicated etc. -gSensor = None - class InstanaTracer(BasicTracer): sensor = None def __init__(self, options=o.Options()): - global gSensor - if gSensor is None: - self.sensor = s.Sensor(options) - gSensor = self.sensor - else: - self.sensor = gSensor + self.sensor = instana.global_sensor super(InstanaTracer, self).__init__( r.InstanaRecorder(self.sensor), r.InstanaSampler()) diff --git a/tests/__init__.py b/tests/__init__.py index 87d192cf..ebd8b01a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -2,13 +2,9 @@ import os import time import threading -import opentracing -import instana.tracer from .apps.flaskalino import app as flaskalino os.environ["INSTANA_TEST"] = "true" -opentracing.global_tracer = instana.tracer.InstanaTracer() - # Spawn our background Flask app that the tests will throw # requests at. Don't continue until the test app is fully # up and running. From 581099d7d933a8dd87a9ca8800741df173e46327 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 23:32:37 +0100 Subject: [PATCH 10/25] Update to follow changes; fill out configuration doc --- Configuration.md | 22 +++++++++++++++++++++- README.md | 24 +++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Configuration.md b/Configuration.md index a0990367..af7dc4d4 100644 --- a/Configuration.md +++ b/Configuration.md @@ -1 +1,21 @@ -TBD +# Configuration + +## Agent Communication + +The sensor tries to communicate with the Instana agent via IP 127.0.0.1 and as a fallback via the host's default gateway for containerized environments. Should the agent not be available under either of these IPs, e.g. due to iptables or other networking tricks, you can use environment variables to configure where the Instana host agent lives. + +To use these, these environment variables should be set in the environment of the running Python process. + +```shell +export INSTANA_AGENT_IP = '127.0.0.1' +export INSTANA_AGENT_PORT = '42699' +``` + +## Debugging & More Verbosity + +Setting `INSTANA_GEM_DEV` to a non nil value will enable extra logging output generally useful +for development. + +```Python +export INSTANA_DEV="true" +``` diff --git a/README.md b/README.md index 0c7225e1..07486922 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ _Note: When the Django or Flask instrumentation is used, runtime monitoring is a To enable runtime monitoring (without request tracing), set the following environment variable in your _application boot environment_ and then restart your application: `export AUTOWRAPT_BOOTSTRAP=runtime` - + ## uWSGI ### Threads @@ -57,9 +57,27 @@ If you use uWSGI in forking workers mode, you must specify `--lazy-apps` (or `la The instana package will automatically collect key metrics from your Python processes. Just install and go. -## Tracing +## OpenTracing + +This Python package supports [OpenTracing](http://opentracing.io/). When using this package, the OpenTracing tracer (`opentracing.tracer`) is automatically set to the `InstanaTracer`. + +```Python +import opentracing + +parent_span = opentracing.tracer.start_span(operation_name="asteroid") +# ... work +child_span = ot.tracer.start_span(operation_name="spacedust", child_of=parent_span) +child_span.set_tag(ext.SPAN_KIND, ext.SPAN_KIND_RPC_CLIENT) +# ... work +child_span.finish() +# ... work +parent_span.finish() +``` + +## Configuration + +See [Configuration.md](https://github.com/instana/python-sensor/blob/master/Configuration.md) -This Python package supports [OpenTracing](http://opentracing.io/). ## Documentation From 1820acb799bb966fcdc0fcb51baa2199e68eb408 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 23:51:07 +0100 Subject: [PATCH 11/25] Load instrumentation directly --- instana/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/instana/__init__.py b/instana/__init__.py index 6ce3cdec..490bc190 100644 --- a/instana/__init__.py +++ b/instana/__init__.py @@ -4,6 +4,9 @@ from .tracer import InstanaTracer from .options import Options +# Import & initialize instrumentation +from .instrumentation import urllib3 + """ The Instana package has two core components: the sensor and the tracer. @@ -44,8 +47,3 @@ # Set ourselves as the tracer. opentracing.tracer = internal_tracer - - -def load_instrumentation(): - # Import & initialize instrumentation - from .instrumentation import urllib3 From 1f193997c2309f363794fd05647541fbf3ecc3a1 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 22 Dec 2017 23:52:11 +0100 Subject: [PATCH 12/25] Better named import --- tests/test_urllib3.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_urllib3.py b/tests/test_urllib3.py index 72d7d733..78bb8ebe 100644 --- a/tests/test_urllib3.py +++ b/tests/test_urllib3.py @@ -1,7 +1,6 @@ from __future__ import absolute_import from nose.tools import assert_equals -import opentracing -import instana.instrumentation.urllib3 +from instana import internal_tracer as tracer import urllib3 @@ -9,7 +8,7 @@ class TestUrllib3: def setUp(self): """ Clear all spans before a test run """ self.http = urllib3.PoolManager() - self.recorder = opentracing.global_tracer.recorder + self.recorder = tracer.recorder self.recorder.clear_spans() def tearDown(self): @@ -21,7 +20,7 @@ def test_vanilla_requests(self): assert_equals(r.status, 200) def test_get_request(self): - span = opentracing.global_tracer.start_span("test") + span = tracer.start_span("test") r = self.http.request('GET', 'http://127.0.0.1:5000/') span.finish() @@ -42,7 +41,7 @@ def test_get_request(self): assert_equals(None, second_span.ec) def test_put_request(self): - span = opentracing.global_tracer.start_span("test") + span = tracer.start_span("test") r = self.http.request('PUT', 'http://127.0.0.1:5000/notfound') span.finish() From 697d56dcd4aae19e6cb2351eb39a5c195f8ed029 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sat, 23 Dec 2017 09:56:41 +0100 Subject: [PATCH 13/25] Expand 5xx coverage; log exceptions --- instana/instrumentation/urllib3.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/instana/instrumentation/urllib3.py b/instana/instrumentation/urllib3.py index 9c872f68..a8a0a8a2 100644 --- a/instana/instrumentation/urllib3.py +++ b/instana/instrumentation/urllib3.py @@ -1,4 +1,6 @@ +from __future__ import absolute_import import opentracing.ext.tags as ext +import instana import opentracing import wrapt @@ -6,21 +8,21 @@ @wrapt.patch_function_wrapper('urllib3', 'PoolManager.urlopen') def urlopen_with_instana(wrapped, instance, args, kwargs): try: - span = opentracing.global_tracer.start_span("urllib3") + span = instana.internal_tracer.start_span("urllib3") span.set_tag(ext.HTTP_URL, args[1]) span.set_tag(ext.HTTP_METHOD, args[0]) - opentracing.global_tracer.inject(span.context, opentracing.Format.HTTP_HEADERS, kwargs["headers"]) - + instana.internal_tracer.inject(span.context, opentracing.Format.HTTP_HEADERS, kwargs["headers"]) rv = wrapped(*args, **kwargs) + span.set_tag(ext.HTTP_STATUS_CODE, rv.status) - if 500 <= rv.status <= 511: + if 500 <= rv.status <= 599: span.set_tag("error", True) ec = span.tags.get('ec', 0) span.set_tag("ec", ec+1) except Exception as e: - print("found error:", e) + span.log_kv({'message': e}) span.set_tag("error", True) ec = span.tags.get('ec', 0) span.set_tag("ec", ec+1) From e86f88b0ab58ecb7951dad2964f8fa2ec6647710 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sat, 23 Dec 2017 09:57:03 +0100 Subject: [PATCH 14/25] More routes to test against --- tests/apps/flaskalino.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/apps/flaskalino.py b/tests/apps/flaskalino.py index 0bc37dd2..315098a9 100644 --- a/tests/apps/flaskalino.py +++ b/tests/apps/flaskalino.py @@ -11,5 +11,30 @@ def hello(): return "

🐍 Hello Stan! 🦄

" +@app.route("/400") +def fourhundred(): + return "Bad Request", 400 + + +@app.route("/405") +def fourhundredfive(): + return "Method not allowed", 405 + + +@app.route("/500") +def fivehundred(): + return "Internal Server Error", 500 + + +@app.route("/504") +def fivehundredfour(): + return "Gateway Timeout", 504 + + +@app.route("/exception") +def exception(): + raise Exception('fake error') + + if __name__ == '__main__': app.run() From 3dda05c2ff3dcb83a4d3a0c1d96dfecaa5204a3d Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sat, 23 Dec 2017 09:57:34 +0100 Subject: [PATCH 15/25] Add tests for errors & exceptions --- tests/test_urllib3.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/test_urllib3.py b/tests/test_urllib3.py index 78bb8ebe..7cf2ae35 100644 --- a/tests/test_urllib3.py +++ b/tests/test_urllib3.py @@ -59,3 +59,47 @@ def test_put_request(self): assert_equals("PUT", second_span.data.http.method) assert_equals(None, second_span.error) assert_equals(None, second_span.ec) + + def test_5xx_request(self): + span = tracer.start_span("test") + r = self.http.request('GET', 'http://127.0.0.1:5000/504') + span.finish() + + spans = self.recorder.queued_spans() + first_span = spans[1] + second_span = spans[0] + + assert(r) + assert_equals(504, r.status) + assert_equals(2, len(spans)) + assert_equals("test", first_span.data.sdk.name) + assert_equals("urllib3", second_span.n) + assert_equals(504, second_span.data.http.status) + assert_equals("http://127.0.0.1:5000/504", second_span.data.http.url) + assert_equals("GET", second_span.data.http.method) + assert_equals(True, second_span.error) + assert_equals(1, second_span.ec) + + def test_exception_logging(self): + span = tracer.start_span("test") + try: + r = self.http.request('GET', 'http://127.0.0.1:5000/exception') + except Exception: + pass + + span.finish() + + spans = self.recorder.queued_spans() + first_span = spans[1] + second_span = spans[0] + + assert(r) + assert_equals(500, r.status) + assert_equals(2, len(spans)) + assert_equals("test", first_span.data.sdk.name) + assert_equals("urllib3", second_span.n) + assert_equals(500, second_span.data.http.status) + assert_equals("http://127.0.0.1:5000/exception", second_span.data.http.url) + assert_equals("GET", second_span.data.http.method) + assert_equals(True, second_span.error) + assert_equals(1, second_span.ec) From b39471dcc0931a9c3587ca28f3bea8127c4e2154 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sat, 23 Dec 2017 09:58:05 +0100 Subject: [PATCH 16/25] Use opentracing.tracer --- instana/django.py | 10 +++++----- instana/django19.py | 10 +++++----- instana/probe.py | 2 +- instana/runtime.py | 2 +- instana/wsgi.py | 10 +++++----- tests/test_ot_propagators.py | 6 +++--- tests/test_ot_span.py | 28 ++++++++++++++-------------- tests/test_ot_tracer.py | 6 +++--- 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/instana/django.py b/instana/django.py index 9f983352..824de6e0 100644 --- a/instana/django.py +++ b/instana/django.py @@ -13,16 +13,16 @@ class InstanaMiddleware(object): def __init__(self, get_response): self.get_response = get_response opts = options.Options(service="Django") - ot.global_tracer = tracer.InstanaTracer(opts) + ot.tracer = tracer.InstanaTracer(opts) self def __call__(self, request): env = request.environ if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env: - ctx = ot.global_tracer.extract(ot.Format.HTTP_HEADERS, env) - span = ot.global_tracer.start_span("django", child_of=ctx) + ctx = ot.tracer.extract(ot.Format.HTTP_HEADERS, env) + span = ot.tracer.start_span("django", child_of=ctx) else: - span = ot.global_tracer.start_span("django") + span = ot.tracer.start_span("django") span.set_tag(ext.HTTP_URL, env['PATH_INFO']) span.set_tag("http.params", env['QUERY_STRING']) @@ -37,7 +37,7 @@ def __call__(self, request): span.set_tag("ec", ec+1) span.set_tag(ext.HTTP_STATUS_CODE, response.status_code) - ot.global_tracer.inject(span.context, ot.Format.HTTP_HEADERS, response) + ot.tracer.inject(span.context, ot.Format.HTTP_HEADERS, response) span.finish() return response diff --git a/instana/django19.py b/instana/django19.py index be94c072..050634cf 100644 --- a/instana/django19.py +++ b/instana/django19.py @@ -12,17 +12,17 @@ class InstanaMiddleware19(object): """ Django 1.9 Middleware to provide request tracing for Instana """ def __init__(self): opts = options.Options(service="Django") - ot.global_tracer = tracer.InstanaTracer(opts) + ot.tracer = tracer.InstanaTracer(opts) self.span = None self def process_request(self, request): env = request.environ if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env: - ctx = ot.global_tracer.extract(ot.Format.HTTP_HEADERS, env) - span = ot.global_tracer.start_span("django", child_of=ctx) + ctx = ot.tracer.extract(ot.Format.HTTP_HEADERS, env) + span = ot.tracer.start_span("django", child_of=ctx) else: - span = ot.global_tracer.start_span("django") + span = ot.tracer.start_span("django") span.set_tag(ext.HTTP_URL, env['PATH_INFO']) span.set_tag("http.params", env['QUERY_STRING']) @@ -38,7 +38,7 @@ def process_response(self, request, response): self.span.set_tag("ec", ec+1) self.span.set_tag(ext.HTTP_STATUS_CODE, response.status_code) - ot.global_tracer.inject(self.span.context, ot.Format.HTTP_HEADERS, response) + ot.tracer.inject(self.span.context, ot.Format.HTTP_HEADERS, response) self.span.finish() self.span = None return response diff --git a/instana/probe.py b/instana/probe.py index 6c401a82..ca2590f3 100644 --- a/instana/probe.py +++ b/instana/probe.py @@ -10,4 +10,4 @@ # c. Detect and instrument any libraries opts = options.Options() -ot.global_tracer = tracer.InstanaTracer(opts) +ot.tracer = tracer.InstanaTracer(opts) diff --git a/instana/runtime.py b/instana/runtime.py index ed06ba21..65e31c97 100644 --- a/instana/runtime.py +++ b/instana/runtime.py @@ -12,4 +12,4 @@ def hook(module): print("==========================================================") opts = options.Options() - ot.global_tracer = tracer.InstanaTracer(opts) + ot.tracer = tracer.InstanaTracer(opts) diff --git a/instana/wsgi.py b/instana/wsgi.py index 983ee1e3..c746231f 100644 --- a/instana/wsgi.py +++ b/instana/wsgi.py @@ -9,7 +9,7 @@ class iWSGIMiddleware(object): def __init__(self, app): self.app = app opts = options.Options() - ot.global_tracer = tracer.InstanaTracer(opts) + ot.tracer = tracer.InstanaTracer(opts) self def __call__(self, environ, start_response): @@ -17,7 +17,7 @@ def __call__(self, environ, start_response): def new_start_response(status, headers, exc_info=None): """Modified start response with additional headers.""" - ot.global_tracer.inject(span.context, ot.Format.HTTP_HEADERS, headers) + ot.tracer.inject(span.context, ot.Format.HTTP_HEADERS, headers) res = start_response(status, headers, exc_info) sc = status.split(' ')[0] @@ -31,10 +31,10 @@ def new_start_response(status, headers, exc_info=None): return res if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env: - ctx = ot.global_tracer.extract(ot.Format.HTTP_HEADERS, env) - span = ot.global_tracer.start_span("wsgi", child_of=ctx) + ctx = ot.tracer.extract(ot.Format.HTTP_HEADERS, env) + span = ot.tracer.start_span("wsgi", child_of=ctx) else: - span = ot.global_tracer.start_span("wsgi") + span = ot.tracer.start_span("wsgi") span.set_tag(tags.HTTP_URL, env['PATH_INFO']) span.set_tag("http.params", env['QUERY_STRING']) diff --git a/tests/test_ot_propagators.py b/tests/test_ot_propagators.py index e3996fa9..06856bb8 100644 --- a/tests/test_ot_propagators.py +++ b/tests/test_ot_propagators.py @@ -19,11 +19,11 @@ def test_basics(): def test_inject(): opts = options.Options() - ot.global_tracer = tracer.InstanaTracer(opts) + ot.tracer = tracer.InstanaTracer(opts) carrier = {} - span = ot.global_tracer.start_span("nosetests") - ot.global_tracer.inject(span.context, ot.Format.HTTP_HEADERS, carrier) + span = ot.tracer.start_span("nosetests") + ot.tracer.inject(span.context, ot.Format.HTTP_HEADERS, carrier) assert 'X-Instana-T' in carrier assert_equals(carrier['X-Instana-T'], util.id_to_header(span.context.trace_id)) diff --git a/tests/test_ot_span.py b/tests/test_ot_span.py index 170d3b88..b6f1fa85 100644 --- a/tests/test_ot_span.py +++ b/tests/test_ot_span.py @@ -6,7 +6,7 @@ class TestOTSpan: def setUp(self): """ Clear all spans before a test run """ - recorder = opentracing.global_tracer.recorder + recorder = opentracing.tracer.recorder recorder.clear_spans() def tearDown(self): @@ -14,7 +14,7 @@ def tearDown(self): return None def test_span_interface(self): - span = opentracing.global_tracer.start_span("blah") + span = opentracing.tracer.start_span("blah") assert hasattr(span, "finish") assert hasattr(span, "set_tag") assert hasattr(span, "tags") @@ -28,13 +28,13 @@ def test_span_ids(self): count = 0 while count <= 1000: count += 1 - span = opentracing.global_tracer.start_span("test_span_ids") + span = opentracing.tracer.start_span("test_span_ids") context = span.context assert -9223372036854775808 <= context.span_id <= 9223372036854775807 assert -9223372036854775808 <= context.trace_id <= 9223372036854775807 def test_span_fields(self): - span = opentracing.global_tracer.start_span("mycustom") + span = opentracing.tracer.start_span("mycustom") assert_equals("mycustom", span.operation_name) assert span.context @@ -45,12 +45,12 @@ def test_span_fields(self): assert_equals(150, span.tags['tagtwo']) def test_span_queueing(self): - recorder = opentracing.global_tracer.recorder + recorder = opentracing.tracer.recorder count = 1 while count <= 20: count += 1 - span = opentracing.global_tracer.start_span("queuethisplz") + span = opentracing.tracer.start_span("queuethisplz") span.set_tag("tagone", "string") span.set_tag("tagtwo", 150) span.finish() @@ -58,9 +58,9 @@ def test_span_queueing(self): assert_equals(20, recorder.queue_size()) def test_sdk_spans(self): - recorder = opentracing.global_tracer.recorder + recorder = opentracing.tracer.recorder - span = opentracing.global_tracer.start_span("custom_sdk_span") + span = opentracing.tracer.start_span("custom_sdk_span") span.set_tag("tagone", "string") span.set_tag("tagtwo", 150) span.set_tag('span.kind', "entry") @@ -88,25 +88,25 @@ def test_sdk_spans(self): assert sdk_span.data.sdk.custom.tags def test_span_kind(self): - recorder = opentracing.global_tracer.recorder + recorder = opentracing.tracer.recorder - span = opentracing.global_tracer.start_span("custom_sdk_span") + span = opentracing.tracer.start_span("custom_sdk_span") span.set_tag('span.kind', "consumer") span.finish() - span = opentracing.global_tracer.start_span("custom_sdk_span") + span = opentracing.tracer.start_span("custom_sdk_span") span.set_tag('span.kind', "server") span.finish() - span = opentracing.global_tracer.start_span("custom_sdk_span") + span = opentracing.tracer.start_span("custom_sdk_span") span.set_tag('span.kind', "producer") span.finish() - span = opentracing.global_tracer.start_span("custom_sdk_span") + span = opentracing.tracer.start_span("custom_sdk_span") span.set_tag('span.kind', "client") span.finish() - span = opentracing.global_tracer.start_span("custom_sdk_span") + span = opentracing.tracer.start_span("custom_sdk_span") span.set_tag('span.kind', "blah") span.finish() diff --git a/tests/test_ot_tracer.py b/tests/test_ot_tracer.py index 1e3706d4..5af3d40b 100644 --- a/tests/test_ot_tracer.py +++ b/tests/test_ot_tracer.py @@ -5,6 +5,6 @@ def test_tracer_basics(): assert hasattr(instana.tracer, 'InstanaTracer') - assert hasattr(opentracing.global_tracer, "start_span") - assert hasattr(opentracing.global_tracer, "inject") - assert hasattr(opentracing.global_tracer, "extract") + assert hasattr(opentracing.tracer, "start_span") + assert hasattr(opentracing.tracer, "inject") + assert hasattr(opentracing.tracer, "extract") From 226a4c1af180f0bf1924a84c76d1d2b300557e9b Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sat, 23 Dec 2017 14:04:46 +0100 Subject: [PATCH 17/25] Make sure to finish span when there is an exception --- instana/instrumentation/urllib3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/instana/instrumentation/urllib3.py b/instana/instrumentation/urllib3.py index a8a0a8a2..0fc69f30 100644 --- a/instana/instrumentation/urllib3.py +++ b/instana/instrumentation/urllib3.py @@ -26,6 +26,7 @@ def urlopen_with_instana(wrapped, instance, args, kwargs): span.set_tag("error", True) ec = span.tags.get('ec', 0) span.set_tag("ec", ec+1) + span.finish() raise else: span.finish() From 4bfca0b320cd8952c55758b18165f45be8e76a4b Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sat, 23 Dec 2017 14:05:09 +0100 Subject: [PATCH 18/25] Add test to validate tracing through client errors. --- tests/test_urllib3.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/tests/test_urllib3.py b/tests/test_urllib3.py index 7cf2ae35..fe704acd 100644 --- a/tests/test_urllib3.py +++ b/tests/test_urllib3.py @@ -25,12 +25,12 @@ def test_get_request(self): span.finish() spans = self.recorder.queued_spans() + assert_equals(2, len(spans)) first_span = spans[1] second_span = spans[0] assert(r) assert_equals(200, r.status) - assert_equals(2, len(spans)) assert_equals("test", first_span.data.sdk.name) assert_equals("urllib3", second_span.n) assert_equals(200, second_span.data.http.status) @@ -46,12 +46,12 @@ def test_put_request(self): span.finish() spans = self.recorder.queued_spans() + assert_equals(2, len(spans)) first_span = spans[1] second_span = spans[0] assert(r) assert_equals(404, r.status) - assert_equals(2, len(spans)) assert_equals("test", first_span.data.sdk.name) assert_equals("urllib3", second_span.n) assert_equals(404, second_span.data.http.status) @@ -66,12 +66,12 @@ def test_5xx_request(self): span.finish() spans = self.recorder.queued_spans() + assert_equals(2, len(spans)) first_span = spans[1] second_span = spans[0] assert(r) assert_equals(504, r.status) - assert_equals(2, len(spans)) assert_equals("test", first_span.data.sdk.name) assert_equals("urllib3", second_span.n) assert_equals(504, second_span.data.http.status) @@ -90,12 +90,12 @@ def test_exception_logging(self): span.finish() spans = self.recorder.queued_spans() + assert_equals(2, len(spans)) first_span = spans[1] second_span = spans[0] assert(r) assert_equals(500, r.status) - assert_equals(2, len(spans)) assert_equals("test", first_span.data.sdk.name) assert_equals("urllib3", second_span.n) assert_equals(500, second_span.data.http.status) @@ -103,3 +103,30 @@ def test_exception_logging(self): assert_equals("GET", second_span.data.http.method) assert_equals(True, second_span.error) assert_equals(1, second_span.ec) + + def test_client_error(self): + span = tracer.start_span("test") + + r = None + try: + r = self.http.request('GET', 'http://doesnotexist.asdf:5000/504', + retries=False, + timeout=urllib3.Timeout(connect=0.5, read=0.5)) + except Exception: + pass + + span.finish() + + spans = self.recorder.queued_spans() + assert_equals(2, len(spans)) + first_span = spans[1] + second_span = spans[0] + + assert_equals(None, r) + assert_equals("test", first_span.data.sdk.name) + assert_equals("urllib3", second_span.n) + assert_equals(None, second_span.data.http.status) + assert_equals("http://doesnotexist.asdf:5000/504", second_span.data.http.url) + assert_equals("GET", second_span.data.http.method) + assert_equals(True, second_span.error) + assert_equals(1, second_span.ec) From 34ea9420c8b334d0d980061a8c85104d03d4523a Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sun, 24 Dec 2017 09:59:24 +0100 Subject: [PATCH 19/25] Add a way to retrieve current context of active span --- instana/tracer.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/instana/tracer.py b/instana/tracer.py index a8f96ca2..d871548b 100644 --- a/instana/tracer.py +++ b/instana/tracer.py @@ -14,6 +14,7 @@ class InstanaTracer(BasicTracer): sensor = None + current_span = None def __init__(self, options=o.Options()): self.sensor = instana.global_sensor @@ -57,7 +58,7 @@ def start_span( ctx.sampled = self.sampler.sampled(ctx.trace_id) # Tie it all together - return BasicSpan( + self.current_span = BasicSpan( self, operation_name=operation_name, context=ctx, @@ -65,6 +66,11 @@ def start_span( tags=tags, start_time=start_time) + return self.current_span + + def current_context(self): + return self.current_span.context + def inject(self, span_context, format, carrier): if format in self._propagators: self._propagators[format].inject(span_context, carrier) From 7c1d6286000494482fea85a3cc2be41639a55950 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Sun, 24 Dec 2017 10:00:00 +0100 Subject: [PATCH 20/25] Make urllib3 childof current span; Add tests to validate --- instana/instrumentation/urllib3.py | 6 +++++- tests/test_urllib3.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/instana/instrumentation/urllib3.py b/instana/instrumentation/urllib3.py index 0fc69f30..2be0e20b 100644 --- a/instana/instrumentation/urllib3.py +++ b/instana/instrumentation/urllib3.py @@ -8,7 +8,8 @@ @wrapt.patch_function_wrapper('urllib3', 'PoolManager.urlopen') def urlopen_with_instana(wrapped, instance, args, kwargs): try: - span = instana.internal_tracer.start_span("urllib3") + context = instana.internal_tracer.current_context() + span = instana.internal_tracer.start_span("urllib3", child_of=context) span.set_tag(ext.HTTP_URL, args[1]) span.set_tag(ext.HTTP_METHOD, args[0]) @@ -31,3 +32,6 @@ def urlopen_with_instana(wrapped, instance, args, kwargs): else: span.finish() return rv + + +instana.log.debug("Instrumenting urllib3") diff --git a/tests/test_urllib3.py b/tests/test_urllib3.py index fe704acd..9bb7596a 100644 --- a/tests/test_urllib3.py +++ b/tests/test_urllib3.py @@ -40,6 +40,9 @@ def test_get_request(self): assert_equals(None, second_span.error) assert_equals(None, second_span.ec) + assert_equals(second_span.t, first_span.t) + assert_equals(second_span.p, first_span.s) + def test_put_request(self): span = tracer.start_span("test") r = self.http.request('PUT', 'http://127.0.0.1:5000/notfound') @@ -60,6 +63,9 @@ def test_put_request(self): assert_equals(None, second_span.error) assert_equals(None, second_span.ec) + assert_equals(second_span.t, first_span.t) + assert_equals(second_span.p, first_span.s) + def test_5xx_request(self): span = tracer.start_span("test") r = self.http.request('GET', 'http://127.0.0.1:5000/504') @@ -80,6 +86,9 @@ def test_5xx_request(self): assert_equals(True, second_span.error) assert_equals(1, second_span.ec) + assert_equals(second_span.t, first_span.t) + assert_equals(second_span.p, first_span.s) + def test_exception_logging(self): span = tracer.start_span("test") try: @@ -104,6 +113,9 @@ def test_exception_logging(self): assert_equals(True, second_span.error) assert_equals(1, second_span.ec) + assert_equals(second_span.t, first_span.t) + assert_equals(second_span.p, first_span.s) + def test_client_error(self): span = tracer.start_span("test") @@ -130,3 +142,6 @@ def test_client_error(self): assert_equals("GET", second_span.data.http.method) assert_equals(True, second_span.error) assert_equals(1, second_span.ec) + + assert_equals(second_span.t, first_span.t) + assert_equals(second_span.p, first_span.s) From f7a16d458a92d36ebeab97e3bc0ab864ac3cf430 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Wed, 27 Dec 2017 14:45:36 +0100 Subject: [PATCH 21/25] Runtime metrics are now automatic. Remove runtime section. --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 07486922..493660fe 100644 --- a/README.md +++ b/README.md @@ -35,14 +35,6 @@ To enable the Flask instrumentation, set the following environment variable in y `export AUTOWRAPT_BOOTSTRAP=flask` -## Runtime Monitoring Only - -_Note: When the Django or Flask instrumentation is used, runtime monitoring is automatically included. Use this section if you only want to see runtime metrics._ - -To enable runtime monitoring (without request tracing), set the following environment variable in your _application boot environment_ and then restart your application: - - `export AUTOWRAPT_BOOTSTRAP=runtime` - ## uWSGI ### Threads From ad914ab1f8bff9c86f9fba57fd490a5920df1094 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Wed, 27 Dec 2017 14:46:36 +0100 Subject: [PATCH 22/25] Have instrumentation always use internal_tracer --- instana/django.py | 12 +++++------- instana/django19.py | 12 +++++------- instana/wsgi.py | 12 +++++------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/instana/django.py b/instana/django.py index 824de6e0..604b5a4d 100644 --- a/instana/django.py +++ b/instana/django.py @@ -1,6 +1,6 @@ from __future__ import print_function import opentracing as ot -from instana import tracer, options +from instana import internal_tracer import opentracing.ext.tags as ext import os @@ -12,17 +12,15 @@ class InstanaMiddleware(object): """ Django Middleware to provide request tracing for Instana """ def __init__(self, get_response): self.get_response = get_response - opts = options.Options(service="Django") - ot.tracer = tracer.InstanaTracer(opts) self def __call__(self, request): env = request.environ if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env: - ctx = ot.tracer.extract(ot.Format.HTTP_HEADERS, env) - span = ot.tracer.start_span("django", child_of=ctx) + ctx = internal_tracer.extract(ot.Format.HTTP_HEADERS, env) + span = internal_tracer.start_span("django", child_of=ctx) else: - span = ot.tracer.start_span("django") + span = internal_tracer.start_span("django") span.set_tag(ext.HTTP_URL, env['PATH_INFO']) span.set_tag("http.params", env['QUERY_STRING']) @@ -37,7 +35,7 @@ def __call__(self, request): span.set_tag("ec", ec+1) span.set_tag(ext.HTTP_STATUS_CODE, response.status_code) - ot.tracer.inject(span.context, ot.Format.HTTP_HEADERS, response) + internal_tracer.inject(span.context, ot.Format.HTTP_HEADERS, response) span.finish() return response diff --git a/instana/django19.py b/instana/django19.py index 050634cf..620fa0ce 100644 --- a/instana/django19.py +++ b/instana/django19.py @@ -1,6 +1,6 @@ from __future__ import print_function import opentracing as ot -from instana import tracer, options +from instana import internal_tracer import opentracing.ext.tags as ext import os @@ -11,18 +11,16 @@ class InstanaMiddleware19(object): """ Django 1.9 Middleware to provide request tracing for Instana """ def __init__(self): - opts = options.Options(service="Django") - ot.tracer = tracer.InstanaTracer(opts) self.span = None self def process_request(self, request): env = request.environ if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env: - ctx = ot.tracer.extract(ot.Format.HTTP_HEADERS, env) - span = ot.tracer.start_span("django", child_of=ctx) + ctx = internal_tracer.extract(ot.Format.HTTP_HEADERS, env) + span = internal_tracer.start_span("django", child_of=ctx) else: - span = ot.tracer.start_span("django") + span = internal_tracer.start_span("django") span.set_tag(ext.HTTP_URL, env['PATH_INFO']) span.set_tag("http.params", env['QUERY_STRING']) @@ -38,7 +36,7 @@ def process_response(self, request, response): self.span.set_tag("ec", ec+1) self.span.set_tag(ext.HTTP_STATUS_CODE, response.status_code) - ot.tracer.inject(self.span.context, ot.Format.HTTP_HEADERS, response) + internal_tracer.inject(self.span.context, ot.Format.HTTP_HEADERS, response) self.span.finish() self.span = None return response diff --git a/instana/wsgi.py b/instana/wsgi.py index c746231f..58d19e4f 100644 --- a/instana/wsgi.py +++ b/instana/wsgi.py @@ -1,5 +1,5 @@ import opentracing as ot -from instana import tracer, options +from instana import internal_tracer import opentracing.ext.tags as tags @@ -8,8 +8,6 @@ class iWSGIMiddleware(object): def __init__(self, app): self.app = app - opts = options.Options() - ot.tracer = tracer.InstanaTracer(opts) self def __call__(self, environ, start_response): @@ -17,7 +15,7 @@ def __call__(self, environ, start_response): def new_start_response(status, headers, exc_info=None): """Modified start response with additional headers.""" - ot.tracer.inject(span.context, ot.Format.HTTP_HEADERS, headers) + internal_tracer.inject(span.context, ot.Format.HTTP_HEADERS, headers) res = start_response(status, headers, exc_info) sc = status.split(' ')[0] @@ -31,10 +29,10 @@ def new_start_response(status, headers, exc_info=None): return res if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env: - ctx = ot.tracer.extract(ot.Format.HTTP_HEADERS, env) - span = ot.tracer.start_span("wsgi", child_of=ctx) + ctx = internal_tracer.extract(ot.Format.HTTP_HEADERS, env) + span = internal_tracer.start_span("wsgi", child_of=ctx) else: - span = ot.tracer.start_span("wsgi") + span = internal_tracer.start_span("wsgi") span.set_tag(tags.HTTP_URL, env['PATH_INFO']) span.set_tag("http.params", env['QUERY_STRING']) From 83002fa038e4482642ee441072fab647a04a504f Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Wed, 27 Dec 2017 15:12:43 +0100 Subject: [PATCH 23/25] Better non-*nix process command line handling. --- instana/fsm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instana/fsm.py b/instana/fsm.py index 1afe968d..d9c7a9ca 100644 --- a/instana/fsm.py +++ b/instana/fsm.py @@ -124,7 +124,7 @@ def announce_sensor(self, e): cmdinfo = cmd.read() cmdline = cmdinfo.split('\x00') else: - cmdline = [os.path.basename(sys.executable)] + cmdline = [sys.executable] cmdline += sys.argv d = Discovery(pid=pid, From 80a130c41c365326a55800f3093a6fd7d29530df Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Wed, 27 Dec 2017 16:22:14 +0100 Subject: [PATCH 24/25] Fix environment variable name --- Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configuration.md b/Configuration.md index af7dc4d4..356a0652 100644 --- a/Configuration.md +++ b/Configuration.md @@ -13,7 +13,7 @@ export INSTANA_AGENT_PORT = '42699' ## Debugging & More Verbosity -Setting `INSTANA_GEM_DEV` to a non nil value will enable extra logging output generally useful +Setting `INSTANA_DEV` to a non nil value will enable extra logging output generally useful for development. ```Python From dad4f3dd3df800cc3085a52fa41eab94e109fd8a Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Wed, 27 Dec 2017 16:28:03 +0100 Subject: [PATCH 25/25] Fix OpenTracing example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 493660fe..06c960b4 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ import opentracing parent_span = opentracing.tracer.start_span(operation_name="asteroid") # ... work -child_span = ot.tracer.start_span(operation_name="spacedust", child_of=parent_span) +child_span = opentracing.tracer.start_span(operation_name="spacedust", child_of=parent_span) child_span.set_tag(ext.SPAN_KIND, ext.SPAN_KIND_RPC_CLIENT) # ... work child_span.finish()