# Ray Log Notebook
This is a tiny **FIX** for Ray to display logs under the **last executed cell** instead of **ray.init()** cell.
Q: Why would this happen?\
A: Ipykernel captures thread output and redir to the cell where thread is created.
This is desired in some scenarios, but definitely not for Ray, whose logging thread
is created upon `ray.init()` initialization.
Q: How can you fix this?\
A: Utilizing IPython Events and mock Ray's internal log event handler.
**This may be unstable because we depend on Ray's non-public API.**
In normal mode, Ray would log by emitting logs to `global_worker_stdstream_dispatcher`,
replacing the original handler with ours just works.
For client mode, things get trickier. `client_worker`'s LogStreamClient `log_client`
would receive remote log stream by gRPC and print to stdout/stderr.
We directly **mock replace** the `stdstream` method of that LogStreamClient instance.
There may be more robust and non-intrusive ways to do it,
for example capturing the `ray.init()`
cell output.
Q: How can I use this?
A: As simple as:
```python
% cell 1
import ray
ray.init()
% cell 2
import ray_log_notebook
ray_log_notebook.enable()
% cell 3
@ray.remote
def test_print():
print("Woola!")
await test_print.remote()
```


Logs will always go to the last executed cell, instead of where the Ray Tasks are created.
Tested on Python 3.13 and Ray 2.50.0, generally should work but I don't have much time to test.
Raw data
{
"_id": null,
"home_page": null,
"name": "ray-log-notebook",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "ray, log, IPython, jupyter, notebook",
"author": "Clouder0",
"author_email": "Clouder0 <clouder0@outlook.com>",
"download_url": "https://files.pythonhosted.org/packages/c8/33/18a08d363f28a04b66cee2a26c955a967f6a443fa40a9af9f90e45655fd6/ray_log_notebook-0.0.1.tar.gz",
"platform": null,
"description": "# Ray Log Notebook\n\nThis is a tiny **FIX** for Ray to display logs under the **last executed cell** instead of **ray.init()** cell.\n\nQ: Why would this happen?\\\nA: Ipykernel captures thread output and redir to the cell where thread is created.\nThis is desired in some scenarios, but definitely not for Ray, whose logging thread\nis created upon `ray.init()` initialization.\n\nQ: How can you fix this?\\\nA: Utilizing IPython Events and mock Ray's internal log event handler.\n**This may be unstable because we depend on Ray's non-public API.**\nIn normal mode, Ray would log by emitting logs to `global_worker_stdstream_dispatcher`,\nreplacing the original handler with ours just works.\nFor client mode, things get trickier. `client_worker`'s LogStreamClient `log_client`\nwould receive remote log stream by gRPC and print to stdout/stderr.\nWe directly **mock replace** the `stdstream` method of that LogStreamClient instance.\nThere may be more robust and non-intrusive ways to do it,\nfor example capturing the `ray.init()`\ncell output.\n\nQ: How can I use this?\nA: As simple as:\n\n```python\n% cell 1\nimport ray\nray.init()\n\n% cell 2\nimport ray_log_notebook\nray_log_notebook.enable()\n\n% cell 3\n@ray.remote\ndef test_print():\n print(\"Woola!\")\n\nawait test_print.remote()\n```\n\n\n\n\nLogs will always go to the last executed cell, instead of where the Ray Tasks are created.\n\nTested on Python 3.13 and Ray 2.50.0, generally should work but I don't have much time to test.\n",
"bugtrack_url": null,
"license": null,
"summary": "Capture and redir ray logs in Jupyter Notebook.",
"version": "0.0.1",
"project_urls": {
"Repository": "https://github.com/clouder0/ray-log-notebook.git"
},
"split_keywords": [
"ray",
" log",
" ipython",
" jupyter",
" notebook"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "9c02820ba7904b34eb85bf64d0f27187915ea7c240c67414fefb3fe4f5277737",
"md5": "dd847678277a6391791de2326ff11114",
"sha256": "32f6208b692cf6f5feaa5fe75adf0332f43f5465a9d2c6433cd1270234a9a97a"
},
"downloads": -1,
"filename": "ray_log_notebook-0.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "dd847678277a6391791de2326ff11114",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 4216,
"upload_time": "2025-10-17T22:37:27",
"upload_time_iso_8601": "2025-10-17T22:37:27.167255Z",
"url": "https://files.pythonhosted.org/packages/9c/02/820ba7904b34eb85bf64d0f27187915ea7c240c67414fefb3fe4f5277737/ray_log_notebook-0.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c83318a08d363f28a04b66cee2a26c955a967f6a443fa40a9af9f90e45655fd6",
"md5": "4f2947a0fd513541e62930a1fe2205f7",
"sha256": "08479b73309774d5937efba19c9296da122250cf8dcbaec93b7c51171fc01e1f"
},
"downloads": -1,
"filename": "ray_log_notebook-0.0.1.tar.gz",
"has_sig": false,
"md5_digest": "4f2947a0fd513541e62930a1fe2205f7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 3254,
"upload_time": "2025-10-17T22:37:28",
"upload_time_iso_8601": "2025-10-17T22:37:28.159353Z",
"url": "https://files.pythonhosted.org/packages/c8/33/18a08d363f28a04b66cee2a26c955a967f6a443fa40a9af9f90e45655fd6/ray_log_notebook-0.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-17 22:37:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "clouder0",
"github_project": "ray-log-notebook",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "ray-log-notebook"
}