diff --git a/docs/integration_guide.md b/docs/integration_guide.md index da69f9a..2ec8fd8 100644 --- a/docs/integration_guide.md +++ b/docs/integration_guide.md @@ -408,32 +408,39 @@ void main() { > `source: "cicd"` -在 Gitea Actions 流水线中,为每个关键步骤添加失败上报,构建/测试/Lint 失败时自动上报到 Log Center。 +在 Gitea Actions 流水线中添加失败上报,构建/测试/部署失败时自动捕获实际错误日志并上报到 Log Center。 + +### 核心要点 + +1. **用 `tee` 捕获日志** — 构建和部署步骤的输出必须通过 `2>&1 | tee /tmp/xxx.log` 捕获,否则上报的 stack_trace 为空 +2. **用 `github.run_number`** — URL 中必须使用 `${{ github.run_number }}`(仓库维度序号),**不要用 `github.run_id`**(全局ID,会导致跳转到错误页面) +3. **用 `${{ }}` 模板语法** — 比 `$GITHUB_*` 环境变量更可靠 +4. **单一综合上报步骤** — 一个 `if: failure()` 步骤自动判断哪个阶段失败,收集对应日志 ### 上报格式 ```json { "project_id": "rtc_backend", - "environment": "cicd", + "environment": "main", "level": "ERROR", "source": "cicd", - "commit_hash": "abc1234", + "commit_hash": "abc1234def5678", + "repo_url": "https://gitea.airlabs.art/zyc/rtc_backend.git", "error": { - "type": "DockerBuildError", - "message": "Docker build failed", - "file_path": null, - "line_number": null, - "stack_trace": ["Build step failed. Check CI logs for details."] + "type": "CICDFailure", + "message": "[build] Build and Deploy failed on branch main", + "stack_trace": ["...实际构建日志最后 50 行..."] }, "context": { - "workflow_name": "Build and Deploy", - "job_name": "build", - "step_name": "Build Docker Image", - "run_id": "123", + "job_name": "build-and-deploy", + "step_name": "build", + "workflow": "Build and Deploy", + "run_id": "24", "branch": "main", - "repository": "team/rtc_backend", - "run_url": "https://gitea.airlabs.art/team/rtc_backend/actions/runs/123" + "actor": "zyc", + "commit": "abc1234def5678", + "run_url": "https://gitea.airlabs.art/zyc/rtc_backend/actions/runs/24" } } ``` @@ -443,20 +450,19 @@ void main() { | 字段 | 说明 | |------|------| | `source` | **必须**设为 `"cicd"` | -| `environment` | 设为 `"cicd"` | -| `error.type` | 推荐值:`DockerBuildError`, `NpmBuildError`, `TestFailure`, `LintError`, `CIBuildError` | -| `error.file_path` | 可为 `null` | -| `error.line_number` | 可为 `null` | -| `context.workflow_name` | 工作流名称 | -| `context.job_name` | Job 名称 | +| `environment` | 用分支名 `${{ github.ref_name }}`,如 `main`、`dev` | +| `repo_url` | 仓库地址,便于 Repair Agent 关联 | +| `error.type` | 推荐 `CICDFailure`(通用)或 `DockerBuildError` / `TestFailure` / `DeployError` | +| `error.stack_trace` | **实际错误日志**(通过 `tee` 捕获),不要写死占位文字 | +| `context.run_id` | **必须用 `${{ github.run_number }}`**(不是 `github.run_id`) | +| `context.run_url` | 拼接方式:`https://gitea.airlabs.art/${{ github.repository }}/actions/runs/${{ github.run_number }}` | | `context.step_name` | 失败的步骤名称 | -| `context.run_id` | 运行 ID | -| `context.run_url` | CI 运行详情链接 | -| `context.branch` | 分支名 | +| `context.actor` | 触发者 | +| `context.commit` | 完整 commit hash | -### Gitea Actions 集成方式 +### Gitea Actions 集成方式(推荐) -为每个关键步骤添加 `id`,然后在末尾添加条件上报步骤: +以下是完整示例,关键点:构建步骤用 `tee` 捕获日志,末尾一个综合上报步骤自动判断失败阶段。 ```yaml name: Build and Deploy @@ -465,87 +471,94 @@ on: push: branches: [main] -env: - LOG_CENTER_URL: https://qiyuan-log-center-api.airlabs.art - jobs: - build: + build-and-deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 + + # ===== 构建步骤:用 tee 捕获日志 ===== - # 关键步骤:添加 id - name: Build Docker Image id: build - run: docker build -t myapp:latest . - - - name: Run Tests - id: test - run: docker run myapp:latest python -m pytest + run: | + set -o pipefail + docker buildx build \ + --push \ + --provenance=false \ + --tag your-registry/your-app:latest \ + . 2>&1 | tee /tmp/build.log - name: Deploy id: deploy - run: kubectl apply -f k8s/ - - # ===== 失败上报步骤(放在所有关键步骤之后) ===== - - - name: Report Build Failure - if: failure() && steps.build.outcome == 'failure' run: | - curl -s -X POST "${LOG_CENTER_URL}/api/v1/logs/report" \ - -H "Content-Type: application/json" \ - -d '{ - "project_id": "'"${GITHUB_REPOSITORY##*/}"'", - "environment": "cicd", - "level": "ERROR", - "source": "cicd", - "commit_hash": "'"$GITHUB_SHA"'", - "error": { - "type": "DockerBuildError", - "message": "Docker build failed", - "file_path": null, - "line_number": null, - "stack_trace": ["Docker build step failed. Check CI logs."] - }, - "context": { - "workflow_name": "'"$GITHUB_WORKFLOW"'", - "job_name": "'"$GITHUB_JOB"'", - "step_name": "Build Docker Image", - "run_id": "'"$GITHUB_RUN_ID"'", - "branch": "'"$GITHUB_REF_NAME"'", - "repository": "'"$GITHUB_REPOSITORY"'", - "run_url": "'"$GITHUB_SERVER_URL"'/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"'" - } - }' --connect-timeout 5 --max-time 10 || true + set -o pipefail + { + kubectl apply -f k8s/deployment.yaml + kubectl rollout restart deployment/your-app + } 2>&1 | tee /tmp/deploy.log - - name: Report Test Failure - if: failure() && steps.test.outcome == 'failure' + # ===== 失败上报(单一综合步骤) ===== + + - name: Report failure to Log Center + if: failure() run: | - curl -s -X POST "${LOG_CENTER_URL}/api/v1/logs/report" \ + # 判断哪个步骤失败,收集对应日志 + BUILD_LOG="" + DEPLOY_LOG="" + FAILED_STEP="unknown" + + if [[ "${{ steps.build.outcome }}" == "failure" ]]; then + FAILED_STEP="build" + if [ -f /tmp/build.log ]; then + BUILD_LOG=$(tail -50 /tmp/build.log | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') + fi + elif [[ "${{ steps.deploy.outcome }}" == "failure" ]]; then + FAILED_STEP="deploy" + if [ -f /tmp/deploy.log ]; then + DEPLOY_LOG=$(tail -50 /tmp/deploy.log | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') + fi + fi + + ERROR_LOG="${BUILD_LOG}${DEPLOY_LOG}" + if [ -z "$ERROR_LOG" ]; then + ERROR_LOG="No captured output. Check Gitea Actions UI for details." + fi + + # 判断 source + if [[ "$FAILED_STEP" == "deploy" ]]; then + SOURCE="deployment" + ERROR_TYPE="DeployError" + else + SOURCE="cicd" + ERROR_TYPE="DockerBuildError" + fi + + curl -s -X POST "https://qiyuan-log-center-api.airlabs.art/api/v1/logs/report" \ -H "Content-Type: application/json" \ - -d '{ - "project_id": "'"${GITHUB_REPOSITORY##*/}"'", - "environment": "cicd", - "level": "ERROR", - "source": "cicd", - "commit_hash": "'"$GITHUB_SHA"'", - "error": { - "type": "TestFailure", - "message": "Tests failed in CI pipeline", - "file_path": null, - "line_number": null, - "stack_trace": ["Test step failed. Check CI logs."] + -d "{ + \"project_id\": \"your_project_id\", + \"environment\": \"${{ github.ref_name }}\", + \"level\": \"ERROR\", + \"source\": \"${SOURCE}\", + \"commit_hash\": \"${{ github.sha }}\", + \"repo_url\": \"https://gitea.airlabs.art/zyc/your_project.git\", + \"error\": { + \"type\": \"${ERROR_TYPE}\", + \"message\": \"[${FAILED_STEP}] Build and Deploy failed on branch ${{ github.ref_name }}\", + \"stack_trace\": [\"${ERROR_LOG}\"] }, - "context": { - "workflow_name": "'"$GITHUB_WORKFLOW"'", - "job_name": "'"$GITHUB_JOB"'", - "step_name": "Run Tests", - "run_id": "'"$GITHUB_RUN_ID"'", - "branch": "'"$GITHUB_REF_NAME"'", - "repository": "'"$GITHUB_REPOSITORY"'", - "run_url": "'"$GITHUB_SERVER_URL"'/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"'" + \"context\": { + \"job_name\": \"build-and-deploy\", + \"step_name\": \"${FAILED_STEP}\", + \"workflow\": \"${{ github.workflow }}\", + \"run_id\": \"${{ github.run_number }}\", + \"branch\": \"${{ github.ref_name }}\", + \"actor\": \"${{ github.actor }}\", + \"commit\": \"${{ github.sha }}\", + \"run_url\": \"https://gitea.airlabs.art/${{ github.repository }}/actions/runs/${{ github.run_number }}\" } - }' --connect-timeout 5 --max-time 10 || true + }" || true ``` ### 使用 report-cicd-error.sh 脚本