{ "info": { "author": "Paul Wolf", "author_email": "paul.wolf@yewleaf.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "LogTrace\n========\n\n|Build Status|\n\nAggregate messages to produce a log entry representing a single event or\nprocedure. The purpose of this module is to easily asssociate log\nmessages together that belong together.\n\n::\n\n import logging\n from logtrace import LogTrace\n\n logger = logging.getLogger(__name__)\n trace = LogTrace(logger=logger)\n\n trace.add(\"Let's get started\")\n ...\n trace.add(\"Later, something else happens\")\n ...\n trace.add(\"And finally...\")\n\n trace.emit()\n\nYou get a single log entry like this:\n\n::\n\n [05/Jan/2018 11:11:00] DEBUG [21, .30s] Let's get started; [65, .132s] Later, something else happens; [75, .330s] And finally...\n\nInstall\n-------\n\n::\n\n pip install logtrace\n\nNote that this only suppports Python 3. Let me know if anyone wants\nsupport for Python 2. There are no dependencies outside the Python\nStandard Library for this module.\n\nExample\n-------\n\nLogs can be hard to read because you have cases where you log\ninformation as you go through a procedure. These log entries get\nscattered with all the other logs from other processes. You end up\nhaving to search for related entries possibly implanting identifying\ninformation in each one to tie them together. ``LogTrace`` fixes this\nproblem by letting you collect logs and then output once. Take the\nexample of a token authentication procedure where transient tokens are\nrequired to be authenticated. You want to record the following events:\n\n- Check the HTTP header info with the token\n- What table are we going to use to check the token?\n- Did the token service authenticate the token?\n- Is the token in a local cache?\n- Successfully authenticated?\n\nThe following records five separate instances where you would have\ncalled ``logger.info()`` with a line number and the time in seconds\nsince constructing the ``LogTrace`` object ``[, s]``:\n\n::\n\n [12:12:54] INFO [132, 0.0006s] auth header: [b'Token', b'2c59999137******************************']; [132, 0.0007s] authenticate key, model: ; [132, 0.1057s] token renewal for API call confirmed; [132, 0.1078s] got key from token table: paul; [163, 0.1079s] Successfully authenticated\n\nDetails\n-------\n\nWe respect logging levels. So, the overhead of using LogTrace is minimal\nif your log level is not effective. If your log level is\n``logging.INFO`` and you call ``logtrace.emit_debug()``, almost all\noverhead is avoided minus some function call overhead and one or two\nconditional expressions.\n\nWhat LogTrace is *not*: This is *not* a logging framework. LogTrace uses\nthe standard Python ``logging`` module. All your configuration to\n``logging`` is going to be used by LogTrace. All your handlers are going\nto act exactly as before. If you use a framework like Django, you use it\njust like you do now. No changes whatever are required to your logging\nconfiguration.\n\nWe also provide other features like\n\n- Easily generate a UUID for the logged event.\n\n- Timing for each message since LogTrace was created.\n\n- Frame information for each part message, like filename, function,\n lineno\n\n- Any logging mechanism can be used, not just standard Python logging.\n\n- Pass structured data (JSON).\n\nWe wanted to provide something that works in perfect harmony with the\nexisting Python logging module without unnecessary duplication of\nfeatures and no external dependencies (outside the PSL).\n\n::\n\n LogTrace(logger=None, # we'll emit output here\n delimiter=\"; \", # delimiter between messages\n tag='', # add a non-unique label \n unique_id=False, # create a uuid to identify the log?\n verbosity='v' # level of output for frame information\n )\n\n- ``logger``: the standard logger returned from\n ``import logging; logger = logging.getLogger(__name__)``. You can\n create a ``LogTrace()`` without a logger in which case it creates\n with the value of ``__name__``.\n\n- ``delimiter``: the character(s) used between messages\n\n- ``tag``: This is a convenience to tell LogTrace() to use hash+tag at\n the start of every entry after calling ``.emit()`` for ease of\n searching.\n\n- ``unique_id``: generate a uuid to associate with the final message\n output.\n\n- ``verbosity``: v, vv, vvv for three levels of verbosity when adding\n frame information\n\n``LogTrace.get_uid()``: return the unique id. If one has not been set\nduring construction of the LogTrace, a uuid is generated. Otherwise, it\nreturns the existing one.\n\n``LogTrace.set_uid(uid)``: Set a unique id. This can be done by\nconstructing ``LogTrace()`` with ``unique_id=True``. This takes normally\neither a uuid or str argument.\n\n``LogTrace.add(msg, data, backup)``: Add a message to the list. This\nwill get frame information for the call depending on the verbosity\nlevel.\n\n``LogTrace.emit_string()``: return a string that is the final log\nmessage.\n\n``LogTrace.emit()``: call ``logger.debug(message)``\n\n``LogTrace.emit_error()``: call ``logger.error(message)``\n\n``LogTrace.emit_info()``: call ``logger.info(message)``\n\n``LogTrace.emit_debug()``: call ``logger.debug(message)``\n\n``LogTrace.emit_warning()``: call ``logger.warning(message)``\n\n``LogTrace.emit_critical()``: call ``logger.critical(message)``\n\nWhen the ``LogTrace`` is created, ``time.time()`` is recorded. Whenever\n``LogTrace.add()`` is called, the start time is subtracted from the\ncurrent time when the message is added. The final message prints the\nnumber of seconds since creating.\n\nYou probably want to avoid including ``LogTrace.add()`` in loops. You\nalso probably want to create it as a local, not a module-level variable.\nPass it as a method argument rather than using a module level instance.\nIf you do want to re-use a ``LogTrace`` and clear messages, you can call\n``LogTrace.clear()``. But be aware the uid might need to be reset\ndepending on your application requirements.\n\nExtra Data\n----------\n\n``LogTrace.add()`` has an optional parameter ``data`` that takes a\ndictionary. We keep a dict in the object and ``update()`` it whenever\nthe ``data`` parameter is used. This doesn\u2019t do anything within\n``LogTrace`` itself other than maintain the ``data`` member variable.\nBut you can accumulate data and later ship the data to a service like\nAWS S3 or whatever, like this:\n\n::\n\n logger.info(trace.emit_string(), extra=trace.data)\n\nThis would be useful if you are using a logging handler that ships the\n``logging.LogRecord`` as JSON to some service like a document oriented\ndata store, Elasticsearch, etc.\n\nTesting\n-------\n\n::\n\n pip install pytest\n cd logtrace\n pytest test.py --verbose\n\nor\n\n::\n\n python3 logtrace/test.py\n\nPerformance\n-----------\n\n``LogTrace()`` appends to a list of strings everytime you call\n``add()``. But it firstly calls ``inspect.getFrameInfo()`` and builds\nthe string with that information. When ``emit()`` is called, it\nconcatenates all the strings in the list separated by ``delimiter`` and\nthen calls ``logger.info()`` or whatever method is appropriate. If the\neffective level is not the current level for the method, then the list\nwill be empty and it won\u2019t do the call to the ``logger`` method.\n\nAcknowledgements\n----------------\n\nThanks to\n\n.. @metazet: https://github.com/metazet\n\nFor important fixes.\n\n.. |Build Status| image:: https://travis-ci.org/paul-wolf/logtrace.svg?branch=master\n :target: https://travis-ci.org/paul-wolf/logtrace", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/paul-wolf/logtrace", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "LogTrace", "package_url": "https://pypi.org/project/LogTrace/", "platform": "", "project_url": "https://pypi.org/project/LogTrace/", "project_urls": { "Homepage": "https://github.com/paul-wolf/logtrace" }, "release_url": "https://pypi.org/project/LogTrace/0.1.2/", "requires_dist": null, "requires_python": "", "summary": "Aggregate Python log messages into a single log entry.", "version": "0.1.2" }, "last_serial": 4268108, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "9cd35ff150edb367dbefbb7992a9e5bb", "sha256": "7a81e7a24816b5fbd710daafbe08a3d301613746a862aa14743b9c7825dbefde" }, "downloads": -1, "filename": "LogTrace-0.1.0.tar.gz", "has_sig": false, "md5_digest": "9cd35ff150edb367dbefbb7992a9e5bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7167, "upload_time": "2018-01-01T11:55:20", "url": "https://files.pythonhosted.org/packages/5b/3b/7493fead5403364efd0b81b53525018026261e0e05f5a3cf98880fa3f6b3/LogTrace-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "c2d7c6e0091aa4bb416d753881e6fecf", "sha256": "4853e7d6bc83acaf0c9247281c20f331db5de3da38db96061f8918e702eefb89" }, "downloads": -1, "filename": "LogTrace-0.1.1.tar.gz", "has_sig": false, "md5_digest": "c2d7c6e0091aa4bb416d753881e6fecf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7995, "upload_time": "2018-01-14T13:59:13", "url": "https://files.pythonhosted.org/packages/9b/ca/a59f69e3c3951ab9f66883ebe93bc07c5b79010ebb94c7c504370042a694/LogTrace-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "37daaac662d0545e66be973048405894", "sha256": "ec3df90d6a18963b70cffbf444418fda75ab4fd130143a4c3c1e2699324b119e" }, "downloads": -1, "filename": "LogTrace-0.1.2.tar.gz", "has_sig": false, "md5_digest": "37daaac662d0545e66be973048405894", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8112, "upload_time": "2018-09-13T09:28:19", "url": "https://files.pythonhosted.org/packages/7d/4f/8997c4e792ff5b1924e6c84dbe303d31ca51558843ea3426075a9dce8e10/LogTrace-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "37daaac662d0545e66be973048405894", "sha256": "ec3df90d6a18963b70cffbf444418fda75ab4fd130143a4c3c1e2699324b119e" }, "downloads": -1, "filename": "LogTrace-0.1.2.tar.gz", "has_sig": false, "md5_digest": "37daaac662d0545e66be973048405894", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8112, "upload_time": "2018-09-13T09:28:19", "url": "https://files.pythonhosted.org/packages/7d/4f/8997c4e792ff5b1924e6c84dbe303d31ca51558843ea3426075a9dce8e10/LogTrace-0.1.2.tar.gz" } ] }