במדריך הזה מפורט פורמט בקשת ה-JSON לנקודת הקצה /api/v1/generate_metrics_config של הכלי Metrics Configuration Generator (מחולל הגדרות מדדים, MCG). הפורמט הזה מאפשר להגדיר קמפיין טלמטריה – לציין איסוף נתונים, עיבוד במכשיר ויצירת דוחות – במבנה שקריא לאנשים.
הכלי MCG מאמת את אובייקט ה-JSON הזה, בודק אם יש בעיות כמו אי התאמות בסוגים, תלות מעגלית או הפניות לא מוגדרות, ואז מהדר אותו להודעת MetricsConfig מאגר אחסון לפרוטוקולים (protobuf). ההודעה הזו היא בפורמט בינארי ששירות הטלמטריה במכשיר מריץ כדי להפעיל את הקמפיין.MetricsConfig
דרישות מוקדמות: מומלץ להכיר סכימות JSON, protobuf ומבני נתונים בסיסיים. סקירה כללית של המושגים מופיעה במאמר מושגים בנושא הגדרת מדדים.
איך כותבים תיאור של הגדרה
כדי לתכנן קמפיין לאיסוף מדדים, צריך לפעול לפי הרצף הלוגי הבא:
- ציון מקורות נתונים: מגדירים מאיפה מגיעים הנתונים.
- הגדרת לוגיקה ועיבוד: מגדירים כללים לקביעת הזמן שבו הנתונים ייאספו ולאופן העיבוד שלהם.
- יצירת פלט: אריזת הנתונים המעובדים בהודעה סופית.
- שדות ברמה העליונה: מוסיפים שדות ברמה העליונה כמו UUID, signal definitions ו-lifecycle control.
דוגמה: דוח מהירות ממוצעת
במדריך הזה מוצגות דוגמאות שממחישות איך כל הרכיבים משתלבים זה בזה. הדוגמאות יוצרות דוח שמחשב את המהירות הממוצעת של כלי רכב בכל דקה. בדוגמאות מוגדר מקור נתונים (SpeedSource) לאיסוף נתוני מהירות, טריגרים (OnNewSpeed, EveryMinute) לשליטה בזרימת הביצוע, רכיב Aggregator (SpeedAggregator) לחישוב הממוצע ורכיב Metrics Report Configuration (MinuteReport) לאריזת התוצאה. הדוגמאות מוצגות בקטעים שניתן להרחיב, והן מבוססות על התרחיש הזה.
ציון מקורות נתונים
טלמטריה תומכת באיסוף נתונים משירותי SDV (באמצעות SDV Middleware) וממפרסמים מבוססי-Configurable Publisher Registry.
שירותי SDV (מבוססי pub/sub): הנתונים זמינים מערוצי pub/sub שמוגדרים ב-VSIDL.
שירותי SDV (מבוססי RPC): הנתונים זמינים אם השירות חושף
CreateSubscriptionאוGetLatestMessageRPC.בעלי תוכן דיגיטלי שניתן להגדיר אותם ומבוססים על מאגר בעלי תוכן דיגיטלי: הנתונים זמינים אם האפליקציה נרשמת באמצעות
IConfigurablePublisherRegistryממשק Android Binder או ספריית מאגר בעלי תוכן דיגיטלי שניתן להגדרה מתוך Telemetry SDK.
כדי להשתמש בנתונים ב-SDV, צריך להגדיר מקור נתונים (מושג) ולהוסיף אותו למערך data_sources.
שדות של אובייקט במקור נתונים (פריט ברשימה data_sources) |
|||||
|---|---|---|---|---|---|
name |
מחרוזת שהוגדרה על ידי המשתמש ומזהה את מקור הנתונים הזה בהגדרת המדדים. | ||||
source_identifier |
המזהה שמשמש לגילוי השירות. פרטים נוספים זמינים במאמר בנושא הפורמט של source_identifier. |
||||
connection_type |
SUBSCRIPTION לסטרימינג רציף של נתונים (נדרש לטריגרים של נתונים), או ON_DEMAND לאחזור לפי דרישה (פרטים נוספים זמינים במאמר בנושא הגדרה של מקורות נתונים). |
||||
אופציונליconfiguration |
רק ב-RPC ובמאגר הניתן להגדרה של בעלי תוכן דיגיטלי. אובייקט להגדרת מקור הנתונים עם השדות הבאים:
|
||||
שדות לסוג החיבור SUBSCRIPTION |
|||||
אופציונליsub_sampling_interval_ms |
Pub/Sub בלבד. מספר שלם לא שלילי (אלפיות השנייה) לוויסות נתונים (throttle) תדירות ההודעות על ידי ציון המרווח המינימלי בין ההודעות. | ||||
אופציונליfetch_last_message(ברירת מחדל: false) |
Pub/Sub בלבד. בוליאני. אם true,
ההודעה האחרונה תאוחזר עם ההתחברות. |
||||
לא כל האפשרויות זמינות לכל סוגי מקורות הנתונים. מידע מפורט זמין במדריך לשילוב מקורות נתונים.
הפורמט של source_identifier
שירות הטלמטריה מקבל כמה פורמטים של מזהי מקורות. מידע נוסף מופיע במאמר הגדרת מקור נתונים בהגדרות של מדדים.
MCG מסיק את סוג הודעת ה-protobuf מ-source_identifier רק אם הוא משתמש בפורמט של שם סוג היחידה. אם משתמשים ב-FQIN או בשם מותאם אישית (מתוך Configurable Publisher Registry), מערכת MCG לא יכולה להסיק את הסוג. במקרים כאלה, עליכם לספק data_source_message_types. אם הסוג לא מופיע בקטלוג, צריך לספק גם את ההגדרה שלו ב-descriptor_protos.
דוגמה: הגדרה של מקור נתונים
בדוגמה הזו מדווחת מהירות הרכב. קודם כל, צריך לעיין בקטלוג VSIDL כדי לזהות את השירות שמפרסם את הנתונים האלה.
בעזרת קטלוג לדוגמה בבסיס הקוד של SDV, מזהים את השירות הרלוונטי. בהתאם לפורמט של
source_identifier, מציינים את סוג ההודעה של protobuf mcg.test.subpkg.speed_msg. בדרך כלל מהירות ההעלאה מתפרסמת בתדירות גבוהה, ולכן כדאי להשתמש ב-sub_sampling_interval_ms כדי להגביל את העדכונים להודעה אחת לשנייה:
{ "name": "SpeedSource", "source_identifier": "mcg.test.subpkg.speed_msg", "connection_type": "SUBSCRIPTION", "sub_sampling_interval_ms": 1000 // Limit updates to 1 per second }
הגדרת הלוגיקה והעיבוד
הלוגיקה מנוהלת על ידי שני רכיבים שפועלים יחד: טריגרים (מושג) מגדירים מתי משהו קורה. אגרגטורים (מושג) מגדירים איך הנתונים מעובדים על סמך הטריגרים האלה. מכיוון שביטויים (מושג) הם מרכזיים לתנאי הטריגר וללוגיקת האגרגציה, בחלק הזה נסביר קודם איך לכתוב אותם.
הבעות
בעזרת ביטויים אפשר להגדיר חישובים ותנאים באמצעות תחביר שקל לקרוא. MCG מהדר את המחרוזות האלה לפורמט הפעלה שעבר אופטימיזציה לבדיקה במכשיר.
ביטויים יכולים לבטא חישובים אריתמטיים, תנאים לוגיים והשוואות נתונים. למידע על התחביר המלא, כולל אופרטורים ופונקציות, אפשר לעיין במאמר בנושא תחביר של ביטויים.
עדכניות הנתונים: כשביטוי ניגש למקור נתונים, אופן האחזור תלוי בסוג החיבור:
-
SUBSCRIPTION: נעשה שימוש בהודעה האחרונה שהתקבלה שנשמרה במטמון על ידי שירות הטלמטריה. (הערה: אם הערך שלsub_sampling_interval_msמוגדר, יכול להיות שהערך הזה יהיה שונה מההודעה האחרונה שפורסמה). -
ON_DEMAND: מפעיל קריאה מיידית כדי לאחזר את ההודעה החדשה מהשירות.
הגדרת מגבלות
- מערכים: אין תמיכה בגישה ישירה לאינדקס של מערך (לדוגמה,
my_data_source.my_array[0]). - בדיקת סוגים: הקפידו להשוות בין סוגים תואמים (לדוגמה, אל תשוו שדה מחרוזת לרשימה של מספרים שלמים).
דוגמה: ביטויים
בדוגמה צריך לחלץ את ערך המהירות כדי לחשב את הממוצע שלה. היא גם צריכה לקבוע אם הרכב נוסע במהירות מופרזת (מעל 100 קמ"ש) כדי להפעיל את הטריגר המותנה. אפשר למצוא את שמות השדות (במקרה הזה
speed) בהגדרת הודעת ה-protobuf שמשמשת את
מקור הנתונים. הביטויים הבאים מבצעים את הפעולה הזו:
-
SpeedSource.speed: מאחזרת את הערך של השדהspeedממקור הנתוניםSpeedSource. -
SpeedSource.speed > 27.7: הערך שמתקבל הוא trueאם המהירות גבוהה מ-27.7 מ'/שנייה (כ-100 קמ"ש).
טריגרים: הגדרה של מתי הפעולות מתרחשות
הטריגרים מגדירים מתי הפעולות יתבצעו: הערכת נתונים מצטברים, יצירת דוח או שליטה במחזור החיים של איסוף הנתונים. מוסיפים את כל הטריגרים המוגדרים למערך triggers ברמה העליונה.
שדות של אובייקט הפעלה (פריט ברשימה triggers) |
|
|---|---|
name |
מזהה ייחודי של הטריגר הזה בהגדרת המדדים. |
periodicdataconditional |
כדי להגדיר את ההתנהגות, צריך לספק בדיוק אחד מהשדות האלה. |
טריגר נתונים
מופעל כשSUBSCRIPTION מקור נתונים מספק הודעה חדשה (מושג).
שדות של אובייקט data (בטריגר) |
|
|---|---|
source_name |
ה-name של data_source שהטריגר הזה מאזין לו. |
דוגמה: טריגר נתונים
בדוגמה, צריך לעדכן את החישוב של המהירות הממוצעת בכל פעם ש-SpeedSource מפרסם הודעה חדשה. הפעלת הטריגר הזה מתבצעת בכל אחד מהמקרים הבאים:
{ "name": "OnNewSpeed", "data": { "source_name": "SpeedSource" // Reference to the defined data source } }
טריגר תקופתי
שריפות במרווחים קבועים (מושג).
שדות של אובייקט periodic (בטריגר) |
|
|---|---|
period_ms |
מספר לא שלילי שמגדיר את המרווח באלפיות השנייה. |
דוגמה: הפעלה תקופתית
בדוגמה נדרש דוח כל דקה. הטריגר המחזורי הזה מופעל כל 60,000 אלפיות השנייה כדי ליצור את הדוח:
{ "name": "EveryMinute", "periodic": { "period_ms": 60000 // 60,000 ms = 60 seconds } }
טריגר מותנה
מופעל על סמך הערכה של ביטוי (מושג). כדי להתחיל את ההערכה שלו, צריך להגדיר טריגר אחד או יותר של הורה. לרוב זה טריגר נתונים למקורות הנתונים או לאגרגטורים בביטוי, או טריגר תקופתי לשליחת נתונים.
שדות של אובייקט conditional (בטריגר) |
|
|---|---|
triggers |
מערך עם לפחות שם אחד של טריגר ראשי. כשמופעל טריגר ראשי, הטריגר המותנה בודק את הביטוי. |
expression |
הביטוי להערכה. מידע נוסף על ביטויים |
condition_type |
מציין מתי הטריגר צריך לפעול, על סמך הערכת הביטוי. |
סוגי התנאים
המילון condition_type צריך להכיל בדיוק אחד מסוגי התנאים הזמינים כמפתח. מידע נוסף מופיע במאמר טריגרים מותנים.
שדות של אובייקט condition_type (בלעדיים) |
|
|---|---|
is_trueis_false |
מופעלת כשביטוי בוליאני שווה ל-true או ל-false, בהתאמה. |
rising_edge |
אם הערך מספרי, התג מתחיל לפעול כשהערך שלו עולה. אם הביטוי הוא בוליאני, האירוע מופעל כשהוא משתנה מ- יכול להכיל אובייקט |
falling_edge |
אם הערך מספרי, התגובה מופעלת כשהערך יורד. אם הביטוי הוא בוליאני, האירוע מופעל כשהוא משתנה מ- יכול להכיל אובייקט |
all_changes |
התג מופעל כשהתוצאה של הביטוי שונה מהערך הקודם שלו. אם מוגדרות אפשרויות של קצה, המערכת תומכת רק בערכים מספריים ובערכים בוליאניים. יכול להכיל |
אפשרויות קצה
לאובייקטים rising_options ו-falling_options יש את השדות הבאים. אם מציינים משך זמן, משך המעבר המתאים חייב לעמוד בדרישה.
מעברים ללא אפשרויות שצוינו מופעלים באופן מיידי.
| שדות לאובייקטים של אפשרויות קצה | |
|---|---|
min_duration_ms |
מספר לא שלילי (באלפיות שנייה) שמציין כמה זמן התנאי צריך להתקיים במצב החדש לפני שהטריגר מופעל. |
אופציונליrequire_exact |
בוליאני. אם הערך הוא True, כל הערכים שמתפרסמים במהלך משך הזמן צריכים להיות זהים כדי שהטריגר יופעל. |
דוגמה: הפעלה מותנית
הטריגר הבא משתמש באפשרויות של קצה. הוא מופעל אם המהירות עולה על 27.7 מ' לשנייה ונשארת גבוהה למשך 5 שניות לפחות:
{ "name": "SpeedingFor5Seconds", "conditional": { "triggers": ["OnNewSpeed"], "expression": "SpeedSource.speed > 27.7", "condition_type": { "rising_edge": { "rising_options": { "min_duration_ms": 5000 // Condition must hold for 5s in new state } } } } }
פונקציות צבירה: הגדרה של אופן עיבוד הנתונים
שימוש באגרגטור לעיבוד נתונים ביניים עם שמירת מצב (מושג).
מגדירים פונקציית צבירה ומוסיפים אותה למערך aggregators.
מצבר נתונים משנה את הנתונים ומאפשר למצברים אחרים ולדוחות לגשת אליהם.
שדות של אתר אגרגטור (פריט ברשימה aggregators) |
|
|---|---|
name |
מחרוזת שהמשתמש מגדיר ומזהה את האגרגטור. ביטויים יכולים להפנות לאגרגטור הזה לפי שם כדי לגשת לתוצאות שלו. |
trigger_names |
מערך של שם טריגר אחד או יותר שגורמים להערכה של הצבירה הזו. |
אופציונליreset_on_get |
בוליאני, ברירת מחדל: `false`. אם הערך הוא `true`, המערכת מאפסת את מצב הצבירה אחרי שערך הצבירה נגיש לצבר אחר, לדוח מדדים או להפעלה מותנית. |
message_builder |
הפעולה מגדירה את הנתונים לקריאה, לעיבוד ולצבירה. השדות של הודעת הפלט הופכים למקור נתונים עבור צוברים ודוחות אחרים. הפעולה משתמשת ב-field_assignments, וכל הקצאה מגדירה שדה בהודעת הפלט. |
הכלי ליצירת הודעות
אובייקט message_builder מגדיר את מבנה הודעת הפלט ואת לוגיקת הצבירה שמשמשת לחישוב השדות שלו. הוא משמש גם במצברים וגם בהגדרות של דוחות.
שדות של אובייקט message_builder (בצבירה או בדוח) |
|
|---|---|
message_type |
השם המלא של סוג הודעת ה-protobuf לפלט. אם לא מציינים שם, MCG יוצר סוג הודעה מותאם אישית על סמך field_assignmentsסוגי הפלט המשוערים. משתמשים בזה רק אם כלי ליצירת ההודעות הוא חלק מדוח מדדים והדוח צריך להתאים להגדרה ספציפית ומוגדרת מראש של הודעת protobuf. |
field_assignments |
מערך של אובייקטים להגדרת שדות. כל אובייקט מציין שדה בהודעת הפלט ואת הלוגיקה לחישוב הערך שלו. |
שדות של אובייקט הקצאת שדה (פריט ברשימה field_assignments) |
|||||||
|---|---|---|---|---|---|---|---|
field_name |
שם שהמשתמש נתן לשדה. הוא מזהה את הערך הספציפי באובייקט כשמשתמשים בסימון נקודות בביטויים (aggregator_name.field_name). |
||||||
aggregation |
אובייקט שמגדיר איך המערכת מחשבת את הערך של השדה, עם השדות הבאים:
|
||||||
דוגמה: צובר
בדוגמה, נחשב נתונים סטטיסטיים בין דוחות של דקה. האגרגטור הזה מופעל על ידי OnNewSpeed כדי לחשב את המהירות הממוצעת (avg), לספור את הקריאות (count) ולאחסן את 5 ערכי המהירות האחרונים (vector). מגדירים את reset_on_get ל-true. כך הנתונים הסטטיסטיים מאופסים בכל פעם ש-MinuteReport קורא אותם, ומתחיל חלון איסוף חדש לאגרגטור לדקה הבאה:
{ "name": "SpeedAggregator", "trigger_names": ["OnNewSpeed"], // Update aggregation on new speed data "reset_on_get": true, // Reset stats after they are read by the report configuration "message_builder": { "field_assignments": [ { "field_name": "average_speed", "aggregation": { "@type": "avg", "expression": "SpeedSource.speed" } }, { "field_name": "speed_reading_count", "aggregation": { "@type": "count" // Counts triggers (that is, processed speed readings) since last reset } }, { "field_name": "speed_history_last5", "aggregation": { "@type": "vector", "expression": "SpeedSource.speed", "max_length": 5 // Keep last 5 readings } } ] } }
יצירת פלט
כדי להגדיר את הפלט הסופי של קמפיין הטלמטריה, מוסיפים אובייקטים למערך report_configs (concept). ההגדרות האלה קובעות איך הנתונים המעובדים נארזים ומתי הם נוצרים. אתם יכולים להגדיר כמה הגדרות דוחות בהגדרת מדדים אחת כדי לעשות שימוש חוזר ברכיבים.
אתם שולטים ביצירת הדוחות באמצעות השדה trigger_names. בנוסף, אתם יכולים להשתמש ב-report_initial כדי ליצור דוח באופן מיידי כשההגדרה מופעלת, וב-report_incomplete כדי ליצור דוח סופי כשהאיסוף של הנתונים מופסק.
הערה: כדי לקשר בין העיבוד לבין הפלט, צריך להשתמש בסוג הצבירה none (@type: "none") כדי לקרוא ערכים שחושבו מראש מתוך Aggregator. מכיוון שדוחות הם בדרך כלל תמונות מצב חסרות מצב, הפעולה הזו מאפשרת לשמור את הלוגיקה המורכבת של מצב בתוך Aggregators ולשמור את הדוחות לעיצוב.
שדות של אובייקט הגדרת דוח (פריט ברשימה report_configs) |
|
|---|---|
name |
שם ייחודי לדוח. השם הזה מופיע במטא-נתונים של הדוח שנוצר. |
trigger_names |
מערך של שמות טריגרים שגורמים ליצירה ולפרסום של הדוח. |
message_builder |
פרטים נוספים זמינים במאמר בנושא כלי ליצירת הודעות. כאן מוגדר התוכן של הדוח. צבירות נבדקות רק כשהדוח מופעל. לדוגמה, צבירה של וקטור מוסיפה ערך אחד לכל דוח, וצבירה של ספירה משקפת את מספר הדוח. |
אופציונליreport_incomplete(ברירת מחדל: `false`) |
ערך בוליאני. אם הערך הוא true, המערכת יוצרת דוח סופי כשמכבים אותה או כשאיסוף הנתונים מסתיים, גם אם חסרים נתונים. |
אופציונליreport_initial(ברירת מחדל: `false`) |
ערך בוליאני. אם הערך הוא true, המערכת יוצרת דוח באופן מיידי כשהגדרת המדדים מופעלת. |
דוגמה: הגדרת דוח
לבסוף, מגדירים את תצורת הדוח לדוגמה. ההפעלה שלו מתבצעת על ידי EveryMinute. הוא קורא את המהירות הממוצעת המחושבת ואת מספר הקריאות מ-SpeedAggregator באמצעות noneצבירה, שמעבירה את הערך שצבר מראש לדוח:
{ "name": "MinuteReport", "trigger_names": ["EveryMinute"], // Generate report every minute "message_builder": { "field_assignments": [ { "field_name": "average_speed", "aggregation": { "@type": "none", // Read the value directly from the aggregator "expression": "SpeedAggregator.average_speed" } }, { "field_name": "reading_count", "aggregation": { "@type": "none", "expression": "SpeedAggregator.speed_reading_count" } } ] } }
שדות ברמה העליונה
בנוסף למערכים data_sources, aggregators, triggers ו-report_configs, התיאור של הגדרת מדדים צריך לכלול הפניה לקטלוג האותות. אפשר גם לכלול שדות אופציונליים כדי להקצות UUID ספציפי ולנהל את מחזור החיים של האיסוף.
הגדרת UUID
לכל MetricsConfig נדרש מזהה ייחודי אוניברסלי (UUID). אם מספקים existing_uuid, הכלי להמרת מטבעות משתמש בו. אחרת, המערכת יוצרת סיסמה אקראית. כדי לשמור על עקביות בין פריסות וכלים, צריך לציין existing_uuid.
המחרוזת צריכה להיות UUID תקף עם מקפים, שמכיל רק אותיות קטנות.
"existing_uuid": "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
הגדרות של אותות
כדי לאמת את השמות והסוגים של האותות, ל-MCG נדרשת גישה לקטלוג אותות רכב. זהו קובץ protobuf FileDescriptorSet שמכיל את ההגדרות של VSIDL .proto (ארוז ומועלה ל-MCG). פרטים על יצירה והעלאה של קטלוג זמינים במאמר קטלוגים של אותות רכב.
מציינים את גרסת הקטלוג בשדה vs_version של אובייקט ה-JSON:
"vs_version": "v1.0",
הגדרת טריגרים של מחזור חיים
בהקשר של קמפיין טלמטריה, מחזור החיים של MetricsConfig קובע מתי הנתונים נרשמים בפועל. בזמן שמערכת ניהול הקמפיין פורסת ומפעילה את ההגדרה במכשיר, אפשר להשתמש בטריגרים של מחזור החיים כדי לשלוט בדיוק מתי הנתונים נאספים במסגרת הפריסה הזו.
כך אפשר להתאים את איסוף הנתונים לדפוסי השימוש ברכב, כמו 'נסיעה' (IgnitionOn עד IgnitionOff) או 'סשן טעינה', בלי להשבית את ההגדרה.
שליטה בסשן (התחלה/השהיה): משתמשים במקשים
start_trigger_nameו-stop_trigger_nameכדי לשלוט מתי מתבצע האיסוף. לדוגמה, כדי לאסוף נתונים רק בזמן שהרכב נוסע, משתמשים ב-IgnitionOnכטריגר התחלה וב-IgnitionOffכטריגר עצירה. ההגדרה נשארת פעילה במכשיר, אבל למעשה היא מושהית (האיסוף והעיבוד של הנתונים נפסק) כשהטריגר להפסקת הפעולה מופעל, והיא מתחדשת רק כשהטריגר להפעלת הפעולה מופעל שוב.חשוב: הפעולה הזו רק משהה את האיסוף. היא לא מגדירה חלונות לוגיים, מערכי נתונים נפרדים או גורמת לתופעות לוואי אחרות. הערכים של האגרגטור לא מתאפסים כשהאיסוף מושהה או מופעל מחדש.
זיהוי חד-פעמי (סיום): משתמשים ב-
deactivate_trigger_nameאם ההגדרה צריכה לפעול רק פעם אחת (לדוגמה, כדי לזהות את המופע הראשון של קוד תקלה ספציפי) ואז להשבית את עצמה באופן קבוע במכשיר הזה, גם אם הקמפיין עדיין פעיל מבחינה טכנית.
אם לא מציינים טריגרים של מחזור חיים, איסוף הנתונים מתחיל מיד כשהקמפיין מפעיל את ההגדרה, וממשיך ברציפות עד שהקמפיין מסתיים.
| שדות מחזור החיים ברמה העליונה (אובייקט הבסיס) | |
|---|---|
אופציונליstart_trigger_name |
השם של טריגר שמתחיל את סשן האיסוף. אפשר להגדיר בלי stop_trigger_name. |
אופציונליstop_trigger_name |
השם של טריגר שמשהה את סשן האיסוף (לדוגמה, כשהרכב לא בתנועה). אם המדיניות הזו מוגדרת, חובה להגדיר גם את start_trigger_name. |
אופציונליdeactivate_trigger_name |
השם של טריגר שמסיים ומשבית את ה-`MetricsConfig` באופן מלא. |
מתקדם: הגדרות proto מותאמות אישית
בשני מקרים עיקריים, vs_version לבד לא מספיק כדי ש-MCG יבין את כל סוגי ההודעות בתיאור של הגדרת מדדים:
- כשל בהסקת סוג: כפי שמוסבר ב
source_identifierפורמט, MCG לא יכול להסיק את הסוג כשמשתמשים ב-FQIN או בשם מותאם אישית.source_identifier - הודעות בהתאמה אישית: תיאור ההגדרה של המדדים משתמש בהודעות protobuf שלא נמצאות בקטלוג VSIDL שצוין ב-
vs_version. זה קורה כשמגדירים אתmessage_typeב-message_builderעבור פורמט דוח בהתאמה אישית.
במקרים כאלה, כדאי להשתמש ב-data_source_message_types כדי לעזור ל-MCG להסיק את הסוגים וב-descriptor_protos כדי לספק הגדרות של הודעות.
data_source_message_types
ממפים את המחרוזת source_identifier לסוג ההודעה של פרוטוקול protobuf שמוגדר במלואו.
המפתח ב-data_source_message_types צריך להיות זהה לערך source_identifier מהרשומה data_sources:
"data_source_message_types": {
"MyCustomSpeedService": "com.sdv.example.SampleMessage"
}
descriptor_protos
צריך לספק הגדרות לכל סוגי ההודעות שמשמשים ב-data_source_message_types או ב-message_builder שלא מופיעים ב-vs_version שהוגדר.
מעבירים descriptorpb.FileDescriptorSet בקידוד Base64 במערך descriptor_protos. אפשר ליצור את הקובץ הזה מקובצי .proto באמצעות קומפיילר Protobuf protoc.
"descriptor_protos": [
"Cu8BCiZtY2cvdGVzdGRhdGEvbWF4YXZnY3..." // Base64 string
]
דוגמה: תיאור מלא של ההגדרה
בקטעים הקודמים מוגדרים כל הרכיבים של הדוגמה: יצירת דוח כל דקה עם מהירות הרכב הממוצעת שנמדדה במהלך אותה דקה.
הרכיבים הם:
- מקור נתונים (
SpeedSource) לקבלת נתוני מהירות עד פעם בשנייה. - טריגר נתונים (
OnNewSpeed) שמופעל כש-SpeedSourceשולח נתונים. - טריגר מחזורי (
EveryMinute) שמופעל כל 60 שניות. - אגרגטור (
SpeedAggregator) שמשתמש ב-OnNewSpeedכדי לחשב את המהירות הממוצעת, לספור קריאות ולאחסן ערכים עדכניים, ומתאפס אחרי קריאה. - הגדרת דוח (
MinuteReport) שמשתמשת ב-EveryMinuteכדי להפעיל דוח שמכיל את המהירות הממוצעת ואת הספירה מ-SpeedAggregator. - שדות ברמה העליונה (
existing_uuid, vs_version) לזיהוי הגדרות המדדים ולציון קטלוג VSIDL שבו יש להשתמש להגדרות האותות.
כשמשלבים את החלקים האלה, מקבלים את התיאור המלא של הגדרת מדדים:
{ "existing_uuid": "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", // Unique identifier for the configuration "vs_version": "example_version", // Version of the VSIDL catalog to use "data_sources": [ { "name": "SpeedSource", "source_identifier": "mcg.test.subpkg.speed_msg", "connection_type": "SUBSCRIPTION", "sub_sampling_interval_ms": 1000 } ], "aggregators": [ { "name": "SpeedAggregator", "trigger_names": ["OnNewSpeed"], "reset_on_get": true, "message_builder": { "field_assignments": [ { "field_name": "average_speed", "aggregation": { "@type": "avg", "expression": "SpeedSource.speed" } }, { "field_name": "speed_reading_count", "aggregation": { "@type": "count" } }, { "field_name": "speed_history_last5", "aggregation": { "@type": "vector", "expression": "SpeedSource.speed", "max_length": 5 } } ] } } ], "triggers": [ { "name": "OnNewSpeed", "data": { "source_name": "SpeedSource" } }, { "name": "EveryMinute", "periodic": { "period_ms": 60000 } } ], "report_configs": [ { "name": "MinuteReport", "trigger_names": ["EveryMinute"], "message_builder": { "field_assignments": [ { "field_name": "average_speed", "aggregation": { "@type": "none", "expression": "SpeedAggregator.average_speed" } }, { "field_name": "reading_count", "aggregation": { "@type": "none", "expression": "SpeedAggregator.speed_reading_count" } } ] } } ] }
תבנית לדוגמה
הגדרת ה-API מופיעה במאמר MCG API reference.
בקטעים הבאים מופיע תיאור מלא של הגדרת מדדים. אפשר להשתמש בו כמדריך ליצירת תיאור משלכם של הגדרת מדדים.
שדות ברמה העליונה
{
"existing_uuid": "00000000-0000-0000-0000-000000000000", // Optional
"vs_version": "example_version", // Optional
"descriptor_protos": ["..."], // Optional. Base64 encoded FileDescriptorSet
"data_source_message_types": {
"ExampleServiceName": "com.example.ProtoMessage"
}, // Optional
"start_trigger_name": "DataTriggerExample", // Optional
"stop_trigger_name": "ConditionalTriggerExample", // Optional
"deactivate_trigger_name": "PeriodicTriggerExample" // Optional
}
קלט: מקורות נתונים וצבירה
{
"data_sources": [
{
"name": "SubscriptionExample",
"source_identifier": "com.example.sdv.ExampleMessage|example-unit",
"connection_type": "SUBSCRIPTION", // Options: SUBSCRIPTION (default), ON_DEMAND
"sub_sampling_interval_ms": 100, // Optional
"fetch_last_message": false // Optional. Default: false
},
{
"name": "RegistryExample",
// Configurable Publisher Registry-based publisher (matches data_source_message_types)
"source_identifier": "ExampleServiceName",
"connection_type": "SUBSCRIPTION"
},
{
"name": "GetterExample",
"source_identifier": "com.example.sdv.ExampleConfig|example-unit",
"connection_type": "ON_DEMAND",
"configuration": {
"type_url": "type.googleapis.com/example.Config",
"value_json": {} // Or value_textproto, value (base64)
}
}
],
"aggregators": [
{
"name": "AggregatorExample",
"trigger_names": ["DataTriggerExample"],
"reset_on_get": false, // Optional. Default: false. If true, resets state after it's read
"message_builder": {
"message_type": "com.example.AggregatedMessage", // Optional
"field_assignments": [
{
"field_name": "avg_example",
"aggregation": {
// Options: avg, count, min, max, sum, stddev, delta, vector, none
"@type": "avg",
"expression": "SubscriptionExample.value"
}
},
{
"field_name": "count_example",
"aggregation": {
"@type": "count" // Counts number of evaluations. No expression needed
}
},
{
"field_name": "vector_example",
"aggregation": {
"@type": "vector",
"expression": "SubscriptionExample.value",
"max_length": 10 // Optional. If set, creates a ring buffer
}
}
]
}
}
]
}
לוגיקה ועיבוד: טריגרים
{
"triggers": [
{
"name": "PeriodicTriggerExample",
"periodic": { "period_ms": 1000 }
},
{
"name": "DataTriggerExample",
"data": { "source_name": "SubscriptionExample" }
},
{
"name": "ConditionalTriggerExample",
"conditional": {
"triggers": ["PeriodicTriggerExample"],
"expression": "SubscriptionExample.value > 0",
"condition_type": {
// Options: is_true, is_false, rising_edge, falling_edge, all_changes
"rising_edge": {
"rising_options": { "min_duration_ms": 0, "require_exact": false }
}
}
}
}
]
}
פלט: הגדרות הדוח
{
"report_configs": [
{
"name": "ReportExample",
"trigger_names": ["PeriodicTriggerExample"],
"report_incomplete": false, // Optional. Default: false
"report_initial": false, // Optional. Default: false
"message_builder": {
"message_type": "com.example.ReportMessage", // Optional. Must be defined in VSIDL catalog or descriptor_protos. Message type will be inferred if not provided
"field_assignments": [
{
"field_name": "avg_example",
"aggregation": {
"@type": "none", // Passthrough since aggregation is done in AggregatorExample
"expression": "AggregatorExample.avg_example"
}
}
]
}
}
]
}
תחביר של ביטויים
| קטגוריה | תחביר | תיאור |
|---|---|---|
| גישה לנתונים | source_namesource_name.fieldsource_name.field.subfield |
גישה להודעה מלאה ממקור נתונים או מצבר גישה לשדה ספציפי בהודעה (כולל שדות מקוננים) |
| Arithmetic | +, -, *, /, %, ** |
מתמטיקה רגילה. ** הוא העלאה בחזקה. |
| Logical | &&, ||, !, ^ |
AND, OR, NOT, XOR. |
| רלציוני | ==, !=, <, <=, >, >= |
== ו-!= פועלים בכל הסוגים. באחרים נדרשים מספרים. |
| רשימה | contains(list, item)doesnotcontain(list, item)alleq(list, value) |
הפונקציה פועלת על וקטורים (מערכים). הפונקציה alleq(list, value) מחזירה true אם כל הפריטים ב-list שווים ל-value. |
| פונקציות | timestamp(clock_type) |
השעה הנוכחית בננו-שניות.clock_type: REALTIME_CLOCK אוMONOTONIC_TIME_SINCE_BOOT_OR_RESUME |
abs(n) |
ערך מוחלט | |
floor(n), round(n), ceil(n) |
פונקציות עיגול | |
| סדר הפעולות | () |
קיבוץ רגיל לפי סדר עדיפות |