הגדרת עובד להעלאת פרופיל

‫ProfilingManager שומר את המעקבים באופן מקומי במכשיר. אפשר לאחזר את הקבצים האלה באמצעות ADB לניפוי באגים מקומי, אבל כדי לאסוף נתונים מהשטח צריך להעלות אותם לשרת.

קובצי מעקב יכולים להיות גדולים (לרוב כמה מגה-בייט). כדי לא לפגוע בחוויית המשתמש או לצרוך חבילת גלישה, כדאי לתזמן את ההעלאות כך שיתרחשו ברקע, רצוי כשהמכשיר מחובר לרשת ללא חיוב לפי שימוש (Wi-Fi), בטעינה ובמצב חוסר פעילות.

הגדרת משימת העלאה ב-WorkManager

‫ProfilingManager לא תלוי בענן, ואפשר להעלות את נתוני המעקב לכל תשתית שבוחרים. בדוגמה הבאה אפשר לראות איך משתמשים ב-WorkManager כדי לתזמן משימת העלאה שלא תפריע למשתמש.

דוגמה לקוד להגדרת משימת העלאה

הנה דוגמה לאופן שבו אפשר להגדיר משימה שלא מפריעה למשתמש להעלות נתוני מעקב לשרת.

הוספת יחסי תלות של WorkManager

בנוסף ליחסי התלות הקיימים של ProfilingManager, מוסיפים את ספריות Jetpack האלה לקובץ build.gradle.kts. הם נדרשים ל-WorkManager.

Kotlin

   dependencies {
       implementation("androidx.work:work-runtime:2.12.0")
   }
   

מגניב

   dependencies {
       implementation 'androidx.work:work-runtime:2.12.0'
   }
   

קטע קוד

הקוד הזה מראה איך להגדיר משימה להעלאת נתוני מעקב. צריך להגדיר את המשימה כשהאפליקציה מקבלת את ה-ProfilingResult. הקטע של יצירת הפרופיל לא מופיע כאן, אבל אפשר למצוא דוגמה בתיעוד עקבות המערכת.

Kotlin

class TraceUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        // Perform your uploading work here
        Log.d("ProfileTest", "Uploading trace: " + inputData.getString("PROFILE_PATH"))

        return Result.success()
    }
}

fun setupProfileUploadWorker(profileFilepath: String?) {
    val workMgr = WorkManager.getInstance(applicationContext)
    val workRequestBuilder = OneTimeWorkRequest.Builder(TraceUploadWorker::class)

    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.UNMETERED)
        .setRequiresDeviceIdle(true)
        .setRequiresCharging(true)
        .build()
    workRequestBuilder.setConstraints(constraints)

    val inputDataBuilder = Data.Builder()
    inputDataBuilder.putString("PROFILE_PATH", profileFilepath)
    workRequestBuilder.setInputData(inputDataBuilder.build())

    workMgr.enqueue(workRequestBuilder.build())
}

Java

public static class TraceUploadWorker extends Worker {

  public TraceUploadWorker(
      @androidx.annotation.NonNull Context context,
      @androidx.annotation.NonNull WorkerParameters workerParams) {
    super(context, workerParams);
  }

  @androidx.annotation.NonNull
  @Override
  public Result doWork() {
    // Perform your uploading work here
    Log.d("ProfileTest", "Uploading trace: " + getInputData().getString("PROFILE_PATH"));

    return Result.success();
  }
}

public void setupProfileUploadWorker(String profileFilepath) {
  WorkManager workMgr = WorkManager.getInstance(getApplicationContext());
  OneTimeWorkRequest.Builder workRequestBuilder = new OneTimeWorkRequest.Builder(
      TraceUploadWorker.class);

  Constraints constraints = new Constraints.Builder()
      .setRequiredNetworkType(NetworkType.UNMETERED)
      .setRequiresDeviceIdle(true)
      .build();
  workRequestBuilder.setConstraints(constraints);

  Data.Builder inputDataBuilder = new Data.Builder();
  inputDataBuilder.putString("PROFILE_PATH", profileFilepath);
  workRequestBuilder.setInputData(inputDataBuilder.build());

  workMgr.enqueue(workRequestBuilder.build());
}

הדרכה מפורטת על הקוד

הקוד מבצע את הפעולות הבאות:

  • הגדרת ה-worker: יוצרים מחלקה של TraceUploadWorker שמרחיבה את Worker. מטמיעים את השיטה doWork() כדי לטפל בלוגיקה של העלאת הקובץ בפועל באמצעות ה-SDK המועדף של הקצה העורפי או צד הלקוח ב-HTTP.

  • יצירת פרופיל של בקשות: משתמשים ב-SystemTraceRequestBuilder כדי להגדיר את המעקב (משך הזמן, מדיניות המאגר) וב-Profiling.requestProfiling כדי להתחיל אותו.

  • תזמון העבודה:

    • יוצרים OneTimeWorkRequest לעובד.

    • הגדרת אילוצים: משתמשים ב-setRequiredNetworkType(NetworkType.UNMETERED), ב-setRequiresDeviceIdle(true) וב-setRequiresCharging(true) כדי לוודא שההעלאה מתבצעת רק כשהמשתמש מחובר ל-Wi-Fi, המכשיר בטעינה ולא בשימוש פעיל. זה חשוב כדי למנוע הפרעה למשתמש עם משימת ההעלאה.

    • העברת נתונים: משתמשים ב-setInputData כדי להעביר את נתיב המעקב ל-worker.

    • הוספה לתור: שולחים את הבקשה ל-WorkManager באמצעות קריאה ל-WorkManager#enqueue.

השלבים הבאים

אחרי שמעלים את נתוני המעקב, אפשר לנתח אותם בנפרד או לבצע ניתוח של נתוני מעקב בכמות גדולה. במאמר פריסת Bigtrace ב-Kubernetes מוסבר איך להגדיר צינור עיבוד נתונים לניתוח שניתן להתאמה לעומס.