调试

服务器

在开发过程中运行 bench start 命令时,Procfile 中每个进程的日志都会输出到终端窗口中。

▶ bench start
14:55:17 system | redis_cache.1 started (pid=4085)
14:55:17 system | redis_socketio.1 started (pid=4086)
14:55:17 system | redis_queue.1 started (pid=4088)
14:55:17 system | web.1 started (pid=4089)
14:55:17 system | socketio.1 started (pid=4090)
14:55:17 system | watch.1 started (pid=4094)
14:55:17 system | worker_short.1 started (pid=4096)
14:55:17 system | schedule.1 started (pid=4095)
14:55:17 redis_queue.1 | 4088:C 22 May 14:55:17.257 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14:55:17 redis_queue.1 | 4088:C 22 May 14:55:17.264 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=4088, just started
14:55:17 redis_queue.1 | 4088:C 22 May 14:55:17.264 # Configuration loaded
14:55:17 redis_queue.1 | 4088:M 22 May 14:55:17.265 * Increased maximum number of open files to 10032 (it was originally set to 4864).
14:55:17 redis_cache.1 | 4085:C 22 May 14:55:17.262 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14:55:17 redis_cache.1 | 4085:C 22 May 14:55:17.268 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=4085, just started
14:55:17 redis_cache.1 | 4085:C 22 May 14:55:17.268 # Configuration loaded
14:55:17 redis_cache.1 | 4085:M 22 May 14:55:17.269 * Increased maximum number of open files to 10032 (it was originally set to 4864).
14:55:17 redis_socketio.1 | 4086:C 22 May 14:55:17.262 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14:55:17 redis_socketio.1 | 4086:C 22 May 14:55:17.270 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=4086, just started
14:55:17 redis_socketio.1 | 4086:C 22 May 14:55:17.270 # Configuration loaded
14:55:17 redis_socketio.1 | 4086:M 22 May 14:55:17.272 * Increased maximum number of open files to 10032 (it was originally set to 4864).
14:55:17 redis_queue.1 | 4088:M 22 May 14:55:17.285 * Running mode=standalone, port=11002.
14:55:17 redis_queue.1 | 4088:M 22 May 14:55:17.285 # Server initialized
14:55:17 redis_queue.1 | 4088:M 22 May 14:55:17.286 * Ready to accept connections
14:55:17 redis_cache.1 | 4085:M 22 May 14:55:17.287 * Running mode=standalone, port=13002.
14:55:17 redis_cache.1 | 4085:M 22 May 14:55:17.292 # Server initialized
14:55:17 redis_cache.1 | 4085:M 22 May 14:55:17.292 * Ready to accept connections
14:55:17 redis_socketio.1 | 4086:M 22 May 14:55:17.294 * Running mode=standalone, port=12002.
14:55:17 redis_socketio.1 | 4086:M 22 May 14:55:17.294 # Server initialized
14:55:17 redis_socketio.1 | 4086:M 22 May 14:55:17.295 * Ready to accept connections
14:55:17 system | worker_long.1 started (pid=4098)
14:55:17 system | worker_default.1 started (pid=4100)
14:55:18 socketio.1 | listening on *: 9002
14:55:20 socketio.1 | { Error: connect ECONNREFUSED 0.0.0.0:8002
14:55:20 socketio.1 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14)
14:55:20 socketio.1 | errno: 'ECONNREFUSED',
14:55:20 socketio.1 | code: 'ECONNREFUSED',
14:55:20 socketio.1 | syscall: 'connect',
14:55:20 socketio.1 | address: '0.0.0.0',
14:55:20 socketio.1 | port: 8002,
14:55:20 socketio.1 | response: undefined }
14:55:24 web.1 | * Running on http://0.0.0.0:8002/ (Press CTRL+C to quit)
14:55:24 web.1 | * Restarting with fsevents reloader
14:55:24 watch.1 | yarn run v1.10.1
14:55:24 watch.1 | $ node rollup/watch.js
14:55:25 web.1 | * Debugger is active!
14:55:25 web.1 | * Debugger PIN: 321-355-865
14:55:26 watch.1 |
14:55:26 watch.1 | Rollup Watcher Started
14:55:26 watch.1 |
14:55:26 watch.1 | Watching...
14:55:26 watch.1 | Rebuilding frappe-web.css
14:55:27 watch.1 | Rebuilding frappe-web-b4.css
14:55:27 watch.1 | Rebuilding chat.js
14:55:28 web.1 |
14:55:28 web.1 | test print

当你在 Python 代码中编写任何 print 语句时,如果是请求/响应相关的,它会显示在 web: 进程日志中;如果代码在后台任务中运行,则会显示在某个 worker_ 进程中。

> 如果你是 VSCode 用户,可以直接在编辑器中通过设置断点来调试代码。按照这些[步骤](在 VS Code 中调试 / 调试适配器协议)进行设置。

日志

如果你运行的是生产环境,你就更需要日志来跟踪 Frappe 环境的尽可能多的信息。

开箱即用,日志存储在 bench 中的 ./logs 文件夹下。从 Frappe 13 版本开始,日志也可以在站点级别访问,位于 ./sites/{site}/logs 下。

这些站点日志由 Frappe 应用程序创建,而许多 bench 级别的日志文件则由支持你 Frappe 环境的进程生成。查看 bench 中的 Procfile 或 supervisor.conf 以获取更多信息。

> 在此处了解更多关于 Frappe 日志的信息,在此处了解 Frappe 日志 API。

控制台

要使用 Python API,bench 提供了一个 iPython shell。运行以下命令后,它会导入 frappe、初始化它并连接到数据库。

▶ bench --site [sitename] console

In [1]: frappe.get_doc('Task', 'TASK00004')
Out[1]: <erpnext.projects.doctype.task.task.task at="" 0x10825d710="">

客户端

客户端调试就像在你的 JS 文件中添加一个 debugger 语句一样简单。你必须在浏览器中打开开发者工具,它才会在该语句处暂停。

frappe.db.get_value('Task', 'TASK00004', 'status')
    .then(values => {
        debugger
        console.log(values);
    })

控制台

要使用客户端 API,你可以打开浏览器的控制台,使用全局可用的 frappe 对象来探索和运行方法以及访问属性。

浏览器控制台

> 在此处了解更多关于客户端 API 的信息

在 VS Code 中调试 / 调试适配器协议

正常运行的检查清单。

  • 更新 Procfile
  • 获取 Visual Studio Code(废话!)
  • 为 VS Code 安装 Python 扩展
  • 更新 launch.json
  • 开始调试

注意事项:

  1. 禁用自动重载功能(不过你可以通过手动重载(⌘⇧F5)达到相同效果)
  2. 禁用 Werkzeug 多线程

1. 更新 Procfile

注意:这会修改 bench start 的行为

从 Procfile(位于 bench 目录中)注释掉一行(在其前面加上 #),该行看起来像这样。

web: bench serve --port 8000

我们将从 VS Code 运行此进程,而不是用 bench start 来运行它。

2. 更新 launch.json 在 VS Code 中为你的 launch.json 添加一个配置,应该看起来像这样(这大致上就是被移除的 Procfile 行所做的事情)。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Bench",
            "type": "python",
            "request": "launch",
            "justMyCode": false,
            "program": "${workspaceFolder}/frappe/frappe/utils/bench_helper.py",
            "args": [
             "frappe", "serve", "--port", "8000", "--noreload", "--nothreading"
            ],
            "python": "${workspaceFolder}/../env/bin/python",
            "cwd": "${workspaceFolder}/../sites",
            "env": {
             "DEV_SERVER": "1"
            }
        }
    ]
}

给定配置中提到的路径假设你将 apps 目录作为你的工作区目录(你用 code 打开的目录)。workspaceFolder 是一个 VS Code 变量,指向(如果从名字看不出来的话)工作区目录。

你并非必须使用 apps 作为你的工作区目录,但请记得相应地修改 workspaceFolder、pythonPath 和 cwd。

3. 执行 bench start

这应该像往常一样保持运行。

4. 开始调试

VS Code -> 调试面板(⌘⇧D)-> 开始调试,或使用键盘快捷键(⌘⇧F5)。

说明

1. program 和 args

"program": "${workspaceFolder}/frappe/frappe/utils/bench_helper.py",
"args": ["frappe", "serve", "--port", "8000", "--noreload", "--nothreading"],

做的事情与 bench serve --port 8000 --noreload --nothreading 完全相同,也就是等同于

cd sites
../env/bin/python ../apps/frappe/frappe/utils/bench_helper.py frappe serve  --port 8000 --noreload --nothreading

--noreload 禁用了 Werkzeug 的自动重载功能,--nothreading 禁用了多线程。

2. cwd

"cwd": "${workspaceFolder}/../sites",

上述命令必须从 sites 目录执行。

3. env

"env": {
    "DEV_SERVER": "1"
}

bench start 创建一个环境变量 DEV_SERVER 并将其设置为 1。没有这个,Socket.io 无法正常工作(说来话长)。

仅运行 bench serve 不会设置此变量,所以你需要显式设置它。

注意:

目前,frappe 使用 use_reloader=True 和 threaded=True 运行,VS Code 调试器由于某些原因与这些功能配合不佳,Django 和 Flask 也有这个问题。