{ "info": { "author": "Andreas Bontozoglou", "author_email": "bodozoglou@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: System :: Logging" ], "description": "# LazyLog\n\n[](https://travis-ci.com/urban-1/lazylog)\n[](http://lazylog.readthedocs.io/en/latest/?badge=latest)\n\n\nYet another python logger that aims to:\n\n- Simplify logging setup - down to config and a single line\n- Be minimal - single file, no dependencies\n- Support console and file logging with different log levels, different format\n and file rotation out of the box\n- Prettify an align console output to be more human readable\n- Allow for easy JSON logging (TODO)\n- \"Fix some issues\" of the default logging facility:\n - Handles new-lines in messages by either re-adding the preamble or escaping\n the new-line characters\n - Adds color to the console, based on the log level\n - Prettifies basic structures (list, dicts and tuples)\n - Handles logfile permissions for multi-user deployments\n - Supports easy logger mocking (into StringIO)\n\n## Install\n\nYou can install this lib via `pip`:\n\n pip install lazylog\n\nor you can just download the code in your project:\n\n curl https://raw.githubusercontent.com/urban-1/lazylog/master/lazylog/__init__.py > /path/to/lazylog.py\n\n## Usage\n\n**NOTE:** For pretty colors on this README please visit the\n[readthedocs version](http://lazylog.readthedocs.io/en/latest/)\n\n**NOTE2:** You can find all the sources of this section in `examples` folder\n\n### Basics\n\nIn the simplest form, you can initialize `lazylog` with:\n\n # Import the Logger class\n from lazylog import Logger\n\n # Initialize with all defaults\n Logger.init()\n\n\nThis creates a console-only logger with all the values set to their defaults:\n\n {\n 'color': True,\n 'splitLines': True,\n 'level': logging.DEBUG,\n 'pretty': True\n }\n\n- `color`: Instructs `lazylog` to use different colors for different levels\n- `splitLines`: Enables handling new-lines by re-printing the preamble on every\n line\n- `level`: As usual, sets the logging level for the terminal\n- `pretty`: Enables prettifying dicts, lists and tuples to be more readable\n\nOnce initialized you can use the `logging` module as usual - nothing special:\n\n```python\nlogging.debug(\"This is an example log line\")\nlogging.info(\"This logger handles\\nNew\\nLines\")\nlogging.warning({\"also\": \"handles basic structures\", \"like\": list(\"lists\"), \"and\": (\"colors\", \"!\")})\nlogging.error(\"Errors stick out\")\nlogging.critical(\"but critical sticks out more...\")\n```\n\nThe output should look like:\n\n
\n08-05-2018 21:40:16.943 13859:139943539918656 DEBUG console 17 : This is an example log line\n08-05-2018 21:40:16.943 13859:139943539918656 INFO console 18 : This logger handles\n08-05-2018 21:40:16.943 13859:139943539918656 INFO console 18 : New\n08-05-2018 21:40:16.943 13859:139943539918656 INFO console 18 : Lines\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : (dict) {\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 'and': (\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 'colors',\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : '!'\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : ),\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 'like': [\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 'l',\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 'i',\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 's',\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 't',\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 's'\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : ],\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : 'also': 'handles basic structures'\n08-05-2018 21:40:16.943 13859:139943539918656 WARNING console 19 : }\n08-05-2018 21:40:16.943 13859:139943539918656 ERROR console 20 : Errors stick out\n08-05-2018 21:40:16.943 13859:139943539918656 CRITICAL console 21 : but critical sticks out more...\n\n\n\n### Customizing\n\nYou can customize `lazylog` and disable any of the features you don't like, so\n\n```python\n# Init\ntermSpecs = {\"level\": logging.DEBUG, \"splitLines\": False, \"pretty\": False }\nLogger.init(LOGDIR, termSpecs=termSpecs)\n\n# Use ...\nlogging.debug(\"You can remove all the fancy stuff:\")\nlogging.info(\"... keeping\\n each message\\n in its own line\")\nlogging.warning({\"and\": \"flatten structures\", \"like\": list(\"lists\")})\n```\n\ngives you:\n\n08-05-2018 21:19:40.688 11639:140599510849344 DEBUG console_customi 18 : You can remove all the fancy stuff:\n08-05-2018 21:19:40.689 11639:140599510849344 INFO console_customi 19 : ... keeping\\n each message\\n in its own line\n08-05-2018 21:19:40.689 11639:140599510849344 WARNING console_customi 20 : {'like': ['l', 'i', 's', 't', 's'], 'and': 'flatten structures'}\n\n\n... while initializing with:\n\n```python\ntermSpecs = {\"level\": logging.DEBUG, \"splitLines\": True, \"pretty\": False }\n```\n\ngives you:\n\n08-05-2018 21:30:05.312 12648:140218785630016 ERROR console_customi 25 : However,\n08-05-2018 21:30:05.312 12648:140218785630016 ERROR console_customi 25 : You can choose to split\n08-05-2018 21:30:05.312 12648:140218785630016 ERROR console_customi 25 : lines\n08-05-2018 21:30:05.312 12648:140218785630016 CRITICAL console_customi 26 : ['but', 'not', 'prettify\\nstructs']\n\n\nOf course you can disable everything, falling back to the default `logging`\nbehaviour with the only difference being the log format:\n\n08-05-2018 21:30:05.312 12648:140218785630016 INFO console_customi 31 : Boooriiiing\n\n\nFinally, in the `init()` function you can override the default format and date\nformat by passing `fmt` and `datefmt` parameters. The defaults are:\n\n```python\nDATEFORMAT = '%d-%m-%Y %H:%M:%S'\nLOGFORMAT = '%(asctime)s.%(msecs)03d %(process)s:%(thread)u %(levelname)-8s %(module)15.15s %(lineno)-4s: %(message)s'\n```\n\n### Files\n\nIn case where you (the developer) are not the one running the code, you most\nprobably need a log-file! If your application is a CLI one, probably the end-user\nshould not be seeing all the debugging info, but warnings and errors only. Python\nlogging facility supports multiple handlers working simultaneously and `lazylog`\nallows you to use this feature hassle-free. To define a file logger do:\n\n termSpecs = {\"level\": logging.DEBUG}\n fileSpecs = [{\"filename\": LOGFILE, \"level\":logging.DEBUG}]\n Logger.init(LOGDIR, termSpecs=termSpecs, fileSpecs=fileSpecs)\n\nThe above creates a file in `LOGDIR/LOGFILE` with the default settings which are:\n\n```python\n {\n 'format': 'console'\n 'backupCount': 20\n 'maxBytes': 10000000 # 10MB\n 'color': False,\n 'splitLines': True,\n 'pretty': False\n }\n```\n\n- `backupCount`: Is the number of files we keep\n- `maxBytes`: Is the maximum file size, after which rotation takes place\n- `format`: Controls which LogFormatter is being used. By default the\n ColorFormatter is used and thus the options `color`, `splitLines` and\n `pretty` are also supported. Other values include: `default` and `json`\n which we will see later on\n\nThe above settings produce the following output in the file:\n\n```text\n08-05-2018 15:57:24.118 16142:140509479982912 DEBUG logfile 23 : ^---same as console, this is an example log line\n08-05-2018 15:57:24.118 16142:140509479982912 INFO logfile 24 : This logger handles\n08-05-2018 15:57:24.118 16142:140509479982912 INFO logfile 24 : New\n08-05-2018 15:57:24.118 16142:140509479982912 INFO logfile 24 : Lines\n08-05-2018 15:57:24.119 16142:140509479982912 WARNING logfile 25 : {'but': 'Flattens structs by default'}\n08-05-2018 15:57:24.119 16142:140509479982912 ERROR logfile 26 : Errors DONT stick out - color is not used\n```\n\nwith `splitLines: False` you get:\n\n```text\n# Code:\n# logging.info(\"Like console\\nYou can avoid\\nsplitting lines\")\n\n08-05-2018 15:57:24.119 16142:140509479982912 INFO logfile 42 : Like console\\nYou can avoid\\nsplitting lines\n```\n\n\nwhile with `pretty: True` you get:\n\n```text\n# Code:\n# logging.info({\"or\": \"enable prettifying!\"})\n\n08-05-2018 15:57:24.120 16142:140509479982912 INFO logfile 55 : (dict) {\n08-05-2018 15:57:24.120 16142:140509479982912 INFO logfile 55 : 'or': 'enable prettifying!'\n08-05-2018 15:57:24.120 16142:140509479982912 INFO logfile 55 : }\n```\n\n#### JSON format\n\nJSON logging is most useful when we need to index our logs to a database or\nstream them and generally for machine-to-machine communication. At the moment,\n`lazylog` does not support JSON logging on the terminal but does support it\nfor files. To enable it, initialize with:\n\n```python\nfileSpecs = [{\"filename\": LOGFILE, \"level\":logging.DEBUG, \"format\":\"json\"}]\n```\n\nThe following ways of logging are supported:\n\n```python\nlogging.info(\"Simple str message\")\nlogging.warning(\"Message with metadata\", extra={\"user\": \"nwj12\"})\nlogging.debug({\"what\": \"dict-based logging\"}, extra={\"user\": \"asd32\"})\nlogging.info([\"anything\", \"json\", \"serializable\", \"see OBJECT\"], extra={\"foo\":\"bar\"})\n```\n\nand the results will be (each one in a single line in the logfile):\n\n```json\n{\n \"filename\": \"logfile.py\",\n \"module\": \"logfile\",\n \"timestamp\": 1525799704.8904743,\n \"message\": \"Simple str message\",\n \"thread\": 140193498228544,\n \"levelname\": \"INFO\",\n \"process\": 27529\n}\n\n{\n \"filename\": \"logfile.py\",\n \"user\": \"nwj12\",\n \"module\": \"logfile\",\n \"timestamp\": 1525799704.890644,\n \"message\": \"Message with metadata\",\n \"thread\": 140193498228544,\n \"levelname\": \"WARNING\",\n \"process\": 27529\n}\n\n{\n \"filename\": \"logfile.py\",\n \"user\": \"asd32\",\n \"module\": \"logfile\",\n \"what\": \"dict-based logging\",\n \"timestamp\": 1525799704.8907733,\n \"message\": \"\",\n \"process\": 27529,\n \"levelname\": \"DEBUG\",\n \"thread\": 140193498228544\n}\n\n{\n \"filename\": \"logfile.py\",\n \"timestamp\": 1525799704.8909438,\n \"module\": \"logfile\",\n \"thread\": 140193498228544,\n \"foo\": \"bar\",\n \"message\": \"\",\n \"process\": 27529,\n \"levelname\": \"INFO\",\n \"object\": [\n \"anything\",\n \"json\",\n \"serializable\",\n \"see OBJECT\"\n ]\n}\n\n\n```\n\nFinally, one can have multiple log files with different formats and log levels.\nThis can be done either on initialization state, or later on with `addFileLogger`\nmethod:\n\n```python\n# On init:\nfileSpecs = [\n {\"filename\": LOGFILE, \"level\":logging.DEBUG, \"format\":\"json\"},\n {\"filename\": LOGFILE2, \"level\":logging.INFO}\n]\nLogger.init(LOGDIR, termSpecs=termSpecs, fileSpecs=fileSpecs)\n\n# Later-on:\nfileSpecs2 = {\"filename\": LOGFILE2, \"level\":logging.INFO}\nLogger.addFileLogger(fileSpecs2)\n```\n\n#### Default format\n\nI would really not suggest this... but you get\n\n```text\n# Code:\n# logging.info(\"You\\n can set the \\n format to\\n default\")\n# logging.warning(\"But I don't like it...\")\n\n08-05-2018 15:57:24.120 16142:140509479982912 INFO logfile 70 : You\n can set the\n format to\n default\n08-05-2018 15:57:24.120 16142:140509479982912 WARNING logfile 71 : But I don't like it...\n```\n\n\n\n## Acknowledgements\n\nThis project has been put together by bits and pieces of code over fairly long\ntime (and \"as required\"). I have rewritten lots of parts, cleaned up and packaged\nit in a reusable form. However, lots of other people's code is included and as\nyou will see in the comments in the source, credit is given when applicable.\nJust to mention some (for the ones that will not read the source):\n\n- Merging dicts: https://stackoverflow.com/a/20666342/3727050\n- JSON file logging: https://github.com/madzak/python-json-logger\n- Prettifying structures:: http://stackoverflow.com/questions/3229419/pretty-printing-nested-dictionaries-in-python",
"description_content_type": "text/markdown",
"docs_url": null,
"download_url": "https://github.com/urban-1/lazylog/archive/master.tar.gz",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "http://lazylog.readthedocs.io/en/latest/",
"keywords": "logging,color,logfile,json",
"license": "",
"maintainer": "",
"maintainer_email": "",
"name": "lazylog",
"package_url": "https://pypi.org/project/lazylog/",
"platform": "",
"project_url": "https://pypi.org/project/lazylog/",
"project_urls": {
"Documentation": "http://lazylog.readthedocs.io/en/latest/",
"Download": "https://github.com/urban-1/lazylog/archive/master.tar.gz",
"Homepage": "http://lazylog.readthedocs.io/en/latest/",
"Source": "https://github.com/urban-1/lazylog",
"Tracker": "https://github.com/urban-1/lazylog/issues"
},
"release_url": "https://pypi.org/project/lazylog/0.2.4/",
"requires_dist": null,
"requires_python": "",
"summary": "Yet another python logger that simplifies json file logging and prettifies console output",
"version": "0.2.4"
},
"last_serial": 3851374,
"releases": {
"0.2.3": [
{
"comment_text": "",
"digests": {
"md5": "e2247e985415d4953afdfb79c6f8be5f",
"sha256": "2979d18f1420405c54b36654ad8dc3990cf2e84f581739558248852bdc823594"
},
"downloads": -1,
"filename": "lazylog-0.2.3.tar.gz",
"has_sig": false,
"md5_digest": "e2247e985415d4953afdfb79c6f8be5f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12691,
"upload_time": "2018-05-10T11:24:46",
"url": "https://files.pythonhosted.org/packages/66/ab/55649b833cb2ff12dd466acdfcc228985faa8343f1c164ae1d9d4abce4a5/lazylog-0.2.3.tar.gz"
}
],
"0.2.4": [
{
"comment_text": "",
"digests": {
"md5": "328bcf7cdf4f3ed0121f257ffdc96f32",
"sha256": "b9200eb5206e501d03c597d12c9ac71b776269a9f2f3c2b96a89d134c4fe4ec6"
},
"downloads": -1,
"filename": "lazylog-0.2.4.tar.gz",
"has_sig": false,
"md5_digest": "328bcf7cdf4f3ed0121f257ffdc96f32",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12709,
"upload_time": "2018-05-10T18:27:11",
"url": "https://files.pythonhosted.org/packages/6b/b3/4404051dc03cf4c95763d7c08b9f3154e3aeb6362e9d765ae00de2c1fefa/lazylog-0.2.4.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "328bcf7cdf4f3ed0121f257ffdc96f32",
"sha256": "b9200eb5206e501d03c597d12c9ac71b776269a9f2f3c2b96a89d134c4fe4ec6"
},
"downloads": -1,
"filename": "lazylog-0.2.4.tar.gz",
"has_sig": false,
"md5_digest": "328bcf7cdf4f3ed0121f257ffdc96f32",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12709,
"upload_time": "2018-05-10T18:27:11",
"url": "https://files.pythonhosted.org/packages/6b/b3/4404051dc03cf4c95763d7c08b9f3154e3aeb6362e9d765ae00de2c1fefa/lazylog-0.2.4.tar.gz"
}
]
}