Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var/
*.egg-info/
.installed.cfg
*.egg
*.whl

# PyInstaller
# Usually these files are written by a python script from a template
Expand Down
21 changes: 18 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@

task :build do
sh "pip wheel ./"
end

task :test do
sh "nosetests"
sh "python setup.py test"
end

task :install => :build do
sh "pip install *.whl"
end

task :dist do
sh "python setup.py sdist"
task :upgrade => :build do
sh "pip install -U *.whl"
end

task :clean do
sh "python setup.py clean"
sh "rm -rf *.whl dist *.egg-info build"
end

task :ci => [:clean, :test, :build]
7 changes: 7 additions & 0 deletions ddtrace/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@
except ImportError:
from Queue import Queue

try:
import ujson as json
except ImportError:
try:
import simplejson as json
except ImportError:
import json
7 changes: 5 additions & 2 deletions ddtrace/contrib/flask/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import logging

# project
from tracer.ext import http
from ...ext import http

# 3p
from flask import g, request, signals
Expand All @@ -20,6 +20,7 @@ class TraceMiddleware(object):

def __init__(self, app, tracer, service="flask", use_signals=True):
self.app = app
self.app.logger.info("initializing trace middleware")

# save our traces.
self._tracer = tracer
Expand All @@ -30,14 +31,15 @@ def __init__(self, app, tracer, service="flask", use_signals=True):
if self.use_signals and signals.signals_available:
# if we're using signals, and things are correctly installed, use
# signal hooks to track the responses.
self.app.logger.info("connecting trace signals")
signals.request_started.connect(self._request_started, sender=self.app)
signals.request_finished.connect(self._request_finished, sender=self.app)
signals.got_request_exception.connect(self._request_exception, sender=self.app)
signals.before_render_template.connect(self._template_started, sender=self.app)
signals.template_rendered.connect(self._template_done, sender=self.app)
else:
if self.use_signals: # warn the user that signals lib isn't installed
self.app.logger.warn(_blinker_not_installed_msg)
self.app.logger.info(_blinker_not_installed_msg)

# Fallback to using after request hook. Unfortunately, this won't
# handle exceptions.
Expand Down Expand Up @@ -117,6 +119,7 @@ def _request_exception(self, *args, **kwargs):
def _template_started(self, sender, template, *args, **kwargs):
span = self._tracer.trace('flask.template')
try:
span.span_type = http.TEMPLATE
span.set_tag("flask.template", template.name or "string")
finally:
g.flask_datadog_tmpl_span = span
Expand Down
20 changes: 9 additions & 11 deletions ddtrace/contrib/flask/test_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from flask import Flask, render_template
from nose.tools import eq_

from tracer import Tracer
from tracer.contrib.flask import TraceMiddleware
from tracer.test_tracer import DummyWriter
from tracer.ext import http
from ... import Tracer
from ...contrib.flask import TraceMiddleware
from ...test_tracer import DummyWriter
from ...ext import http

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -74,8 +74,6 @@ def handle_my_exception(e):
class TestFlask(object):

def setUp(self):
from nose.plugins.skip import SkipTest
raise SkipTest("fix deps")
# ensure the last test didn't leave any trash
spans = writer.pop()
assert not spans, spans
Expand Down Expand Up @@ -133,7 +131,7 @@ def test_success(self):
assert s.start >= start
assert s.duration <= end - start
eq_(s.error, 0)
eq_(s.meta.get(http.STATUS_CODE), 200)
eq_(s.meta.get(http.STATUS_CODE), '200')

def test_template(self):
start = time.time()
Expand All @@ -155,7 +153,7 @@ def test_template(self):
assert s.start >= start
assert s.duration <= end - start
eq_(s.error, 0)
eq_(s.meta.get(http.STATUS_CODE), 200)
eq_(s.meta.get(http.STATUS_CODE), '200')

t = by_name["flask.template"]
eq_(t.get_tag("flask.template"), "test.html")
Expand Down Expand Up @@ -184,7 +182,7 @@ def test_template_err(self):
assert s.start >= start
assert s.duration <= end - start
eq_(s.error, 1)
eq_(s.meta.get(http.STATUS_CODE), 500)
eq_(s.meta.get(http.STATUS_CODE), '500')

def test_error(self):
start = time.time()
Expand All @@ -204,7 +202,7 @@ def test_error(self):
eq_(s.resource, "error")
assert s.start >= start
assert s.duration <= end - start
eq_(s.meta.get(http.STATUS_CODE), 500)
eq_(s.meta.get(http.STATUS_CODE), '500')

def test_fatal(self):
if not traced_app.use_signals:
Expand All @@ -228,5 +226,5 @@ def test_fatal(self):
eq_(s.resource, "fatal")
assert s.start >= start
assert s.duration <= end - start
eq_(s.meta.get(http.STATUS_CODE), 500)
eq_(s.meta.get(http.STATUS_CODE), '500')

19 changes: 16 additions & 3 deletions ddtrace/contrib/psycopg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@

# stdlib
import functools
import logging

from tracer.ext import net
from tracer.ext import sql as sqlx
from ...ext import net
from ...ext import sql as sqlx

# 3p
from psycopg2.extensions import connection, cursor
_installed = False
try:
from psycopg2.extensions import connection, cursor
_installed = True
except ImportError:
connection, cursor = object, object


log = logging.getLogger(__name__)


def connection_factory(tracer, service="postgres"):
Expand All @@ -19,6 +28,10 @@ def connection_factory(tracer, service="postgres"):
>>> factory = connection_factor(my_tracer, service="my_db_service")
>>> conn = pyscopg2.connect(..., connection_factory=factory)
"""
if not _installed:
log.info("missing psycopg import")
return None

return functools.partial(TracedConnection,
datadog_tracer=tracer,
datadog_service=service,
Expand Down
13 changes: 8 additions & 5 deletions ddtrace/contrib/psycopg/test_psycopg.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import time

import psycopg2
from nose.tools import eq_
from nose.plugins.skip import SkipTest

from tracer import Tracer
from tracer.contrib.psycopg import connection_factory
from tracer.test_tracer import DummyWriter
from ... import Tracer
from ...contrib.psycopg import connection_factory
from ...test_tracer import DummyWriter

def test_wrap():
raise SkipTest("matt")

try:
import psycopg2
except ImportError:
raise SkipTest("missing psycopg")

writer = DummyWriter()
tracer = Tracer(writer=writer)
Expand Down
2 changes: 1 addition & 1 deletion ddtrace/contrib/pylons/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from tracer.ext import http
from ...ext import http

log = logging.getLogger(__name__)

Expand Down
8 changes: 4 additions & 4 deletions ddtrace/contrib/pylons/test_pylons.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

from nose.tools import eq_

from tracer import Tracer
from tracer.contrib.pylons import PylonsTraceMiddleware
from tracer.test_tracer import DummyWriter
from tracer.ext import http
from ... import Tracer
from ...contrib.pylons import PylonsTraceMiddleware
from ...test_tracer import DummyWriter
from ...ext import http


class FakeWSGIApp(object):
Expand Down
2 changes: 1 addition & 1 deletion ddtrace/contrib/sqlite3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import functools

from sqlite3 import Connection, Cursor
from tracer.ext import sql as sqlx
from ...ext import sql as sqlx


def connection_factory(tracer, service="sqlite3"):
Expand Down
6 changes: 3 additions & 3 deletions ddtrace/contrib/sqlite3/test_sqlite3.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

from nose.tools import eq_

from tracer import Tracer
from tracer.contrib.sqlite3 import connection_factory
from tracer.test_tracer import DummyWriter
from ... import Tracer
from ...contrib.sqlite3 import connection_factory
from ...test_tracer import DummyWriter

def test_foo():
writer = DummyWriter()
Expand Down
3 changes: 3 additions & 0 deletions ddtrace/ext/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@
URL = "http.url"
METHOD = "http.method"
STATUS_CODE = "http.status_code"

# template render span type
TEMPLATE = 'template'
4 changes: 2 additions & 2 deletions ddtrace/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import logging
import threading
from time import sleep, time
import ujson as json
import os

from compat import Queue
# project
from compat import Queue, json


DEFAULT_TIMEOUT = 10
Expand Down
1 change: 1 addition & 0 deletions ddtrace/span.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def pprint(self):
("parent_id", self.parent_id),
("service", self.service),
("resource", self.resource),
('type', self.span_type),
("start", self.start),
("end", "" if not self.duration else self.start + self.duration),
("duration", self.duration),
Expand Down
7 changes: 5 additions & 2 deletions ddtrace/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,11 @@ def write(self, spans):
""" Submit the given spans to the agent. """
if spans:
if self.debug_logging:
log.info("submitting %s spans", len(spans))
log.debug("submitting %s spans", len(spans))
for span in spans:
log.info("\n%s" % span.pprint())
log.debug("\n%s" % span.pprint())

self._writer.write(spans)



37 changes: 29 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
from setuptools import setup

setup(name='ddtrace',
version='0.1',
description='Datadog tracing code',
url='https://github.com/DataDog/dd-trace-py',
author='Datadog, Inc.',
author_email='[email protected]',
license='BSD',
packages=['ddtrace'])
tests_require = [
'nose',
#'psycopg2',
#'sqlite3'
'flask',
'blinker',
]

setup(
name='ddtrace',
version='0.1',
description='Datadog tracing code',
url='https://github.com/DataDog/dd-trace-py',
author='Datadog, Inc.',
author_email='[email protected]',
license='BSD',
packages=[
'ddtrace',
'ddtrace.contrib',
'ddtrace.contrib.flask',
'ddtrace.contrib.psycopg',
'ddtrace.contrib.pylons',
'ddtrace.contrib.sqlite3',
'ddtrace.ext',
],
tests_require=tests_require,
test_suite="nose.collector",
)