{ "info": { "author": "Cameron Simpson", "author_email": "cs@cskk.id.au", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "*Latest release 20190923*:\nNew `TRACK` constant equal to `logging.INFO+5` to provide a level higher than `INFO`\n(which seems unreasonably noisy) and lower than `WARNING`\nwarning for tracking salient events.\nNew `track()` function to match.\n\nLogging convenience routines.\n\nThe logging package is very useful, but a little painful to use.\nThis package provides low impact logging setup and some extremely\nuseful if unconventional context hooks for logging.\n\nThe default logging verbosity output format has different defaults\nbased on whether an output log file is a tty\nand whether the environment variable $DEBUG is set, and to what.\n\nOn terminals warnings and errors get ANSI colouring.\n\nA mode is available that uses cs.upd.\n\nSome examples:\n--------------\n\nProgram initialisation::\n\n from cs.logutils import setup_logging\n\n def main(argv):\n cmd = os.path.basename(argv.pop(0))\n setup_logging(cmd)\n\nBasic logging from anywhere::\n\n from cs.logutils import info, warning, error\n [...]\n def some_function(...):\n [...]\n error(\"nastiness found! bad value=%r\", bad_value)\n\n## Function `add_logfile(filename, logger=None, mode='a', encoding=None, delay=False, format=None, no_prefix=False)`\n\nAdd a FileHandler logging to the specified `filename`;\nreturn the chosen logger and the new handler.\n\nParameters:\n* `logger`: if supplied and not None, add the FileHandler to that\n Logger, otherwise to the root Logger. If `logger` is a string, call\n `logging.getLogger(logger)` to obtain the logger.\n* `mode`, `encoding` and `delay`: passed to the logging.FileHandler\n initialiser.\n* `format`: used to override the handler's default format.\n* `no_prefix`: if true, do not put the Pfx context onto the front of the message.\n\n## Function `critical(msg, *args, **kwargs)`\n\nEmit a log at `logging.CRITICAL` `level` with the current Pfx prefix.\n\n## Function `D(msg, *args)`\n\nPrint formatted debug string straight to sys.stderr if D_mode is true,\nbypassing the logging modules entirely.\nA quick'n'dirty debug tool.\n\n## Function `debug(msg, *args, **kwargs)`\n\nEmit a log at `logging.DEBUG` `level` with the current Pfx prefix.\n\n## Function `error(msg, *args, **kwargs)`\n\nEmit a log at `logging.ERROR` `level` with the current Pfx prefix.\n\n## Function `exception(msg, *args)`\n\nEmit an exception log with the current Pfx prefix.\n\n## Function `ftrace(func)`\n\nDecorator to trace a function if __module__.DEBUG is true.\n\n## Function `ifdebug()`\n\nTest the `logging_level` against `logging.DEBUG`.\n\n## Function `infer_logging_level(env_debug=None, environ=None, verbose=None)`\n\nInfer a logging level from the `env_debug`, which by default\ncomes from the environment variable `$DEBUG`.\n\nUsually default to logging.WARNING, but if sys.stderr is a terminal,\ndefault to logging.INFO.\n\nParse the environment variable $DEBUG as a comma separated\nlist of flags.\n\nExamine the in sequence flags to affect the logging level:\n* `numeric < 1`: `logging.WARNING`\n* `numeric >= 1 and < 2`: `logging.INFO`\n* `numeric >= 2`: `logging.DEBUG`\n* `\"DEBUG\"`: `logging.DEBUG`\n* `\"INFO\"`: ` logging.INFO`\n* `\"WARNING\"`: `logging.WARNING`\n* `\"ERROR\"`: `logging.ERROR`\n\nReturn an object with the following attributes:\n* `.level`: A logging level.\n* `.flags`: All the words from $DEBUG as separated by commas and uppercased.\n* `.module_names`: Module names to be debugged.\n* `.function_names`: Functions to be traced in the for \"module_name.func_name()\".\n\n## Function `info(msg, *args, **kwargs)`\n\nEmit a log at `logging.INFO` `level` with the current Pfx prefix.\n\n## Function `log(level, msg, *args, **kwargs)`\n\nEmit a log at the specified `level` with the current Pfx prefix.\n\n## Function `logException(exc_type, exc_value, exc_tb)`\n\nReplacement for sys.excepthook that reports via the cs.logutils\nlogging wrappers.\n\n## Class `LogTime`\n\nLogTime is a content manager that logs the elapsed time of the enclosed\ncode. After the run, the field .elapsed contains the elapsed time in\nseconds.\n\n### Method `LogTime.__init__(self, tag, *args, **kwargs)`\n\nSet up a LogTime.\n\nParameters:\n* `tag`: label included at the start of the log entry\n* `args`: optional array; if not empty `args` is applied to\n `tag` with `%`\n* `level`: keyword argument specifying a log level for a\n default log entry, default `logging.INFO`\n* `threshold`: keyword argument specifying minimum time to\n cause a log, default None (no minimum)\n* `warning_level`: keyword argument specifying the log level\n for a warning log entry, default `logging.WARNING`\n* `warning_threshold`: keyword argument specifying a time\n which raises the log level to `warning_level`\n\n## Function `logTo(filename, logger=None, mode='a', encoding=None, delay=False, format=None, no_prefix=False)`\n\nAdd a FileHandler logging to the specified `filename`;\nreturn the chosen logger and the new handler.\n\nParameters:\n* `logger`: if supplied and not None, add the FileHandler to that\n Logger, otherwise to the root Logger. If `logger` is a string, call\n `logging.getLogger(logger)` to obtain the logger.\n* `mode`, `encoding` and `delay`: passed to the logging.FileHandler\n initialiser.\n* `format`: used to override the handler's default format.\n* `no_prefix`: if true, do not put the Pfx context onto the front of the message.\n\n## Class `NullHandler`\n\nMRO: `logging.Handler`, `logging.Filterer` \nA Handler which discards its requests.\n\n## Function `OBSOLETE(func)`\n\nDecorator for obsolete functions.\n\nUse:\n\n @OBSOLETE\n def f(...):\n\nThis emits a warning log message before calling the decorated function.\n\n## Class `PfxFormatter`\n\nMRO: `logging.Formatter` \nA Formatter subclass that has access to the program's cmd and Pfx state.\n\n### Method `PfxFormatter.__init__(self, fmt=None, datefmt=None, cmd=None)`\n\nInitialise the PfxFormatter.\n\n`fmt` and `datefmt` are passed to Formatter.\nIf `fmt` is None, DEFAULT_PFX_FORMAT is used.\nIf `cmd` is not None, the message is prefixed with the string `cmd`.\n\n## Function `setup_logging(cmd_name=None, main_log=None, format=None, level=None, flags=None, upd_mode=None, ansi_mode=None, trace_mode=None, module_names=None, function_names=None, verbose=None)`\n\nArrange basic logging setup for conventional UNIX command\nline error messaging; return an object with informative attributes.\n\nParameters:\n* `cmd_name`: program name, default from `basename(sys.argv[0])`.\n Side-effect: sets `cs.pfx.cmd` to this value.\n* `main_log`: default logging system.\n If None, the main log will go to sys.stderr;\n if `main_log` is a string, is it used as a filename to\n open in append mode;\n otherwise main_log should be a stream suitable\n for use with `logging.StreamHandler()`.\n The resulting log handler is added to the `logging` root logger.\n* `format`: the message format for `main_log`.\n If `None`, use `DEFAULT_PFX_FORMAT_TTY`\n when `main_log` is a tty or FIFO,\n otherwise `DEFAULT_PFX_FORMAT`.\n* `level`: `main_log` logging level.\n If None, infer a level from the environment\n using `infer_logging_level()`.\n* `flags`: a string containing debugging flags separated by commas.\n If `None`, infer the flags from the environment using\n `infer_logging_level()`.\n The following flags have meaning:\n `D`: set cs.logutils.D_mode to True;\n `TDUMP`: attach a signal handler to SIGHUP to do a thread stack dump;\n `TRACE`: enable various noisy tracing facilities;\n `UPD`, `NOUPD`: set the default for `upd_mode` to True or False respectively.\n* `upd_mode`: a Boolean to activate cs.upd as the `main_log` method;\n if `None`, set it to `True` if `flags` contains 'UPD',\n otherwise to `False` if `flags` contains 'NOUPD',\n otherwise set it to `False` (was from main_log.isatty()).\n A true value causes the root logger to use `cs.upd` for logging.\n* `ansi_mode`: if `None`, set it from `main_log.isatty()`.\n A true value causes the root logger to colour certain logging levels\n using ANSI terminal sequences (currently only if `cs.upd` is used).\n* `trace_mode`: if `None`, set it according to the presence of\n 'TRACE' in flags. Otherwise if `trace_mode` is true, set the\n global `trace_level` to `logging_level`; otherwise it defaults\n to `logging.DEBUG`.\n* `verbose`: if `None`, then if stderr is a tty then the log\n level is `INFO` otherwise `WARNING`. Otherwise, if `verbose` is\n true then the log level is `INFO` otherwise `WARNING`.\n\n## Function `status(msg, *args, **kwargs)`\n\nWrite a message to the terminal's status line.\n\nParameters:\n* `msg`: message string\n* `args`: if not empty, the message is %-formatted with `args`\n* `file`: optional keyword argument specifying the output file.\n Default: `sys.stderr`.\n\nHack: if there is no status line use the xterm title bar sequence :-(\n\n## Function `trace(msg, *args, **kwargs)`\n\nEmit a log message at `trace_level` with the current Pfx prefix.\n\n## Function `track(msg, *args, **kwargs)`\n\nEmit a log at `TRACK` `level` with the current Pfx prefix.\n\n## Function `upd(msg, *args)`\n\nIf we're using an UpdHandler,\nupdate the status line otherwise write an info message.\n\n## Class `UpdHandler`\n\nMRO: `logging.StreamHandler`, `logging.Handler`, `logging.Filterer` \nA `StreamHandler` subclass whose `.emit` method\nuses a `cs.upd.Upd` for transcription.\n\n### Method `UpdHandler.__init__(self, strm=None, nl_level=None, ansi_mode=None)`\n\nInitialise the UpdHandler.\n\nParameters:\n* `strm`: the output stream, default `sys.stderr`.\n* `nl_level`: the logging level at which conventional line-of-text\n output is written; log messages of a lower level go via the\n update-the-current-line method.\n Default: `logging.WARNING`.\n* `ansi_mode`: if `None`, set from `strm.isatty()`.\n A true value causes the handler to colour certain logging levels\n using ANSI terminal sequences.\n\n## Function `warning(msg, *args, **kwargs)`\n\nEmit a log at `logging.WARNING` `level` with the current Pfx prefix.\n\n## Function `with_log(filename, **kw)`\n\nContext manager to add a Logger to the output logs temporarily.\n\n\n\n# Release Log\n\n*Release 20190923*:\nNew `TRACK` constant equal to `logging.INFO+5` to provide a level higher than `INFO`\n(which seems unreasonably noisy) and lower than `WARNING`\nwarning for tracking salient events.\nNew `track()` function to match.\n\n*Release 20190220*:\nImprovements to upd_mode.\n\n*Release 20190103*:\nDocumentation updates.\n\n*Release 20190101*:\nBugfix for @contextmanager usage.\n\n*Release 20171030*:\nAssorted fixes from recent module reshuffle. Other small features and cleanups. Drop a couple of unused functions.\n\n*Release 20160828*:\nUse \"install_requires\" instead of \"requires\" in DISTINFO.\n\n*Release 20160827*:\nPfx: import __exit__ handler\nPreliminary per-module and per-function syntax accepted in $DEBUG envvar.\nImprovements to X(), add DP() and XP() prefixed flavours.\nstatus() function to update terminal status line.\nNew X_via_tty global flag: directs X() to tty instead of sys.stderr.\nAssorted other minor improvements.\n\n*Release 20150118*:\nmetadata updates\n\n*Release 20150110*:\nInitial PyPI release.", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/cameron_simpson/css/commits/all", "keywords": "python2,python3", "license": "GNU General Public License v3 or later (GPLv3+)", "maintainer": "", "maintainer_email": "", "name": "cs.logutils", "package_url": "https://pypi.org/project/cs.logutils/", "platform": "", "project_url": "https://pypi.org/project/cs.logutils/", "project_urls": { "Homepage": "https://bitbucket.org/cameron_simpson/css/commits/all" }, "release_url": "https://pypi.org/project/cs.logutils/20190923/", "requires_dist": null, "requires_python": "", "summary": "Logging convenience routines.", "version": "20190923" }, "last_serial": 5870700, "releases": { "20150118": [ { "comment_text": "", "digests": { "md5": "bb80b8cf2fa20e5c1f872279bbffa4e0", "sha256": "d0f42906d7704acb41ce21bc85965c08ac41c712a65a68a10f4978e4c70b8e33" }, "downloads": -1, "filename": "cs.logutils-20150118.tar.gz", "has_sig": false, "md5_digest": "bb80b8cf2fa20e5c1f872279bbffa4e0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8065, "upload_time": "2015-01-18T06:01:10", "url": "https://files.pythonhosted.org/packages/d6/b7/9facee2ae6ad32c32d987b5be0bb146980a6dfdfffff0c88b672bfe66afa/cs.logutils-20150118.tar.gz" } ], "20160827": [ { "comment_text": "", "digests": { "md5": "c3db9e6b6a101301f16a3fc33f74cd39", "sha256": "ff7239d6ea8db141f4adfdb2d8b332b8b5c07e9c963a101fd4a807c19a136234" }, "downloads": -1, "filename": "cs.logutils-20160827.tar.gz", "has_sig": false, "md5_digest": "c3db9e6b6a101301f16a3fc33f74cd39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9590, "upload_time": "2016-08-27T03:36:16", "url": "https://files.pythonhosted.org/packages/53/51/c3a69f8a099061c32ee46f67c1acf187e529a5982e34a9ad261e7c29b14c/cs.logutils-20160827.tar.gz" } ], "20160828": [ { "comment_text": "", "digests": { "md5": "0e8f1897f8c0c95536e7402fd2fa40e7", "sha256": "7058295d0e4b554954b4b3ab3ca1ae8235f9d49eb047063e5344c3677af8e873" }, "downloads": -1, "filename": "cs.logutils-20160828.tar.gz", "has_sig": false, "md5_digest": "0e8f1897f8c0c95536e7402fd2fa40e7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9960, "upload_time": "2016-08-28T06:07:37", "url": "https://files.pythonhosted.org/packages/76/64/87ffab23537ec0683b5fcc7a9c830ae53a2a6e497c85cbb33a3c433786e3/cs.logutils-20160828.tar.gz" } ], "20171030": [ { "comment_text": "", "digests": { "md5": "6621eff2e2a3527fbda0f6eb32ee74fd", "sha256": "068c3557c224ec2949defbd4556f0e3dc1e90efb27c8b3d1eb60849e102df6e9" }, "downloads": -1, "filename": "cs.logutils-20171030.tar.gz", "has_sig": false, "md5_digest": "6621eff2e2a3527fbda0f6eb32ee74fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7597, "upload_time": "2017-10-30T10:35:12", "url": "https://files.pythonhosted.org/packages/5b/05/140ca9a889b0f7b84e50b6b470ae71be94c8b960fb40545c43727a3b0b07/cs.logutils-20171030.tar.gz" } ], "20190101": [ { "comment_text": "", "digests": { "md5": "c0d63be0c881411007a11d6827c005b3", "sha256": "e4ab65974f5cebf9abd188ac33721fe4c61a9f81ea47307898ed7cf19b7c8925" }, "downloads": -1, "filename": "cs.logutils-20190101.tar.gz", "has_sig": false, "md5_digest": "c0d63be0c881411007a11d6827c005b3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9451, "upload_time": "2019-01-01T02:42:26", "url": "https://files.pythonhosted.org/packages/09/10/5262447301323280f5ff681f711c07c1465e7452dbb57a680dcb69f00d2e/cs.logutils-20190101.tar.gz" } ], "20190103": [ { "comment_text": "", "digests": { "md5": "9306e34730ece25420ecbeb0e38b8cdc", "sha256": "845c4e6cc9ffd27f9f992c3e1d6c4860273bc76f57ba587639ca51a07fc6c170" }, "downloads": -1, "filename": "cs.logutils-20190103.tar.gz", "has_sig": false, "md5_digest": "9306e34730ece25420ecbeb0e38b8cdc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9548, "upload_time": "2019-01-02T22:40:34", "url": "https://files.pythonhosted.org/packages/d5/41/7f1eadd433f3c6ecba56c655a9ff44e32adac69920adc62d4471c5242d3a/cs.logutils-20190103.tar.gz" } ], "20190220": [ { "comment_text": "", "digests": { "md5": "e5c25c4803f576cfad63d5f938565f04", "sha256": "6775d5cb43019fcaba94e223942252ec7ceed784fa7f3f1008bc496b9b04f486" }, "downloads": -1, "filename": "cs.logutils-20190220.tar.gz", "has_sig": false, "md5_digest": "e5c25c4803f576cfad63d5f938565f04", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9894, "upload_time": "2019-02-20T09:21:14", "url": "https://files.pythonhosted.org/packages/7b/89/d38a23d316dbafe3640cdf6e226aeb301a2b4045be0005146c905d579231/cs.logutils-20190220.tar.gz" } ], "20190923": [ { "comment_text": "", "digests": { "md5": "b2a8b04547c1f14ada882ebcbe0a1089", "sha256": "f4805feb5eef4e9be7987342a7ec1bb62107ffe9b4dd5347a236e669040a338f" }, "downloads": -1, "filename": "cs.logutils-20190923.tar.gz", "has_sig": false, "md5_digest": "b2a8b04547c1f14ada882ebcbe0a1089", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13117, "upload_time": "2019-09-22T22:59:20", "url": "https://files.pythonhosted.org/packages/d9/3c/33d440a29b4ded539c191b4fe18cb56a82f6a337390f8509bed95e421dd5/cs.logutils-20190923.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b2a8b04547c1f14ada882ebcbe0a1089", "sha256": "f4805feb5eef4e9be7987342a7ec1bb62107ffe9b4dd5347a236e669040a338f" }, "downloads": -1, "filename": "cs.logutils-20190923.tar.gz", "has_sig": false, "md5_digest": "b2a8b04547c1f14ada882ebcbe0a1089", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13117, "upload_time": "2019-09-22T22:59:20", "url": "https://files.pythonhosted.org/packages/d9/3c/33d440a29b4ded539c191b4fe18cb56a82f6a337390f8509bed95e421dd5/cs.logutils-20190923.tar.gz" } ] }