{ "info": { "author": "Ruslan Spivak", "author_email": "ruslan.spivak@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: Unix", "Programming Language :: Python", "Topic :: Software Development :: Libraries" ], "description": "::\n\n _ ___ ___ ___ _ _ _\n | | / _ \\ / __/ __| \\| | /_\\\n | |_| (_) | (_ \\__ \\ .` |/ _ \\\n |____\\___/ \\___|___/_|\\_/_/ \\_\\\n\n\n**logsna** is a small Python library that provides a sane log output\nformat.\n\n`http://logsna.readthedocs.org `_\n\nInstallation\n------------\n\n::\n\n $ [sudo] pip install logsna\n\nOr the bleeding edge version from the git master branch:\n\n::\n\n $ [sudo] pip install git+https://github.com/rspivak/logsna.git#egg=logsna\n\n\nHow to use it\n-------------\n\n**logsna** provides a custom formatter class *logsna.Formatter* that can be used in a logging config file:\n\n::\n\n # sanefmt.py\n import logging\n import logging.config\n from StringIO import StringIO\n\n CONFIG = \"\"\"\\\n [loggers]\n keys=root\n\n [handlers]\n keys=console\n\n [handler_console]\n class=logging.StreamHandler\n args=(sys.stderr,)\n formatter=sane\n\n [formatters]\n keys=sane\n\n [logger_root]\n level=DEBUG\n handlers=console\n\n # Our custom formatter class\n [formatter_sane]\n class=logsna.Formatter\n \"\"\"\n\n config = StringIO(CONFIG)\n logging.config.fileConfig(config)\n\n log = logging.getLogger('mylogger.component1')\n\n log.debug('debug message')\n log.info('info message')\n log.warning('warning message')\n log.critical('critical message')\n try:\n 1 / 0\n except:\n log.exception('Houston we have a problem')\n\n\nThis is how to use it in code directly:\n\n::\n\n import logging\n\n import logsna\n\n # create logger\n log = logging.getLogger('mylogger.component1')\n log.setLevel(logging.DEBUG)\n\n # create console handler and set level to debug\n ch = logging.StreamHandler()\n ch.setLevel(logging.DEBUG)\n\n # create an instance of the sane formatter\n formatter = logsna.Formatter()\n\n # add our formatter to the console handler\n ch.setFormatter(formatter)\n\n # add the console handler to the logger\n log.addHandler(ch)\n\n log.debug('debug message')\n log.info('info message')\n log.warning('warning message')\n log.critical('critical message')\n try:\n 1 / 0\n except:\n log.exception('Houston we have a problem')\n\n\nThe Log Format\n--------------\n\nHere is an output from the above program:\n::\n\n DEBUG [2012-05-21 01:59:23,686] mylogger.component1: debug message\n INFO [2012-05-21 01:59:23,686] mylogger.component1: info message\n WARNING [2012-05-21 01:59:23,686] mylogger.component1: warning message\n CRITICAL [2012-05-21 01:59:23,686] mylogger.component1: critical message\n ERROR [2012-05-21 01:59:23,686] mylogger.component1: Houston we have a problem\n ! Traceback (most recent call last):\n ! File \"/home/alienoid/python/sanefmt.py\", line 67, in \n ! 1 / 0\n ! ZeroDivisionError: integer division or modulo by zero\n\n\nThe Log Format Goals\n--------------------\n\n1. To be human readable as much as possible\n\n2. Make it easy to use with standard Unix utilities **tail** and **grep**\n to help quickly figure out why things are going south\n\n\nThe Log Format Notes\n--------------------\n\n1. All timestamps are in **ISO8601** and **UTC** format\n\n2. To grep for messages of a specific level\n\n ::\n\n $ tail -f sanefmt.log | grep '^INFO'\n\n3. To grep for messages from a particular logger\n\n ::\n\n $ tail -f sanefmt.log | grep 'component1:'\n\n4. To pull out full exception tracebacks with a corresponding log message\n\n ::\n\n $ tail -f sanefmt.log | grep -B 1 '^\\!'\n\n The output of the above command will look like this\n\n ::\n\n ERROR [2012-05-21 01:59:23,686] mylogger.component1: Houston we have a problem\n ! Traceback (most recent call last):\n ! File \"fmttest.py\", line 72, in \n ! 1 / 0\n ! ZeroDivisionError: integer division or modulo by zero\n\n\nEnhancing The Log Format Output\n-------------------------------\n\nHere is the format string used by *Logsna* formatter:\n\n::\n\n '%(levelname)-8s [%(asctime)s] %(name)s: %(message)s'\n\nYou can explicitly specify it in your configuration file using **format**\ndirective\n\n::\n\n # Our custom formatter class\n [formatter_sane]\n format=%(levelname)-8s [%(asctime)s] %(name)s: %(message)s\n class=logsna.Formatter\n\nAnd you can also enhance the format string by adding your custom\nattributes to it if you need to.\nFor a set of predefined log record attributes see `here `_\n\nAcknowledgments\n---------------\n\n- `Release It! `_\n- `Logula `_\n\n\nLicense\n-------\n\nCopyright (c) 2012 Ruslan Spivak\n\nPublished under The MIT License, see LICENSE\n\nChange History\n==============\n1.2 (2012-10-02)\n----------------\n- Python 2.6.x compatibility\n\n1.1 (2012-05-21)\n----------------\n- Typo in setup.py: https://github.com/rspivak/logsna/pull/1\n\n1.0 (2012-05-21)\n----------------\n- Public release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rspivak/logsna", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "logsna", "package_url": "https://pypi.org/project/logsna/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/logsna/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/rspivak/logsna" }, "release_url": "https://pypi.org/project/logsna/1.2/", "requires_dist": null, "requires_python": null, "summary": "A small Python library that provides a sane log output format", "version": "1.2" }, "last_serial": 794337, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "59cf44034ab31dddb161e7e2fdb8638a", "sha256": "daaae3f07da909180cca5ae72aec9b2a65b1a599ca23f9b3abaa4c4cf6655352" }, "downloads": -1, "filename": "logsna-1.0.zip", "has_sig": false, "md5_digest": "59cf44034ab31dddb161e7e2fdb8638a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9064, "upload_time": "2012-05-21T05:21:05", "url": "https://files.pythonhosted.org/packages/db/63/f409606204b3f06be16525c97ea9511799bbfdd5c7288a1aaecb4692c129/logsna-1.0.zip" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "d74c85c0228d8e5f6e258df7479f6e40", "sha256": "f492c215090e9dca4bde82e853c472a521dae33b0b36024046606b4810dfee13" }, "downloads": -1, "filename": "logsna-1.1.zip", "has_sig": false, "md5_digest": "d74c85c0228d8e5f6e258df7479f6e40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9174, "upload_time": "2012-05-21T17:35:23", "url": "https://files.pythonhosted.org/packages/f9/ea/b3afd102e7e7466202000bde07fa93e13731f082129acc895fdd7c637d2f/logsna-1.1.zip" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "d08a764505ae309070b721d1cad754da", "sha256": "c6ce37cebafcc2e1f3f25c89f1c64c07106e96b264e860ff9a9dbfe5933236fa" }, "downloads": -1, "filename": "logsna-1.2.zip", "has_sig": false, "md5_digest": "d08a764505ae309070b721d1cad754da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10178, "upload_time": "2012-10-02T22:33:37", "url": "https://files.pythonhosted.org/packages/08/4b/16a8fe062b0c2520510bea6be2a1d165bc3ee2105cf945884b2834b551c1/logsna-1.2.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d08a764505ae309070b721d1cad754da", "sha256": "c6ce37cebafcc2e1f3f25c89f1c64c07106e96b264e860ff9a9dbfe5933236fa" }, "downloads": -1, "filename": "logsna-1.2.zip", "has_sig": false, "md5_digest": "d08a764505ae309070b721d1cad754da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10178, "upload_time": "2012-10-02T22:33:37", "url": "https://files.pythonhosted.org/packages/08/4b/16a8fe062b0c2520510bea6be2a1d165bc3ee2105cf945884b2834b551c1/logsna-1.2.zip" } ] }