fix(deploy): prioritize BaoTa-visible container logs
This commit is contained in:
@@ -35,15 +35,17 @@ GitLab 在独立 Node 镜像中自动执行拓扑合同,随后才允许服务
|
||||
|
||||
## 容器日志
|
||||
|
||||
所有服务只向标准输出和标准错误写日志,不在容器内生成应用日志文件,也不把应用日志目录挂载到宿主机。国内、海外 Compose 统一使用 Docker `local` 日志驱动;仍可通过 `docker logs` 排查。文件服务的 `/data/files` 是业务文件目录,不属于日志目录,必须继续持久化。
|
||||
所有服务只向标准输出和标准错误写日志,不在容器内生成应用日志文件,也不把应用日志目录挂载到宿主机。国内、海外及基础设施 Compose 默认使用宝塔可见的 Docker `json-file` 日志驱动,并设置强制轮转;仍可通过 `docker logs` 排查。文件服务的 `/data/files` 是业务文件目录,不属于日志目录,必须继续持久化。
|
||||
|
||||
单容器默认保留 `50m × 3`,可在各环境部署变量中覆盖:
|
||||
|
||||
| 环境 | `DOCKER_LOG_MAX_SIZE` | `DOCKER_LOG_MAX_FILE` | 长期留存 |
|
||||
|---|---:|---:|---|
|
||||
| 开发 | `20m` | `2` | 不要求 |
|
||||
| 测试 | `50m` | `3` | 不要求 |
|
||||
| 生产 | `100m` | `5` | 必须由集中日志系统负责,Docker 本机日志只作短期缓冲 |
|
||||
| 环境 | `DOCKER_LOG_DRIVER` | `DOCKER_LOG_MAX_SIZE` | `DOCKER_LOG_MAX_FILE` | 长期留存 |
|
||||
|---|---|---:|---:|---|
|
||||
| 开发 | `json-file` | `20m` | `2` | 不要求 |
|
||||
| 测试 | `json-file` | `50m` | `3` | 不要求 |
|
||||
| 生产前期 | `json-file` | `100m` | `5` | 宝塔与 `docker logs` 提供短期排障能力 |
|
||||
|
||||
当前优先保证宝塔可观测性,因此不启用 `json-file` 压缩或非阻塞投递,避免面板无法读取轮转文件或在日志压力下静默丢弃。接入集中日志系统后,可通过 `DOCKER_LOG_DRIVER` 切换驱动,并由集中系统承担长期检索与留存。
|
||||
|
||||
调整日志策略后必须重新创建容器;只重启既有容器不会改变其日志驱动。历史 `/data/logs/baiyue-firstleg` 文件和旧容器日志不自动删除,确认无需保留后再单独清理。
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ x-overseas-common: &overseas-common
|
||||
SPRING_SQL_INIT_MODE: never
|
||||
TZ: Asia/Shanghai
|
||||
logging:
|
||||
# 应用只写 stdout/stderr;local 驱动负责单份本机日志与轮转。
|
||||
driver: local
|
||||
# 应用只写 stdout/stderr;json-file 兼容宝塔查看,大小与数量均受控。
|
||||
driver: ${DOCKER_LOG_DRIVER:-json-file}
|
||||
options:
|
||||
max-size: ${DOCKER_LOG_MAX_SIZE:-50m}
|
||||
max-file: "${DOCKER_LOG_MAX_FILE:-3}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: firstleg-${DEPLOY_ENV:-test}-rocketmq
|
||||
|
||||
x-bounded-logging: &bounded-logging
|
||||
driver: local
|
||||
driver: ${DOCKER_LOG_DRIVER:-json-file}
|
||||
options:
|
||||
max-size: ${DOCKER_LOG_MAX_SIZE:-50m}
|
||||
max-file: "${DOCKER_LOG_MAX_FILE:-3}"
|
||||
|
||||
@@ -28,8 +28,8 @@ x-common: &common
|
||||
DATA_RESIDENCY: ${DATA_RESIDENCY:-CN}
|
||||
TZ: Asia/Shanghai
|
||||
logging:
|
||||
# 应用只写 stdout/stderr;local 驱动负责单份本机日志与轮转。
|
||||
driver: local
|
||||
# 应用只写 stdout/stderr;json-file 兼容宝塔查看,大小与数量均受控。
|
||||
driver: ${DOCKER_LOG_DRIVER:-json-file}
|
||||
options:
|
||||
max-size: ${DOCKER_LOG_MAX_SIZE:-50m}
|
||||
max-file: "${DOCKER_LOG_MAX_FILE:-3}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: firstleg-test-infra
|
||||
|
||||
x-bounded-logging: &bounded-logging
|
||||
driver: local
|
||||
driver: ${DOCKER_LOG_DRIVER:-json-file}
|
||||
options:
|
||||
max-size: ${DOCKER_LOG_MAX_SIZE:-50m}
|
||||
max-file: "${DOCKER_LOG_MAX_FILE:-3}"
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ node scripts/create-pending-review-orders.mjs
|
||||
| Mapper 注册静态合同 | `node scripts/mapper-scan-contract.mjs`、`node --test scripts/mapper-scan-contract.test.mjs`;自动核对全部持久化模块的 `@Mapper`、服务根包注解过滤扫描和唯一扫描入口,不启动 Spring、不连接数据库;`backend-full-regression.ps1` 在 Maven 前强制执行 |
|
||||
| Java 质量聚合摘要 | `node --test scripts/java-quality-summary.test.mjs`、`node scripts/java-quality-summary.mjs --output target/java-quality-summary.json`;聚合 Maven/服务拓扑、OpenAPI 覆盖、JaCoCo 和 SpotBugs 报告,默认只报告存量缺口,CI 用显式 `--require-jacoco --require-spotbugs` 检查报告完整性且当前允许失败 |
|
||||
| 单服务部署失败回滚合同 | `scripts/deploy-built-service-rollback.test.mjs`;模拟成功、健康失败和启动失败,确认仅恢复同服务先前健康镜像且部署任务仍失败 |
|
||||
| 容器日志单写合同 | `scripts/container-logging-contract.test.mjs`;离线确认应用只写标准输出、Compose 使用有界 `local` 驱动且不挂载应用日志目录 |
|
||||
| 容器日志单写合同 | `scripts/container-logging-contract.test.mjs`;离线确认应用只写标准输出、Compose 默认使用宝塔可见的有界 `json-file` 驱动且不挂载应用日志目录 |
|
||||
|
||||
Admin/Client HTTP 脚本的离线合同只验证脚本结构、参数和模块边界,不访问测试环境:
|
||||
|
||||
|
||||
@@ -40,10 +40,10 @@ test('deployable applications log only to stdout and stderr', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('Compose uses one bounded local log stream without application log mounts', () => {
|
||||
test('Compose uses one bounded BaoTa-compatible log stream without application log mounts', () => {
|
||||
for (const path of composeFiles) {
|
||||
const source = readFileSync(path, 'utf8');
|
||||
assert.match(source, /driver:\s+local/, path);
|
||||
assert.match(source, /driver:\s+\$\{DOCKER_LOG_DRIVER:-json-file\}/, path);
|
||||
assert.match(source, /DOCKER_LOG_MAX_SIZE/, path);
|
||||
assert.match(source, /DOCKER_LOG_MAX_FILE/, path);
|
||||
assert.doesNotMatch(source, /LOG_PATH|LOG_ROOT|\/app\/logs/, path);
|
||||
@@ -58,11 +58,11 @@ test('runtime image does not prepare an application log directory', () => {
|
||||
assert.doesNotMatch(dockerfile, /\/app\/logs/);
|
||||
});
|
||||
|
||||
test('infrastructure containers also use bounded local logs', () => {
|
||||
test('infrastructure containers also use bounded BaoTa-compatible logs', () => {
|
||||
for (const [path, expectedServiceCount] of infrastructureComposeFiles) {
|
||||
const source = readFileSync(path, 'utf8');
|
||||
assert.match(source, /x-bounded-logging:\s+&bounded-logging/, path);
|
||||
assert.match(source, /driver:\s+local/, path);
|
||||
assert.match(source, /driver:\s+\$\{DOCKER_LOG_DRIVER:-json-file\}/, path);
|
||||
assert.match(source, /DOCKER_LOG_MAX_SIZE/, path);
|
||||
assert.match(source, /DOCKER_LOG_MAX_FILE/, path);
|
||||
assert.equal(
|
||||
@@ -70,6 +70,6 @@ test('infrastructure containers also use bounded local logs', () => {
|
||||
expectedServiceCount,
|
||||
path,
|
||||
);
|
||||
assert.doesNotMatch(source, /driver:\s+json-file/, path);
|
||||
assert.doesNotMatch(source, /driver:\s+local/, path);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user