{"id":19175076,"url":"https://github.com/paul-wolf/ukpc","last_synced_at":"2025-02-23T00:45:11.926Z","repository":{"id":76126400,"uuid":"118417368","full_name":"paul-wolf/ukpc","owner":"paul-wolf","description":"A Python module for parsing United Kingdom postcodes","archived":false,"fork":false,"pushed_at":"2020-10-24T09:48:48.000Z","size":10,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-04T12:48:40.928Z","etag":null,"topics":["parser","postcodes","python","uk"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paul-wolf.png","metadata":{"files":{"readme":"README.txt","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-22T06:43:27.000Z","updated_at":"2021-03-01T14:05:39.000Z","dependencies_parsed_at":"2023-02-25T05:30:41.664Z","dependency_job_id":null,"html_url":"https://github.com/paul-wolf/ukpc","commit_stats":{"total_commits":6,"total_committers":2,"mean_commits":3.0,"dds":0.5,"last_synced_commit":"c02f1e477f4f44023349460e1d075b58868b32cc"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-wolf%2Fukpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-wolf%2Fukpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-wolf%2Fukpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-wolf%2Fukpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paul-wolf","download_url":"https://codeload.github.com/paul-wolf/ukpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240254181,"owners_count":19772386,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["parser","postcodes","python","uk"],"created_at":"2024-11-09T10:20:52.119Z","updated_at":"2025-02-23T00:45:11.905Z","avatar_url":"https://github.com/paul-wolf.png","language":"Python","readme":"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 ``[\u003clineno\u003e, \u003csecs\u003es]``:\n\n::\n\n    [12:12:54] INFO [132, 0.0006s] auth header: [b'Token', b'2c59999137******************************']; [132, 0.0007s] authenticate key, model: \u003cclass 'tastypie.models.ApiKey'\u003e; [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't 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't do the call to the ``logger`` method.\n\n.. |Build Status| image:: https://travis-ci.org/paul-wolf/logtrace.svg?branch=master\n   :target: https://travis-ci.org/paul-wolf/logtrace\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaul-wolf%2Fukpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaul-wolf%2Fukpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaul-wolf%2Fukpc/lists"}