{ "info": { "author": "W. Trevor King", "author_email": "wking@tremily.us", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": ".. -*- coding: utf-8 -*-\n\n========================\nGetting Started With bes\n========================\n\nbes is a flexible `bulk uploader`_ for `Elastic Search`_. At the\nmoment, it only supports index uploads `over UDP`_. You can retrieve\nthe logged data from Elastic Search and analyze it dynamically using\nKibana_ (source__). This package just makes the initial upload to\nElastic Search as painless as possible.\n\n__ `Kibana source`_\n\nThe connection parameters and other configuration options are stored\nin ``bes.DEFAULT``. Override them as you see fit (e.g. to connect to\na remote Elastic Search server)::\n\n >>> import bes\n >>> bes.DEFAULT['host'] = 'my-es-server.example.com'\n\nThen log away::\n\n >>> bes.log(type='record', user='jdoe', action='swims')\n\nIf you are so inclined, you can override the ``DEFAULT`` index_ on a\nper-call basis::\n\n >>> bes.log(index='my-index', type='my-type', user='jdoe', action='bikes')\n\nThe log generated by the above will look like::\n\n {\n \"@timestamp\": \"2013-09-26T16:34:09.179048\",\n \"@version\": 1,\n \"action\": \"bikes\",\n \"user\": \"jdoe\"\n }\n\nfollowing Jordan Sissel's `new format`__ for Logstash_:\n\n__ `Logstash format`_\n\nYou should specify a unique type_ for each record you create, because\nElastic Search doesn't recalculate its mapping_ if you post a new\nevent that uses an old key with a new data type. If you are only\nlogging a single record type, you can configure a global default::\n\n >>> bes.DEFAULT['type'] = 'record'\n >>> bes.log(user='jdoe', action='runs')\n\nDjango\n======\n\nAlthough the core of the library is framework-agnostic, we'll be using\nthis to log events in a Django_ website. There are a few helpers for\nextracting information from HttpRequest_ to make this as easy as\npossible. Drop it into your views__ with somthing like::\n\n import django.http\n imort django.shortcuts\n import bes.django\n from polls.models import Poll\n\n def detail(request, poll_id):\n try:\n p = Poll.objects.get(pk=poll_id)\n except Poll.DoesNotExist:\n bes.django.log_user_request_path(\n request=request, type='404', poll_id=poll_id)\n raise django.http.Http404\n bes.django.log_user_request_path(\n request=request, type='poll-detail',\n poll_id=poll_id, poll_name=p.name)\n return django.shortcutsrender_to_response(\n 'polls/detail.html', {'poll': p})\n\n__ `Django views`_\n\nYou can also override bes' defaults in your Django config::\n\n BULK_ELASTIC_SEARCH_LOGGING_HOST = 'my-es-server.example.com'\n\nThe Django config names match the uppercased ``DEFAULT`` keys with a\n``BULK_ELASTIC_SEARCH_LOGGING_`` prefix (for example, ``host`` \u2192\n``BULK_ELASTIC_SEARCH_LOGGING_HOST``).\n\nTracing\n=======\n\nTo log activity for critical functions, bes has tracing decorators::\n\n import bes.trace\n\n @bes.trace.trace()\n def my_function():\n return 1 + 2 / 3\n\nBy default this logs with ``bes.log`` using the decorated function's\nname (e.g. ``my_function``) as the log type. You can override this if\nyou want something different::\n\n def my_logger(*args, **kwargs):\n print((args, kwargs))\n\n @bes.trace.trace(type='my-type', logger=my_logger)\n def my_function():\n return 1 + 2 / 3\n\nAdditional ``trace`` arguments are passed straight through to the\nlogger::\n\n @bes.trace.trace(index='my-index', type='my-type', sport='triathalon')\n def my_function():\n return 1 + 2 / 3\n\nBy default, you'll get separate logged messages before the decorated\nfunction starts, after it completes, or if it raises an exception. An\n``action`` argument is passed to the logger in each case, with values\nof ``start``, ``complete``, and ``error`` respectively. In the error\ncase, the logger is also passed the string-ified exception\n(``error=str(e)``) to help with debugging the problem. If you don't\nwant one or more of these logged messages, you can turn them off::\n\n @bes.trace.trace(start=False, error=False, complete=False):\n def my_function():\n return 1 + 2 / 3\n\nalthough if you turn them all off, you're not going to get any\nmessages at all ;).\n\nThe trace decorator uses wrapt_ (if it's installed) to create\nintrospection-preserving decorators. If wrapt is not installed, we\nfallback to the builtin `functools.wraps`_ which handles the basics\nlike docstrings, but doesn't do as well for more involved\nintrospection (e.g. `inspect.getsource`_).\n\nTesting\n=======\n\nTesting uses unittest's `automatic test discovery`_. Run the test\nsuite with::\n\n $ python -m unittest discover\n\nFor Python <3.3, the test suite requires the external mock_ package,\nwhich is bundled as `unittest.mock`_ in Python 3.3.\n\n.. _Elastic Search: http://www.elasticsearch.org/\n.. _bulk uploader: http://www.elasticsearch.org/guide/reference/api/bulk/\n.. _over UDP: http://www.elasticsearch.org/guide/reference/api/bulk-udp/\n.. _Kibana: http://www.elasticsearch.org/overview/kibana/\n.. _Kibana source: https://github.com/elasticsearch/kibana\n.. _index: http://www.elasticsearch.org/guide/reference/glossary/#field\n.. _type: http://www.elasticsearch.org/guide/reference/glossary/#type\n.. _mapping: http://www.elasticsearch.org/guide/reference/mapping/\n.. _Logstash: http://logstash.net/\n.. _Logstash format: https://logstash.jira.com/browse/LOGSTASH-675\n.. _Django: https://www.djangoproject.com/\n.. _HttpRequest:\n https://docs.djangoproject.com/en/dev/ref/request-response/#httprequest-objects\n.. _Django views: https://docs.djangoproject.com/en/dev/topics/http/views/\n.. _wrapt: https://github.com/GrahamDumpleton/wrapt\n.. _functools.wraps:\n http://docs.python.org/3/library/functools.html#functools.wraps\n.. _inspect.getsource:\n http://docs.python.org/3/library/inspect.html#inspect.getsource\n.. _automatic test discovery:\n http://docs.python.org/3/library/unittest.html#unittest-test-discovery\n.. _mock: https://pypi.python.org/pypi/mock\n.. _unittest.mock: http://docs.python.org/3/library/unittest.mock.html", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/wking/bes/archive/v0.3.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/wking/bes", "keywords": null, "license": "BSD License", "maintainer": null, "maintainer_email": null, "name": "bes", "package_url": "https://pypi.org/project/bes/", "platform": "all", "project_url": "https://pypi.org/project/bes/", "project_urls": { "Download": "https://github.com/wking/bes/archive/v0.3.tar.gz", "Homepage": "https://github.com/wking/bes" }, "release_url": "https://pypi.org/project/bes/0.3/", "requires_dist": null, "requires_python": null, "summary": "Log actions to Elastic Search via bulk upload", "version": "0.3" }, "last_serial": 875481, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "d81b6c1306b8c35cb7b21b79931bd23e", "sha256": "7f61cd9076ba531ba5771297263c06e145b5b563b13ec8207b2ec4cba959846a" }, "downloads": -1, "filename": "bes-0.1.tar.gz", "has_sig": false, "md5_digest": "d81b6c1306b8c35cb7b21b79931bd23e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4538, "upload_time": "2013-09-26T05:16:23", "url": "https://files.pythonhosted.org/packages/58/f3/9246ca589b6c3c593aa6f97c30bf8cb74969127410f75f9c14d607a29313/bes-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "af0efa78ff32e6c76a4e2d6948ad5c86", "sha256": "8582a07ee608caa67f6743d757cfcd649277eaa34ec6a7e3c24fb6b7331e06d2" }, "downloads": -1, "filename": "bes-0.2.tar.gz", "has_sig": false, "md5_digest": "af0efa78ff32e6c76a4e2d6948ad5c86", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6907, "upload_time": "2013-09-26T18:22:08", "url": "https://files.pythonhosted.org/packages/cc/ee/26ea5d6b9387a2061a8e7ff7ed622cb0e875b7afd4d41f2a7ba19da13f87/bes-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "b6a87e8514067414b84f0e4f922194bb", "sha256": "756de58580426589b977c33577d9ea11866a7467cb296c092650c6c460b067d5" }, "downloads": -1, "filename": "bes-0.3.tar.gz", "has_sig": false, "md5_digest": "b6a87e8514067414b84f0e4f922194bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9027, "upload_time": "2013-09-27T17:43:30", "url": "https://files.pythonhosted.org/packages/d8/ea/53248d24ed9c636f56089dd0f96d7f8dc3ec98fa9fd5828b95ecc72ace5e/bes-0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b6a87e8514067414b84f0e4f922194bb", "sha256": "756de58580426589b977c33577d9ea11866a7467cb296c092650c6c460b067d5" }, "downloads": -1, "filename": "bes-0.3.tar.gz", "has_sig": false, "md5_digest": "b6a87e8514067414b84f0e4f922194bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9027, "upload_time": "2013-09-27T17:43:30", "url": "https://files.pythonhosted.org/packages/d8/ea/53248d24ed9c636f56089dd0f96d7f8dc3ec98fa9fd5828b95ecc72ace5e/bes-0.3.tar.gz" } ] }