使用 API 建立快訊政策

快訊政策在 Cloud Monitoring API 中以 AlertPolicy 物件表示,說明一組用來指出您系統中可能存在不良健康狀態的條件。

本文說明下列事項:

  • Monitoring API 如何表示快訊政策。
  • Monitoring API 為快訊政策提供的條件類型。
  • 如何使用 Google Cloud CLI 或用戶端程式庫建立快訊政策。

這項功能僅支援 Google Cloud 專案。 如要進行 App Hub 設定,請選取 App Hub 主專案或啟用應用程式的資料夾管理專案。

快訊政策的結構

AlertPolicy 結構會定義快訊政策的元件。建立政策時,請為下列 AlertPolicy 欄位指定值:

  • displayName:政策的描述性標籤。
  • documentation:建議您使用這個欄位提供有助於事件回應人員的資訊。詳情請參閱「使用使用者定義的註解標註通知」。
  • userLabels:附加至政策的任何使用者定義標籤。 快訊政策、事件和通知會顯示這些標籤。 如要瞭解如何搭配快訊使用標籤,請參閱使用標籤為事件加上註解

  • conditions[]Condition 結構的陣列。

  • combiner:邏輯運算子,用於決定如何處理多項條件。

  • notificationChannels[]:資源名稱陣列,每個名稱都代表一個 NotificationChannel

  • alertStrategy:指定下列項目:

    • 監控服務在資料停止傳送時,關閉事件的速度。
    • 如果是以指標為準的快訊政策,Monitoring 是否會在事件關閉時傳送通知。
    • 以指標為準的快訊政策是否啟用重複通知,以及通知間隔。詳情請參閱「設定以指標為基礎的快訊政策,重複傳送通知」。

使用 Cloud Monitoring API 和 Google Cloud 控制台時,您也可以指定 severity 欄位。這個欄位可讓您定義事件的嚴重程度。如果未指定嚴重性,Cloud Monitoring 會將警告政策嚴重性設為 No Severity

視您建立的條件而定,您可能會使用其他欄位。

如果警告政策只包含一個條件,系統會在符合該條件時傳送通知。如要瞭解快訊政策包含多個條件時的通知,請參閱「包含多個條件的政策」和「每項政策的通知數量」。

建立或修改警告政策時,Monitoring 也會設定其他欄位,包括 name 欄位。name 欄位的值是快訊政策的資源名稱,可識別政策。資源名稱的格式如下:

projects/PROJECT_ID/alertPolicies/POLICY_ID

在上述運算式中:

  • PROJECT_ID:專案的 ID。如要進行 App Hub 設定,請選取 App Hub 主專案或啟用應用程式的資料夾管理專案。
  • POLICY_ID:快訊政策的 ID

API 中的條件類型

Cloud Monitoring API 支援 Condition 結構中的各種條件類型。以指標為準的快訊政策有多種條件類型,以記錄為準的快訊政策則有一種。以下各節說明可用的條件類型。

以指標為準的快訊政策條件

如要建立監控指標資料 (包括記錄指標) 的快訊政策,可以使用下列類型的條件:

以篩選條件為依據的指標條件

MetricAbsenceMetricThreshold 條件會使用監控篩選器選取要監控的時間序列資料。條件結構中的其他欄位會指定如何篩選、分組及匯總資料。如要進一步瞭解這些概念,請參閱「篩選和彙整:操控時間序列」。

如果您使用 MetricAbsence 條件類型,則可以建立條件,只有在所有時間序列都不存在時才會符合條件。這個條件會使用 aggregations 參數,將多個時間序列匯總為單一時間序列。詳情請參閱 API 說明文件中的 MetricAbsence 參考資料。

以指標缺席為基礎的快訊政策必須先寫入部分資料,詳情請參閱「建立以指標缺席為基礎的快訊政策」。

如要根據預測值接收通知,請將快訊政策設為使用 MetricThreshold 條件類型,並設定 forecastOptions 欄位。如果未設定這個欄位,系統會將測量資料與門檻進行比較。不過,如果設定這個欄位,系統就會將預測資料與門檻進行比較。詳情請參閱「建立預估指標值快訊政策」。

以 MQL 為基礎的指標條件

MonitoringQueryLanguageCondition 條件會使用 Monitoring Query Language (MQL) 選取及操縱要監控的時間序列資料。您可以建立警報政策,根據門檻比較值,或使用這個條件類型測試值是否不存在。如果使用 MonitoringQueryLanguageCondition 條件,警告政策中就只能有這項條件。詳情請參閱「使用 MQL 的快訊政策」。

以 PromQL 為基礎的指標條件

PrometheusQueryLanguageCondition 條件會使用 Prometheus 查詢語言 (PromQL) 查詢,選取及操控要監控的時間序列資料。條件可以計算指標比率、評估指標比較結果等。

如果使用 PrometheusQueryLanguageCondition 條件,警告政策中就只能有這項條件。詳情請參閱「使用 PromQL 的快訊政策」。

根據比率發出快訊的條件

您可以建立指標閾值快訊政策,監控兩項指標的比率。您可以使用 MetricThresholdMonitoringQueryLanguageCondition 條件類型建立這些政策。您也可以直接在 Google Cloud 控制台中使用 MQL。您無法使用圖形介面建立或管理以比率為準的條件,也無法透過圖形介面建立門檻條件。

建議使用 MQL 建立以比率為基礎的快訊政策。 與使用 MetricTheshold 條件類型和監控篩選器建立的查詢相比,MQL 可讓您建構更強大且彈性的查詢。舉例來說,使用 MonitoringQueryLanguageCondition 條件,您可以計算計量表指標與 delta 指標的比率。如需範例,請參閱「MQL 快訊政策範例」。

如果您使用 MetricThreshold 條件,比率的分子和分母必須具有相同的 MetricKind。如需指標及其屬性的清單,請參閱「指標清單」。

一般來說,最好根據單一指標類型收集的時間序列,使用標籤值計算比率。如果比率是根據兩種不同的指標類型計算而得,由於取樣週期和對齊視窗不同,可能會出現異常。

舉例來說,假設您有兩種不同的指標類型:RPC 總計數和 RPC 錯誤計數,且您想計算 RPC 錯誤計數與 RPC 總計數的比率。這兩種指標類型都會將 RPC 失敗次數計入時間序列。因此,當您對齊時間序列時,RPC 失敗的事件可能不會出現在兩個時間序列的相同對齊間隔中。造成差異的原因有很多,包括:

  • 因為有兩個不同的時間序列記錄同一個事件,所以有兩個基礎計數器值實作集合,而且這些值不會以原子方式更新。
  • 取樣率可能有所不同。如果時間序列與共同週期對齊,單一事件的計數可能會出現在不同指標的時間序列中,相鄰的對齊間隔。

如果對應對齊間隔中的值數量不同,可能會導致 error/total 比率值不合理,例如 1/0 或 2/1。

較大數字的比率較不可能產生無意義的值。 您可以透過匯總取得較大的數字,方法是使用比取樣週期更長的對齊視窗,或是將特定標籤的資料分組。這些技術可將特定間隔內點數的微小差異影響降至最低。也就是說,如果預期間隔點數為 3,則 2 點的差異會比預期點數為 300 時更顯著。

如果您使用內建指標類型,可能就只能計算指標類型之間的比例,才能取得所需值。

如果您設計的自訂指標可能會在兩個不同指標中計算相同項目 (例如傳回錯誤狀態的 RPC),建議改用單一指標,這樣每個計數只會計算一次。舉例來說,假設您要計算 RPC,並追蹤不成功 RPC 與所有 RPC 的比率。如要解決這個問題,請建立單一指標類型來計算 RPC,並使用標籤記錄叫用狀態,包括「OK」狀態。接著,系統會更新該情況的單一計數器,記錄每個狀態值 (錯誤或「OK」)。

記錄型快訊政策的條件

如要建立記錄式快訊政策,在記錄項目中出現符合篩選器的訊息時通知您,請使用 LogMatch 條件類型。如果使用 LogMatch 條件,警告政策就只能有一個條件。

請勿嘗試將 LogMatch 條件類型與以記錄為準的指標搭配使用。監控記錄指標的快訊政策是以指標為準的政策。如要進一步瞭解如何選擇監控記錄指標或記錄項目的警告政策,請參閱「監控記錄」一文。

透過 API 管理快訊政策」一文範例中使用的快訊政策是以指標為準的快訊政策,但以記錄為準的快訊政策也適用相同原則。如要瞭解記錄檔快訊政策的相關資訊,請參閱 Cloud Logging 說明文件中的「使用 Monitoring API 建立記錄檔快訊政策」。

如何將快訊政策與 App Hub 應用程式建立關聯

Google Cloud 會產生資訊主頁,協助您監控 App Hub 應用程式。這些資訊主頁會顯示應用程式的記錄和指標資料,以及應用程式所含的服務和工作負載。如果警報政策與應用程式的服務或工作負載相關聯,這些資訊也會顯示在資訊主頁上。如要進一步瞭解 Application Monitoring,請參閱「查看應用程式遙測資料」。

如要將快訊政策與 App Hub 應用程式建立關聯,請將含有下列鍵的標籤附加至政策:

  • apphub_application_location
  • apphub_application_id
  • apphub_service_idapphub_workload_id
舉例來說,快訊政策的 JSON 表示法中的 userLabels 區段可能如下所示:

  "userLabels": {
    "apphub_service_id": "my-service-id",
    "apphub_application_location": "my-app-location",
    "apphub_application_id": "my-app"
  },

事前準備

在針對 API 編寫程式碼之前,您應該先:

  • 熟悉適用於快訊政策的一般概念與術語;詳情請參閱快訊總覽
  • 確保啟用 Cloud Monitoring API 以供使用;詳情請參閱啟用 API
  • 如果您打算使用用戶端程式庫,請針對您想使用的語言安裝程式庫;詳情請參閱用戶端程式庫。目前只為 C#、Go、Java、Node.js 與 Python 提供 API 快訊支援。
  • 如果您打算使用 Google Cloud CLI,請安裝該工具。 不過,如果您使用 Cloud Shell,系統會預先安裝 Google Cloud CLI。

    這裡還提供了使用 gcloud 介面的範例。 請注意,gcloud 範例都假設目前的專案已設為目標 (gcloud config set project [PROJECT_ID]),因此叫用會省略明確的 --project 標記。範例中目前專案的 ID 為 a-gcp-project。如要進行 App Hub 設定,請選取 App Hub 主專案或啟用應用程式的資料夾管理專案。

建立快訊政策

如要在專案中建立快訊政策,請使用 alertPolicies.create 方法。如要瞭解如何叫用這個方法、其參數和回應資料,請參閱alertPolicies.create參考頁面。

您可以利用 JSON 或 YAML 檔案建立政策,Google Cloud CLI 接受這些檔案做為引數。您可以透過程式讀取 JSON 檔案、將該檔案轉換為 AlertPolicy 物件,並透過 alertPolicies.create 方法來利用這些檔案建立政策。如果您有包含警告規則的 Prometheus JSON 或 YAML 設定檔,gcloud CLI 可以將其遷移至 Cloud Monitoring 警告政策,並加入 PromQL 條件。詳情請參閱「從 Prometheus 遷移快訊規則和接收者」。

每項快訊政策都屬於指標範圍的限定範圍專案。每個專案最多可包含 500 項政策。發出 API 呼叫時,您必須提供「專案 ID」,並使用指標範圍的範圍專案 ID 做為值。在這些範例中,指標範圍的範圍設定專案 ID 為 a-gcp-project

下列範例說明如何建立快訊政策,但未說明如何建立描述快訊政策的 JSON 或 YAML 檔案。不過,這些範例會假設有 JSON 格式的檔案,並說明如何發出 API 呼叫。如需 JSON 檔案範例,請參閱「範例政策」。如要瞭解如何監控指標比率,請參閱「指標比率」。

gcloud

如要在專案中建立快訊政策,請使用 gcloud alpha monitoring policies create 指令。下列範例會利用 rising-cpu-usage.json 檔案,在 a-gcp-project 中建立快訊政策:

gcloud alpha monitoring policies create --policy-from-file="rising-cpu-usage.json"

若成功,這個指令會傳回新政策的名稱,例如:

Created alert policy [projects/a-gcp-project/alertPolicies/12669073143329903307].

rising-cpu-usage.json 檔案包含顯示名稱為「High CPU rate of change」的政策 JSON。如要瞭解這項政策的詳細資料,請參閱「變更率政策」。

詳情請參閱 gcloud alpha monitoring policies create 參考資料。

C#

如要驗證 Monitoring,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

static void RestorePolicies(string projectId, string filePath)
{
    var policyClient = AlertPolicyServiceClient.Create();
    var channelClient = NotificationChannelServiceClient.Create();
    List<Exception> exceptions = new List<Exception>();
    var backup = JsonConvert.DeserializeObject<BackupRecord>(
        File.ReadAllText(filePath), new ProtoMessageConverter());
    var projectName = new ProjectName(projectId);
    bool isSameProject = projectId == backup.ProjectId;
    // When a channel is recreated, rather than updated, it will get
    // a new name.  We have to update the AlertPolicy with the new
    // name.  Track the names in this map.
    var channelNameMap = new Dictionary<string, string>();
    foreach (NotificationChannel channel in backup.Channels)
    {
    }
    foreach (AlertPolicy policy in backup.Policies)
    {
        string policyName = policy.Name;
        // These two fields cannot be set directly, so clear them.
        policy.CreationRecord = null;
        policy.MutationRecord = null;
        // Update channel names if the channel was recreated with
        // another name.
        for (int i = 0; i < policy.NotificationChannels.Count; ++i)
        {
            if (channelNameMap.ContainsKey(policy.NotificationChannels[i]))
            {
                policy.NotificationChannels[i] =
                    channelNameMap[policy.NotificationChannels[i]];
            }
        }
        try
        {
            Console.WriteLine("Updating policy.\n{0}",
                policy.DisplayName);
            bool updated = false;
            if (isSameProject)
                try
                {
                    policyClient.UpdateAlertPolicy(null, policy);
                    updated = true;
                }
                catch (Grpc.Core.RpcException e)
                when (e.Status.StatusCode == StatusCode.NotFound)
                { }
            if (!updated)
            {
                // The policy no longer exists.  Recreate it.
                policy.Name = null;
                foreach (var condition in policy.Conditions)
                {
                    condition.Name = null;
                }
                policyClient.CreateAlertPolicy(projectName, policy);
            }
            Console.WriteLine("Restored {0}.", policyName);
        }
        catch (Exception e)
        {
            // If one failed, continue trying to update the others.
            exceptions.Add(e);
        }
    }
    if (exceptions.Count > 0)
    {
        throw new AggregateException(exceptions);
    }
}

Go

如要驗證 Monitoring,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。


// restorePolicies updates the project with the alert policies and
// notification channels in r.
func restorePolicies(w io.Writer, projectID string, r io.Reader) error {
	b := backup{}
	if err := json.NewDecoder(r).Decode(&b); err != nil {
		return err
	}
	sameProject := projectID == b.ProjectID

	ctx := context.Background()

	alertClient, err := monitoring.NewAlertPolicyClient(ctx)
	if err != nil {
		return err
	}
	defer alertClient.Close()
	channelClient, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}
	defer channelClient.Close()

	// When a channel is recreated, rather than updated, it will get
	// a new name.  We have to update the AlertPolicy with the new
	// name.  channelNames keeps track of the new names.
	channelNames := make(map[string]string)
	for _, c := range b.Channels {
		fmt.Fprintf(w, "Updating channel %q\n", c.GetDisplayName())
		c.VerificationStatus = monitoringpb.NotificationChannel_VERIFICATION_STATUS_UNSPECIFIED
		updated := false
		if sameProject {
			req := &monitoringpb.UpdateNotificationChannelRequest{
				NotificationChannel: c.NotificationChannel,
			}
			_, err := channelClient.UpdateNotificationChannel(ctx, req)
			if err == nil {
				updated = true
			}
		}
		if !updated {
			req := &monitoringpb.CreateNotificationChannelRequest{
				Name:                "projects/" + projectID,
				NotificationChannel: c.NotificationChannel,
			}
			oldName := c.GetName()
			c.Name = ""
			newC, err := channelClient.CreateNotificationChannel(ctx, req)
			if err != nil {
				return err
			}
			channelNames[oldName] = newC.GetName()
		}
	}

	for _, policy := range b.AlertPolicies {
		fmt.Fprintf(w, "Updating alert %q\n", policy.GetDisplayName())
		policy.CreationRecord = nil
		policy.MutationRecord = nil
		for i, aChannel := range policy.GetNotificationChannels() {
			if c, ok := channelNames[aChannel]; ok {
				policy.NotificationChannels[i] = c
			}
		}
		updated := false
		if sameProject {
			req := &monitoringpb.UpdateAlertPolicyRequest{
				AlertPolicy: policy.AlertPolicy,
			}
			_, err := alertClient.UpdateAlertPolicy(ctx, req)
			if err == nil {
				updated = true
			}
		}
		if !updated {
			req := &monitoringpb.CreateAlertPolicyRequest{
				Name:        "projects/" + projectID,
				AlertPolicy: policy.AlertPolicy,
			}
			if _, err = alertClient.CreateAlertPolicy(ctx, req); err != nil {
				log.Fatal(err)
			}
		}
	}
	fmt.Fprintf(w, "Successfully restored alerts.")
	return nil
}

Java

如要驗證 Monitoring,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

private static void restoreRevisedPolicies(
    String projectId, boolean isSameProject, List<AlertPolicy> policies) throws IOException {
  try (AlertPolicyServiceClient client = AlertPolicyServiceClient.create()) {
    for (AlertPolicy policy : policies) {
      if (!isSameProject) {
        policy = client.createAlertPolicy(ProjectName.of(projectId), policy);
      } else {
        try {
          client.updateAlertPolicy(null, policy);
        } catch (Exception e) {
          policy =
              client.createAlertPolicy(
                  ProjectName.of(projectId), policy.toBuilder().clearName().build());
        }
      }
      System.out.println(String.format("Restored %s", policy.getName()));
    }
  }
}

Node.js

如要驗證 Monitoring,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

const fs = require('fs');

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.AlertPolicyServiceClient();

async function restorePolicies() {
  // Note: The policies are restored one at a time due to limitations in
  // the API. Otherwise, you may receive a 'service unavailable'  error
  // while trying to create multiple alerts simultaneously.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const projectId = 'YOUR_PROJECT_ID';

  console.log('Loading policies from ./policies_backup.json');
  const fileContent = fs.readFileSync('./policies_backup.json', 'utf-8');
  const policies = JSON.parse(fileContent);

  for (const index in policies) {
    // Restore each policy one at a time
    let policy = policies[index];
    if (await doesAlertPolicyExist(policy.name)) {
      policy = await client.updateAlertPolicy({
        alertPolicy: policy,
      });
    } else {
      // Clear away output-only fields
      delete policy.name;
      delete policy.creationRecord;
      delete policy.mutationRecord;
      policy.conditions.forEach(condition => delete condition.name);

      policy = await client.createAlertPolicy({
        name: client.projectPath(projectId),
        alertPolicy: policy,
      });
    }

    console.log(`Restored ${policy[0].name}.`);
  }
  async function doesAlertPolicyExist(name) {
    try {
      const [policy] = await client.getAlertPolicy({
        name,
      });
      return policy ? true : false;
    } catch (err) {
      if (err && err.code === 5) {
        // Error code 5 comes from the google.rpc.code.NOT_FOUND protobuf
        return false;
      }
      throw err;
    }
  }
}
restorePolicies();

PHP

如要驗證 Monitoring,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

use Google\Cloud\Monitoring\V3\AlertPolicy;
use Google\Cloud\Monitoring\V3\AlertPolicy\Condition;
use Google\Cloud\Monitoring\V3\AlertPolicy\Condition\MetricThreshold;
use Google\Cloud\Monitoring\V3\AlertPolicy\ConditionCombinerType;
use Google\Cloud\Monitoring\V3\Client\AlertPolicyServiceClient;
use Google\Cloud\Monitoring\V3\ComparisonType;
use Google\Cloud\Monitoring\V3\CreateAlertPolicyRequest;
use Google\Protobuf\Duration;

/**
 * @param string $projectId Your project ID
 */
function alert_create_policy($projectId)
{
    $alertClient = new AlertPolicyServiceClient([
        'projectId' => $projectId,
    ]);
    $projectName = 'projects/' . $projectId;

    $policy = new AlertPolicy();
    $policy->setDisplayName('Test Alert Policy');
    $policy->setCombiner(ConditionCombinerType::PBOR);
    /** @see https://cloud.google.com/monitoring/api/resources for a list of resource.type */
    /** @see https://cloud.google.com/monitoring/api/metrics_gcp for a list of metric.type */
    $policy->setConditions([new Condition([
        'display_name' => 'condition-1',
        'condition_threshold' => new MetricThreshold([
            'filter' => 'resource.type = "gce_instance" AND metric.type = "compute.googleapis.com/instance/cpu/utilization"',
            'duration' => new Duration(['seconds' => '60']),
            'comparison' => ComparisonType::COMPARISON_LT,
        ])
    ])]);
    $createAlertPolicyRequest = (new CreateAlertPolicyRequest())
        ->setName($projectName)
        ->setAlertPolicy($policy);

    $policy = $alertClient->createAlertPolicy($createAlertPolicyRequest);
    printf('Created alert policy %s' . PHP_EOL, $policy->getName());
}

Python

如要驗證 Monitoring,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

def restore(project_name, backup_filename):
    """Restore alert policies in a project.

    Arguments:
        project_name (str): The Google Cloud Project to use. The project name
            must be in the format - 'projects/<PROJECT_NAME>'.
        backup_filename (str): Name of the file (along with its path) from
            which the alert policies will be restored.
    """
    print(
        "Loading alert policies and notification channels from {}.".format(
            backup_filename
        )
    )
    record = json.load(open(backup_filename, "rt"))
    is_same_project = project_name == record["project_name"]
    # Convert dicts to AlertPolicies.
    policies_json = [json.dumps(policy) for policy in record["policies"]]
    policies = [
        monitoring_v3.AlertPolicy.from_json(policy_json)
        for policy_json in policies_json
    ]
    # Convert dicts to NotificationChannels
    channels_json = [json.dumps(channel) for channel in record["channels"]]
    channels = [
        monitoring_v3.NotificationChannel.from_json(channel_json)
        for channel_json in channels_json
    ]

    # Restore the channels.
    channel_client = monitoring_v3.NotificationChannelServiceClient()
    channel_name_map = {}

    for channel in channels:
        updated = False
        print("Updating channel", channel.display_name)
        # This field is immutable and it is illegal to specify a
        # non-default value (UNVERIFIED or VERIFIED) in the
        # Create() or Update() operations.
        channel.verification_status = (
            monitoring_v3.NotificationChannel.VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED
        )

        if is_same_project:
            try:
                channel_client.update_notification_channel(notification_channel=channel)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The channel was deleted.  Create it below.

        if not updated:
            # The channel no longer exists.  Recreate it.
            old_name = channel.name
            del channel.name
            new_channel = channel_client.create_notification_channel(
                name=project_name, notification_channel=channel
            )
            channel_name_map[old_name] = new_channel.name

    # Restore the alerts
    alert_client = monitoring_v3.AlertPolicyServiceClient()

    for policy in policies:
        print("Updating policy", policy.display_name)
        # These two fields cannot be set directly, so clear them.
        del policy.creation_record
        del policy.mutation_record

        # Update old channel names with new channel names.
        for i, channel in enumerate(policy.notification_channels):
            new_channel = channel_name_map.get(channel)
            if new_channel:
                policy.notification_channels[i] = new_channel

        updated = False

        if is_same_project:
            try:
                alert_client.update_alert_policy(alert_policy=policy)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The policy was deleted.  Create it below.
            except google.api_core.exceptions.InvalidArgument:
                # Annoying that API throws InvalidArgument when the policy
                # does not exist.  Seems like it should throw NotFound.
                pass  # The policy was deleted.  Create it below.

        if not updated:
            # The policy no longer exists.  Recreate it.
            old_name = policy.name
            del policy.name
            for condition in policy.conditions:
                del condition.name
            policy = alert_client.create_alert_policy(
                name=project_name, alert_policy=policy
            )
        print("Updated", policy.name)

建立的 AlertPolicy 物件將擁有其他欄位。 政策本身會包含 namecreationRecordmutationRecord 欄位。此外,政策中的每項條件也會標示 name。這些欄位無法從外部修改,因此建立政策時不必設定。用於建立政策的所有 JSON 範例都不包含這些欄位,但如果在利用這些欄位建立政策之後擷取政策,這些欄位會顯示出來。

為以指標為準的快訊政策設定重複通知

根據預設,以指標為準的快訊政策會在事件開啟時,向每個通知管道傳送一則通知。不過,您可以變更預設行為,並設定快訊政策,將通知重新傳送至快訊政策的所有或部分通知管道。如果事件狀態為「開啟」或「已確認」,系統就會重複傳送通知。這些通知之間的時間間隔必須至少 30 分鐘,且不得超過 24 小時,以秒為單位。

如要設定重複通知,請在快訊政策的設定中新增 AlertStrategy 物件,該物件至少包含一個 NotificationChannelStrategy 物件。NotificationChannelStrategy 物件有兩個欄位:

  • renotifyInterval:重複通知之間的時間間隔 (以秒為單位)。

    如果快訊政策的事件開啟時,您變更 renotifyInterval 欄位的值,則會發生下列情況:

    • 快訊政策會針對事件傳送另一則通知。
    • 快訊政策會重新啟動間隔週期。
  • notificationChannelNames:通知管道資源名稱陣列,格式為 projects/PROJECT_ID/notificationChannels/CHANNEL_ID 的字串,其中 CHANNEL_ID 是數值。如要瞭解如何擷取管道 ID,請參閱「列出專案中的通知管道」。

舉例來說,下列 JSON 範例顯示設定的快訊策略,每 1800 秒 (30 分鐘) 會將重複通知傳送至一個通知管道:

  "alertStrategy": {
    "notificationChannelStrategy": [
      {
        "notificationChannelNames": [
          "projects/PROJECT_ID/notificationChannels/CHANNEL_ID"
        ],
        "renotifyInterval": "1800s"
      }
    ]
  }

如要暫時停止接收重複通知,請建立延後。如要避免重複收到通知,請使用 API 編輯快訊政策,並移除 NotificationChannelStrategy 物件。

後續步驟