狀態監控

健康狀態監控 (HM) 是在每部虛擬機器 (VM) 上執行的 SDV 代理程式,可追蹤服務套件的狀態、判斷 VM 的健康狀態,並定期產生 VM 健康狀態報告。

OEM 定義的服務套裝組合必須監聽 HM 回報的各種健康信號,並根據資料執行復原動作。舉例來說,如果 SDV 執行個體發生服務套件當機問題,可能需要重新啟動或更新。

您可以設定 HM 代理程式追蹤下列項目:

  • 監控存活心跳信號,判斷執行週期性工作的實體是否仍存活。您可以為服務套件執行個體和自訂 OEM 代理程式設定這項監控功能。
    • 服務套件執行個體的復原狀態。在 SDV 2.0 中,您可以設定服務套裝組合,在當機時自動重新啟動。HM 會提供信號來監控這項復原程序。
    • 通訊 QoS
  • SDV 和 OEM 自訂代理的存續狀態

如需參考資料,請前往 //system/software_defined_vehicle/health_monitor/catalog/health_monitor.vsidl查看完整 VSIDL 目錄,包括 Proto 定義。

術語

本頁面會使用這些詞彙。

存活活動訊號 (HB)
服務套裝組合產生的訊息,表示服務套裝組合處於啟用狀態。訊息會顯示時間戳記,指出訊息的產生時間。詳情請參閱「發布存活心跳訊號」。

服務品質 (QoS) 心跳
SDV 支援多種 Pub/Sub 和遠端程序呼叫 (RPC) 通訊模型。正在監聽通訊的服務套件執行個體可以發布 QoS 心跳,讓 HM 代理程式偵測 QoS 違規事項。詳情請參閱「QoS 監控」。

服務組合復原監控
SDV 服務套件執行個體可設定為在當機時重新啟動。執行個體可能會成功復原,也可能復原失敗。HM 會追蹤服務套件執行個體的復原狀態,並在 VM 健康狀態報告中回報復原失敗情形。詳情請參閱「服務套裝組合復原監控」。

代理程式當機監控
與服務套裝組合執行個體不同,SDV 代理程式是系統正常運作的關鍵。這些程序無法設定復原功能,因此絕不應當機。HM 會監控 SDV 代理程式,並在 VM 健康狀態報告中回報當機情形。您可以監控自訂 OEM 代理程式。詳情請參閱「代理程式當機監控」。

虛擬機器健康狀態報告
HM 產生的訊息,指出 VM 的健康狀態。詳情請參閱「VM 健康狀態報告」。

使用 HM 子系統

如要使用 HM 功能,OEM 實作項目必須:

  • 如「設定健康狀態監控系統」一文所述,提供設定檔來設定健康狀態監控系統。
  • 使用 OEM 定義的 HM 監聽器服務套件,監聽 HM 輸出內容並採取適當行動。
  • 根據健康狀態設定,開發主動發布信號的服務套件。這份出版品可供 HM 評估健康狀態。詳情請參閱服務套裝組合開發人員指南

設定 HM 系統

任何與 HM 相關的設定都位於下列其中一種設定類型:

  • 全域或每個 VM 的健康狀態設定
  • 每個服務套件的健康狀態設定,定義套件所有執行個體的健康狀態參數

每個 VM 的健康狀態設定

在執行階段,HM 代理程式會預期 VM 範圍的健康狀態設定:這是 VMHealth 類型的 textproto 檔案 (副檔名為 .textproto),定義於 //system/software_defined_vehicle/health_monitor/catalog/health_monitoring_config.proto。VM 健康狀態設定應位於使用開機時間系統屬性 androidboot.sdv.health_monitor.config_path 指定的路徑。或者,您也可以將 persist.sdv.health_monitor.config_path 系統屬性設為自訂路徑,在執行階段動態設定此屬性。persist.* 設定的優先順序高於 androidboot.* 設定。您必須重新啟動裝置,新設定才會生效。

您可以透過 VM 健康狀態設定,設定下列項目:

  • 透過 period_ms 產生 VM 健康狀態報告的頻率。設定這個值時,必須在「更快發出訊號,表示偵測到健康狀態違規事項」和「HM 子系統效能」之間取捨。建議值為 100 毫秒。

  • 要監控哪些代理程式的當機情形 (請參閱「代理程式當機監控」)。

設定檔範例位於 //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 代理程式已設定為監控當機情形,且 VM 健康狀態報告的發布頻率設為每 100 毫秒一次。

每個服務套裝組合的設定

您可以選擇是否監控服務套件執行個體的健康狀態。如要啟用這項功能,請將健康狀態設定檔儲存在服務套件的 APEX 中,並在 sdv_service_bundles_manifest.textprotosdv_service_bundle_metadata 欄位中定義該檔案的路徑 health_config_path。如要進一步瞭解服務套件資訊清單,請參閱「服務套件中繼資料」。

健康狀態設定檔是下列類型的 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;
}

如要進一步瞭解各項功能的設定,請參閱「Aliveness 心跳監控」和「QoS 監控」。

聆聽 HM 輸出內容

您可以透過週期性報表或 RPC API 監聽 HM。

虛擬機器健康狀態報告

健康狀態監控功能會定期產生高頻率的 VM 健康狀態報告,提供受監控實體的健康狀態簡要資訊。

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;
}

OEM 定義的 HM 監聽器服務套件應監聽 VMHealth 報告,並根據完整的系統架構採取適當行動。可採取的行動包括:

  • 在 VM 上執行診斷常式。
  • 重新啟動 VM。
  • 執行遙測廣告活動,找出原因。
  • 如果系統發生故障,請更新系統或停止更新。

HM RPC API

VM 健康狀態報告是經過最佳化的發布內容,可提高頻率和傳輸速度,並提供系統健康狀態的廣泛資訊。

健康監控 RPC API 可讓健康監控接聽程式取得健康違規來源的詳細資訊。介面是在 //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 會預期執行個體發布週期性心跳,證明業務邏輯運作正常。這項監控功能最適合執行週期性工作的服務套裝組合例項。此外,使用非同步執行階段的套件可以透過存活狀態監控,證明執行緒集區並未耗盡。

HM 存活狀態監控流程

圖 1. HM 存活狀態監控流程。

設定

如要在服務套件執行個體上啟用存活 HB,請在套件設定health_config 欄位中新增 HealthConfiguration 的執行個體。

存活心跳設定會定義一組預先決定的參數,建立評估服務週期性心跳信號的條件。如果服務心跳的特徵偏離這些參數,心跳就會歸類為延遲,對應的服務套裝組合也會歸類為不正常,這可能表示運作狀態不佳。

如果服務套件根據健康狀態設定及時回報心跳,即視為健康狀態良好。如果發生當機或系統負載過高的情況,心跳可能會遺失或延遲,導致服務套件標示為不正常。在這種情況下,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 常式後,立即發布 HB。建議將 on_start 保持在較短的時間,以免阻礙系統啟動,因此請在 on_start 中啟動的非同步工作中發布心跳訊號。

套件開發人員可以使用 initial_delay_ms 設定項目,自訂預期第一次心跳的時間。

在停止前,套件執行個體應會持續發布心跳訊號。執行個體的 on_stop 常式完成後,即視為已停止。

特殊用途:明確註冊心跳監控

存活心跳監控中描述的行為 (心跳應介於 on_starton_stop 之間),稱為「隱含存活監控」。建議您採用這種方式使用這項功能,因為這樣可以簡化套件的商業邏輯,並確保系統一律會監控套件。

不過,在某些情況下,預設監控週期可能會受到限制:

  • 服務套件例項包含時間間隔內的週期性商業邏輯,與 startstop 事件無關。只有在這個自訂期間,可能才需要存活監控。
  • HM 會在暫停和恢復期間準確追蹤 HB。因此,套裝組合可能想在 on_stop 後繼續受到監控。
  • 自訂 OEM 代理程式可能不會以服務套件的形式實作。因此無法從隱含存活監控機制獲益。不過,這些程序可能仍需要存活監控。

在這些情況下,HM 可讓您略過隱含註冊,改為明確註冊,以監控存活狀態。如要使用明確註冊,套件執行個體必須選擇不使用隱含註冊,方法是在套件的資訊清單中,不為特定執行個體加入 HealthConfiguration 類型的項目。然後,在執行階段,套件例項應使用 //system/software_defined_vehicle/health_monitor/catalog/health_monitor_registration_service.proto 中定義的 RPC API,手動註冊及取消註冊監控。註冊 RPC 呼叫成功後,系統應會立即發布心跳信號。

如需實作範例,請參閱 //system/software_defined_vehicle/samples/health/stable/health_monitored_service_bundle/

服務品質監控

服務品質 (QoS) 是通訊的衡量標準,HM 會監控傳送的訊息是否花費過多時間傳輸,或在定期通訊的情況下,訊息是否未以所選頻率接收。

SDV 提供多種 Pub/Sub 和 RPC 通訊方式。共同點是所有通訊架構都至少包含一個接聽程式。為讓 HM 監控通訊,這個監聽服務套件執行個體必須在收到感興趣的訊息時,發布特殊的 QoS 心跳訊號。

設定

如要啟用通訊的 QoS 監控功能,請先找出會發布 QoS 心跳的通訊接聽程式。然後,針對已識別的服務套件例項,在 qos_config 欄位中,將一或多個主題新增至 QosMonitoringConfiguration 對應。詳情請參閱「每個服務的套件設定」。

topic 是定義發布主題的字串,HM 預期在執行階段會收到 QoS HB。一個接聽套裝組合執行個體可參與多項通訊,並回報多個主題的 QoS HB。

主題應具描述性,因為如果在執行階段偵測到 QoS 違規情形,系統會將主題回報給 HM 監聽器 服務套裝組合。

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 是 VM 內 Pub/Sub 通訊的合理值。30

執行階段注意事項

與存活 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 HB。當受監控的通訊向 SDV 通訊堆疊註冊時,訊息監聽套件應註冊 QoS HB 發布項目。HM 可以使用供應情形 API 執行這項操作。詳情請參閱「判斷服務可用性」。

服務套裝組合復原監控

服務套件執行個體的復原作業是在編排代理程式設定檔中設定。如要完整瞭解這個主題,請參閱「服務組合」。HM 子系統會被動觀察復原程序。如果系統偵測到無法復原的套件執行個體,就會在 VMHealth 報表中新增違規事項。與其他 HM 監控功能不同,復原監控為必要功能,無法設定。

如果服務套件執行個體未設定為復原,首次當機時會產生健康狀態違規。

服務套裝組合執行個體復原功能旨在整合心跳存活監控機制。如果 HM 系統偵測到套件正在復原,評估心跳時會較為寬鬆。在實務上,這項寬容措施表示服務套件當機時,不需要採取任何額外的監控取消註冊或註冊步驟。

代理程式當機監控

HM 會使用繫結器 linkToDeath 機制偵測 SDV 代理程式是否可能當機。

您可以設定當做 VM 健康狀態設定一部分的當機監控 (請參閱「每個 SDV 執行個體 (VM) 的設定」),具體來說是 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 權限,監聽適當的繫結器介面。

系統屬性 ro.boot.sdv.health_monitor.agent_startup_timeout_sec 可以覆寫 HM 啟動後,HM 等待代理程式註冊繫結器介面的時間長度。除非自訂代理程式有相關規定,否則預設值 (3 秒) 即可。

服務套裝組合開發指南

本節提供逐步指南,說明如何使用服務套裝組合中的 HM 功能,與前幾節的理論處理方式形成對比。這些指南所依據的最新參考範本是 qos_monitoring 範本。請按照範例操作,體驗實際情況。//system/software_defined_vehicle/samples/health/stable/qos_monitoring/README

在服務套件中新增存活心跳監控

這是為服務套裝組合啟用健康狀態監控功能最直接的方法:

  1. 在名為 health_configuration.textproto 的檔案中,為套件執行個體定義 ServiceBundleHealthConfiguration 的執行個體:

    # 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 { ... }
    
      }
    }
    
  2. 將設定檔新增至服務套件 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"],
    }
    
    
  3. 將健康狀態設定儲存在 APEX 中,並在資訊清單中設定 health_config_path

    # sdv_service_bundles_manifest.textproto
    sdv_service_bundle_metadata {
      ...
      health_config_path: "etc/config/health_configuration.textproto"
    }
    
  4. 在 VSIDL 定義中,確認套件發布 com.android.sdv.health.ServiceHeartbeat

    sdv_service_bundle {
      name: "SampleBundle"
      publisher {
        message: "com.android.sdv.health.ServiceHeartbeat"
        topic: "arbitrary-topic"
        capacity: 2
      }
    }
    
  5. 將 SDV 權限新增至套件,授權套件發布 HB:

      publisher {
        type: "com.android.sdv.health.ServiceHeartbeat"
      }
    
  6. 在程式碼中定期發布服務心跳訊號,從 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()
        })?;
      }
    }
    

特殊用途:明確註冊

如果是更特殊的使用案例,需要針對自訂生命週期監控套件的 HB (例如監控開始時間較早或結束時間較晚,而非標準 STARTED 狀態),則可以使用明確的註冊方法:

  1. 在 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"
      }
    }
    
  2. 新增 SDV 權限,以使用存活 HB 註冊 RPC:

      # ...
      client {
        service: "com.android.sdv.health.HealthMonitorRegistrationService"
        channel: "com-android-sdv-health-health-monitor-registration-service"
      }
    
  3. 透過 RPC 向 HM 註冊,例如在 on_startnew 中:

    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();
    
  4. 發布 HB。

  5. 不再需要監控時,請取消註冊:

    let _ = rpc_client
      .UnregisterConfiguration(&UnregisterConfigurationRequest { ..Default::default() })
      .await
      .unwrap();
    

在通訊中新增 QoS 監控功能

  1. 確認服務套件執行個體是 VSIDL 目錄中名為 fog-light-status 的主題訂閱者:

      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;
    }
    
  2. 在包含 QoS 監控的 health_configuration.textproto 檔案中,為套件例項定義 ServiceBundleHealthConfiguration 例項:

    # 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 HB 會發布在這個主題上,因此可以監控名為 fog-light-status 的主題。

  3. 將設定檔新增至服務套件 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"],
    }
    
  4. 將健康狀態設定儲存在 APEX 中,並在資訊清單中設定 health_config_path

    # sdv_service_bundles_manifest.textproto
    sdv_service_bundle_metadata {
      ...
      health_config_path: "etc/config/health_configuration.textproto"
    }
    
  5. 在 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
      }
    }
    
  6. 將 SDV 權限新增至套件,授權套件發布 QoS HB:

    publisher { message: "com.android.sdv.health.QosHeartbeat" topic: "qos-hb-right-fog-light-status" }
    
  7. 只有在註冊受監控的通訊時,才註冊 QoS HB 發布。使用 libsdv_mw_clientlib 的供應情形 API:

    // 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?;
    
    // ...
    
  8. 每次收到訊息時發布 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
        // ...
      }
    }
    
  9. 如要停止 QoS 監控,請捨棄發布商物件:

    // ...
    drop(qos_hb_pub);
    

偵錯健康狀態監控

如要進行偵錯和系統總覽,請使用 dumpsys 工具監控 VM 健康狀態監控狀態:

adb shell dumpsys com.google.sdv.ISdvAgent/hm

這份報表會詳細列出 VM 健康狀態回報設定、套件組合設定和監控狀態。這類報表的範例如下:

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

----------------