Skip to content

feat: add dde session boot time analysis tool#202

Merged
yixinshark merged 1 commit intolinuxdeepin:masterfrom
yixinshark:perf-analyzeBootTime
Apr 24, 2026
Merged

feat: add dde session boot time analysis tool#202
yixinshark merged 1 commit intolinuxdeepin:masterfrom
yixinshark:perf-analyzeBootTime

Conversation

@yixinshark
Copy link
Copy Markdown
Contributor

@yixinshark yixinshark commented Apr 16, 2026

Add a professional boot time analysis script for DDE session.

  • Displays systemd user service timelines and critical paths.
  • Provides reliable systemd-analyze blame data by filtering notification/dbus types.
  • Lists session processes with memory usage and relative start times.
  • Analyzes dde-shell and desktop logs for internal bottlenecks.
  • Validates systemd service configurations and gives optimization advice.

新增 DDE 会话启动耗时分析专业脚本。

  • 显示 systemd 用户服务启动时间线和关键路径耗时。
  • 通过过滤 notification/dbus 类型提供可靠的 systemd-analyze blame 数据。
  • 列出会话进程及其内存占用和相对启动时刻。
  • 分析 dde-shell 和桌面日志以识别内部瓶颈。
  • 验证 systemd 服务配置并提供具体的优化建议。

Log: add dde session boot time analysis tool
Pms: TASK-384099
Change-Id: Ib6fa8374eacc3c93822c1c17b3301386d42c92d9

Summary by Sourcery

Add a DDE session boot time analysis script that inspects systemd user targets, session processes, logs, and service configs to highlight boot bottlenecks and optimization opportunities.

New Features:

  • Introduce a Bash tool to visualize DDE systemd user target timelines and key milestones during session startup.
  • Provide filtered systemd-analyze blame output focused on reliable notify/dbus services.
  • List systemd-managed session processes with relative start times and memory usage to aid performance analysis.
  • Analyze dde-shell and desktop-related journal logs to detect common bottlenecks such as DConfig issues and DBus timeouts.
  • Offer automated checks of critical systemd user service units and summarize concrete optimization suggestions, including an optional Markdown report output.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 16, 2026

Reviewer's Guide

Adds a new Bash utility script to analyze DDE user-session boot performance, computing relative timelines from systemd user service timestamps, filtering and presenting systemd-analyze blame data, listing key user services/processes with memory and start times, inspecting journal logs for dde-shell/desktop bottlenecks, validating systemd service unit configs, and optionally generating a Markdown report with findings and optimization suggestions.

Sequence diagram for running the DDE boot time analysis and optional report generation

sequenceDiagram
  actor User
  participant Script_analyze_boot_time_sh as Script_analyze_boot_time_sh
  participant SystemdUser as systemd_user
  participant Journalctl as journalctl
  participant ProcFS as procfs
  participant FS as filesystem

  User->>Script_analyze_boot_time_sh: run ./analyze-boot-time.sh [--report]

  Script_analyze_boot_time_sh->>SystemdUser: show dde-session-* targets and services
  SystemdUser-->>Script_analyze_boot_time_sh: timestamps and unit properties

  Script_analyze_boot_time_sh->>Script_analyze_boot_time_sh: compute baseline and relative times
  Script_analyze_boot_time_sh->>SystemdUser: systemd-analyze --user blame
  SystemdUser-->>Script_analyze_boot_time_sh: blame list
  Script_analyze_boot_time_sh->>SystemdUser: show Type for each blamed service
  SystemdUser-->>Script_analyze_boot_time_sh: Type=notify/dbus

  Script_analyze_boot_time_sh->>SystemdUser: list-units --type=service --state=running
  SystemdUser-->>Script_analyze_boot_time_sh: running service list
  Script_analyze_boot_time_sh->>ProcFS: read /proc/PID/status and cmdline
  ProcFS-->>Script_analyze_boot_time_sh: memory, ppid, command line

  Script_analyze_boot_time_sh->>Journalctl: journalctl --user -u dde-shell@DDE.service
  Journalctl-->>Script_analyze_boot_time_sh: dde-shell logs
  Script_analyze_boot_time_sh->>Journalctl: journalctl --user -u dde-shell-plugin@org.deepin.ds.desktop.service
  Journalctl-->>Script_analyze_boot_time_sh: desktop plugin logs

  Script_analyze_boot_time_sh->>FS: read unit files under /usr/lib/systemd/user
  FS-->>Script_analyze_boot_time_sh: unit contents
  Script_analyze_boot_time_sh->>Script_analyze_boot_time_sh: derive optimization suggestions

  alt --report flag provided
    Script_analyze_boot_time_sh->>FS: write boot-analysis-YYYYMMDD-HHMMSS.md
    FS-->>Script_analyze_boot_time_sh: report file path
    Script_analyze_boot_time_sh-->>User: console summary + report path
  else no --report
    Script_analyze_boot_time_sh-->>User: console summary only
  end
Loading

Flow diagram for DDE boot time analysis script main logic

flowchart TD
  Start[Start analyze-boot-time.sh] --> ParseArgs[Parse CLI args]
  ParseArgs --> InitOutput[Print header and colorized sections]

  InitOutput --> CollectTimestamps[Collect systemd user target timestamps]
  CollectTimestamps --> FindBaseline[Find earliest pre-stage service as baseline]
  FindBaseline -->|baseline found| CalcPhaseTimes[Compute relative times for targets]
  FindBaseline -->|no baseline| ErrorExit[Print error and exit]

  CalcPhaseTimes --> Phase1Table[Print phase tables for pre/core/initialized/session]
  Phase1Table --> BlameSection[Run systemd-analyze blame and filter Type=notify/dbus]
  BlameSection --> ProcList[List top 50 running user services with PID, mem, start time]
  ProcList --> LogAnalysis[Analyze dde-shell and desktop plugin logs for bottlenecks]
  LogAnalysis --> UnitValidation[Inspect installed user unit files for bad dependencies]
  UnitValidation --> BuildSuggestions[Build optimization suggestions array]
  BuildSuggestions --> Summary[Print timing summary and quality assessment]

  Summary --> CheckReportFlag{--report passed?}
  CheckReportFlag -->|yes| GenReport[Generate Markdown report]
  CheckReportFlag -->|no| End[End script]
  GenReport --> End
Loading

File-Level Changes

Change Details Files
Introduce comprehensive DDE session boot-time analysis script driven by systemd user-session data
  • Define colorized, sectioned TUI-style output helpers for headers, sections, services, and conclusions
  • Collect monotonic timestamps for key DDE systemd user targets and services, derive a baseline earliest service, and compute relative/elapsed times in milliseconds
  • Render phase-by-phase timelines for dde-session-pre/core/initialized targets, including baseline and key shell/session services, sorted by start time
  • Summarize key target completion times and classify overall startup performance against predefined thresholds
tools/analyze-boot-time.sh
Add filtered systemd-analyze blame and process listing to focus on reliable service timing and resource usage
  • Run systemd-analyze --user blame, filter to Type=notify/dbus units only, and show the top 10 entries in a dedicated section
  • Enumerate running systemd user services, derive their MainPID and start times, and print a top-50 process table including PID/PPID, relative start time, RSS, service name, and command line
  • Handle /proc parsing for memory and cmdline defensively, with fallbacks for missing data
tools/analyze-boot-time.sh
Inspect dde-shell and desktop-related journal logs to surface internal bottlenecks
  • Locate current-session logs for dde-shell@DDE and dde-shell-plugin@org.deepin.ds.desktop via journalctl --user --boot 0 and extract first log entries as rough startup markers
  • Count DConfig "acquire failed" occurrences for both services and flag them with severity indications
  • Detect notification-related logs and DBus NoReply timeouts (e.g., wallpaper service readiness issues), emitting specific optimization hints like using local config or async DBus calls
tools/analyze-boot-time.sh
Validate key systemd user service unit configuration for known dependency and type issues and aggregate optimization suggestions
  • Check installed unit files (XSettings1, Daemon1, dde-shell@DDE, dde-session@x11) in /usr/lib/systemd/user for problematic Before= and ExecStartPre= directives and non-notify Type settings
  • Interrogate live systemd user units to detect blocking relationships (e.g., file manager Before=initialized, AM After=pre) and collect issues into a prioritized SUGGESTIONS list
  • Print a summarized, prioritized optimization list (P0/P1/P2, including already-fixed items) or note if no obvious optimizations are found
tools/analyze-boot-time.sh
Support optional Markdown report generation with a condensed summary of key metrics and checks
  • Implement generate_markdown_report to write a timestamped markdown file capturing raw systemd-analyze blame output, key target times, dependency status, and static optimization checklist
  • Gate report generation behind a --report CLI argument that runs the report function after the interactive analysis sections
  • Ensure report filenames include a timestamp and echo the saved path to the user
tools/analyze-boot-time.sh

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The function get_svc_timestamps is defined twice with identical content; consider keeping a single definition to avoid confusion and maintenance issues.
  • In generate_markdown_report, variables XSETTINGS_BEFORE and DAEMON_BEFORE are used but never assigned in the script, so the dependency check in the report is effectively broken—populate these values (e.g., from the earlier unit file inspection) or adjust the logic.
  • When building the service list with systemctl --user list-units --type=service --state=running | awk '{print $1}', consider adding --no-legend --no-pager or otherwise filtering out headers to avoid treating non-unit lines as service names.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The function `get_svc_timestamps` is defined twice with identical content; consider keeping a single definition to avoid confusion and maintenance issues.
- In `generate_markdown_report`, variables `XSETTINGS_BEFORE` and `DAEMON_BEFORE` are used but never assigned in the script, so the dependency check in the report is effectively broken—populate these values (e.g., from the earlier unit file inspection) or adjust the logic.
- When building the service list with `systemctl --user list-units --type=service --state=running | awk '{print $1}'`, consider adding `--no-legend --no-pager` or otherwise filtering out headers to avoid treating non-unit lines as service names.

## Individual Comments

### Comment 1
<location path="tools/analyze-boot-time.sh" line_range="85-86" />
<code_context>
+    fi
+}
+
+# 辅助函数:获取服务的时间戳
+get_svc_timestamps() {
+    local svc="$1"
+    local start=$(get_timestamp "$svc" "ExecMainStartTimestampMonotonic")
</code_context>
<issue_to_address>
**suggestion:** get_svc_timestamps is defined twice; consider keeping a single definition to avoid divergence later.

This function is already defined earlier in the script with the same body. Duplicating it increases the risk that only one copy is updated later. Please keep a single definition and reuse it where needed.

Suggested implementation:

```
# Target 只有就绪时刻
PRE_READY=$(get_timestamp "dde-session-pre.target" "ActiveEnterTimestampMonotonic")
CORE_READY=$(get_timestamp "dde-session-core.target" "ActiveEnterTimestampMonotonic")
INIT_READY=$(get_timestamp "dde-session-initialized.target" "ActiveEnterTimestampMonotonic")
SESSION_READY=$(get_timestamp "dde-session.target" "ActiveEnterTimestampMonotonic")

```

This assumes the earlier definition of `get_svc_timestamps` (with the same body) remains in the script. If that earlier definition is not present or differs, keep a single definition near the top-level helpers section and remove any other copies similarly.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +85 to +86
# 辅助函数:获取服务的时间戳
get_svc_timestamps() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: get_svc_timestamps is defined twice; consider keeping a single definition to avoid divergence later.

This function is already defined earlier in the script with the same body. Duplicating it increases the risk that only one copy is updated later. Please keep a single definition and reuse it where needed.

Suggested implementation:

# Target 只有就绪时刻
PRE_READY=$(get_timestamp "dde-session-pre.target" "ActiveEnterTimestampMonotonic")
CORE_READY=$(get_timestamp "dde-session-core.target" "ActiveEnterTimestampMonotonic")
INIT_READY=$(get_timestamp "dde-session-initialized.target" "ActiveEnterTimestampMonotonic")
SESSION_READY=$(get_timestamp "dde-session.target" "ActiveEnterTimestampMonotonic")

This assumes the earlier definition of get_svc_timestamps (with the same body) remains in the script. If that earlier definition is not present or differs, keep a single definition near the top-level helpers section and remove any other copies similarly.

Add a professional boot time analysis script for DDE session.
- Displays systemd user service timelines and critical paths.
- Provides reliable systemd-analyze blame data by filtering notification/dbus types.
- Lists session processes with memory usage and relative start times.
- Analyzes dde-shell and desktop logs for internal bottlenecks.
- Validates systemd service configurations and gives optimization advice.

新增 DDE 会话启动耗时及内存分析专业脚本。
- 显示 systemd 用户服务启动时间线和关键路径耗时。
- 通过过滤 notification/dbus 类型提供可靠的 systemd-analyze blame 数据。
- 列出会话进程及其内存占用和相对启动时刻。
- 分析 dde-shell 和桌面日志以识别内部瓶颈。
- 验证 systemd 服务配置并提供具体的优化建议。

Log: add dde session boot time analysis tool
Pms: TASK-384099
Change-Id: Ib6fa8374eacc3c93822c1c17b3301386d42c92d9
@yixinshark yixinshark force-pushed the perf-analyzeBootTime branch from 4f3806e to 1f0928c Compare April 20, 2026 07:27
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码包含两个用于分析 DDE(Deepin Desktop Environment)启动性能和内存占用的 Bash 脚本。整体来看,代码结构清晰,功能完善,注释详细。以下是对代码的详细审查和改进建议:

一、语法和逻辑审查

  1. analyze-boot-time.sh:

    • 重复定义: get_svc_timestamps 函数在第 51-54 行和第 128-131 行被定义了两次,第二次定义会覆盖第一次。建议删除其中一个。
    • 变量引用: 在 calc_mscalc_rel_ms 函数中,使用了 $(( )) 进行算术运算,但没有对变量进行严格验证,如果输入不是数字会导致错误。建议添加验证逻辑。
    • 临时文件处理: 使用了多个 mktemp 创建临时文件,并在结束时使用 rm -f 删除。建议使用 trap 命令确保脚本异常退出时也能清理临时文件。
  2. analyze-memory.sh:

    • 权限检查: 脚本开头检查了 root 权限,这是正确的,因为读取 /proc/$pid/smaps 需要特权。
    • 内存计算: 使用 bc 进行浮点数运算,但未检查 bc 是否安装。建议添加检查或使用 awk 替代。
    • 进程过滤: 使用 ps aux | awk 过滤进程,逻辑较为复杂,建议简化或使用 pgrep 替代部分逻辑。

二、代码质量改进

  1. 错误处理:

    • 两个脚本都使用了 set +e,这意味着某些命令失败不会中断脚本。建议在关键命令后添加错误检查,例如:
      if ! systemctl --user show "$service" -p "$prop" --no-pager >/dev/null 2>&1; then
          echo "错误:无法获取服务 $service 的属性 $prop"
          return 1
      fi
  2. 代码复用:

    • 两个脚本中都有颜色定义和打印函数(如 print_headerprint_section),可以提取到一个公共脚本中,通过 source 引入。
  3. 函数命名:

    • get_svc_timestamps 函数名不够清晰,建议改为 get_service_timestamps 以提高可读性。

三、性能优化

  1. 减少系统调用:

    • analyze-boot-time.sh 中,多次调用 systemctl --user show 获取服务属性,可以合并调用或缓存结果。
    • analyze-memory.sh 中,多次读取 /proc/$pid/smaps/proc/$pid/status,可以合并读取。
  2. 并行处理:

    • 在获取多个服务的时间戳时,可以使用 xargs -Pparallel 进行并行处理,提高效率。

四、安全性改进

  1. 输入验证:

    • calc_mscalc_rel_ms 函数中,应验证输入是否为数字:
      if ! [[ "$start" =~ ^[0-9]+$ ]] || ! [[ "$end" =~ ^[0-9]+$ ]]; then
          echo "N/A"
          return
      fi
  2. 临时文件安全:

    • 使用 mktemp 创建临时文件时,应指定 --tmpdir 和更安全的文件名模式:
      tmpfile=$(mktemp --tmpdir=/tmp analyze-boot-time.XXXXXX)
  3. 命令注入风险:

    • analyze-memory.sh 中,使用 ps aux | awk 过滤进程时,如果进程名包含特殊字符可能导致注入风险。建议使用 pgrep -f 替代:
      pgrep -f "dde-shell.*-C DDE" | head -1

五、具体改进建议

  1. analyze-boot-time.sh:

    • 删除重复的 get_svc_timestamps 函数定义。
    • 添加 trap 命令清理临时文件:
      trap 'rm -f "$tmpfile" "$baseline_file"' EXIT
    • calc_mscalc_rel_ms 函数中添加数字验证。
  2. analyze-memory.sh:

    • 检查 bc 是否安装,或使用 awk 替代:
      if ! command -v bc >/dev/null 2>&1; then
          echo "错误:bc 未安装"
          exit 1
      fi
    • 简化进程过滤逻辑,使用 pgrep 替代部分 ps aux | awk
  3. 通用改进:

    • 提取公共函数到单独的脚本中,通过 source 引入。
    • 添加更多错误处理和日志记录,便于调试。

六、改进后的代码示例

以下是改进后的 calc_ms 函数示例:

calc_ms() {
    local start="$1"
    local end="$2"
    
    # 验证输入是否为数字
    if ! [[ "$start" =~ ^[0-9]+$ ]] || ! [[ "$end" =~ ^[0-9]+$ ]]; then
        echo "N/A"
        return
    fi
    
    if [ "$start" = "0" ] || [ "$end" = "0" ] || [ -z "$start" ] || [ -z "$end" ]; then
        echo "N/A"
        return
    fi
    
    echo $(( (end - start) / 1000 ))
}

七、总结

这两个脚本整体质量较高,功能完善,但在错误处理、代码复用、性能优化和安全性方面还有改进空间。建议按照上述建议进行优化,以提高脚本的健壮性和可维护性。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy, yixinshark

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@yixinshark yixinshark merged commit 3d3ba21 into linuxdeepin:master Apr 24, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants