{ "info": { "author": "Balanced", "author_email": "dev@balancedpayments.com", "bugtrack_url": null, "classifiers": [], "description": "balog\n=====\n\n[![Build Status](https://travis-ci.org/balanced/balog.svg?branch=master)](https://travis-ci.org/balanced/balog)\n\nBalanced event logging schema and library\n\nLog schema design goals\n=======================\n\n - Schema version annotated\n - Provide sufficient information about the event\n - Open and close (be flexible, avoid unnecessary change to schema)\n\nDesign rationals\n================\n\nOSI Network Model Structure\n---------------------------\n\nData in the log can be divided into two major groups, one is the meta data,\nwhich is the data about the event. The another group is the log for application \nitself. In most cases, applications should only be interested in the \napplication log itself. And the logging facility should only be interested in \nhow to handle the whole event rather than to consume the content of application \nlog. Also, since schema of application can variant, we don't want change the\nwhole schema everytime when application log is change. Consider these issues,\none idea come to my mind is Internet OSI model is actually dealing with the\nsame issue. It's like TCP/IP protocol doesn't need to know the content of\napplication layer. Similarly, logging facility doesn't have to know the content\nof application log. With this idea in mind, I define two layers for our logging\nsystem.\n\n - Facility layer\n - Application layer\n\nFacility layer is all about the event, when it is generated, who emited this\nevent, what's its routing tag and etc. Application layer is all about\napplication data, like a dispute is processed, a debit is created and etc.\n\nUsage\n=====\n\nProduce logs\n------------\n\nTo produce a log, here you can write\n\n```python\nfrom balog import get_logger\nbalogger = get_logger(__name__)\n\nbalogger.info('done', payload={\n 'cls_type': 'metrics',\n 'values': [\n {'name': 'total', 'value': 123},\n {'name': 'succeeded', 'value': 456},\n {'name': 'failed', 'value': 789},\n ],\n})\n```\n\nThe channel name will be the logger name + the given suffix name, in the above example, the say if the `__name__` is \n`justitia.scripts.process_results` here, then the channel name will be `justitia.scripts.process_results.done`. If you want to overwrite the channel name, you can also pass `channel` argument to balog logging methods.\n\nConsume logs\n------------\n\nTo consume events, you can use `consumer_config` like this\n\n```python\nfrom balog.consumers import consumer_config\n\n@consumer_config(\n topic='myproj-events-{env}',\n cls_type='metrics',\n version='<1.0',\n)\ndef process_metrics(settings, event):\n pass\n```\n\nThis `consumer_config` decorator is mainly for declaring what this consumer wants, in the example above, since want to subscribe the queue `myproj-events-develop` or `myproj-events-prod`, so we set the topic to `myproj-events-{env}`, for the `{env}` placeholder, we will talk about that later. And then we're only interested in `metrics` type events, so we set `cls_type` to `metrics`. We also don't want to process events that are not compatible, so we set the `version` to `<1.0`. \n\nWith these configured consumers, to process events, you need to use `ConsumerHub` first. It is basically a collection of consumers. It provides scanning method to make collecting consumers pretty easy. For example, here you can write\n\n```python\nimport yourpackage\nfrom balog.consumers import ConsumerHub\n\nhub = ConsumerHub()\nhub.scan(yourpackage)\n```\n\nBy doing that, you have all consuemrs in the hub. Then you can create an event processing engine. We only have Amazon SQS event processing engine for now, but it should be fairly easy to impelement any other engine type as they are needed. Before we create the engine, you need to define a `ConsumerOperator` first. It's basically an object which knows how to operate these consumer. So that you can call these consumer functions in the way you want. Here is an example:\n\n\n```python\nclass ConsumerOperator(object):\n\n def __init__(self, settings):\n self.settings = settings\n\n def get_topic(self, consumer):\n env = self.settings['api.sqs.queue_env']\n return consumer.topic.format(env=env)\n\n def process_event(self, consumer, event):\n return consumer.func(self.settings, event)\n```\n\nIt has two methods, the first is `get_topic`, it is for getting topic, namely, the queue name to subscribe. As we saw the topic name in `consumer_config` is `myproj-events-{env}` above, here I explain why it looks like that. Since we may need to subscribe to different event queue in different environment, like integration or production environment, so we cannot just leave a static value there. To make it as flexible as possible, I let the consumer operator decide how to get the topic name. So in our example, you can see it gets `api.sqs.queue_env` from settings and replace the `env` placeholder. By doing that, we can determine which queue to subscribe later. Similar to the deferred topic name, I also want to make it possible to call the consumer function in the way you like, the `process_event` method of consumer operator is for that purpose. Since in our consumer handler function, we may need some extra information other than just the event, in our example, we also need to read settings. So that in our example, we pass an extra argument `settings` to the consumer function.\n\nOkay, now let's put it altogether\n\n\n```python\nfrom __future__ import unicode_literals\n\nfrom balog.consumers import ConsumerHub\nfrom balog.consumers.sqs import SQSEngine\n\nimport yourpackage\n\n\nclass ConsumerOperator(object):\n\n def __init__(self, settings):\n self.settings = settings\n\n def get_topic(self, consumer):\n env = self.settings['api.sqs.queue_env']\n return consumer.topic.format(env=env)\n\n def process_event(self, consumer, event):\n return consumer.func(self.settings, event)\n\n\ndef process_events(settings):\n \"\"\"Process log events in SQS\n\n \"\"\"\n hub = ConsumerHub()\n hub.scan(yourpackage)\n consumer_op = ConsumerOperator(settings)\n engine = SQSEngine(\n hub=hub,\n region=settings['api.sqs.region'],\n aws_access_key_id=settings['api.sqs.aws_access_key_id'],\n aws_secret_access_key=settings['api.sqs.aws_secret_access_key'],\n consumer_operator=consumer_op,\n )\n engine.run()\n```\n", "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/balanced/balog/", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "balog", "package_url": "https://pypi.org/project/balog/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/balog/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/balanced/balog/" }, "release_url": "https://pypi.org/project/balog/1.2.3/", "requires_dist": null, "requires_python": null, "summary": "Balanced event logging schema and library", "version": "1.2.3" }, "last_serial": 1269435, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "b94c5739d11322b66a034ed4b2374fb9", "sha256": "075cda70f291974fe4af7fbd0f75ab013aba0aa0efc210347c2e112e828cb824" }, "downloads": -1, "filename": "balog-0.0.1.tar.gz", "has_sig": false, "md5_digest": "b94c5739d11322b66a034ed4b2374fb9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3666, "upload_time": "2014-09-17T23:46:09", "url": "https://files.pythonhosted.org/packages/66/eb/fc1bfab453bbb0f09350d254f3226b5c153a395d503e6dacdf00b255a300/balog-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "bb14980c6019820c448c82aad32b0f40", "sha256": "c9bd147b2d7fd2300ddef2eb0e92961e044763a5b0aea185d4f76f960143b524" }, "downloads": -1, "filename": "balog-0.0.2.tar.gz", "has_sig": false, "md5_digest": "bb14980c6019820c448c82aad32b0f40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8148, "upload_time": "2014-09-18T22:24:51", "url": "https://files.pythonhosted.org/packages/db/f0/470d62589fef8f4f7ec8ad28c8a4254fa28693c1470a1af85c2b815cf937/balog-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "1005947c0754fc0040315a2095aabdfd", "sha256": "ac55e0cc193c4ff175cca95f57b8c0adf3404fcf6af5d4c0064e95e4390ca5eb" }, "downloads": -1, "filename": "balog-0.0.3.tar.gz", "has_sig": false, "md5_digest": "1005947c0754fc0040315a2095aabdfd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9342, "upload_time": "2014-09-22T20:56:37", "url": "https://files.pythonhosted.org/packages/26/07/8639aa9db7a051224dbebc1aaf350a1e9b6582e3883a0dbf18d5d0cb4f7a/balog-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "3c726ab3157dafa163b18c70893d650b", "sha256": "32256ebdba440282b7b5a3ef653c8c046adc3c31021fb7673ec215356b36022a" }, "downloads": -1, "filename": "balog-0.0.4.tar.gz", "has_sig": false, "md5_digest": "3c726ab3157dafa163b18c70893d650b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9549, "upload_time": "2014-09-24T16:35:18", "url": "https://files.pythonhosted.org/packages/bc/2f/929a2b574f98b92db2e3d37f949b051f292aa0fc220b88e5fac2b30bf778/balog-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "8504d9ac4840ac425e99339102f4774d", "sha256": "998e2142fd807f08269954ec1ab85f5f03fb3ce384d8935ce1124ec6841b963f" }, "downloads": -1, "filename": "balog-0.0.5.tar.gz", "has_sig": false, "md5_digest": "8504d9ac4840ac425e99339102f4774d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10890, "upload_time": "2014-09-25T19:57:46", "url": "https://files.pythonhosted.org/packages/85/30/65b8b81f81a8f66ca0ad44d78e931ae312546da77f3e181f54b54912982f/balog-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "e3148102d919ee2a64f8139dbd160020", "sha256": "451901d0bd966a291b4f2d8e10ce1a3d5c1bcf3a8b91917f8a9c695d4b55b3dc" }, "downloads": -1, "filename": "balog-0.0.6.tar.gz", "has_sig": false, "md5_digest": "e3148102d919ee2a64f8139dbd160020", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12082, "upload_time": "2014-09-26T00:00:51", "url": "https://files.pythonhosted.org/packages/98/ba/7c0f2ad214835e710819fa7765741c8737cecebf087a99dba515e5b4eb73/balog-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "9b46c099118b3234729ebf7d878caa66", "sha256": "65e641a84c2b30416d68fcd8d1877f9262bf28eb775d68a464d868e05aaaee95" }, "downloads": -1, "filename": "balog-0.0.7.tar.gz", "has_sig": false, "md5_digest": "9b46c099118b3234729ebf7d878caa66", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12089, "upload_time": "2014-09-26T01:22:11", "url": "https://files.pythonhosted.org/packages/30/05/dd6b74121f82158bf67753ed161c78d33e1490e108336c6a4f76dadf631e/balog-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "55a584c30fd32b541e67e38fcc3a6f8d", "sha256": "b74474cabcf85b3e5c559c9058a6ba721c49145fbc5539627b32142aded7f4bc" }, "downloads": -1, "filename": "balog-0.0.8.tar.gz", "has_sig": false, "md5_digest": "55a584c30fd32b541e67e38fcc3a6f8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12912, "upload_time": "2014-09-29T20:07:32", "url": "https://files.pythonhosted.org/packages/d7/97/f06826da9e43b459e6ea3eb4c58f5ba652479210c383032cabb93057697d/balog-0.0.8.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "7b7ec70d206067b288a86b265b3a6295", "sha256": "ea6430382bc059a89f867b7b73b39b446d0b41265f68b9235f999b1bae322583" }, "downloads": -1, "filename": "balog-1.0.0.tar.gz", "has_sig": false, "md5_digest": "7b7ec70d206067b288a86b265b3a6295", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13097, "upload_time": "2014-09-29T23:00:26", "url": "https://files.pythonhosted.org/packages/79/bc/5f323eb9fbe6c5f363ff499fc90b50d7aa53ce2f9a8879a96c2a76de3d89/balog-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "98b360f5408f222f564e025b18421c89", "sha256": "78d80b337e510bef3551e671d5a98851c5c3314a487804905ea29729436134e1" }, "downloads": -1, "filename": "balog-1.0.1.tar.gz", "has_sig": false, "md5_digest": "98b360f5408f222f564e025b18421c89", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13253, "upload_time": "2014-09-30T19:28:53", "url": "https://files.pythonhosted.org/packages/1f/20/b916deb0bb00f03db030a5c8c515d2500c8ac9db731fd4dc65b65bb7316d/balog-1.0.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "0ffaf646db785eabd0f351f5ef0bbe5f", "sha256": "21c19f55c158ba0c79b474c92924bed4888a2709064d558b9581bd8edd2f449b" }, "downloads": -1, "filename": "balog-1.2.0.tar.gz", "has_sig": false, "md5_digest": "0ffaf646db785eabd0f351f5ef0bbe5f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16014, "upload_time": "2014-10-08T23:13:58", "url": "https://files.pythonhosted.org/packages/69/b4/358f8ce36cad6abb7a4a7c090ba2a1a931fe27bc75c9313140ae467391eb/balog-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "95ab76f560d5ca8ea027a1b26537657d", "sha256": "893ca5f1cbd3fd53fd98fc5ed3d9bd6db27c1e5992f5659dc40806097a9239c7" }, "downloads": -1, "filename": "balog-1.2.1.tar.gz", "has_sig": false, "md5_digest": "95ab76f560d5ca8ea027a1b26537657d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16061, "upload_time": "2014-10-09T20:54:26", "url": "https://files.pythonhosted.org/packages/8b/f2/4542a62825155736060832ab7f8b906cd4a9a4931275db78c5079d598de4/balog-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "2faa480c5499379afebdbc9eddee4a42", "sha256": "212939be425f54840d2bce1f9b753df06e8adf9d82e0e1c994b3fa44058af110" }, "downloads": -1, "filename": "balog-1.2.2.tar.gz", "has_sig": false, "md5_digest": "2faa480c5499379afebdbc9eddee4a42", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16064, "upload_time": "2014-10-09T21:00:02", "url": "https://files.pythonhosted.org/packages/bb/10/4989a0fa078ae997f7e5297e07e444119f80b5ad1a9104ade02b98bc027f/balog-1.2.2.tar.gz" } ], "1.2.3": [ { "comment_text": "", "digests": { "md5": "248700674ed391d3d3df33f5a1e7808e", "sha256": "493666b3044bd793bf3143a01b1e426bf14d877a5f710a0e72bc08f18bb3f3c2" }, "downloads": -1, "filename": "balog-1.2.3.tar.gz", "has_sig": false, "md5_digest": "248700674ed391d3d3df33f5a1e7808e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16108, "upload_time": "2014-10-14T00:49:35", "url": "https://files.pythonhosted.org/packages/57/ed/9c1950a1342d011389d1141149540bd0419091bd9396af1bf554fa1bcb0d/balog-1.2.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "248700674ed391d3d3df33f5a1e7808e", "sha256": "493666b3044bd793bf3143a01b1e426bf14d877a5f710a0e72bc08f18bb3f3c2" }, "downloads": -1, "filename": "balog-1.2.3.tar.gz", "has_sig": false, "md5_digest": "248700674ed391d3d3df33f5a1e7808e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16108, "upload_time": "2014-10-14T00:49:35", "url": "https://files.pythonhosted.org/packages/57/ed/9c1950a1342d011389d1141149540bd0419091bd9396af1bf554fa1bcb0d/balog-1.2.3.tar.gz" } ] }