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

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

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

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

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

השלב הראשון בניתוח בכמות גדולה הוא יצירת שאילתת 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). ההשוואה הזו מצביעה על כך שדגל תכונה ספציפי, שהופעל עבור קבוצת משנה של משתמשים, מפעיל את הרגרסיה.

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

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