mirror of
https://github.com/sprockets/sprockets.mixins.metrics.git
synced 2024-11-23 19:29:52 +00:00
SYN
This commit is contained in:
commit
3bb6be0ffc
16 changed files with 337 additions and 0 deletions
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
coverage.xml
|
||||||
|
nosetests.xml
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
/.coverage
|
||||||
|
/build/
|
||||||
|
/dist/
|
||||||
|
/downloads/
|
||||||
|
/env/
|
||||||
|
/htmlcov/
|
15
.travis.yml
Normal file
15
.travis.yml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
language: python
|
||||||
|
python:
|
||||||
|
- 2.7
|
||||||
|
- 3.4
|
||||||
|
- 3.5
|
||||||
|
- pypy
|
||||||
|
before_install:
|
||||||
|
- pip install nose coverage codecov
|
||||||
|
- pip install -r requires/testing.txt
|
||||||
|
install:
|
||||||
|
- pip install -e .
|
||||||
|
script: nosetests
|
||||||
|
after_success:
|
||||||
|
- codecov
|
||||||
|
sudo: false
|
25
LICENSE
Normal file
25
LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2016 AWeber Communications
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of Sprockets nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
4
MANIFEST.in
Normal file
4
MANIFEST.in
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
include LICENSE
|
||||||
|
include tests.py
|
||||||
|
graft docs
|
||||||
|
graft requires
|
39
README.rst
Normal file
39
README.rst
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
sprockets.mixins.metrics
|
||||||
|
========================
|
||||||
|
Adjust counter and timer metrics in InfluxDB or Graphite using the same API.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sprockets.mixins import mediatype, metrics
|
||||||
|
from tornado import gen, web
|
||||||
|
import queries
|
||||||
|
|
||||||
|
class MyHandler(metrics.StatsdMixin, mediatype.ContentMixin,
|
||||||
|
web.RequestHandler):
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
super(MyHandler, self).initialize()
|
||||||
|
self.db = queries.TornadoSession(os.environ['MY_PGSQL_DSN'])
|
||||||
|
|
||||||
|
@gen.coroutine
|
||||||
|
def get(self, obj_id):
|
||||||
|
with self.execution_timer('dbquery.get'):
|
||||||
|
result = yield self.db.query('SELECT * FROM foo WHERE id=%s',
|
||||||
|
obj_id)
|
||||||
|
self.send_response(result)
|
||||||
|
|
||||||
|
This simple handler will emit a timer metric that identifies each call to the
|
||||||
|
``get`` method as well as a separate metric for the database query. Switching
|
||||||
|
from using `statsd`_ to `InfluxDB`_ is simply a matter of switch from the
|
||||||
|
``metrics.StatsdMixin`` to the ``metrics.InfluxDBMixin``.
|
||||||
|
|
||||||
|
Development Quickstart
|
||||||
|
----------------------
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ python3.4 -mvenv env
|
||||||
|
$ . ./env/bin/activate
|
||||||
|
(env)$ pip install -r requires/development.txt
|
||||||
|
|
||||||
|
.. _statsd: https://github.com/etsy/statsd
|
||||||
|
.. _InfluxDB: https://influxdata.com
|
41
docs/conf.py
Normal file
41
docs/conf.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import alabaster
|
||||||
|
from sprockets.mixins import metrics
|
||||||
|
|
||||||
|
project = 'sprockets.mixins.metrics'
|
||||||
|
copyright = 'AWeber Communications, Inc.'
|
||||||
|
version = metrics.__version__
|
||||||
|
release = '.'.join(str(v) for v in metrics.version_info[0:2])
|
||||||
|
|
||||||
|
needs_sphinx = '1.0'
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.intersphinx',
|
||||||
|
'sphinx.ext.viewcode',
|
||||||
|
]
|
||||||
|
|
||||||
|
templates_path = []
|
||||||
|
source_suffix = '.rst'
|
||||||
|
source_encoding = 'utf-8-sig'
|
||||||
|
master_doc = 'index'
|
||||||
|
exclude_patterns = []
|
||||||
|
pygments_style = 'sphinx'
|
||||||
|
html_style = 'custom.css'
|
||||||
|
html_static_path = ['.']
|
||||||
|
html_theme = 'alabaster'
|
||||||
|
html_theme_path = [alabaster.get_path()]
|
||||||
|
html_sidebars = {
|
||||||
|
'**': ['about.html', 'navigation.html'],
|
||||||
|
}
|
||||||
|
html_theme_options = {
|
||||||
|
'github_user': 'sprockets',
|
||||||
|
'github_repo': 'sprockets.mixins.metrics',
|
||||||
|
'description': 'Application metrics tracker',
|
||||||
|
'github_banner': True,
|
||||||
|
'travis_button': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
intersphinx_mapping = {
|
||||||
|
'python': ('http://docs.python.org/3/', None),
|
||||||
|
'tornado': ('http://tornadoweb.org/en/latest/', None),
|
||||||
|
}
|
112
docs/contributing.rst
Normal file
112
docs/contributing.rst
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
How to Contribute
|
||||||
|
=================
|
||||||
|
Do you want to contribute fixes or improvements?
|
||||||
|
|
||||||
|
**AWesome!** *Thank you very much, and let's get started.*
|
||||||
|
|
||||||
|
Set up a development environment
|
||||||
|
--------------------------------
|
||||||
|
The first thing that you need is a development environment so that you can
|
||||||
|
run the test suite, update the documentation, and everything else that is
|
||||||
|
involved in contributing. The easiest way to do that is to create a virtual
|
||||||
|
environment for your endevours::
|
||||||
|
|
||||||
|
$ virtualenv -p python2.7 env
|
||||||
|
|
||||||
|
Don't worry about writing code against previous versions of Python unless
|
||||||
|
you you don't have a choice. That is why we run our tests through `tox`_.
|
||||||
|
If you don't have a choice, then install `virtualenv`_ to create the
|
||||||
|
environment instead. The next step is to install the development tools
|
||||||
|
that this project uses. These are listed in *requires/development.txt*::
|
||||||
|
|
||||||
|
$ env/bin/pip install -qr requires/development.txt
|
||||||
|
|
||||||
|
At this point, you will have everything that you need to develop at your
|
||||||
|
disposal. *setup.py* is the swiss-army knife in your development tool
|
||||||
|
chest. It provides the following commands:
|
||||||
|
|
||||||
|
**./setup.py nosetests**
|
||||||
|
Run the test suite using `nose`_ and generate a nice coverage report.
|
||||||
|
|
||||||
|
**./setup.py build_sphinx**
|
||||||
|
Generate the documentation using `sphinx`_.
|
||||||
|
|
||||||
|
**./setup.py flake8**
|
||||||
|
Run `flake8`_ over the code and report style violations.
|
||||||
|
|
||||||
|
If any of the preceding commands give you problems, then you will have to
|
||||||
|
fix them **before** your pull request will be accepted.
|
||||||
|
|
||||||
|
Running Tests
|
||||||
|
-------------
|
||||||
|
The easiest (and quickest) way to run the test suite is to use the
|
||||||
|
*nosetests* command. It will run the test suite against the currently
|
||||||
|
installed python version and report not only the test result but the
|
||||||
|
test coverage as well::
|
||||||
|
|
||||||
|
$ ./setup.py nosetests
|
||||||
|
|
||||||
|
running nosetests
|
||||||
|
running egg_info
|
||||||
|
writing dependency_links to sprockets.http.egg-info/dependency_links.txt
|
||||||
|
writing top-level names to sprockets.http.egg-info/top_level.txt
|
||||||
|
writing sprockets.http.egg-info/PKG-INFO
|
||||||
|
reading manifest file 'sprockets.http.egg-info/SOURCES.txt'
|
||||||
|
reading manifest template 'MANIFEST.in'
|
||||||
|
warning: no previously-included files matching '__pycache__'...
|
||||||
|
warning: no previously-included files matching '*.swp' found ...
|
||||||
|
writing manifest file 'sprockets.http.egg-info/SOURCES.txt'
|
||||||
|
...
|
||||||
|
|
||||||
|
Name Stmts Miss Branch BrMiss Cover Missing
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
...
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
TOTAL 95 2 59 2 97%
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Ran 44 tests in 0.054s
|
||||||
|
|
||||||
|
OK
|
||||||
|
|
||||||
|
That's the quick way to run tests. The slightly longer way is to run
|
||||||
|
the `detox`_ utility. It will run the test suite against all of the
|
||||||
|
supported python versions in parallel. This is essentially what Travis-CI
|
||||||
|
will do when you issue a pull request anyway::
|
||||||
|
|
||||||
|
$ env/bin/detox
|
||||||
|
py27 recreate: /.../sprockets.http/build/tox/py27
|
||||||
|
GLOB sdist-make: /.../sprockets.http/setup.py
|
||||||
|
py34 recreate: /.../sprockets.http/build/tox/py34
|
||||||
|
py27 installdeps: -rtest-requirements.txt, mock
|
||||||
|
py34 installdeps: -rtest-requirements.txt
|
||||||
|
py27 inst: /.../sprockets.http/build/tox/dist/sprockets.http-0.0.0.zip
|
||||||
|
py27 runtests: PYTHONHASHSEED='2156646470'
|
||||||
|
py27 runtests: commands[0] | /../sprockets.http/build/tox/py27/bin/nosetests
|
||||||
|
py34 inst: /../sprockets.http/.build/tox/dist/sprockets.http-0.0.0.zip
|
||||||
|
py34 runtests: PYTHONHASHSEED='2156646470'
|
||||||
|
py34 runtests: commands[0] | /.../sprockets.http/build/tox/py34/bin/nosetests
|
||||||
|
_________________________________ summary _________________________________
|
||||||
|
py27: commands succeeded
|
||||||
|
py34: commands succeeded
|
||||||
|
congratulations :)
|
||||||
|
|
||||||
|
This is what you want to see. Now you can make your modifications and keep
|
||||||
|
the tests passing.
|
||||||
|
|
||||||
|
Submitting a Pull Request
|
||||||
|
-------------------------
|
||||||
|
Once you have made your modifications, gotten all of the tests to pass,
|
||||||
|
and added any necessary documentation, it is time to contribute back for
|
||||||
|
posterity. You've probably already cloned this repository and created a
|
||||||
|
new branch. If you haven't, then checkout what you have as a branch and
|
||||||
|
roll back *master* to where you found it. Then push your repository up
|
||||||
|
to github and issue a pull request. Describe your changes in the request,
|
||||||
|
if Travis isn't too annoyed someone will review it, and eventually merge
|
||||||
|
it back.
|
||||||
|
|
||||||
|
.. _flake8: http://flake8.readthedocs.org/
|
||||||
|
.. _nose: http://nose.readthedocs.org/
|
||||||
|
.. _sphinx: http://sphinx-doc.org/
|
||||||
|
.. _detox: http://testrun.org/tox/
|
||||||
|
.. _tox: http://testrun.org/tox/
|
||||||
|
.. _virtualenv: http://virtualenv.pypa.io/
|
4
docs/custom.css
Normal file
4
docs/custom.css
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@import url("alabaster.css");
|
||||||
|
h1.logo {
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
9
docs/history.rst
Normal file
9
docs/history.rst
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.. :changelog:
|
||||||
|
|
||||||
|
Release History
|
||||||
|
===============
|
||||||
|
|
||||||
|
`Next Release`_
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. _Next Release: https://github.com/sprockets/sprockets.mixins.metrics/compare/0.0.0...master
|
11
docs/index.rst
Normal file
11
docs/index.rst
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.. include:: ../README.rst
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
.. include:: ../LICENSE
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:hidden:
|
||||||
|
|
||||||
|
contributing
|
||||||
|
history
|
1
requires/development.txt
Normal file
1
requires/development.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Sphinx
|
60
setup.py
Executable file
60
setup.py
Executable file
|
@ -0,0 +1,60 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import setuptools
|
||||||
|
|
||||||
|
from sprockets.mixins import metrics
|
||||||
|
|
||||||
|
|
||||||
|
def read_requirements(name):
|
||||||
|
requirements = []
|
||||||
|
try:
|
||||||
|
with open(os.path.join('requires', name)) as req_file:
|
||||||
|
for line in req_file:
|
||||||
|
if '#' in line:
|
||||||
|
line = line[:line.index('#')]
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith('-r'):
|
||||||
|
requirements.extend(read_requirements(line[2:].strip()))
|
||||||
|
elif line and not line.startswith('-'):
|
||||||
|
requirements.append(line)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return requirements
|
||||||
|
|
||||||
|
|
||||||
|
setuptools.setup(
|
||||||
|
name='sprockets.mixins.metrics',
|
||||||
|
version=metrics.__version__,
|
||||||
|
description='Record performance metrics about your application',
|
||||||
|
long_description='\n'+open('README.rst').read(),
|
||||||
|
author='AWeber Communications',
|
||||||
|
author_email='api@aweber.com',
|
||||||
|
license='BSD',
|
||||||
|
url='https://github.com/sprockets/sprockets.mixins.metrics',
|
||||||
|
install_requires=read_requirements('installation.txt'),
|
||||||
|
tests_require=read_requirements('testing.txt'),
|
||||||
|
packages=setuptools.find_packages(),
|
||||||
|
namespace_packages=['sprockets', 'sprockets.mixins'],
|
||||||
|
classifiers=[
|
||||||
|
'Development Status :: 1 - Planning',
|
||||||
|
'Environment :: No Input/Output (Daemon)',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'License :: OSI Approved :: BSD License',
|
||||||
|
'Natural Language :: English',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'Programming Language :: Python :: 2',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Programming Language :: Python :: 3.4',
|
||||||
|
'Programming Language :: Python :: 3.5',
|
||||||
|
'Programming Language :: Python :: Implementation :: CPython',
|
||||||
|
'Programming Language :: Python :: Implementation :: PyPy',
|
||||||
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
|
'Topic :: Software Development :: Libraries',
|
||||||
|
'Topic :: Software Development :: Libraries :: Python Modules'],
|
||||||
|
test_suite='nose.collector',
|
||||||
|
zip_safe=True,
|
||||||
|
)
|
1
sprockets/__init__.py
Normal file
1
sprockets/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
__import__('pkg_resources').declare_namespace(__name__)
|
1
sprockets/mixins/__init__.py
Normal file
1
sprockets/mixins/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
__import__('pkg_resources').declare_namespace(__name__)
|
2
sprockets/mixins/metrics/__init__.py
Normal file
2
sprockets/mixins/metrics/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
version_info = (0, 0, 0)
|
||||||
|
__version__ = '.'.join(str(v) for v in version_info)
|
0
tests.py
Normal file
0
tests.py
Normal file
Loading…
Reference in a new issue