Hồ sơ theo dõi JSON

Báo cáo vấn đề Xem nguồn Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Hồ sơ dấu vết JSON có thể rất hữu ích để nhanh chóng nắm được thời gian Bazel đã dành cho lệnh gọi.

Theo mặc định, đối với tất cả các lệnh và truy vấn giống như bản dựng, Bazel sẽ ghi một hồ sơ vào cơ sở đầu ra có tên là command-$INOVCATION_ID.profile.gz, trong đó $INOVCATION_ID là giá trị nhận dạng lệnh gọi của lệnh. Bazel cũng tạo một đường liên kết tượng trưng có tên là command.profile.gz trong cơ sở đầu ra, trỏ đến hồ sơ của lệnh mới nhất. Bạn có thể định cấu hình xem một hồ sơ có được ghi bằng cờ --generate_json_trace_profile hay không và vị trí mà hồ sơ được ghi bằng cờ --profile. Các vị trí kết thúc bằng .gz được nén bằng GZIP. Bazel giữ 5 hồ sơ gần đây nhất, có thể định cấu hình bằng --profiles_to_retain, trong cơ sở đầu ra theo mặc định để phân tích sau khi xây dựng. Việc truyền rõ ràng một đường dẫn hồ sơ bằng --profile sẽ tắt tính năng tự động thu thập rác.

Công cụ

Bạn có thể tải hồ sơ này vào chrome://tracing hoặc phân tích và xử lý hậu kỳ bằng các công cụ khác.

chrome://tracing

Để trực quan hoá hồ sơ, hãy mở chrome://tracing trong một thẻ trình duyệt Chrome, nhấp vào "Load" (Tải) rồi chọn tệp hồ sơ (có thể đã nén). Để xem kết quả chi tiết hơn, hãy nhấp vào các hộp ở góc dưới cùng bên trái.

Hồ sơ mẫu:

Hồ sơ mẫu

Hình 1. Hồ sơ mẫu.

Bạn có thể sử dụng các chế độ điều khiển bằng bàn phím sau để di chuyển:

  • Nhấn 1 để chuyển sang chế độ "chọn". Ở chế độ này, bạn có thể chọn các hộp cụ thể để kiểm tra thông tin chi tiết về sự kiện (xem góc dưới bên trái). Chọn nhiều sự kiện để xem thông tin tóm tắt và số liệu thống kê tổng hợp.
  • Nhấn 2 để chuyển sang chế độ "lia máy". Sau đó, kéo chuột để di chuyển chế độ xem. Bạn cũng có thể dùng a/d để di chuyển sang trái/phải.
  • Nhấn 3 để chuyển sang chế độ "thu phóng". Sau đó, kéo chuột để thu phóng. Bạn cũng có thể dùng w/s để phóng to/thu nhỏ.
  • Nhấn 4 để chuyển sang chế độ "đo thời gian", trong đó bạn có thể đo khoảng cách giữa hai sự kiện.
  • Nhấn vào ? để tìm hiểu về tất cả các chế độ kiểm soát.

bazel analyze-profile

Lệnh con Bazel analyze-profile sử dụng một định dạng hồ sơ và in số liệu thống kê tích luỹ cho các loại tác vụ khác nhau cho từng giai đoạn xây dựng và phân tích đường dẫn quan trọng.

Ví dụ: các lệnh

$ bazel build --profile=/tmp/profile.gz //path/to:target
...
$ bazel analyze-profile /tmp/profile.gz

có thể tạo ra kết quả ở dạng sau:

INFO: Profile created on Tue Jun 16 08:59:40 CEST 2020, build ID: 0589419c-738b-4676-a374-18f7bbc7ac23, output base: /home/johndoe/.cache/bazel/_bazel_johndoe/d8eb7a85967b22409442664d380222c0

=== PHASE SUMMARY INFORMATION ===

Total launch phase time         1.070 s   12.95%
Total init phase time           0.299 s    3.62%
Total loading phase time        0.878 s   10.64%
Total analysis phase time       1.319 s   15.98%
Total preparation phase time    0.047 s    0.57%
Total execution phase time      4.629 s   56.05%
Total finish phase time         0.014 s    0.18%
------------------------------------------------
Total run time                  8.260 s  100.00%

Critical path (4.245 s):
       Time Percentage   Description
    8.85 ms    0.21%   _Ccompiler_Udeps for @local_config_cc// compiler_deps
    3.839 s   90.44%   action 'Compiling external/com_google_protobuf/src/google/protobuf/compiler/php/php_generator.cc [for host]'
     270 ms    6.36%   action 'Linking external/com_google_protobuf/protoc [for host]'
    0.25 ms    0.01%   runfiles for @com_google_protobuf// protoc
     126 ms    2.97%   action 'ProtoCompile external/com_google_protobuf/python/google/protobuf/compiler/plugin_pb2.py'
    0.96 ms    0.02%   runfiles for //tools/aquery_differ aquery_differ

Trình phân tích lệnh gọi Bazel

Trình phân tích lệnh gọi Bazel mã nguồn mở sử dụng một định dạng hồ sơ và in các đề xuất về cách cải thiện hiệu suất của bản dựng. Bạn có thể thực hiện phân tích này bằng CLI của công cụ hoặc trên https://analyzer.engflow.com.

jq

jq tương tự như sed đối với dữ liệu JSON. Ví dụ về cách sử dụng jq để trích xuất tất cả các khoảng thời gian của bước tạo hộp cát trong quá trình thực thi hành động cục bộ:

$ zcat $(../bazel-6.0.0rc1-linux-x86_64 info output_base)/command.profile.gz | jq '.traceEvents | .[] | select(.name == "sandbox.createFileSystem") | .dur'
6378
7247
11850
13756
6555
7445
8487
15520
[...]

Thông tin hồ sơ

Hồ sơ chứa nhiều hàng. Thông thường, phần lớn các hàng đại diện cho các luồng Bazel và các sự kiện tương ứng của chúng, nhưng một số hàng đặc biệt cũng được đưa vào.

Các hàng đặc biệt được đưa vào phụ thuộc vào phiên bản Bazel được gọi khi hồ sơ được tạo và có thể được tuỳ chỉnh bằng các cờ khác nhau.

Hình 1 cho thấy một hồ sơ được tạo bằng Bazel phiên bản 5.3.1 và bao gồm các hàng sau:

  • action count: Hiển thị số lượng hành động đồng thời đang diễn ra. Nhấp vào đó để xem giá trị thực tế. Có thể tăng lên đến giá trị --jobs trong các bản dựng sạch.
  • CPU usage (Bazel): Đối với mỗi giây của bản dựng, hãy hiển thị lượng CPU mà Bazel đã sử dụng (giá trị 1 tương đương với một lõi đang bận 100%).
  • Critical Path: Hiển thị một khối cho mỗi thao tác trên đường dẫn quan trọng.
  • Main Thread: Luồng chính của Bazel. Hữu ích khi bạn muốn xem tổng quan về những việc mà Bazel đang làm, ví dụ: "Launch Blaze", "evaluateTargetPatterns" và "runAnalysisPhase".
  • Garbage Collector: Hiển thị các lần tạm dừng Thu gom rác (GC) nhỏ và lớn.

Các vấn đề thường gặp về hiệu suất

Khi phân tích hồ sơ hiệu suất, hãy tìm:

  • Giai đoạn phân tích diễn ra chậm hơn dự kiến (runAnalysisPhase), đặc biệt là trên các bản dựng gia tăng. Đây có thể là dấu hiệu cho thấy việc triển khai quy tắc không hiệu quả, chẳng hạn như quy tắc làm phẳng depsets. Việc tải gói có thể diễn ra chậm do có quá nhiều mục tiêu, macro phức tạp hoặc glob đệ quy.
  • Các thao tác riêng lẻ có tốc độ chậm, đặc biệt là những thao tác trên đường dẫn quan trọng. Bạn có thể chia các thao tác lớn thành nhiều thao tác nhỏ hơn hoặc giảm tập hợp các phần phụ thuộc (bắc cầu) để tăng tốc độ. Ngoài ra, hãy kiểm tra xem có số lượng lớn bất thường về PROCESS_TIME không phải là PROCESS_TIME (chẳng hạn như REMOTE_SETUP hoặc FETCH) hay không.
  • Nút thắt, tức là một số ít luồng đang bận trong khi tất cả các luồng khác đều ở trạng thái rảnh / chờ kết quả (xem khoảng 22 giây và 29 giây trong Hình 1). Việc tối ưu hoá này có thể sẽ yêu cầu bạn điều chỉnh các cách triển khai quy tắc hoặc chính Bazel để tăng tính song song. Điều này cũng có thể xảy ra khi có một lượng GC bất thường.

Định dạng tệp hồ sơ

Đối tượng cấp cao nhất chứa siêu dữ liệu (otherData) và dữ liệu theo dõi thực tế (traceEvents). Siêu dữ liệu chứa thông tin bổ sung, chẳng hạn như mã nhận dạng lệnh gọi và ngày của lệnh gọi Bazel.

Ví dụ:

{
  "otherData": {
    "build_id": "101bff9a-7243-4c1a-8503-9dc6ae4c3b05",
    "date": "Wed Oct 26 08:22:35 CEST 2022",
    "profile_finish_ts": "1677666095162000",
    "output_base": "/usr/local/google/_bazel_johndoe/573d4be77eaa72b91a3dfaa497bf8cd0"
  },
  "traceEvents": [
    {"name":"thread_name","ph":"M","pid":1,"tid":0,"args":{"name":"Critical Path"}},
    ...
    {"cat":"build phase marker","name":"Launch Blaze","ph":"X","ts":-1306000,"dur":1306000,"pid":1,"tid":21},
    ...
    {"cat":"package creation","name":"foo","ph":"X","ts":2685358,"dur":784,"pid":1,"tid":246},
    ...
    {"name":"thread_name","ph":"M","pid":1,"tid":11,"args":{"name":"Garbage Collector"}},
    {"cat":"gc notification","name":"minor GC","ph":"X","ts":825986,"dur":11000,"pid":1,"tid":11},
    ...
    {"cat":"action processing","name":"Compiling foo/bar.c","ph":"X","ts":54413389,"dur":357594,"pid":1,"args":{"mnemonic":"CppCompile"},"tid":341},
 ]
}

Dấu thời gian (ts) và thời lượng (dur) trong các sự kiện theo dõi được tính bằng phần triệu giây. Danh mục (cat) là một trong các giá trị enum của ProfilerTask. Xin lưu ý rằng một số sự kiện sẽ được hợp nhất nếu chúng rất ngắn và gần nhau; hãy truyền --noslim_profile nếu bạn muốn ngăn việc hợp nhất sự kiện.

Xem thêm Quy cách định dạng sự kiện theo dấu vết của Chrome.