از ردیابی برای به دست آوردن بینش در مورد عملکرد سیستم استفاده کنید

از ردیابی برای ثبت رویدادها و شمارنده‌ها در سیستم و نمایش بصری هر یک در یک جدول زمانی استفاده کنید. ابزار ردیابی استاندارد در اندروید Perfetto است. برای کسب اطلاعات بیشتر، به Tracing 101 مراجعه کنید.

کد خود را ابزاربندی کنید

برای دریافت رویدادها از برنامه، باید با اضافه کردن نقاط ردیابی به کد، آن را به صورت ابزار دقیق درآورد. بخش‌هایی که ابزار دقیق نشده‌اند، در ردیابی‌ها نمایش داده نمی‌شوند.

نمونه ردیابی SDV یک نسخه آزمایشی از ادغام ردیابی، همراه با دستورالعمل‌ها و نمونه‌ای از پیکربندی ردیابی است. این نمونه در system/software_defined_vehicle/core_services/samples/tracing/ قرار دارد.

زنگ زدگی

رویکرد پیشنهادی برای Rust، استفاده از جعبه ردیابی برای انتشار رویدادهای ATrace است. Perfetto از ATrace به عنوان منبع داده پشتیبانی می‌کند. ما قصد داریم وقتی اتصالات Rust در دسترس قرار گرفت و بسته به نحوه تکامل موارد استفاده، به Perfetto SDK تغییر دهیم.

پیش‌فرض‌های ردیابی را به Android.bp اضافه کنید:

rust_binary {
...
    defaults: [
        ...
        "sdv_tracing@rust_defaults",
    ],
...
}

مقداردهی اولیه مشترک. این کار فقط یک بار در هر فرآیند قابل انجام است:

fn main() {
    // Initialize the subscriber, panic if it fails.
    // sdv_tracing::try_init_tracing() is the version that returns a Result.
    sdv_tracing::init_tracing()
    ...
}

می‌توانید فراخوانی مقداردهی اولیه را حذف کنید. انجام این کار باعث می‌شود ردیابی مقداردهی اولیه نشود و Perfetto رویدادهای ابزار دقیق را از برنامه جمع‌آوری نکند.

نقاط ردیابی را اضافه کنید. می‌توانید نمونه‌های بیشتری را در system/software_defined_vehicle/core_services/samples/tracing/rust_tracing_api_demo/tracing.rs بیابید.

use tracing::{instrument, info_span};

// #[tracing::instrument] wraps the method into a tracing span and records arguments.
// Use #[instrument(skip(num))] if you don't want to record the argument.
#[instrument]
fn mul_by_100(num: i32) -> i32 {
    // Create and enter a span with INFO verbosity, name, and a debug field annotation.
    // The span will exit when dropped.
    let _span = info_span!("This is a span", var=123).entered();
    let result = num * 100;
    // Emit an instant INFO event that records the result value.
    // We recommend to fully qualify the crate when using events to avoid confusion with log records.
    tracing::info!(result, "Completed");
    result
}

سی++

ردیابی C++ از Perfetto SDK برای ردیابی رویدادها استفاده می‌کند. پیش‌فرض‌های ردیابی را به Android.bp اضافه کنید:

cc_binary {
...
    defaults: [
...
        "sdv_tracing@cc_defaults",
    ],
...
}

دسته‌ها را تعریف کنید. اگر از دسته‌ها در چندین ماژول استفاده می‌کنید، آنها را به یک کتابخانه مشترک منتقل کنید. برای مثال، system/software_defined_vehicle/core_services/samples/tracing/cpp_service/tracing_categories.h .

در سربرگ:

#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/track_event.h"

PERFETTO_DEFINE_CATEGORIES(
        perfetto::Category("sample")
                .SetTags("tag")
                .SetDescription("Sample events"));

ماکروی ذخیره‌سازی استاتیک را در یک فایل منبع .cpp قرار دهید، نه در یک متد. اگر دسته‌بندی‌ها را بین کامپوننت‌ها به اشتراک می‌گذارید، از فایل منبعی استفاده کنید که با هدر دارای دسته‌بندی‌ها مطابقت دارد.

PERFETTO_TRACK_EVENT_STATIC_STORAGE();

int main() {
    ...
}

برای مقداردهی اولیه Perfetto، ابتدا backend سیستم را مقداردهی اولیه کنید و رویدادهای مسیر را ثبت کنید:


#include <sdv/tracing_init.h>

int main() {
  ...
  android::sdv::InitPerfettoWithTrackEvents<perfetto::TrackEvent>();
  ...
}

ابزار دقیق را اضافه کنید. نمونه‌های بیشتر را در system/software_defined_vehicle/core_services/samples/tracing/cpp_service/client.cpp ببینید.

int32_t mulBy100(int32_t num) {
    // Start a slice that will get closed at the end of the scope.
    TRACE_EVENT("client", "mulBy100", "num", num);

    TRACE_EVENT("client", "This is a slice", "var", 123);
    int32_t result = num * 100;

    // Instant events have zero duration. They are drawn as markers on the track.
    TRACE_EVENT_INSTANT("client", "Completed", "result", result);
    return result;
}

همانند مثال Rust، این کد دو برش تو در تو و یک نشانگر برای رویداد فوری در رابط کاربری تولید می‌کند. مقادیر آرگومان اشکال‌زدایی هنگام انتخاب یک رویداد نشان داده می‌شوند.

جمع‌آوری ردپا

برای ضبط یک مسیر از اسکریپت خط فرمان record\_android\_trace و برای مشاهده آن از رابط کاربری وب Perfetto استفاده کنید.

پیکربندی ضبط

شما باید یک پیکربندی برای record_android_trace با فرمت textproto ارائه دهید. برای اطلاعات بیشتر به Perfetto doc مراجعه کنید.

مخزن SDV شامل یک پیکربندی نمونه ( system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx ) است. این فایل شامل چندین منبع داده است و می‌تواند سفارشی‌سازی شود یا به همان صورت استفاده شود.

از Perfetto UI برای ایجاد یک پیکربندی استفاده کنید

شما می‌توانید با رفتن به بخش ضبط رد جدید در رابط کاربری Perfetto، یک پیکربندی سفارشی پیکربندی کنید و گزینه‌های موجود را بررسی کنید، تنظیمات ضبط و پروب‌ها را تنظیم کنید. سپس می‌توانید نمای "دستور ضبط" را باز کنید تا دستور تولید شده را ببینید و محتوای پیکربندی را از آنجا دریافت کنید.

پیکربندی قابلیت مشاهده ابزار دقیق درون برنامه‌ای

ابزار دقیق Rust از ATrace استفاده می‌کند. این ابزار در بخش ftrace_config از سند پیکربندی شده است. اجزای SDV دارای برچسب ATRACE_TAG_APP هستند و می‌توانند بر اساس هر برنامه فعال شوند. پیکربندی نمونه، همه برنامه‌ها را فعال می‌کند.

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            # Setting atrace_apps to "*" enable ATrace events for all apps.
            # You can set it to a pattern to match specific processes by name.
            # Use multiple atrace_apps entries to enable multiple processes.
            atrace_apps: "*"
        }
    }
}

ما از رویدادهای ردیابی در C++ Perfetto SDK استفاده می‌کنیم. این یک منبع داده track_event ( doc ) است.

شما می‌توانید دسته‌بندی‌ها و برچسب‌ها را در فیلد track_event_config فعال یا غیرفعال کنید. هر تگ پایانی دسته‌بندی به طور پیش‌فرض فعال است، به جز تگ‌های ویژه slow و debug . اگر فقط می‌خواهید دسته‌بندی‌های خاصی را فعال کنید، باید بقیه را غیرفعال کنید، به عنوان مثال با disabled_categories: "*" مانند اینجا:

data_sources: {
    config {
        name: "track_event"
        track_event_config {
            enabled_categories: "the_best_category_in_the_world"
            disabled_categories: "*"
        }
    }
}

ثبت یک ردپا

یک ترمینال در ریشه مخزن اندروید باز کنید. نیازی به انجام envsetup نیست. اسکریپت ضبط در external/perfetto/tools/record_android_trace قرار دارد.

اسکریپت را با پیکربندی نمونه اجرا کنید:

external/perfetto/tools/record_android_trace --config system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx

برای توقف زودهنگام ضبط، Ctrl + C را انتخاب کنید.

انجام این کار باعث می‌شود adb shell perfetto یک ردیابی را ثبت کند و سپس ردیابی را به میزبان، معمولاً در ~/traces ، منتقل کند. وقتی ردیابی جمع‌آوری شد، ابزار یک پنجره مرورگر را برای نمایش ردیابی باز می‌کند.

استدلال‌های مفید:

  • -s SERIAL برای استفاده از دستگاه با سریال داده شده. برای مثال -s 0.0.0.0:6520

  • --no-open-browser یک URL برای ردیابی ایجاد می‌کند اما مرورگر را باز نمی‌کند. این برای جلسات از راه دور زمانی که پورت فورواردینگ (معمولاً ۹۰۰۱) را تنظیم کرده‌اید، مفید است.

  • -n, --no-open مرورگر را باز نمی‌کند یا URL را برای ارائه ردیابی پس از جلسه ردیابی ایجاد نمی‌کند. شما همچنان می‌توانید با کلیک بر روی "باز کردن فایل ردیابی" و انتخاب فایل، فایل‌ها را در رابط کاربری Perfetto باز کنید.

  • -o <path> برای تنظیم مسیر خروجی.

جزئیات استفاده

این بخش جزئیاتی را ارائه می‌دهد که ممکن است هنگام استفاده از سیستم ردیابی مفید باشد.

ابزار دقیق ردیابی در اجزای SDV

در عامل‌هایی که ابزار ردیابی دارند، ردیابی به طور پیش‌فرض در نسخه‌های قابل اشکال‌زدایی ( -eng ، -userdebug ) در دسترس است، مگر اینکه خلاف آن مشخص شده باشد. وقتی ردیابی را جمع‌آوری می‌کنید، باید رویدادهای مربوط به فرآیندها را بدون پیکربندی اضافی مشاهده کنید.

کتابخانه‌ها معمولاً ردیابی را به طور خودکار مقداردهی اولیه نمی‌کنند. در Rust، فایل باینری که از کتابخانه استفاده می‌کند، باید ردیابی را برای فرآیند با استفاده sdv_tracing::init_tracing() مقداردهی اولیه کند. برای کسب اطلاعات بیشتر به Instrumentation کد خود مراجعه کنید.

میان‌افزار

کتابخانه‌ی انتشار/اشتراک : libsdv_middleware_dt

رویدادها:

  • ناشر: انتشار و ثبت مباحث.
  • مشترک: اشتراک و نظرسنجی.

فعال‌سازی: فراخوانی sdv_tracing::init_tracing() یا sdv_tracing::try_init_tracing() در فایل باینری.

کتابخانه gRPC : libsdvmiddleware_rpc_grpc_transport

رویدادها:

  • کلاینت RPC: شروع، اتصال به سرور و فراخوانی متدهای RPC.
  • سرور RPC: شروع، ثبت نام در Service Discovery، اضافه کردن و فراخوانی متدهای RPC.

فعال‌سازی: فراخوانی sdv_tracing::init_tracing() یا sdv_tracing::try_init_tracing() به صورت دودویی.

برخی/IP
  • فرآیند: sdv_someip_broker_agent . \
  • رویدادها: پردازش و ترجمه پیام، اشتراک رویداد.
مدیر چرخه عمر
  • فرآیند: sdv_lifecycle_agent . \
  • رویدادها: عملیات سرویس - راه‌اندازی، توقف، ثبت، لغو ثبت.
حالت قدرت خودرو
  • فرآیند: sdv_vpm_agent . \
  • رویدادها: تغییرات وضعیت برق و اشتراک‌ها.
تونل داده

ما قصد داریم در آینده از ادغام ردیابی پشتیبانی کنیم.

سربار عملکرد ردیابی

اندازه‌گیری‌های سربار با این هشدار معمول همراه هستند که عملکرد ممکن است در سیستم‌های مختلف و به خصوص بین شبیه‌ساز و سخت‌افزار واقعی متفاوت باشد.

زنگ زدگی

داده‌های خام بنچمارک در AOSP موجود است. این داده‌ها روی یک ماشین مجازی Cuttlefish جمع‌آوری شده‌اند.

  • تک‌فاصله: tracing::info_span!() ، #[tracing::instrument] و موارد مشابه:
    • ردیابی بدون مقداردهی اولیه: 1ns.
    • ردیابی مقداردهی اولیه و غیرفعال شد (هیچ ضبط ردیابی اتفاق نمی‌افتد): 30 نانوثانیه.
    • ردیابی فعال شد: ۳ میکروثانیه. حاشیه‌نویسی‌های فیلد اشکال‌زدایی می‌توانند بسته به پیچیدگی رشته‌بندی، ۱ تا ۲ میکروثانیه اضافه کنند.
  • رویداد واحد: tracing::info!() و موارد مشابه:
    • ردیابی بدون مقداردهی اولیه: 1ns.
    • ردیابی مقداردهی اولیه و غیرفعال شد: 30ns.
    • ردیابی فعال شد: ۱.۵ میکروثانیه. حاشیه‌نویسی‌های فیلد اشکال‌زدایی می‌توانند بسته به پیچیدگی stringification ، ۰.۵ تا ۱ میکروثانیه اضافه کنند.
سی++

اعداد مربوط به عملکرد از بخش عملکرد در سند رویدادهای Track در Perfetto گرفته شده‌اند. زمان‌های Pixel 3 در جدول با مشاهدات ما در Cuttlefish VM مطابقت دارد.

برش تکی: TRACE_EVENT() و موارد مشابه. ردیابی:

  • معلول: ۲ نانوثانیه.
  • فعال شده: ۳۰۰ نانوثانیه. استفاده از حاشیه‌نویسی‌های فیلد اشکال‌زدایی می‌تواند ۵۰ تا ۱۰۰ نانوثانیه اضافه کند.