{"id":25961879,"url":"https://github.com/nameko/nameko-tracer","last_synced_at":"2025-03-04T19:50:06.242Z","repository":{"id":45392882,"uuid":"45618733","full_name":"nameko/nameko-tracer","owner":"nameko","description":null,"archived":false,"fork":false,"pushed_at":"2023-02-02T14:53:52.000Z","size":183,"stargazers_count":19,"open_issues_count":5,"forks_count":10,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-02-24T05:17:15.096Z","etag":null,"topics":["logging","nameko","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nameko.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-05T15:06:06.000Z","updated_at":"2023-09-05T08:17:04.000Z","dependencies_parsed_at":"2023-02-17T21:15:37.412Z","dependency_job_id":null,"html_url":"https://github.com/nameko/nameko-tracer","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nameko%2Fnameko-tracer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nameko%2Fnameko-tracer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nameko%2Fnameko-tracer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nameko%2Fnameko-tracer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nameko","download_url":"https://codeload.github.com/nameko/nameko-tracer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241913762,"owners_count":20041461,"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":["logging","nameko","python"],"created_at":"2025-03-04T19:50:04.409Z","updated_at":"2025-03-04T19:50:06.224Z","avatar_url":"https://github.com/nameko.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. image:: https://travis-ci.org/nameko/nameko-tracer.svg?branch=master\n    :target: https://travis-ci.org/nameko/nameko-tracer\n\n========================\nNameko Entrypoint Tracer\n========================\n\nUsage\n=====\n\nInstall from PyPI:\n\n.. code:: console\n\n    pip install nameko-tracer\n\n\nAdd ``nameko_tracer.Tracer`` dependency provider to your service\nplus add a simple RPC entrypoint so we have an endpoint to trace:\n\n\n.. code:: python\n\n    # traced.py\n\n    from nameko.rpc import rpc\n    from nameko_tracer import Tracer\n\n\n    class Service:\n\n        name = 'traced'\n\n        tracer = Tracer()\n\n        @rpc\n        def hello(self, name):\n            return 'Hello, {}!'.format(name)\n\n\nNow, if you start your service in a shell:\n\n.. code:: console\n\n    $ nameko run traced\n\nAnd invoke the `test` entrypoint in another:\n\n.. code:: console\n\n    $ nameko shell\n    In [1]: n.rpc.traced.hello(name='ナメコ')\n    Out[2]: 'Hello, ナメコ!'\n\nYou should see two log records printed out in the first shell:\n\n.. code:: console\n\n    $ nameko run traced\n    starting services: traced\n    Connected to amqp://guest:***@127.0.0.1:5672//\n    [traced.hello.8eb11de2-0b28-495d-af91-98bd6a051bca] entrypoint call trace\n    [traced.hello.8eb11de2-0b28-495d-af91-98bd6a051bca] entrypoint result trace\n\nThe output does not tell much, given the default logging formatter prints\njust the message. But there's much more on the log records, to get it out\nlet's configure service logging and customize the formatter to include the\ntrace details (the tracer adds safely serialisable details to ``nameko_trace``\nattribute of the log record):\n\n.. code:: yaml\n\n    # config.yaml\n\n    AMQP_URI: 'pyamqp://guest:guest@localhost'\n    LOGGING:\n        version: 1\n        formatters:\n            tracer:\n                format: \"[%(name)-12s] %(nameko_trace)s\"\n        handlers:\n            tracer:\n                class: logging.StreamHandler\n                formatter: tracer\n        loggers:\n            nameko_tracer:\n                level: INFO\n                handlers: [tracer]\n\nStop the service and start it again pointing to the new config file:\n\n.. code:: console\n\n    $ nameko run traced --config config.yaml\n\nAnd invoke the ``test`` entrypoint again in the second shell:\n\n.. code:: console\n\n    $ nameko shell\n    In [1]: n.rpc.traced.hello(name='ナメコ')\n    Out[1]: 'Hello, ナメコ!'\n    In [2]: n.rpc.traced.hello(name='ナメコ')\n    Out[2]: 'Hello, ナメコ!'\n\nIn the first shell where the service runs you'll find the string\nrepresentation of the gathered trace information printed out:\n\n.. code:: console\n\n    $ nameko run traced --config config.yaml\n    [nameko_tracer] {'call_args_redacted': False, 'context_data': {}, 'entrypoint':\n     'traced.hello', 'call_id': 'traced.hello.f51733a0-1851-47e6-9d47-29bef5eaf581'\n    , 'provider': 'Rpc', 'timestamp': datetime.datetime(2017, 8, 10, 18, 7, 12, 106\n    972), 'service': 'traced', 'call_stack': ['standalone_rpc_proxy.call.14caabf9-8\n    92f-4ab2-b04b-e0fb90167fe5', 'traced.hello.f51733a0-1851-47e6-9d47-29bef5eaf581\n    '], 'call_args': {'name': 'ナメコ'}, 'lifecycle_stage': 'request', 'provider_na\n    me': 'hello'}\n    [nameko_tracer] {'call_args_redacted': False, 'context_data': {}, 'call_id': 't\n    raced.hello.f51733a0-1851-47e6-9d47-29bef5eaf581', 'provider': 'Rpc', 'return_a\n    rgs': 'Hello, ナメコ!', 'response_time': 0.023348, 'call_stack': ['standalone_r\n    pc_proxy.call.14caabf9-892f-4ab2-b04b-e0fb90167fe5', 'traced.hello.f51733a0-185\n    1-47e6-9d47-29bef5eaf581'], 'entrypoint': 'traced.hello', 'timestamp': datetime\n    .datetime(2017, 8, 10, 18, 7, 12, 130320), 'status': 'success', 'service': 'tra\n    ced', 'call_args': {'name': 'ナメコ'}, 'lifecycle_stage': 'response', 'provider\n    _name': 'hello'}\n\nThe traces include comprehensive information about the entrypoint fired and\nit would be more practical to have the details serialised in a format which\nis readable by both humans and machines. The tracer comes with a simple JSON\nformatter of the trace log record attribute. Now reconfigure the logging to\nuse ``nameko_tracer.formatters.JSONFormatter``:\n\n.. code:: yaml\n\n    # config.yaml\n\n    AMQP_URI: 'pyamqp://guest:guest@localhost'\n    LOGGING:\n        version: 1\n        formatters:\n            tracer:\n                (): nameko_tracer.formatters.JSONFormatter\n        handlers:\n            tracer:\n                class: logging.StreamHandler\n                formatter: tracer\n        loggers:\n            nameko_tracer:\n                level: INFO\n                handlers: [tracer]\n\nAfter restarting the service with the updated config and after invoking the\ntesting call you will find the traces logged as JSON:\n\n.. code:: console\n\n    $ nameko run traced --config config.yaml\n    {\"call_id\": \"traced.hello.19522441-9581-484b-bad5-8d14b8b5c291\", \"call_args_red\n    acted\": false, \"service\": \"traced\", \"entrypoint\": \"traced.hello\", \"provider\": \"\n    Rpc\", \"lifecycle_stage\": \"request\", \"context_data\": {}, \"call_stack\": [\"standal\n    ...\n\nFind more about what's included in the trace in the Trace Data section.\n\n\nTrace data\n==========\n\nTODO more words here ...\n\nThe **request** stage trace includes the following details:\n\n- A **timestamp**.\n- Entrypoint **metadata** consisting of:\n\n  - service name\n  - entrypoint method name\n  - entrypoint type (e.g. ``Rpc``),\n  - worker context data\n\n- Tracking data with **call ID** and **call ID stack** holding a chain of\n  call IDs of all consecutive calls leading to this one.\n- Entrypoint **call arguments**. The tracer honours ``sensitive_variables``\n  of each entrypoint and redacts values of sensitive arguments before\n  placing them on the trace (there is also a flag saying whether the call\n  arguments were redacted).\n\nThe **response** stage trace includes same details as the *request* stage\ntrace plus the following additional response specific fields:\n\n- Response **status** which is either ``success`` or ``error`` in case the\n  entrypoint execution failed.\n- **Result** returned by the entrypoint (the package includes a logging\n  filter for truncating the response if needed).\n- **Exception** details if the entrypoint execution failed.\n- **Response time** saying how long it took to process the entrypoint.\n\nEach trace also includes a stage key saying what stage the trace is for.\n\nSee ``constants`` module for the exact key names.\n\n\nJSON Trace Formatter\n====================\n\nThe package includes ``nameko_tracer.formatters.JSONFormatter`` - a simple,\nbut handy formatter which takes ``nameko_trace`` attribute of the log record\nand formats it as JSON string.\n\n\nTruncation Filters\n==================\n\nThe package also includes two filters for truncating bulky parts of trace data.\nThis is useful for reducing the amount of data ending up in your logs.\n\n* ``nameko_tracer.filters.TruncateCallArgsFilter``\n* ``nameko_tracer.filters.TruncateResponseFilter``\n\nThe truncating filter (``TruncateCallArgsFilter``) takes the following\narguments:\n\n* ``entrypoints`` - a list of regex strings identifying entrypoints whose\n  call arguments data should be truncated when logging. Defaults to an empty\n  list - you have to provide an input in order to make this filter to take\n  any effect.\n* ``max_len`` - an integer representing the number of characters to keep.\n  Defaults to ``100``.\n\nThe response truncating filter (``TruncateResponseFilter``) takes the following\narguments:\n\n* ``entrypoints`` - a list of regex strings identifying entrypoints whose\n  response data should be truncated when logging. Defaults to\n  ``\"^get_|^list_|^query_\"``.\n* ``max_len`` - an integer representing the number of characters to keep.\n  Defaults to ``100``.\n\nBoth filters add an additional flag to the trace saying whether the trimming\nwas applied.\n\nNote that the filters first serialise the input to a string before applying\nthe truncation. If the length of string representation of the input is within\nthe ``max_len`` limit, the input is kept untouched.\n\nAn example of configuring logging to use the truncation filters:\n\n.. code:: yaml\n\n    # config.yaml\n\n    AMQP_URI: 'pyamqp://guest:guest@localhost'\n    LOGGING:\n        version: 1\n        filters:\n            truncate_request_trace:\n                (): nameko_tracer.filters.TruncateCallArgsFilter\n                entrypoints:\n                    - insert_big_data\n                max_len: 200\n            truncate_response_trace:\n                (): nameko_tracer.filters.TruncateResponseFilter\n        formatters:\n            tracer:\n                (): nameko_tracer.formatters.JSONFormatter\n        handlers:\n            tracer:\n                class: logging.StreamHandler\n                formatter: tracer\n        loggers:\n            nameko_tracer:\n                level: INFO\n                handlers: [tracer]\n                filters:\n                    - truncate_request_trace\n                    - truncate_response_trace\n\n\nCustom Adapters\n===============\n\nTODO describe ...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnameko%2Fnameko-tracer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnameko%2Fnameko-tracer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnameko%2Fnameko-tracer/lists"}