如何部署可生成日志文件的Plumber Docker容器?
问题:Plumber API Docker部署后无法生成日志文件
我在将R Plumber测试API部署为Docker容器时遇到问题,核心需求是API处理请求时能生成日志文件——这个功能在本地测试正常,但容器化后完全没反应,连/app/logs目录下的日志文件都创建不了。
我的预期是日志能存在容器与主机共享的目录里。
以下是我的相关文件:
plumber.R
# plumber.R # A simple API to illustrate logging with Plumber library(plumber) #* @apiTitle Logging Example #* @apiDescription Simple example API for implementing logging with Plumber #* Echo back the input #* @param msg The message to echo #* @get /echo function(msg = "") { list(msg = paste0("The message is: '", msg, "'")) }
entrypoint.R
library(plumber) # Config #config <- config::get() # logging library(logger) # Ensure glue is a specific dependency so it's avaible for logger library(glue) # Specify how logs are written log_dir <- "/app/logs" if (!fs::dir_exists(log_dir)) fs::dir_create(log_dir) log_appender(appender_tee(tempfile("plumber_", log_dir, ".log"))) convert_empty <- function(string) { if (string == "") { "-" } else { string } } pr <- plumb("plumber.R") pr$registerHooks( list( preroute = function() { # Start timer for log info tictoc::tic() }, postroute = function(req, res) { end <- tictoc::toc(quiet = TRUE) # Log details about the request and the response # TODO: Sanitize log details - perhaps in convert_empty log_info('{convert_empty(req$REMOTE_ADDR)} "{convert_empty(req$HTTP_USER_AGENT)}" {convert_empty(req$HTTP_HOST)} {convert_empty(req$REQUEST_METHOD)} {convert_empty(req$PATH_INFO)} {convert_empty(res$status)} {round(end$toc - end$tic, digits = getOption("digits", 5))}') } ) ) pr
Dockerfile
# Base image https://hub.docker.com/u/rocker/ FROM rstudio/plumber # Install R libraries RUN R -e "install.packages(c('odbc','glue','parsedate','tibble','dplyr','httr','RCurl','jsonlite','rjson','stringr','telegram','R.utils','logger','tictoc'))" # Run plumber package CMD ["/app/plumber.R"]
构建与运行命令
docker build -t logger2 . docker run -d -p 18001:8000 --rm \ -v /home/user/R/projects/logger2/:/app \ -v /tmp/log1:/app/logs \ logger2
解决方案
1. 核心问题定位
当前Docker容器直接启动plumber.R,但日志配置、请求钩子等关键逻辑都在entrypoint.R中,容器根本没加载这部分代码,自然不会生成日志。另外entrypoint.R依赖的fs包也未在Dockerfile中安装。
2. 具体修复步骤
(1)修改Dockerfile
更新安装命令添加fs包,并将启动命令改为运行entrypoint.R:
# Base image FROM rstudio/plumber # Install all required R libraries including fs RUN R -e "install.packages(c('odbc','glue','parsedate','tibble','dplyr','httr','RCurl','jsonlite','rjson','stringr','telegram','R.utils','logger','tictoc','fs'))" # Run entrypoint.R instead of plumber.R CMD ["/app/entrypoint.R"]
(2)确保挂载目录权限
主机的/tmp/log1目录需要让容器内用户有读写权限,可提前设置:
mkdir -p /tmp/log1 chmod 777 /tmp/log1
或者运行容器时指定root用户:
docker run -d -p 18001:8000 --rm \ -v /home/user/R/projects/logger2/:/app \ -v /tmp/log1:/app/logs \ --user root \ logger2
(3)测试日志生成
重启容器后发送测试请求:
curl http://localhost:18001/echo?msg=test
此时查看主机/tmp/log1目录,会生成类似plumber_XXXXXX.log的日志文件,里面包含请求详情。
3. 可选优化:固定日志文件名
如果不想使用临时文件名,可将entrypoint.R中的日志路径改为固定值:
log_file <- file.path(log_dir, "plumber.log") log_appender(appender_tee(log_file))
这样所有请求日志会追加到同一个文件中,方便统一查看。
内容的提问来源于stack exchange,提问作者Andres Mora
相关产品推荐
相关产品推荐

