OnlyOffice 渲染时间获取指南
在使用 OnlyOffice 进行文档处理时,了解文档的渲染时间对于性能优化和用户体验提升至关重要。本文将详细介绍如何获取 OnlyOffice 的渲染时间数据,包括日志配置、数据暴露和结构化处理等完整流程。
1 配置日志级别
1.1 暴露全部日志类型
在部署 OnlyOffice 镜像时,需要添加环境变量参数来启用详细的日志记录:
docker run -dit -p 8888:80 \-e DS_LOG_LEVEL=ALL \--name onlyoffice \--restart=always \onlyoffice/documentserver \bash
1.2 日志级别说明
OnlyOffice 支持以下几种日志级别:
- ALL:记录所有级别的日志信息
- DEBUG:调试信息,包含渲染时间等详细数据
- INFO:一般信息记录
- WARN:警告信息
- ERROR:错误信息
注意:默认情况下,OnlyOffice 只记录 WARN 和 ERROR 级别的日志。要获取渲染时间数据,必须启用 DEBUG 级别的日志。
2 DEBUG 日志格式解析
2.1 渲染时间日志示例
DEBUG 级别的日志包含了丰富的渲染时间信息,典型格式如下:
[2025-08-26T16:58:44.275] [DEBUG] [localhost] [327ad08d1d3ca5d09a6544b61d53023f] [17302426094313758741] nodeJS - clientLog: onDocumentContentReady time:2757 memory:{"totalJSHeapSize":345283309,"usedJSHeapSize":276793837,"jsHeapSizeLimit":4294705152}
2.2 日志字段说明
- 时间戳:
[2025-08-26T16:58:44.275]
- 日志记录时间 - 级别:
[DEBUG]
- 日志级别 - 主机:
[localhost]
- 服务器主机名 - 文档 ID:
[327ad08d1d3ca5d09a6544b61d53023f]
- 唯一文档标识 - 用户 ID:
[17302426094313758741]
- 用户 ID - 事件类型:
onDocumentContentReady
- 渲染事件类型 - 渲染时间:
time:2757
- 渲染耗时(毫秒) - 内存信息:包含 JS 堆内存使用情况
2.3 主要渲染事件类型
- onDownloadFile:文件下载时间
- onOpenDocument:文档打开时间
- onLoadFonts:字体加载时间
- onDocumentContentReady:文档内容渲染完成时间
3 通过 Nginx 暴露日志
3.1 修改启动脚本
为了能够通过 HTTP 接口访问日志文件,需要修改 OnlyOffice 的启动脚本。在 Docker-DocumentServer
的Dockerfile
中添加以下代码:
sed -i '$a\location ^~ /outlog {\n alias /var/log/onlyoffice/documentserver/docservice/out.log;\n}' /etc/onlyoffice/documentserver/nginx/includes/ds-docservice.conf
或run-document-server.sh
中添加代码,这种方式更加优雅,因为run-document-server.sh
是 OnlyOffice 的启动脚本,已经封装了很多便捷方法。
3.2 配置说明
这段代码的作用是:
- 在 Nginx 配置文件末尾添加新的 location 块
- 将
/outlog
路径映射到实际的日志文件 - 允许通过 HTTP GET 请求直接访问日志内容
3.3 访问日志
配置完成后,可以通过以下 URL 访问日志:
http://your-onlyoffice-server/outlog
4 结构化日志 API 实现
4.1 API 概述
为了更好地处理和分析日志数据,我们需要实现一个结构化的 API 服务。该 API 基于 Flask 框架,提供日志解析、筛选和格式化功能。
4.2 核心功能模块
4.2.1 日志解析函数
def parse_log_line(line):"""解析单行日志数据"""pattern = r'^\[(?P<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3})\] \[(?P<level>\w+)\] \[(?P<host>.+?)\] \[(?P<docId>.+?)\] \[(?P<userId>.+?)\] (?P<message>.+)$'match = re.match(pattern, line)if not match:return Nonelog_entry = match.groupdict()# 时间戳格式转换original_timestamp = log_entry['timestamp']dt = datetime.strptime(original_timestamp, '%Y-%m-%dT%H:%M:%S.%f')formatted_timestamp = dt.strftime('%Y-%m-%d %H:%M:%S')log_entry['time'] = forma