odoo-activity đưa các worker của một hệ thống Odoo và các backend PostgreSQL của nó về chung một màn hình, đổ ngăn xếp mà không phải đào log, và mở cùng dữ liệu đó cho agent qua MCP.
Suốt nhiều năm, pg_activity trả lời rất tốt đúng một câu hỏi: postgres đang
làm gì ngay lúc này. Mở nó ra là thấy các truy vấn, cái chạy lâu nhất nằm trên
cùng.
Odoo thì không có thứ tương đương. Khi một hệ thống đang nghẽn cứng và có người hỏi nó đang bận với cái gì, bạn phải xoay xở tạm bợ:
pscho biết một worker đã sống sáu ngày. Nó chẳng nói gì về cái request mà worker ấy đang kẹt trong bốn mươi giây vừa rồi.kill -3 <pid>khiến Odoo in ngăn xếp của mọi thread vào log. Rồi bạn phải đào bới trong log để tìm chúng, theo từng worker, và nếu worker đang bị chặn ở postgres hay ở IO thì traceback tuy chính xác nhưng vô dụng.py-spy dumpcho kết quả tốt hơn, nhưng nó cần quyền root trên một máy mà nhiều khả năng bạn chỉ có userodoo.- Vá Odoo để ghi lời gọi hiện tại vào tiêu đề tiến trình bằng
setproctitle, thứ chúng tôi từng thử từ lâu. Nó đọc rất tiện trongps, đổi lại là một bản vá vào bản lõi phải duy trì cho từng dự án.
Mỗi cách chỉ trả lời một mảnh của câu hỏi, qua một công cụ khác nhau, với kết quả ở một hình dạng khác nhau. Ghép chúng lại là việc làm tay dưới áp lực thời gian, mà đó lại đúng là lúc một bước chẩn đoán bị bỏ qua.
odoo-activity (oa) là nỗ lực của chúng tôi cho cái màn hình còn thiếu đó.
Một màn hình
CPU, bộ nhớ, swap và tải của máy chủ nằm ở phần đầu. Khung thứ hai hiển thị mọi hệ thống Odoo trên máy, với các database lồng bên dưới. Khung thứ ba là khung chi tiết, và các tab của nó đổi theo thứ đang được chọn:
| Đang chọn | Các tab |
|---|---|
| một hệ thống | Top, Processes, Stacks, Logs, Config |
| một database của nó | Queries, Users, Locks, Jobs, Crons, Modules |
Bộ tab này chưa chốt và sẽ còn đổi theo cách chúng tôi dùng công cụ; nguyên tắc chúng tôi giữ là thứ gì xứng đáng có một tab thì phải đáng đọc trong lúc chẩn đoán, chứ không chỉ là có sẵn.
Các hệ thống được tự phát hiện chứ không phải khai báo: unit của
systemd --user, chương trình của supervisor, các bản build trên odoo.sh, và
các hệ thống chạy cục bộ ngay từ terminal, gộp chung vào một danh sách. Từ đó,
mọi thứ về một hệ thống đều phân giải ra từ đúng một file, là file cấu hình của
nó dưới <workdir>/config/: odoo.conf hoặc server.conf, và odooNN.conf
cho một node của hệ thống nhiều node, với tên mang hậu tố -NN tương ứng
(foo-01). Đó là nơi lấy ra danh sách database, file log, cổng database, tất cả.
Máy ở xa cũng hoạt động theo đúng cách đó:
oa # this machine
oa odoo@somehost # over ssh
oa odoo@somehost -p 10113
Kết nối ssh được ghép kênh, nên lần thăm dò đầu tiên mở phiên và mọi thứ sau đó
dùng lại phiên ấy. Với máy ở xa, chu kỳ làm mới chạy chậm hơn, và phím R buộc
tab đang mở làm mới ngay.
Odoo và postgres trong cùng một bảng
Tab Top liệt kê các worker của hệ thống (đi xuống theo cây PPID từ PID của tiến trình master mà trình quản lý báo về) và, trong cùng bảng đó, các backend postgres đang phục vụ các database của hệ thống này.
Cặp đôi ấy là phần chúng tôi dùng nhiều nhất. Một backend đang nhai dữ liệu sẽ
có cổng TCP phía client nằm trong tiêu đề ps của nó; chạy lsof trên cổng đó
sẽ trả về PID ở đầu bên kia, chính là worker Odoo đã mở kết nối. “Truy vấn nào
chậm” và “worker nào đang kẹt” thôi còn là hai cuộc điều tra tách rời.
Khi một hệ thống bốc cháy
Một trình tự thao tác đại khái, từ rẻ nhất tới xâm lấn nhất:
-
Đọc phần đầu màn hình trước. Swap đang leo và tải cao nghĩa là vấn đề bộ nhớ, không phải mã nguồn, và có đổ bao nhiêu ngăn xếp cũng không cho bạn biết điều đó.
-
Top (
p). Có bao nhiêu worker, mỗi cái tốn bao nhiêu bộ nhớ, và chúng đang giữ mở bao nhiêu backend postgres. Một worker chiếm bộ nhớ cao là một vấn đề khác hẳn với việc tất cả chúng đều đang bận. -
Đổ ngăn xếp (
D). Gửi SIGQUIT tới master và mọi worker, rồi đọc lại các bản đổ ngăn xếp mới từ log và phân tích chúng. Mất chừng hai giây. Các worker trả về đã sắp xếp theo mức bận giảm dần, thread bận đứng trước thread rảnh, và mỗi traceback được đảo ngược để khung trong cùng (dòng thật sự đang chạy) là thứ bạn đọc đầu tiên, theo phong cách py-spy.Đây chính là mẹo
kill -3, trừ đi phần khảo cổ trong log. SIGQUIT ở đây không giết gì cả: Odoo cài sẵn một trình xử lý cho tín hiệu này và nó chỉ in ngăn xếp ra. -
Các khung trỏ vào postgres? Chuyển xuống dòng database rồi sang tab Queries bằng
[/]. Các truy vấn không ở trạng thái nghỉ lấy từpg_stat_activity, cái chạy lâu nhất nằm trên cùng. -
Kẹt chứ không phải chậm? Xem Locks (
l) trên database. Đang chờ một cron hay một job trong hàng đợi? Xem Crons (c) và Jobs (j), cũng ở đó. -
Rồi mới ra tay.
Kgiết đúng cái worker hỏng bằng-9.Lgửi-3rồi đưa bạn sang tab Logs nếu muốn ghi lại traceback trước khi giết nó.rkhởi động lại cả hệ thống,sbật tắt start/stop. Tất cả đều nằm sau một hộp thoại xác nhận.
Các bước 1 tới 5 không thay đổi gì trên máy đích. Điều đó có ý nghĩa khi cái máy đang nói tới là production và bạn mới ở phút thứ ba của một sự cố.
Cũng dữ liệu đó, dành cho một agent
Mọi thứ ở trên đều được phơi ra dưới dạng một máy chủ MCP:
oa-mcp odoo@somehost
Các tool đều chỉ đọc, một cách có chủ đích: list_instances, host_stats,
instance_top, instance_databases, instance_version, instance_config,
instance_log_tail, instance_dump_stacks, long_queries, và db_query cho
một tập con có giới hạn các lệnh chẩn đoán của odoo-db (modules, crons, jobs,
users, locks). Không start, không stop, không restart, không kill.
oa-mcp bị ghim vào đúng một máy, y như oa <host>. Một lời gọi tool nêu tên
máy khác sẽ bị từ chối chứ không bị âm thầm chuyển đích. oa-mcp-multi thì để
đích được chỉ định theo từng lời gọi, giới hạn bởi một regex --host-filter và
một --host-file chứa các bí danh ssh.
Hình dung mong muốn là hai người cùng xử lý một sự cố, mà một trong hai là một
agent: bạn ở oa somehost, nó ở oa-mcp somehost, cả hai cùng nhìn vào một hệ
thống. Bạn hỏi vì sao cái này chậm, nó đổ ngăn xếp và đọc pg_stat_activity,
còn bạn thì đã đang nhìn vào đúng cái bảng nó đang mô tả.
Các tool hành động sẽ do bạn chạy, không phải agent. Bắt đầu từ chế độ chỉ đọc là nhắm vào đúng nút thắt thật: khâu chẩn đoán.
Nó cần những gì
- Hệ thống được quản lý bằng
systemd --user,supervisor, chạy trên odoo.sh, hoặc chạy cục bộ ngay từ terminal. odoo-dbnằm trongPATHcho các tab database,odoo-configvàodoo-addons-pathcho tab Config.psqlđể phát hiện database và cho tab Queries,lsofcho phần nối backend với worker.- Với một máy đích ở xa: đúng những công cụ đó phải có trên máy ở xa, không phải trên máy của bạn.
uv tool install odoo-activity