ניתוח של נתוני מעקב בכמות גדולה

אחרי שאוספים עקבות רבים באמצעות ProfilingManager, כבר לא מעשי לבדוק אותם בנפרד כדי למצוא בעיות בביצועים. ניתוח של עקבות רבים בבת אחת מאפשר לכם להשתמש במערך הנתונים כדי:

  • לזהות ירידות נפוצות בביצועים.
  • לחשב התפלגויות סטטיסטיות (לדוגמה, זמן טעינה P50, ‏ P90, ‏ P99).
  • לזהות דפוסים.
  • לאתר עקבות חריגים כדי להבין בעיות בביצועים ולנפות באגים.

בקטע הזה מוסבר איך להשתמש במעבד של Perfetto Python Batch Trace כדי לנתח מדדי הפעלה של קבוצה של עקבות שמאוחסנים באופן מקומי, ולאתר עקבות חריגים לניתוח מעמיק יותר.

עיצוב השאילתה

השלב הראשון בניתוח בכמות גדולה הוא יצירת שאילתת PerfettoSQL.

בקטע הזה מוצגת דוגמה לשאילתה שמודדת את זמן הטעינה של האפליקציה. באופן ספציפי, אפשר למדוד את משך הזמן מ-activityStart עד ליצירת הפריים הראשון (המופע הראשון של פרוסת Choreographer#doFrame) כדי למדוד את זמן הטעינה שנמצא בשליטת האפליקציה. באיור 1 מוצג הקטע שרוצים לבדוק.

תצוגת ציר הזמן של העקבות, עם הדגשה של משך הזמן מהאירוע activityStart ועד לאירוע הראשון Choreographer#doFrame.
איור 1. קטע של העקבות מ-activityStart עד לפריים הראשון שנוצר.
CREATE OR REPLACE PERFETTO FUNCTION find_slices(pattern STRING) RETURNS
TABLE (name STRING, ts LONG, dur LONG) AS
SELECT name,ts,dur FROM slice WHERE name GLOB $pattern;

CREATE OR REPLACE PERFETTO FUNCTION generate_start_to_end_slices(startSlicePattern STRING, endSlicePattern STRING, inclusive BOOL) RETURNS
TABLE(name STRING, ts LONG, dur LONG) AS
SELECT name, ts, MIN(startToEndDur) as dur
FROM
  (SELECT S.name as name, S.ts as ts, E.ts + IIF($inclusive, E.dur, 0) - S.ts as startToEndDur
  FROM find_slices($startSlicePattern) as S CROSS JOIN find_slices($endSlicePattern) as E
  WHERE startToEndDur > 0)
GROUP BY name, ts;

SELECT ts,name,dur from generate_start_to_end_slices('activityStart','*Choreographer#doFrame [0-9]*', true)

אפשר להריץ את השאילתה בממשק המשתמש של Perfetto ואז להשתמש בתוצאות כדי ליצור רצועת ניפוי באגים (איור 2) ולהציג אותה בציר הזמן (איור 3).

צילום מסך של ממשק המשתמש של Perfetto שבו רואים איך ליצור רצועת ניפוי באגים לשאילתת הפעלה.
איור 2. יצירת מסלול ניפוי באגים לשאילתת הפעלה.
תצוגת ציר זמן בממשק המשתמש של Perfetto שמציגה מסלול ניפוי באגים שנוצר לשאילתת הפעלה.
איור 3. מסלול ניפוי באגים שנוצר לשאילתת הפעלה.

הגדרת סביבת Python

מתקינים את Python במחשב המקומי ואת הספריות הנדרשות:

pip install perfetto pandas plotly

יצירת סקריפט לניתוח עקבות בכמות גדולה

הסקריפט לדוגמה הבא מריץ את השאילתה בכמה עקבות באמצעות Python BatchTraceProcessor של Perfetto.

from perfetto.batch_trace_processor import BatchTraceProcessor
import glob
import plotly.express as px

traces = glob.glob('*.perfetto-trace')

if __name__ == '__main__':
    with BatchTraceProcessor(traces) as btp:
        query = """
        CREATE OR REPLACE PERFETTO FUNCTION find_slices(pattern STRING) RETURNS
        TABLE (name STRING, ts LONG, dur LONG) AS
        SELECT name,ts,dur FROM slice WHERE name GLOB $pattern;

        CREATE OR REPLACE PERFETTO FUNCTION generate_start_to_end_slices(startSlicePattern STRING, endSlicePattern STRING, inclusive BOOL) RETURNS
        TABLE(name STRING, ts LONG, dur LONG) AS
        SELECT name, ts, MIN(startToEndDur) as dur
        FROM
          (SELECT S.name as name, S.ts as ts, E.ts + IIF($inclusive, E.dur, 0) - S.ts as startToEndDur
          FROM find_slices($startSlicePattern) as S CROSS JOIN find_slices($endSlicePattern) as E
          WHERE startToEndDur > 0)
        GROUP BY name, ts;

        SELECT ts,name,dur / 1000000 as dur_ms from generate_start_to_end_slices('activityStart','*Choreographer#doFrame [0-9]*', true)
        """
        df = btp.query_and_flatten(query)

        violin = px.violin(df, x='dur_ms', hover_data='_path', title='startup time', points='all')
        violin.show()

הסבר על הסקריפט

כשמריצים את סקריפט Python, הוא מבצע את הפעולות הבאות:

  1. הסקריפט מחפש בספרייה המקומית את כל עקבות Perfetto עם הסיומת .perfetto-trace ומשתמש בהם כעקבות מקור לניתוח.
  2. הכלי מריץ שאילתת מעקב בכמות גדולה שמחשבת את קבוצת המשנה של זמן ההפעלה שמתאימה לזמן מהפרוסה activityStart ועד לפריימים הראשונים שנוצרו על ידי האפליקציה.
  3. הוא משרטט את זמן הטעינה באלפיות שנייה באמצעות תרשים כינור כדי להציג את פיזור זמני ההפעלה.

פירוש התוצאות

תרשים כינור שמציג את ההתפלגות של זמן הטעינה אחרי הפעלה.
איור 4. תרשים כינור של זמן הטעינה אחרי הפעלה.

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

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

כשפותחים עקבות מהקבוצה עם זמן הטעינה הגבוה (איור 5), מוצאים פרוסה נוספת בשם MyFlaggedFeature שפועלת במהלך ההפעלה (איור 6). לעומת זאת, כשבוחרים בעקבות מהאוכלוסייה עם זמן הטעינה הנמוך יותר (השיא הימני ביותר) זה מאשר את היעדר הפרוסה הזאת (איור 7). ההשוואה הזו מצביעה על כך ש-feature flag ספציפי, שהופעל עבור קבוצת משנה של משתמשים, גורם לרגרסיה.

תרשים שמציג עקבות עם זמן טעינה ארוך.
איור 5. נקודת נתונים עם זמן טעינה גבוה בתרשים כינור.
עקבות שמדגישים את זמן הטעינה הארוך של ההפעלה בגלל פרוסת MyFlaggedFeature.
איור 6. עקבות הפעלה עם זמן טעינה ארוך עם פרוסת MyFlaggedFeature נוספת.
דוגמה לעקבות שמדגישים הפעלה עם זמן טעינה נמוך בלי פרוסת MyFlaggedFeature.
איור 7. עקבות הפעלה עם זמן טעינה קצר.

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