# Path: mozsvc/metrics.py
# class metrics_timer(object):
#     """Decorator/context-manager to transparently time chunks of code.
# 
#     This class produces a timing decorator/context-manager that will place
#     its result in the request.metrics dict upon completion.
# 
#     It uses pyramid threadlocals to get the current request object, which is
#     a little bit icky but very convenient.  If you have the proper request
#     object, you can pass it as an optional argument to the constructor.
# 
#     It can be used as a context-manager to time a chunk of code, like this:
# 
#         with metrics_timer("my.timer"):
#             do_some_stuff()
# 
#     Or applied as a function decorator like this:
# 
#         @metrics_timer("my.timer")
#         def do_some_stuff():
#             do_more_stuff()
# 
#     """
# 
#     def __init__(self, key, request=None):
#         self.key = key
#         self._request = request
# 
#     def annotate_request(self, value, key=None, request=None):
#         if key is None:
#             key = self.key
#         if request is None:
#             request = self._request
#         annotate_request(request, key, value)
# 
#     # When used as a context-manager, times the enclosed code.
# 
#     def __enter__(self):
#         self.start_time = timeit.default_timer()
#         return self
# 
#     def __exit__(self, exc_typ=None, exc_val=None, exc_tb=None):
#         stop_time = timeit.default_timer()
#         self.annotate_request(stop_time - self.start_time)
# 
#     # When called, applies itself as a function decorator.
# 
#     def __call__(self, func):
# 
#         @functools.wraps(func)
#         def timed_func(*args, **kwds):
#             # We can't use "with self" here since that stores state on
#             # the object, and hence plays badly with threading or recursion.
#             start_time = timeit.default_timer()
#             try:
#                 return func(*args, **kwds)
#             finally:
#                 stop_time = timeit.default_timer()
#                 self.annotate_request(stop_time - start_time)
# 
#         return timed_func
# 
# def initialize_request_metrics(request, defaults={}):
#     """Request callback to add a "metrics" dict.
# 
#     This function should be invoked upon each new request.  It will create
#     a request.metrics dict into which the application can store any runtime
#     logging or metrics data, and will add response callbacks to log the
#     contents of this dict once the request is complete.
#     """
#     # Create the request.metrics dict.
#     request.metrics = defaults.copy()
#     # Add in some basic information about the request
#     # that should always be logged.
#     request.metrics["method"] = request.method
#     request.metrics["path"] = request.path_url
#     request.metrics["agent"] = request.user_agent or ""
#     xff = request.headers.get('X-Forwarded-For', '')
#     xff = [ip for ip in COMMA_SEPARATED.split(xff) if ip]
#     if request.remote_addr:
#         xff.append(request.remote_addr)
#     request.metrics["remoteAddressChain"] = xff
#     request.metrics["request_start_time"] = timeit.default_timer()
#     # Add hooks to log the metrics at the end of the request.
#     request.add_response_callback(add_response_metrics)
#     request.add_finished_callback(finalize_request_metrics)


import time
import unittest2
import pyramid.testing
from pyramid.request import Request, Response
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
from webtest import TestApp
from testfixtures import LogCapture
from mozsvc.metrics import metrics_timer, initialize_request_metrics
from cornice import Service
from cornice.pyramidhook import register_service_views
        self.logs = LogCapture()

    def tearDown(self):
        self.logs.uninstall()

    def test_service_metrics(self):
        stub_service = Service(name="stub", path="/stub")

        @stub_service.get()
        @metrics_timer("view_time")
        def stub_view(request):
            request.metrics["stub"] = "stub-a-dub-dub"
            return {}

        with pyramid.testing.testConfig() as config:
            config.include("cornice")
            config.include("mozsvc")
            register_service_views(config, stub_service)
            app = TestApp(config.make_wsgi_app())
            res = app.get("/stub")
            self.assertEqual(res.body, "{}")

        self.assertTrue(len(self.logs.records), 1)
        r = self.logs.records[0]
        self.assertEqual(r.stub, "stub-a-dub-dub")
        self.assertTrue(0 < r.request_time < 0.1)
        self.assertTrue(0 < r.view_time <= r.request_time)

    def test_timing_decorator(self):


# Path: mozsvc/metrics.py
# class metrics_timer(object):
#     """Decorator/context-manager to transparently time chunks of code.
# 
#     This class produces a timing decorator/context-manager that will place
#     its result in the request.metrics dict upon completion.
# 
#     It uses pyramid threadlocals to get the current request object, which is
#     a little bit icky but very convenient.  If you have the proper request
#     object, you can pass it as an optional argument to the constructor.
# 
#     It can be used as a context-manager to time a chunk of code, like this:
# 
#         with metrics_timer("my.timer"):
#             do_some_stuff()
# 
#     Or applied as a function decorator like this:
# 
#         @metrics_timer("my.timer")
#         def do_some_stuff():
#             do_more_stuff()
# 
#     """
# 
#     def __init__(self, key, request=None):
#         self.key = key
#         self._request = request
# 
#     def annotate_request(self, value, key=None, request=None):
#         if key is None:
#             key = self.key
#         if request is None:
#             request = self._request
#         annotate_request(request, key, value)
# 
#     # When used as a context-manager, times the enclosed code.
# 
#     def __enter__(self):
#         self.start_time = timeit.default_timer()
#         return self
# 
#     def __exit__(self, exc_typ=None, exc_val=None, exc_tb=None):
#         stop_time = timeit.default_timer()
#         self.annotate_request(stop_time - self.start_time)
# 
#     # When called, applies itself as a function decorator.
# 
#     def __call__(self, func):
# 
#         @functools.wraps(func)
#         def timed_func(*args, **kwds):
#             # We can't use "with self" here since that stores state on
#             # the object, and hence plays badly with threading or recursion.
#             start_time = timeit.default_timer()
#             try:
#                 return func(*args, **kwds)
#             finally:
#                 stop_time = timeit.default_timer()
#                 self.annotate_request(stop_time - start_time)
# 
#         return timed_func
# 
# def initialize_request_metrics(request, defaults={}):
#     """Request callback to add a "metrics" dict.
# 
#     This function should be invoked upon each new request.  It will create
#     a request.metrics dict into which the application can store any runtime
#     logging or metrics data, and will add response callbacks to log the
#     contents of this dict once the request is complete.
#     """
#     # Create the request.metrics dict.
#     request.metrics = defaults.copy()
#     # Add in some basic information about the request
#     # that should always be logged.
#     request.metrics["method"] = request.method
#     request.metrics["path"] = request.path_url
#     request.metrics["agent"] = request.user_agent or ""
#     xff = request.headers.get('X-Forwarded-For', '')
#     xff = [ip for ip in COMMA_SEPARATED.split(xff) if ip]
#     if request.remote_addr:
#         xff.append(request.remote_addr)
#     request.metrics["remoteAddressChain"] = xff
#     request.metrics["request_start_time"] = timeit.default_timer()
#     # Add hooks to log the metrics at the end of the request.
#     request.add_response_callback(add_response_metrics)
#     request.add_finished_callback(finalize_request_metrics)


# Path: mozsvc/tests/test_metrics.py
import time
import unittest2
import pyramid.testing
from pyramid.request import Request, Response
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
from webtest import TestApp
from testfixtures import LogCapture
from mozsvc.metrics import metrics_timer, initialize_request_metrics
from cornice import Service
from cornice.pyramidhook import register_service_views

        self.logs = LogCapture()

    def tearDown(self):
        self.logs.uninstall()

    def test_service_metrics(self):
        stub_service = Service(name="stub", path="/stub")

        @stub_service.get()
        @metrics_timer("view_time")
        def stub_view(request):
            request.metrics["stub"] = "stub-a-dub-dub"
            return {}

        with pyramid.testing.testConfig() as config:
            config.include("cornice")
            config.include("mozsvc")
            register_service_views(config, stub_service)
            app = TestApp(config.make_wsgi_app())
            res = app.get("/stub")
            self.assertEqual(res.body, "{}")

        self.assertTrue(len(self.logs.records), 1)
        r = self.logs.records[0]
        self.assertEqual(r.stub, "stub-a-dub-dub")
        self.assertTrue(0 < r.request_time < 0.1)
        self.assertTrue(0 < r.view_time <= r.request_time)

    def test_timing_decorator(self):


        @metrics_timer("timer1")