From 8ff7edd5d80f389b837ca1fae6ec22291ac62756 Mon Sep 17 00:00:00 2001 From: Dan Yishai Date: Sat, 17 Aug 2024 23:40:34 +0300 Subject: [PATCH] Added setup hints --- README.md | 16 ++++++++ frontend/src/components/common/CodeBlock.tsx | 8 +--- .../src/components/task/RecentTasksPanel.tsx | 39 ++++++++++++++++--- .../components/task/alerts/ExceptionAlert.tsx | 2 +- .../components/worker/WorkersSummaryStack.tsx | 9 +++-- poetry.lock | 2 +- pyproject.toml | 1 + test_project/producer.py | 3 +- 8 files changed, 62 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3521f53..fd911db 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,22 @@ docker run -p 8555:8555 --name celery-insights ghcr.io/danyi1212/celery-insights Next, navigate to http://localhost:8555/ and begin the welcome tour. +### Enabling Celery Events + +Celery Insights relies on Celery events to monitor your Celery cluster. + +The recommended configuration for using Celery Insights are: +```python +app = Celery("myapp") +app.conf.worker_send_task_events = True # Enables task events +app.conf.task_send_sent_event = True # Enables sent events +app.conf.task_track_started = True # (opt) Update task result state to STARTED +app.conf.result_extended = True # (opt) Store args and kwargs in the result +``` +Other events-related configurations should be left as default. + +For more information on Celery events configurations, please refer to the [Celery documentation](https://docs.celeryq.dev/en/stable/userguide/configuration.html#events). + ### Advanced setup Celery Insights comes pre-configured for localhost Redis as Result Backend and RabbitMQ as Broker. diff --git a/frontend/src/components/common/CodeBlock.tsx b/frontend/src/components/common/CodeBlock.tsx index 9ccaffc..8d1a118 100644 --- a/frontend/src/components/common/CodeBlock.tsx +++ b/frontend/src/components/common/CodeBlock.tsx @@ -4,15 +4,11 @@ import { PrismLight as SyntaxHighlighter, SyntaxHighlighterProps } from "react-s import darkStyle from "react-syntax-highlighter/dist/esm/styles/prism/material-dark" import lightStyle from "react-syntax-highlighter/dist/esm/styles/prism/material-light" -interface CodeBlockProps extends Omit { - code: string -} - -const CodeBlock: React.FC = ({ code, ...props }) => { +const CodeBlock: React.FC = ({ children, ...props }) => { const theme = useTheme() return ( - {code} + {children} ) } diff --git a/frontend/src/components/task/RecentTasksPanel.tsx b/frontend/src/components/task/RecentTasksPanel.tsx index 14498b2..70bd54c 100644 --- a/frontend/src/components/task/RecentTasksPanel.tsx +++ b/frontend/src/components/task/RecentTasksPanel.tsx @@ -1,9 +1,12 @@ import AnimatedList from "@components/common/AnimatedList" import AnimatedListItem from "@components/common/AnimatedListItem" +import CodeBlock from "@components/common/CodeBlock" import Panel, { PanelProps } from "@components/common/Panel" import TaskAvatar from "@components/task/TaskAvatar" import ReadMoreIcon from "@mui/icons-material/ReadMore" +import Box from "@mui/material/Box" import Button from "@mui/material/Button" +import Link from "@mui/material/Link" import ListItemAvatar from "@mui/material/ListItemAvatar" import ListItemButton from "@mui/material/ListItemButton" import ListItemSecondaryAction from "@mui/material/ListItemSecondaryAction" @@ -13,13 +16,13 @@ import Typography from "@mui/material/Typography" import { useStateStore } from "@stores/useStateStore" import { format } from "date-fns" import React, { useCallback } from "react" -import { Link as RouterLink, Link } from "react-router-dom" +import { Link as RouterLink } from "react-router-dom" const RecentTaskListItem: React.FC<{ taskId: string }> = ({ taskId }) => { const task = useStateStore(useCallback((store) => store.tasks.get(taskId), [taskId])) return ( - + @@ -57,9 +60,35 @@ const RecentTasksPanel: React.FC> = (props) => { ))} ) : ( - - No recent tasks - + + + No recent tasks + + Make sure you have Celery Events enabled: + + + {[ + 'app = Celery("myapp")', + "app.conf.worker_send_task_events = True", + "app.conf.task_send_sent_event = True", + "app.conf.task_track_started = True", + "app.conf.result_extended = True", + "app.conf.enable_utc = True", + ].join("\n")} + + + + For more information, see the{" "} + + Installation docs + + . + + )} ) diff --git a/frontend/src/components/task/alerts/ExceptionAlert.tsx b/frontend/src/components/task/alerts/ExceptionAlert.tsx index b7f55a3..d4f1f54 100644 --- a/frontend/src/components/task/alerts/ExceptionAlert.tsx +++ b/frontend/src/components/task/alerts/ExceptionAlert.tsx @@ -70,7 +70,7 @@ const ExceptionTraceback: React.FC = ({ exception, trac Traceback - + {traceback} )} diff --git a/frontend/src/components/worker/WorkersSummaryStack.tsx b/frontend/src/components/worker/WorkersSummaryStack.tsx index 0a5acf1..346e7d4 100644 --- a/frontend/src/components/worker/WorkersSummaryStack.tsx +++ b/frontend/src/components/worker/WorkersSummaryStack.tsx @@ -23,9 +23,12 @@ const WorkersSummaryStack: React.FC = () => { ))} ) : ( - - No online workers - + + + No online workers + + Start a Celery worker to see it here + )} ) diff --git a/poetry.lock b/poetry.lock index 4aacaf6..6290228 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3178,4 +3178,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "8b0b4200c00c305e72b8e89fd518d88e1fc4dde49924b96445240aef006b205f" +content-hash = "e86b91c2d073bd00f898f596b85cdb460d77c0bc6ece249592735fee93fe6896" diff --git a/pyproject.toml b/pyproject.toml index aa63c8d..f3b97c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ aiopath = "^0" pydantic = "^2" pydantic-settings = "^2" colorlog = "*" +redis = "^5.0.8" [tool.poetry.group.all] optional = true diff --git a/test_project/producer.py b/test_project/producer.py index 1e91362..b90bb41 100644 --- a/test_project/producer.py +++ b/test_project/producer.py @@ -31,8 +31,7 @@ async def main(): stop_signal = asyncio.Event() logger.info("Starting producer...") - async with asyncio.TaskGroup() as tg: - tg.create_task(timer(10, lambda: publish(order_workflow.si()), stop_signal)) + await timer(10, lambda: publish(order_workflow.si()), stop_signal) if __name__ == "__main__":