Health Monitor (HM) הוא סוכן SDV שפועל בכל מכונה וירטואלית (VM) כדי לעקוב אחרי מצב חבילות השירות, לקבוע את תקינות המכונה הווירטואלית וליצור באופן תקופתי דוח תקינות של המכונה הווירטואלית.
חבילות שירותים שהוגדרו על ידי יצרן ציוד מקורי (OEM) צריכות להאזין לאותות הבריאות השונים שמדווחים על ידי מודול ניהול הבריאות (HM), ולבצע פעולות שחזור על סמך הנתונים. לדוגמה, יכול להיות שיהיה צורך להפעיל מחדש או לעדכן מופע של SDV עם חבילות שירותים שקורסות.
אפשר להגדיר את סוכן HM לעקוב אחרי הפעולות הבאות:
- סטטוס הפעילות של ישויות שמבצעות משימות תקופתיות, באמצעות מעקב אחרי פעימות לב של פעילות. אפשר להגדיר את המעקב הזה גם למופעים של חבילות שירותים וגם לסוכני OEM בהתאמה אישית.
- מצב השחזור של מופעים של חבילות שירותים. ב-SDV 2.0, אתם יכולים להגדיר חבילות שירותים להפעלה מחדש אוטומטית במקרה של קריסה. ה-HM מספק אותות למעקב אחרי תהליך השחזור הזה.
- QoS של תקשורת
- הפעילות של סוכנים מותאמים אישית של SDV ו-OEM
לעיון, הקטלוג המלא של VSIDL, כולל הגדרות פרוטו, זמין בכתובת //system/software_defined_vehicle/health_monitor/catalog/health_monitor.vsidl.
הסברים על המונחים
המונחים האלה מופיעים בדף הזה.
עבודה עם מערכת המשנה HM
כדי להשתמש בתכונות של HM, הטמעה של יצרן ציוד מקורי צריכה:
- מגדירים את מערכת המעקב אחר תקינות המערכת באמצעות קובצי הגדרה, כמו שמתואר במאמר הגדרת מערכת המעקב אחר תקינות המערכת.
- להשתמש בחבילת שירותים של HM Listener שהוגדרה על ידי יצרן הציוד המקורי כדי להאזין לפלט של HM ולבצע פעולה מתאימה.
- לפתח חבילות שירותים שמפרסמות באופן פעיל אותות, בהתאם להגדרת התקינות שלהן. הפרסום הזה מאפשר ל-HM להעריך את מצב הבריאות שלהם. למידע נוסף, ראו מדריכים למפתחים של חבילות שירותים.
הגדרת מערכת HM
כל הגדרה שקשורה ל-HM נמצאת באחד מסוגי ההגדרות הבאים:
- הגדרה גלובלית של בדיקת תקינות לכל מכונה וירטואלית
- הגדרת תקינות של חבילה לכל שירות, שבה מוגדרים פרמטרים של תקינות לכל המופעים של החבילה
הגדרת תקינות לכל מכונה וירטואלית
בזמן הריצה, סוכן ה-HM מצפה להגדרת תקינות ברמת המכונה הווירטואלית: זהו קובץ textproto (עם הסיומת .textproto) מסוג VMHealth שמוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/health_monitoring_config.proto.
ההגדרה של תקינות המכונה הווירטואלית צריכה להיות בנתיב שצוין באמצעות מאפיין המערכת androidboot.sdv.health_monitor.config_path בזמן האתחול.
לחלופין, אפשר להגדיר את הנתיב באופן דינמי בזמן הריצה על ידי הגדרת מאפיין המערכת persist.sdv.health_monitor.config_path לנתיב מותאם אישית. ההגדרה persist.* מקבלת עדיפות על פני ההגדרה androidboot.*. כדי שההגדרה החדשה תיכנס לתוקף, צריך להפעיל מחדש את המכשיר.
בהגדרות הבריאות של מכונה וירטואלית אפשר להגדיר את הפרטים הבאים:
תדירות דוח תקינות ה-VM דרך
period_ms. ההגדרה הזו משפיעה על האיזון בין מהירות האיתות על הפרות של תקינות המערכת לבין הביצועים של מערכת המשנה לניהול בריאות. מומלץ להגדיר ערך של 100 ms.אילו נציגים ינוטרו למקרה של קריסה (ראו מעקב אחר קריסות של נציגים).
דוגמאות לקובץ התצורה מופיעות ב-//system/software_defined_vehicle/health_monitor/src/prod_configs/. הנה קובץ תצורה לדוגמה:
period_ms: 100
monitored_agent {
agent_name: "sdv_dt_agent"
binder_interface_name: "google.sdv.data_tunnel.IAgentService/default"
}
monitored_agent {
agent_name: "sdv_rpc_agent"
binder_interface_name: "google.sdv.rpc.IRpcAgent/default"
}
בדוגמה הזו, סוכני SDV DT ו-RPC מוגדרים לניטור קריסות, ודוח תקינות המכונה הווירטואלית מוגדר להתפרסם כל 100 אלפיות השנייה.
לפי הגדרת חבילת שירות
המעקב אחר תקינות המופעים של חבילת השירות הוא אופציונלי. כדי להפעיל את התכונה, מאחסנים את קובץ הגדרות הבריאות ב-APEX של חבילת השירות ומגדירים נתיב אליו בשדה health_config_path של sdv_service_bundle_metadata ב-sdv_service_bundles_manifest.textproto. מידע נוסף על מניפסטים של חבילות שירות זמין במאמר מטא-נתונים של חבילות שירות.
קובץ תצורת הבריאות הוא קובץ textproto מהסוג הבא:
message ServiceBundleHealthConfiguration {
// Required: An empty ServiceBundleHealthConfiguration is equivalent to no
// implicit health monitoring or QoS monitoring configured.
//
// Key should contain the instance name that the `InstanceConfiguration` applies to.
map<string, InstanceConfiguration> instance_config = 1;
}
לכל מופע אפשר לציין את ההגדרה של אותות החיים ואת הגדרת ה-QoS:
// Service bundle *instance* configuration.
message InstanceConfiguration {
// Optional.
//
// Instance health monitoring configuration. Monitors instance
// general health. Well suited for bundles executing periodic tasks.
optional HealthConfiguration health_config = 1;
// Optional.
//
// Map defining the QoS monitoring profile of the instance.
// The key (string) is the topic name of the specific QoS heartbeat
// publication. Choose a meaningful topic name for
// expressive HM reporting.
//
// Only one publisher should publish on this topic. The HM
// agent ignores all publishers except the first one registered
// by the service bundle instance configured for QoS monitoring.
map<string, QosMonitoringConfiguration> qos_config = 2;
}
מידע נוסף על הגדרה של כל תכונה בנפרד זמין במאמרים מעקב אחרי פעימות לב של פעילות ומעקב אחרי איכות השירות.
האזנה לפלט של HM
אפשר להאזין ל-HM באמצעות דוחות תקופתיים או RPC API.
דוח על תקינות של מכונות וירטואליות
הדוחות של מעקב הבריאות נוצרים בתדירות גבוהה ומספקים מידע תמציתי על מצב הבריאות של הישויות המנוטרות.
תחביר הסוג של VmHealth מוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/health_topic.proto:
message VmHealth {
// Required.
// Describes if all monitored service bundles are healthy and report heartbeats on time.
bool all_monitored_service_bundles_healthy = 1;
// Required.
// Describes if all service bundles which should be running on the VM are alive.
bool all_service_bundles_alive = 2;
// Required.
// Indicates if QoS requirements for all service bundles which should be running
// on the VM are satisfied.
bool qos_violations_detected = 3;
}
חבילת שירותים של מאזין HM שמוגדרת על ידי יצרן ציוד מקורי צריכה להאזין לדוחות VMHealth ולבצע פעולה מתאימה בהתאם לארכיטקטורה המלאה של המערכת.
אלה כמה פעולות אפשריות:
- מריצים סדרות של פעולות אבחון במכונה הווירטואלית.
- מפעילים מחדש את ה-VM.
- מריצים קמפיין טלמטריה כדי לקבוע מה הסיבה.
- לעדכן את המערכת או להפסיק עדכון אם המערכת לא פועלת כמו שצריך.
HM RPC API
דוח תקינות המכונה הווירטואלית הוא פרסום שעבר אופטימיזציה לתדירות ומהירות שידור, ומספק מידע נרחב על סטטוס התקינות של המערכת.
ממשק ה-API של HM RPC מאפשר למאזין HM לקבל מידע מפורט על המקור של הפרות מדיניות שקשורות לבריאות. הממשק מוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/health_monitor_service.proto.
לנוחותכם, הנה תמונה של הממשק:
// RPC Interface of the VM Health Monitor Agent for querying details about the current VM
// health.
//
// An OEM-defined service bundle typically monitors the overall health of the SDV instance by listening to
// high-frequency `VMHealth` publication. If violations are detected, this RPC interface can
// be used to retrieve detailed information about the malfunctioning component.
service HealthMonitorService {
// Returns the list of running SDV service bundles that were created or started
// by the orchestrator on this VM.
rpc ListAllServiceBundles(ListAllServiceBundlesRequest) returns (ListAllServiceBundlesResponse) {}
// Returns the list of crashed SDV service bundles.
rpc ListCrashingServiceBundles(ListCrashingServiceBundlesRequest)
returns (ListCrashingServiceBundlesResponse) {}
// Returns the list of recovering SDV service bundles.
rpc ListRecoveringServiceBundles(ListRecoveringServiceBundlesRequest)
returns (ListRecoveringServiceBundlesResponse) {}
// Returns the list of monitored SDV service bundles, which registered for reporting
// aliveness heartbeats but failed to report heartbeats on time.
rpc ListUnhealthyMonitoredServiceBundles(ListUnhealthyMonitoredServiceBundlesRequest)
returns (ListUnhealthyMonitoredServiceBundlesResponse) {}
// Returns a list of QoS monitoring violations detected.
// Provides a snapshot of the current system state.
rpc ListQosViolations(ListQosViolationsRequest)
returns (ListQosViolationsResponse) {}
}
תיאור מפורט של התכונות
בקטע הזה מתוארים היבטים שונים של HM בפירוט רב יותר.
מעקב אחר פעימות לב של פעילות
כשמגדירים מעקב אחר פעילות של שירות, מודול ה-HM מצפה שהמופע יפרסם מעקבי פעימות לב תקופתיים כדי להוכיח שהלוגיקה העסקית פועלת בצורה תקינה. המעקב הזה מתאים במיוחד למופעים של חבילות שירותים שמבצעים משימות תקופתיות. בנוסף, חבילות שמשתמשות בזמני ריצה אסינכרוניים יכולות להשתמש במעקב אחר פעילות כדי להוכיח שמאגר השרשורים לא מוצה.
איור 1. זרימת הניטור של פעילות ה-HM.
הגדרות אישיות
כדי להפעיל את בדיקת הפעילות (HB) בחבילת שירותים, מוסיפים מופע של HealthConfiguration לשדה health_config בהגדרת החבילה.
הגדרת אותות מחזוריות של פעילות מגדירה קבוצה קבועה מראש של פרמטרים שקובעים את הקריטריונים להערכת אותות מחזוריות של פעילות של שירות. אם המאפיינים של אות החיים של השירות חורגים מהפרמטרים האלה, אות החיים מסווג כמעוכב וחבילת השירות המתאימה מסווגת כלא תקינה, מה שעשוי להצביע על מצב הפעלה לא אופטימלי.
חבילת שירות נחשבת תקינה כשהיא מדווחת על פעימות לב בזמן, בהתאם להגדרת התקינות שלה. במקרה של קריסה או עומס גבוה על המערכת, יכול להיות שחסר או מתעכב אות פעימת לב, ולכן חבילת השירות מסומנת כלא תקינה. במקרה כזה, הפרה תופיע בדוח VmHealth.
מפתחים של חבילות שירות צריכים להגדיר את תצורת הבריאות של חבילת שירות במטא-נתונים המתאימים של APEX. הגדרות הבריאות מגדירות את הקריטריונים הבאים:
ההשהיה המקסימלית המותרת בין הפעלת השירות לבין זיהוי הפעימה הראשונה.
התקופה שבה חבילת שירותי ה-SDV מבצעת לוגיקה עסקית, שתואמת למחזוריות של פרסום אותות חיים של שירות.
מספר התקופות שצריך לפספס לפני שהמערכת לניהול בריאות (HM) מחשיבה את חבילת השירות כלא תקינה.
זמן הביצוע הוא משך הזמן שחבילת שירותים של SDV צריכה כדי לבצע את הלוגיקה העסקית שלה לפני שהיא יכולה לפרסם אותות חיים של שירות.
חבילת השירות יוצרת הפרה של תקינות השירות אם הדופק של השירות מתעכב. יש שני מקרים בהתאם למועד התצפית על הבריאות:
מקרה 1: הדופק הראשוני לא התקבל. אם חלף יותר זמן מההשהיה הראשונית המותרת בין תחילת חבילת השירותים לבין זמן הבדיקה, חבילת השירותים נחשבת כלא תקינה.
מקרה 2: כבר התקבלו פעימות לב. אם חלף פרק זמן מסוים בין הפעימה האחרונה לבין זמן התצפית, חבילת השירות נחשבת כלא תקינה. הסף הזה מחושב כסכום של תקופת הדיווח (כפול מספר התקופות) ומשך המשימה.
פורמט הגדרות הבריאות מוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/health_config.proto:
package com.android.sdv.health;
// Service Bundle's configuration for health monitoring.
message HealthConfiguration {
// Required.
// Initial delay in milliseconds is the time between the service starts and its first heartbeat.
optional uint64 initial_delay_ms = 2;
// Required.
// Period of reporting a heartbeat in milliseconds which corresponds to the periodicity of
// executing a business logic by the SDV service. This value should be larger than 0.
optional uint64 period_ms = 3;
// Required.
// The number of periods missing a heartbeat before the Health Monitor should consider the
// service as unhealthy. This value should be larger than 0.
optional uint64 num_periods = 4;
// Required.
// Duration of the business logic the SDV service bundle executes in milliseconds.
optional uint64 task_duration_ms = 5;
}
שיקולים בזמן ריצה
בקטע הזה מוסבר איך לפרסם פעימות לב של פעילות ולבצע רישום נכון למעקב.
פרסום פעימות לב של פעילות
מופע של חבילת שירותים יוצר הודעת דופק שירות שכוללת חותמת זמן. יוצרים את ההודעה באופן שגרתי, בדרך כלל ישירות אחרי ההפעלה של הלוגיקה העסקית הראשית. פעימת הלב של השירות מציינת שחבילת השירות פעילה.
כדי לעקוב אחרי אובייקט של מופע חבילה, צריך ליצור בעזרתו אובייקט מסוג ServiceHeartbeat, שזמין בספרייה libhealth_api:
message ServiceHeartbeat {
// Required.
// The timestamp.
.google.protobuf.Timestamp timestamp = 1;
}
בוחרים באופן שרירותי את נושא הפרסום. סוכן HM משתמש בגילוי לפי סוג ההודעה כדי לזהות את הפרסום.
כשמגדירים מעקב אחר פעילות באמצעות הגדרת התקינות שמקושרת למניפסט של חבילת השירות המתאימה, סוכן HM מצפה שפעימות הלב יפורסמו ברגע שהמופע יסיים את שגרת on_start שלו. מומלץ להגדיר את on_start לזמן קצר כדי למנוע חסימה של הפעלת המערכת, ולכן כדאי לפרסם פעימות לב במשימה אסינכרונית שהופעלה ב-on_start.
מפתחים של חבילות יכולים להתאים אישית את הזמן שבו צפוי הדופק הראשון באמצעות רשומה בהגדרות initial_delay_ms.
מופע ה-bundle אמור להמשיך לפרסם פעימות לב עד שהוא נעצר. מופע נחשב למופסק כשהשגרה שלו מסתיימת.on_stop
תרחיש שימוש מיוחד: רישום מפורש למעקב אחר אותות פעימת לב
ההתנהגות שמתוארת במאמר מעקב אחר פעימות לב של פעילות, שבה פעימות הלב צפויות בין on_start ל-on_stop, נקראת מעקב מרומז אחר פעילות. זו הדרך המומלצת להשתמש בתכונה: היא מפשטת את הלוגיקה העסקית של החבילה ומבטיחה שהחבילה תמיד תהיה במעקב.
עם זאת, יכול להיות שיהיו תרחישי שימוש שבהם תקופת המעקב שמוגדרת כברירת מחדל תהיה מגבלה:
- מופע של חבילת שירותים מכיל לוגיקה עסקית שמתרחשת באופן מחזורי במרווח זמן שלא מקושר לאירועים
startו-stop. יכול להיות שיהיה צורך במעקב אחר הפעילות רק בתקופה המותאמת אישית הזו. - ה-HM עוקב בצורה מדויקת אחרי ה-HB במהלך תקופות ההשעיה וההפעלה מחדש. לכן, יכול להיות שהחבילה תמשיך להיות במעקב אחרי
on_stop. - יכול להיות שסוכני OEM בהתאמה אישית לא יוטמעו כחבילות שירות. לכן, אי אפשר להשתמש בהם כדי ליהנות ממעקב מרומז אחר פעילות. עם זאת, יכול להיות שעדיין יידרש מעקב אחר הפעילות שלהם.
במקרים כאלה, ה-HM מאפשר לעקוף את ההרשמה המרומזת למעקב אחר פעילות, לטובת הרשמה מפורשת. כדי להשתמש ברישום מפורש, צריך להגדיר את מופע החבילה כך שלא יכלול רשומה מסוג HealthConfiguration עבור המופע הספציפי במניפסט של החבילה, וכך לבטל את הרישום המרומז. לאחר מכן, בזמן הריצה, מופע החבילה צריך להשתמש ב-RPC API שמוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/health_monitor_registration_service.proto כדי להירשם לניטור ולבטל את הרישום ממנו באופן ידני. אחרי שקריאת ה-RPC של הרישום מצליחה, אמורים להתקבל פעימות לב.
דוגמה להטמעה אפשר לראות במאמר //system/software_defined_vehicle/samples/health/stable/health_monitored_service_bundle/.
מעקב אחרי QoS
איכות השירות (QoS) היא מדד של תקשורת. ה-HM עוקב אחרי משך הזמן שההודעה שוהה בדרך, או במקרה של תקשורת תקופתית, אחרי התדירות שבה ההודעות מתקבלות.
SDV מספקת כמה סוגים של תקשורת Pub/Sub ו-RPC. המכנה המשותף הוא שכל תוכניות התקשורת מכילות לפחות מאזין אחד. כדי שמנהל ה-HM יוכל לעקוב אחרי התקשורת, מופע חבילת שירותי ההאזנה הזה צריך לפרסם פעימות לב מיוחדות של QoS בכל פעם שהוא מקבל הודעה שמעניינת אותו.
הגדרות אישיות
כדי להפעיל את המעקב אחר איכות השירות של תקשורת, צריך קודם לזהות את מאזין התקשורת שיפרסם את אותות הדופק של איכות השירות. לאחר מכן, עבור מופע חבילת השירות שזוהה, מוסיפים נושא אחד או יותר למיפויים QosMonitoringConfiguration בשדה qos_config. מידע נוסף זמין במאמר הגדרת חבילות לכל שירות.
הנושא הוא מחרוזת שמגדירה את נושא הפרסום שבו מנהל ה-HM מצפה לקבל פעימות לב של QoS בזמן הריצה. מופע של חבילת האזנה יכול להשתתף בכמה תקשורות ולדווח על פעימות לב של QoS בכמה נושאים.
הנושאים צריכים להיות תיאוריים, כי הם מדווחים בחזרה לחבילת שירותי מאזין HM אם מזוהות הפרות של QoS בזמן הריצה.
הסוג QosMonitoringConfiguration מוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/health_config.proto:
message QosMonitoringConfiguration {
// Optional - If absent, heartbeat frequency monitoring is disabled for this SB.
//
// The maximum allowable interval between consecutive heartbeats (in milliseconds).
// A QoS frequency violation is triggered if the time elapsed between
// two heartbeats exceeds this threshold.
optional uint64 qos_period_threshold_ms = 1;
// Optional - If absent, heartbeat latency monitoring is disabled for this SB.
//
// The maximum allowable interval between data publication and data processing timestamps (in milliseconds).
// A QoS latency violation is triggered if the time elapsed between
// data publication and data processing timestamps exceeds this threshold.
optional uint64 qos_latency_threshold_ms = 2;
}
בתרחישי שימוש רגילים, מומלץ לאכוף את שני סוגי המעקב של QoS. ערך qos_latency_threshold_ms של 30 הוא סביר לתקשורת Pub/Sub בתוך מכונה וירטואלית בעומסי מערכת רגילים.
שיקולים בזמן ריצה
בדומה לניטור של פעימות לב (HB) של פעילות, חבילת ההאזנה לתקשורת אמורה לפרסם סוג של פעימת לב. במקרה כזה, הודעת QoS HB צריכה להתפרסם בכל פעם שמתקבלות הודעות רלוונטיות, ולא בסוף הביצוע של הלוגיקה העסקית.
ה-QoS HB הוא מסוג QosHeartbeat, שמוגדר ב-//system/software_defined_vehicle/health_monitor/catalog/qos_heartbeat.proto:
message QosHeartbeat {
option (.sdv.vsidl.v1.publication) = {
message_count: 2
model: SINGLE_PUB
};
// Required.
// Current timestamp at heartbeat transmission. The heartbeat should be sent
// immediately after the listener receives the related QoS-monitored message.
.google.protobuf.Timestamp timestamp = 1;
// Required.
// Timestamp corresponding to the creation time of the underlying data. This
// implies that, in addition to the data of interest, the monitored message includes
// a data creation timestamp field. The listener is responsible for routing this
// timestamp to the QosHeartbeat upon receiving a QoS-monitored message.
.google.protobuf.Timestamp data_timestamp = 2;
}
הזמן שבו נרשם ובוטל הרישום של פרסום QoS HB הוא קריטי למעקב מדויק. ה-HM מצפה לקבל פעימות לב של QoS בין שני האירועים האלה. חבילת ההאזנה להודעות צריכה לרשום את הפרסום של QoS HB כשמתבצע רישום של התקשורת המנוטרת במערך התקשורת של SDV. מנהל המלון יכול להשתמש ב-API של הזמינות כדי לעשות זאת. מידע נוסף מופיע במאמר בנושא בדיקת זמינות השירות.
מעקב אחר שחזור חבילות שירות
שחזור של מופעים של חבילות שירות מוגדר כחלק מקובצי ההגדרות של סוכן התזמור. למידע נוסף, אפשר לעיין במאמר בנושא חבילות שירותים. מערכת המשנה HM עוקבת באופן פסיבי אחרי תהליך השחזור. כשמזוהה כשל בשחזור של מופע חבילה, מתווספת הפרה לדוח VMHealth. בניגוד לשאר היכולות של ניטור HM, ניטור השחזור הוא חובה ואי אפשר להגדיר אותו.
קריסות של מופעים של חבילות שירותים שלא הוגדרו לשחזור יוצרות הפרה של תקינות המערכת בקריסה הראשונה שלהן.
שחזור של מופע חבילת שירותים נועד להשתלב עם מעקב אחר פעילות באמצעות אותות פעימת לב. מערכת ה-HM סלחנית יותר בהערכת פעימות לב כשהיא מזהה שהחבילה מתאוששת. בפועל, המשמעות של ההקלה הזו היא שאם חבילות שירותים קורסות, הן לא צריכות לבצע שלבים נוספים של ביטול רישום או רישום לצורך מעקב.
מעקב אחרי קריסות של סוכנים
ה-HM מזהה קריסות פוטנציאליות של סוכני SDV באמצעות מנגנון ה-binder linkToDeath.
אפשר להגדיר מעקב אחרי קריסות כחלק מהגדרת תקינות המכונה הווירטואלית (ראו הגדרה לכל מופע SDV (מכונה וירטואלית)), במיוחד את השדה החוזר monitored_agent. השדה הזה צריך להכיל רשומות מסוג BinderServiceAgent:
message BinderServiceAgent {
// agent_names must be unique across configuration
// used for HM internal agent identification, and naming entries in HM dumpsys report
string agent_name = 1;
// Binder interface name/identifier, e.g: "google.sdv.data_tunnel.IAgentService/default"
// HM Agent should have appropriate permissions to find the binder interface
// see also `sdv_crash_monitored_service` selinux attribute
string binder_interface_name = 2;
}
אפשר גם לעקוב אחרי סוכנים מותאמים אישית אם הסוכן חושף ממשק של קובץ מאגד. כדי לעקוב אחרי סוכן בהתאמה אישית, צריך להעניק את הרשאות ה-HM SELinux כדי להאזין לממשק המתאים של Binder.
מאפיין המערכת ro.boot.sdv.health_monitor.agent_startup_timeout_sec יכול לשנות את משך הזמן שבו מנהל ה-HM ממתין לסוכנים כדי לרשום את ממשקי ה-Binder שלהם אחרי שמנהל ה-HM מופעל. אלא אם נדרש אחרת על ידי סוכנים מותאמים אישית, ברירת המחדל של שלוש שניות מתאימה.
מדריכים למפתחים בנושא חבילות שירות
בקטע הזה מופיעים מדריכים מפורטים להפעלת תכונות של HM מחבילות שירות, בניגוד לתיאור התיאורטי שבקטעים הקודמים. הדוגמה העדכנית שאליה מתייחסים במדריכים האלה היא הדוגמה qos_monitoring. כדאי לפעול לפי הדוגמה //system/software_defined_vehicle/samples/health/stable/qos_monitoring/README כדי ללמוד איך זה עובד בפועל.
הוספת ניטור של אותות חיים לחבילת שירותים
השיטה הזו היא הדרך הכי ישירה להפעיל מעקב אחר תקינות של חבילת שירותים:
מגדירים מופע של
ServiceBundleHealthConfigurationלמופעי החבילה בקובץ בשםhealth_configuration.textproto:# health_bundle_configuration.textproto instance_config { key: "instance1" value: { health_config { initial_delay_ms: 1000 period_ms: 500 num_periods: 2 task_duration_ms: 200 } # qos_config entries irrelevant for this dev guide qos_config { ... } } }מוסיפים את קובץ ההגדרות לחבילת השירות APEX. ב-
Android.bp:apex { name: "com.android.sdv.sample.oem.health.qos_monitoring", // ... prebuilts: [ // ... "com.android.sdv.sample.oem.health.qos_monitoring.health_config", ], } prebuilt_etc { name: "com.android.sdv.sample.oem.health.qos_monitoring.health_config", src: "health_configuration.textproto", filename: "health.textproto", // ... // Reduce prebuilt visibility to avoid adding it in another APEX. visibility: ["//system/software_defined_vehicle/samples/health/qos_monitoring/apex"], }שומרים את הגדרת הבריאות ב-APEX ומגדירים את
health_config_pathבמניפסט:# sdv_service_bundles_manifest.textproto sdv_service_bundle_metadata { ... health_config_path: "etc/config/health_configuration.textproto" }בהגדרה של VSIDL, מוודאים שהחבילה מתפרסמת
com.android.sdv.health.ServiceHeartbeat:sdv_service_bundle { name: "SampleBundle" publisher { message: "com.android.sdv.health.ServiceHeartbeat" topic: "arbitrary-topic" capacity: 2 } }מוסיפים הרשאות SDV לחבילה כדי שהחבילה תקבל הרשאה לפרסם HBs:
publisher { type: "com.android.sdv.health.ServiceHeartbeat" }פרסום פעימות לב של השירות בקוד באופן תקופתי, החל מ-
on_start:// ... fn on_start(&mut self) { // ... runtime.spawn(business_logic(self.context)) } async fn business_logic(context: ContextRef) -> SdvResult<()>{ // register HB publication let mw_comms = SdvComms { context }; let aliveness_hb_pub = create_publisher::<PublisherDescriptor<ServiceHeartbeat>>( &mw_comms, PublisherDescriptors::<ServiceHeartbeat>::ARBITRARY_TOPIC, ) .await?; loop{ // do business logic // ... // publish hb aliveness_hb_pub.publish(&ServiceHeartbeat { timestamp: MessageField(Some(Box::new(now.into()))), ..Default::default() })?; } }
תרחיש שימוש מיוחד: רישום מפורש
בתרחישי שימוש מיוחדים יותר, שבהם נדרש מעקב אחר פעימות לב בחבילה למחזורי חיים מותאמים אישית (לדוגמה, מעקב שמתחיל מוקדם יותר או מסתיים מאוחר יותר ממצב STARTED הרגיל), אפשר להשתמש בשיטת הרישום המפורשת:
בהגדרת VSIDL, מוסיפים את הלקוח
com.android.sdv.health.HealthMonitorRegistrationService:sdv_service_bundle { # ... client { service: "com.android.sdv.health.HealthMonitorRegistrationService" channel: "com-android-sdv-health-health-monitor-registration-service" } }מוסיפים הרשאה ל-SDV לשימוש ב-RPC של רישום HB של פעילות:
# ... client { service: "com.android.sdv.health.HealthMonitorRegistrationService" channel: "com-android-sdv-health-health-monitor-registration-service" }להירשם ב-HM דרך RPC, לדוגמה, ב-
on_startאו ב-new:let rpc_client = Self::new_client(comms).await?; let _ = rpc_client .RegisterConfiguration(&RegisterConfigurationRequest { config: Some(HealthConfiguration{ initial_delay_ms: 100, period_ms: 200, num_periods: 3, task_duration_ms: 40, special_fields: protobuf::SpecialFields::default(), }).into(), ..Default::default() }) .await .unwrap();פרסום של HB.
לבטל את הרישום למעקב כשאין בו יותר צורך:
let _ = rpc_client .UnregisterConfiguration(&UnregisterConfigurationRequest { ..Default::default() }) .await .unwrap();
הוספת ניטור של QoS לתקשורת
מוודאים שמופע חבילת השירותים רשום לנושא שנקרא
fog-light-statusבקטלוג VSIDL:subscriber { message: "QosMonitoredFogLightStatus" topic: "left-fog-light-status" }הפורמט של ההודעה הוא:
package com.android.sdv.sample.oem.health.qos_monitoring; import "google/protobuf/timestamp.proto"; message QosMonitoredFogLightStatus { // arbitrary fields related to business logic int32 status = 1; // In SDV1.0, a qos monitored message should include a timestamp field .google.protobuf.Timestamp timestamp = 2; }מגדירים מופע של
ServiceBundleHealthConfigurationלמופעי החבילה בקובץhealth_configuration.textprotoשכולל מעקב אחר QoS:# health_bundle_configuration.textproto instance_config { key: "instance1" value: { # aliveness HB monitoring config irrelevant for this dev guide health_config { ... } qos_config { key: "qos-hb-right-fog-light-status" value { qos_period_threshold_ms: 100 qos_latency_threshold_ms: 50 } } } }הנושא שנבחר בשדה
keyממחיש ש-QoS HBs יפורסמו בנושא הזה, ויאפשר מעקב אחרי נושא בשםfog-light-status.מוסיפים את קובץ ההגדרות ל-APEX של חבילת השירות. ב-
Android.bp:apex { name: "com.android.sdv.sample.oem.health.qos_monitoring", // ... prebuilts: [ // ... "com.android.sdv.sample.oem.health.qos_monitoring.health_config", ], } prebuilt_etc { name: "com.android.sdv.sample.oem.health.qos_monitoring.health_config", src: "health_configuration.textproto", filename: "health.textproto", // ... // Reduce prebuilt visibility to avoid adding it in another APEX. visibility: ["//system/software_defined_vehicle/samples/health/qos_monitoring/apex"], }שומרים את הגדרות הבריאות ב-APEX ומגדירים את
health_config_pathבמניפסט:# sdv_service_bundles_manifest.textproto sdv_service_bundle_metadata { ... health_config_path: "etc/config/health_configuration.textproto" }בהגדרה של VSIDL, מוודאים שהחבילה היא מפרסם של
com.android.sdv.health.QosHeartbeat:sdv_service_bundle { name: "SampleBundle" publisher { message: "com.android.sdv.health.QosHeartbeat" topic: "qos-hb-right-fog-light-status" capacity: 2 } }מוסיפים הרשאות SDV לחבילה כדי שהחבילה תקבל הרשאה לפרסם פעימות לב של QoS:
publisher { message: "com.android.sdv.health.QosHeartbeat" topic: "qos-hb-right-fog-light-status" }רישום הפרסום של QoS HB רק כשהתקשורת המנוטרת רשומה. שימוש ב-Availability API מ-
libsdv_mw_clientlib:// Wait for monitored communication to be available let comms = SdvComms{context}; let registration_stream = create_registration_event_stream( &comms, SubscriberDescriptors::<QosMonitoredFogLightStatus>::LEFT_FOG_LIGHT_STATUS, ).await?; let mut registration_stream = Box::pin(registration_stream.filter(|e|e==Availability::Available)); registration_stream.next().await; // only when available, create QoS HB publication: let qos_hb_pub = create_publisher( &comms, PublisherDescriptors::<QosHeartbeat>::QOS_HB_LEFT_FOG_LIGHT_STATUS, ).await?; // ...פרסום של הודעות QoS HB בכל פעם שמתקבלת הודעה:
// ... use tap::Pipe; fn flatten_mw<T: Send>( s: impl Stream<Item = SdvResult<Vec<T>>> + Send + Unpin, ) -> impl Stream<Item = SdvResult<T>> + Send + Unpin { s.flat_map(|v| match v { Ok(v) => v.into_iter().map(Ok).pipe(stream::iter).left_stream(), Err(err) => Err(err).pipe(future::ready).pipe(stream::once).right_stream(), }) } { // ... let data_stream = create_observer( &comms, SubscriberDescriptors::<QosMonitoredFogLightStatus>::LEFT_FOG_LIGHT_STATUS, SubscribeOptions::default() ) .pipe(flatten_mw) .await?; while let Some(data) = data_stream.next().await { // publish QoS HB. Note how data.timestamp is used to populate the field qos_hb_pub.publish( &QosHeartbeat { timestamp: SystemTime::now(), data_timestamp: data.timestamp, ..Default::default() } ) // use data // ... } }כדי להפסיק את המעקב אחרי איכות השירות, משמיטים את אובייקט השותף:
// ... drop(qos_hb_pub);
ניפוי באגים במעקב אחר תקינות
למטרות ניפוי באגים וסקירה כללית של המערכת, אפשר להשתמש בכלי dumpsys כדי לעקוב אחרי מצב הבריאות של המכונה הווירטואלית:
adb shell dumpsys com.google.sdv.ISdvAgent/hm
בדוח מפורטים ההגדרות של דיווח על תקינות המכונה הווירטואלית, הגדרות החבילה ומצב המעקב. לפניכם דוגמה לדוח כזה:
AGENT NAME: SDV Agent dump - Health Monitor
AGENT FQIN: instance1:com.android.sdv.health.HealthMonitorServiceBundle/instance1
AGENT STATE: Started
----------------
----------------
INTERNAL STATE REPORTERS:
*NAME: VM health report period:
*REPORT:
100----------------
*NAME: Recovery monitor manager
*REPORT:
HEARTBEAT MONITORING:
NO ACTIVE MONITORS
QOS MONITORING:
NO ACTIVE MONITORS
RECOVERY MONITORING:
a. Agent monitoring:
MONITOR 0:
ID: Agent: sdv_vsidl_provider_agent
linked_binder: com.google.sdv.ISdvAgent/vsidl_provider
alive: true
MONITOR 1:
ID: Agent: sdv_someip_broker
linked_binder: com.google.sdv.ISdvAgent/someip_broker
alive: false
b. SB monitoring:
MONITOR 0:
ID: FQIN: instance1:com.android.sdv.test.orchestrator.OrchSampleInitialPowerState/sample-initial-power-state
Recovery State: Normal
Lifecycle State: Started
Health Status: Healthy
MONITOR 1:
ID: FQIN: instance1:com.android.sdv.sample.apex.provider.Provider/sample-provider-v1
Recovery State: Normal
Lifecycle State: Started
Health Status: Healthy
MONITOR 2:
ID: FQIN: instance1:com.sdv.google.display_safety.HarSdvVehicleDataPublisher/instance-1
Recovery State: Normal
Lifecycle State: Started
Health Status: Healthy
----------------
*NAME: Health monitor
*REPORT:
CURR TIMESTAMP(ns): 1775543863756836167
INTERNAL STATE:
background_thread running: true
should_run: true
----------------