Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: rhettg/Ziggy
base: 5b5199d173
...
head fork: rhettg/Ziggy
compare: d444efdb68
  • 5 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
9 README.md
View
@@ -38,11 +38,12 @@ specific request.
Contexts can be heirarchical. This means you can generate sub-events that
are related to the parent event and can be joined together in post-processing by the common id they share.
+Indicate you want this behavior for your context by naming with a prefixing '.'.
For example, inside some application code (in `do_stuff()` above), you might execute some sql queries.
def execute(cursor, query, args):
- with ziggy.Context('request.sql'):
+ with ziggy.Context('.sql'):
ziggy.set('query', query)
with ziggy.timeit('query_time'):
res = cursor.execute(query, args)
@@ -50,7 +51,7 @@ For example, inside some application code (in `do_stuff()` above), you might exe
return res
Each SQL query would then be logged as a seperate event. However, each event
-will have the unique id provided by the parent `request` context.
+will have the unique id provided by the parent `request` context. The name of the context will become `request.sql`.
You can provide you're own id or allow ziggy to autogenerate one for the top-level context.
@@ -58,12 +59,12 @@ Ziggy also provides the ability to do sampling. This means only a set
percentage of generate events will actually be logged. You can choose sampling
based on any level of the context:
- with ziggy.Context('request.memcache', sample=('request', 0.25)):
+ with ziggy.Context('.memcache', sample=('..', 0.25)):
ziggy.set('key', key)
client.set(key, value)
In the above example, only 25% of requests will include the memcache data. If
-the sample argument where `('request.memcache', 0.25)` then 25% of all memcache
+the sample argument where `('memcache', 0.25)` then 25% of all memcache
events would be logged.
### Configuration
10 bin/ziggyview
View
@@ -4,6 +4,7 @@ import sys
import io
import struct
import logging
+import pprint
import bson
import zmq
@@ -57,7 +58,7 @@ def subscribe_stream(context, host, port, type_name):
if len(parts) == 2:
channel, data = parts
# If the client only want exact matches, we'll skip this guy.
- if not prefix and channel != subscription:
+ if not prefix and subscription and channel != subscription:
continue
yield bson.loads(data)
@@ -72,6 +73,7 @@ def main():
parser.add_argument('--type-name', '-n', dest='type_name', action='store', default=None, help="What event types to display. Can end with '*' for prefix matches.")
parser.add_argument('--host', '-H', dest='host', action='store', default="127.0.0.1:3513")
parser.add_argument('--log-path', '-l', dest='log_path', action='store', default=None)
+ parser.add_argument('--pretty', '-p', dest='pretty', action='store_true', default=False)
options = parser.parse_args()
@@ -105,7 +107,11 @@ def main():
out_stream = decode_stream(stdin)
for line in out_stream:
- print line
+ if options.pretty:
+ print
+ pprint.pprint(line)
+ else:
+ print line
if __name__ == '__main__':
1  requirements.txt
View
@@ -3,3 +3,4 @@ pep8
pyflakes
pyzmq
bson
+tornado
5 tests/context_test.py
View
@@ -22,7 +22,8 @@ def test(self):
class NestedIDTestCase(TestCase):
def test(self):
with context.Context('test', 5):
- with context.Context('test.foo') as c:
+ with context.Context('.foo') as c:
+ assert_equal(c.name, 'test.foo')
assert_equal(c.id, 5)
@@ -53,7 +54,7 @@ def test(self):
with parent_context:
sub_enabled = []
for _ in range(10):
- context = ziggy.Context('test.sub', sample=('test', 0.25))
+ context = ziggy.Context('.sub', sample=('..', 0.25))
sub_enabled.append(1 if context.enabled else 0)
enabled.append(1 if context.enabled else 0)
assert all(sub_enabled) or not any(sub_enabled)
18 ziggy/context.py
View
@@ -26,13 +26,21 @@
class Context(object):
__slots__ = ["name", "data", "id", "_writable", "start_time", "_sample_checks", "enabled"]
def __init__(self, type_name, id=None, sample=None):
- self.name = type_name
+
+ if type_name.startswith('.'):
+ parent_ctx = current_context()
+ if parent_ctx is None:
+ self.name = type_name[1:]
+ else:
+ self.name = parent_ctx.name + type_name
+ else:
+ parent_ctx = None
+ self.name = type_name
+
self.data = {}
self.start_time = time.time()
self._sample_checks = {}
- parent_ctx = _get_context(utils.parse_key(type_name)[:-1])
-
if id is not None:
self.id = id
elif parent_ctx:
@@ -47,8 +55,10 @@ def __init__(self, type_name, id=None, sample=None):
self.enabled = False
elif sample:
sample_name, rate = sample
- if sample_name == type_name:
+ if sample_name == type_name or sample_name == '.':
self.enabled = bool(random.random() <= rate)
+ elif parent_ctx and sample_name == '..':
+ self.enabled = parent_ctx.sampled_for(type_name, rate)
else:
self.enabled = _get_context(sample_name).sampled_for(type_name, rate)
else:
30 ziggy/tornado_utils.py
View
@@ -14,11 +14,15 @@
"""
import functools
+import logging
import traceback
import types
+log = logging.getLogger(__name__)
+
import tornado.web
import tornado.gen
+import tornado.simple_httpclient
import ziggy
@@ -143,3 +147,29 @@ def run(self):
finally:
if self.ziggy_ctx:
self.ziggy_ctx.stop()
+
+class AsyncHTTPClient(tornado.simple_httpclient.SimpleAsyncHTTPClient):
+ def __init__(self, *args, **kwargs):
+ self.ziggy_name = '.httpclient'
+ return super(AsyncHTTPClient, self).__init__(*args, **kwargs)
+
+ def fetch(self, request, callback, **kwargs):
+ ctx = ziggy.Context(self.ziggy_name)
+ ctx.start()
+ if isinstance(request, basestring):
+ ctx.set('request.uri', request)
+ else:
+ ctx.set('request.uri', request.url)
+ ctx.set('request.size', len(request.body) if request.body else 0)
+
+ ctx.stop()
+
+ def wrap_callback(response):
+ ctx.start()
+ ctx.set('response.code', response.code)
+ ctx.set('response.size', len(response.body) if response.body else 0)
+ ctx.done()
+ callback(response)
+
+ return super(AsyncHTTPClient, self).fetch(request, wrap_callback, **kwargs)
+

No commit comments for this range

Something went wrong with that request. Please try again.