API를 통한 알림 채널 관리

알림 정책에는 일반적으로 트리거 시기를 알려주는 몇 가지 방법이 있는데 이 같은 방법을 알림 채널이라고 부릅니다. 채널 유형에는 여러 가지가 있으며 각 유형은 알림 채널 설명자를 통해 설명됩니다. 일정 유형의 알림 채널은 해당 유형의 설명자 인스턴스입니다. 알림 정책에는 알림 경로로 사용되는 알림 채널에 대한 참조가 포함됩니다.

알림 정책에서 사용하려면 먼저 알림 채널이 존재해야 합니다. 알림 채널 설명자가 제공되지만 사용하기 전에 채널을 만들어야 합니다.

여기에는 예: 백업 및 복원에서 설명한 알림 정책 API 예에서 추출한 코드 샘플이 사용되었습니다.

채널 설명자

Stackdriver에서는 여러 개의 기본 제공 알림 채널 유형을 제공합니다. 각 유형은 NotificationChannelDescriptor를 통해 설명됩니다. 이 설명자에는 type 필드가 있으며 채널 유형의 인스턴스를 만들 때 이 필드의 값이 식별자로 기능합니다. 다음 명령어를 사용하여 사용 가능한 채널 유형을 검색할 수 있습니다(자세한 설명은 알림 옵션 참조).

$ gcloud alpha monitoring channel-descriptors list --format='value(type)'
email
hipchat
pagerduty
slack
sms
webhook_basicauth
webhook_tokenauth

한 프로젝트의 모든 채널 설명자를 검색하려면 notificationChannelDescriptors.list 메소드를 사용합니다. 검색된 설명자는 읽기 전용입니다.

특정 설명자를 찾고 있는 경우 이름을 알면 notificationChannelDescriptors.get 메소드를 사용해 해당 채널 설명자만 검색할 수 있습니다. 채널 설명자의 이름은 projects/[PROJECT_ID]/notificationChannelDescriptors/[CHANNEL_TYPE]과 같은 형식을 사용하며 [CHANNEL_TYPE]은 위에 나온 유형 중 하나여야 합니다. 예를 들면 다음과 같습니다.

projects/a-gcp-project/notificationChannelDescriptors/email

gcloud 명령어

한 프로젝트의 모든 알림 채널 설명자를 나열하려면 gcloud alpha monitoring channel-descriptors list 명령어를 사용합니다.

gcloud alpha monitoring channel-descriptors list

성공하면 list 명령어가 특정 프로젝트의 모든 채널 설명자가 포함된 목록을 제공합니다. 예를 들어 email 채널 설명자는 다음과 같은 목록에 표시됩니다.

---
description: A channel that sends notifications via email.
displayName: Email
labels:
- description: An address to send email.
  key: email_address
name: projects/a-gcp-project/notificationChannelDescriptors/email
type: email
---

단일 채널 설명자를 나열하려면 gcloud alpha monitoring channel-descriptors describe을 대신 사용하고 채널 설명자의 이름을 지정합니다. 예를 들어 이 명령어로는 위의 목록만 반환됩니다.

gcloud alpha monitoring channel-descriptors describe projects/a-gcp-project/notificationChannelDescriptors/email

자세한 내용은 gcloud alpha monitoring channel-descriptors listdescribe 참조를 확인하세요. describe 명령어는 API의 notificationChannelDescriptors.get 메소드에 해당합니다.

알림 채널

알림 채널은 채널 설명자에서 다룬 알림 채널 설명자의 인스턴스입니다.

NotificationChannel 리소스에서 다음과 같은 5개 작업을 지원합니다.

  • 새 채널 만들기
  • 기존 채널 삭제
  • 특정 채널 검색
  • 모든 채널 검색
  • 기존 채널 수정

채널의 verificationStatus 필드 관리와 관련된 3개 작업도 가능합니다.

  • 인증 코드 전송
  • 확인된 채널의 인증 상태를 동일 또는 새 프로젝트의 동일한 다른 채널에 복사하는 코드 생성
  • 이전 두 작업으로 만든 코드를 사용한 채널 확인

자세한 내용은 notificationChannels 참조를 확인하세요.

채널 만들기

gcloud 명령줄 유틸리티를 사용해 프로그래매틱 방식으로 JSON 또는 YAML 파일에서 알림 채널을 만들 수 있습니다.

알림 채널을 만들려면 해당 설명자의 필드에 값을 제공해야 합니다. type과 같은 이러한 값은 대부분 모든 알림 채널 설명자에 일반적입니다. notificationChannelDescriptors를 참조하세요.

각 설명자에는 일련의 라벨이 있으며, 이는 설명자별로 다릅니다. 특정 설명자의 라벨 집합을 보려면 채널 설명자에 설명된 gcloud alpha monitoring channel-descriptors describe 명령어를 사용하여 설명자를 검색하세요. 예를 들어 email 채널 설명자를 검색하면 단일 라벨이 표시됩니다.

labels:
- description: An address to send email.
  key: email_address

webhook_basicauth 채널 설명자를 검색하면 몇 가지 라벨이 표시됩니다.

labels:
- description: The password. The field is obfuscated when the channel is fetched.
  key: password
- description: The URL to which to publish the webhook.
  key: url
- description: The username.
  key: username

새 채널을 만들 때 프로그래매틱 방식을 사용하든, 명령줄을 사용하든, 해당 사양의 type 값은 해당하는 알림 채널 설명자의 type 필드와 일치해야 합니다. 모든 필수 라벨 키도 채널 설명자의 값과 일치해야 합니다.

일부 라벨은 공급자에 인증하는 데 사용되는 사용자 인증 정보에 해당합니다. 채널을 만들 때 공급자로부터 이러한 라벨의 값을 받아야 합니다. 사용자 인증 정보를 받으려면 공급자의 웹사이트에 있는 API 키 생성 페이지를 사용하거나 공급자와 관련된 OAuth 로그인 흐름을 완료하면 됩니다. 이러한 사용자 인증 정보를 받는 방법에 대한 세부정보는 공급자에 따라 다릅니다.

예를 들어 다음은 JSON 형식의 새 email 알림 채널 사양을 보여줍니다.

{
  "type": "email",
  "displayName": "test e-mail channel",
  "description": "E-mail channel created by gcloud as a test",
  "labels": {
    "email_address": "user@example.com"
  },
  "enabled": false
}

type 값(email)과 단일 라벨 키(email_address)는 해당하는 채널 설명자의 typelabels.key 필드와 일치합니다.

다음 예에서는 알림 채널의 생성을 보여줍니다.

gcloud 명령어

프로젝트에서 알림 채널을 만들려면 gcloud alpha monitoring channels create 명령어를 사용하세요. 파일을 통해 채널을 로드하려면 --channel-content-from-file 플래그를 사용해 파일을 지정합니다.

다음 예에서는 new-email-channel.json 파일로 a-gcp-project의 새 이메일 채널을 만듭니다.

gcloud alpha monitoring channels create --channel-content-from-file="new-email-channel.json"

성공하면 이 명령어가 새 채널의 이름을 반환합니다. 예를 들면 다음과 같습니다.

Created notification channel [projects/a-gcp-project/notificationChannels/1355376463305411567].

자세한 내용은 gcloud alpha monitoring channels create 참조를 확인하세요.

C#

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)
    {
        try
        {
            bool updated = false;
            Console.WriteLine("Updating channel.\n{0}",
                channel.DisplayName);
            // This field is immutable and it is illegal to specify a
            // non-default value (UNVERIFIED or VERIFIED) in the
            // Create() or Update() operations.
            channel.VerificationStatus = NotificationChannel.Types
                .VerificationStatus.Unspecified;
            if (isSameProject)
                try
                {
                    channelClient.UpdateNotificationChannel(
                        null, channel);
                    updated = true;
                }
                catch (Grpc.Core.RpcException e)
                when (e.Status.StatusCode == StatusCode.NotFound)
                { }
            if (!updated)
            {
                // The channel no longer exists.  Recreate it.
                string oldName = channel.Name;
                channel.Name = null;
                var response = channelClient.CreateNotificationChannel(
                    projectName, channel);
                channelNameMap.Add(oldName, response.Name);
            }
        }
        catch (Exception e)
        {
            // If one failed, continue trying to update the others.
            exceptions.Add(e);
        }
    }
    foreach (AlertPolicy policy in backup.Policies)
    {
    }
    if (exceptions.Count > 0)
    {
        throw new AggregateException(exceptions);
    }
}

Node.js

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

// Creates clients
const alertClient = new monitoring.AlertPolicyServiceClient();
const notificationClient = new monitoring.NotificationChannelServiceClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const alertPolicyId = '123456789012314';
// const channelIds = [
//   'channel-1',
//   'channel-2',
//   'channel-3',
// ];

const notificationChannels = channelIds.map(id =>
  notificationClient.notificationChannelPath(projectId, id)
);

for (const channel of notificationChannels) {
  const updateChannelRequest = {
    updateMask: {paths: ['enabled']},
    notificationChannel: {
      name: channel,
      enabled: {value: true},
    },
  };
  try {
    await notificationClient.updateNotificationChannel(updateChannelRequest);
  } catch (err) {
    const createChannelRequest = {
      notificationChannel: {
        name: channel,
        notificationChannel: {type: 'email'},
      },
    };
    const newChannel = await notificationClient.createNotificationChannel(
      createChannelRequest
    );
    notificationChannels.push(newChannel);
  }
}

const updateAlertPolicyRequest = {
  updateMask: {paths: ['notification_channels']},
  alertPolicy: {
    name: alertClient.alertPolicyPath(projectId, alertPolicyId),
    notificationChannels: notificationChannels,
  },
};
const [alertPolicy] = await alertClient.updateAlertPolicy(
  updateAlertPolicyRequest
);
console.log(`Updated ${alertPolicy.name}.`);

Go

// 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
	}
	channelClient, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}

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

자바

private static Map<String, String> restoreNotificationChannels(
    String projectId,
    List<NotificationChannel> channels,
    boolean isSameProject) throws IOException {
  Map<String, String> newChannelNames = Maps.newHashMap();
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    for (NotificationChannel channel : channels) {
      // Update channel name if project ID is different.
      boolean channelUpdated = false;
      if (isSameProject) {
        try {
          NotificationChannel updatedChannel =
              client.updateNotificationChannel(NOTIFICATION_CHANNEL_UPDATE_MASK, channel);
          newChannelNames.put(channel.getName(), updatedChannel.getName());
          channelUpdated = true;
        } catch (Exception e) {
          channelUpdated = false;
        }
      }
      if (!channelUpdated) {
        NotificationChannel newChannel = client.createNotificationChannel(
            ProjectName.of(projectId),
            channel
                .toBuilder()
                .clearName()
                .clearVerificationStatus()
                .build());
        newChannelNames.put(channel.getName(), newChannel.getName());
      }
    }
  }
  return newChannelNames;
}

PHP

use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;
use Google\Cloud\Monitoring\V3\NotificationChannel;

/**
 * @param string $projectId Your project ID
 */
function alert_create_channel($projectId)
{
    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);
    $projectName = $channelClient->projectName($projectId);

    $channel = new NotificationChannel();
    $channel->setDisplayName('Test Notification Channel');
    $channel->setType('email');
    $channel->setLabels(['email_address' => 'fake@example.com']);

    $channel = $channelClient->createNotificationChannel($projectName, $channel);
    printf('Created notification channel %s' . PHP_EOL, $channel->getName());
}

Python

def restore(project_name):
    print('Loading alert policies and notification channels from backup.json.')
    record = json.load(open('backup.json', 'rt'))
    is_same_project = project_name == record['project_name']
    # Convert dicts to AlertPolicies.
    policies_json = [json.dumps(policy) for policy in record['policies']]
    policies = [google.protobuf.json_format.Parse(
        policy_json, monitoring_v3.types.alert_pb2.AlertPolicy())
        for policy_json in policies_json]
    # Convert dicts to NotificationChannels
    channels_json = [json.dumps(channel) for channel in record['channels']]
    channels = [google.protobuf.json_format.Parse(
        channel_json, monitoring_v3.types.notification_pb2.
        NotificationChannel()) 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.enums.NotificationChannel.\
            VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED

        if is_same_project:
            try:
                channel_client.update_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
            channel.ClearField("name")
            new_channel = channel_client.create_notification_channel(
                project_name, 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.
        policy.ClearField('creation_record')
        policy.ClearField('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(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
            policy.ClearField("name")
            for condition in policy.conditions:
                condition.ClearField("name")
            policy = alert_client.create_alert_policy(project_name, policy)
        print('Updated', policy.name)

채널 검색

한 채널의 모든 알림 채널을 검색하려면 notificationChannels.list 메소드를 사용합니다. 또한 이 메소드는 결과를 제한하고 정렬하는 filterorderBy 옵션을 지원합니다. 자세한 내용은 정렬 및 필터링하기를 참조하세요.

특정 채널을 찾고 있는 경우 이름을 알면 notificationChannels.get 메소드를 사용해 해당 채널만 검색할 수 있습니다. 채널의 이름은 projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]와 같은 형식을 사용합니다. 예를 들면 다음과 같습니다.

projects/a-gcp-project/notificationChannels/1355376463305411567

채널을 검색할 때 인증 토큰 및 API 키와 같은 중요한 값이 보안상의 이유로 난독화될 수 있습니다. 기존 채널을 복사하여 새로운 채널을 생성하는 경우 난독화된 값을 수정해야 합니다.

gcloud 명령어

한 프로젝트의 모든 알림 채널을 나열하려면 gcloud alpha monitoring channels list 명령어를 사용합니다.

gcloud alpha monitoring channels list

성공하면 list 명령어가 특정 프로젝트의 모든 채널이 포함된 목록을 제공합니다. 예를 들어 위의 명령어로는 다음과 같은 목록이 결과로 반환됩니다.

---
description: E-mail channel created by gcloud as a test
displayName: test e-mail channel
enabled: false
labels:
  email_address: user@example.com
name: projects/a-gcp-project/notificationChannels/1355376463305411567
type: email
---

단일 채널을 나열하려면 gcloud alpha monitoring channels describe을 대신 사용하고 채널 이름을 지정합니다. 예를 들어 이 명령어로는 위의 목록만 반환됩니다.

gcloud alpha monitoring channels describe projects/a-gcp-project/notificationChannels/1355376463305411567

자세한 내용은 gcloud alpha monitoring channels listdescribe 참조를 확인하세요. describe 명령어는 API의 notificationChannels.get 메소드에 해당합니다.

C#

static void ListNotificationChannels(string projectId)
{
    var client = NotificationChannelServiceClient.Create();
    var response = client.ListNotificationChannels(new ProjectName(projectId));
    foreach (NotificationChannel channel in response)
    {
        Console.WriteLine(channel.Name);
        if (channel.DisplayName != null)
        {
            Console.WriteLine(channel.DisplayName);
        }
        Console.WriteLine();
    }
}

Node.js

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

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

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const filter = 'A filter for selecting policies, e.g. description:"cloud"';

const request = {name: client.projectPath(projectId), filter};
const channels = await client.listNotificationChannels(request);
console.log(channels);
for (const channel of channels[0]) {
  console.log(`Deleting channel ${channel.displayName}`);
  try {
    await client.deleteNotificationChannel({
      name: channel.name,
    });
  } catch (err) {
    // ignore error
  }
}

Go

channelClient, err := monitoring.NewNotificationChannelClient(ctx)
if err != nil {
	return err
}
channelReq := &monitoringpb.ListNotificationChannelsRequest{
	Name: "projects/" + projectID,
	// Filter:  "", // See https://cloud.google.com/monitoring/api/v3/sorting-and-filtering.
	// OrderBy: "", // See https://cloud.google.com/monitoring/api/v3/sorting-and-filtering.
}
channelIt := channelClient.ListNotificationChannels(ctx, channelReq)
for {
	resp, err := channelIt.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	b.Channels = append(b.Channels, &channel{resp})
}

자바

private static List<NotificationChannel> getNotificationChannels(String projectId)
    throws IOException {
  List<NotificationChannel> notificationChannels = Lists.newArrayList();
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    ListNotificationChannelsPagedResponse listNotificationChannelsResponse =
        client.listNotificationChannels(ProjectName.of(projectId));
    for (NotificationChannel channel : listNotificationChannelsResponse.iterateAll()) {
      notificationChannels.add(channel);
    }
  }
  return notificationChannels;
}

PHP

use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;

/**
 * @param string $projectId Your project ID
 */
function alert_list_channels($projectId)
{
    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);

    $channels = $channelClient->listNotificationChannels(
        $channelClient->projectName($projectId)
    );
    foreach ($channels->iterateAllElements() as $channel) {
        printf('Name: %s (%s)' . PHP_EOL, $channel->getDisplayName(), $channel->getName());
    }
}

Python

def list_notification_channels(project_name):
    client = monitoring_v3.NotificationChannelServiceClient()
    channels = client.list_notification_channels(project_name)
    print(tabulate.tabulate(
        [(channel.name, channel.display_name) for channel in channels],
        ('name', 'display_name')))

채널 삭제

프로젝트의 알림 채널을 삭제하려면 notificationChannels.delete 메소드를 사용하고 삭제할 알림 채널의 이름을 제공합니다. NotificationChannel 인스턴스의 displayName이 아니라 name 필드의 값이 채널의 이름입니다. 채널의 이름은 projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]와 같은 형식을 사용합니다. 예를 들면 다음과 같습니다.

projects/a-gcp-project/notificationChannels/1355376463305411567

기본적으로 알림 정책에서 참조하는 채널을 삭제하려고 하면 채널이 삭제되지 않습니다. 알림 정책의 참조를 강제로 삭제하고 채널을 삭제하려면 force 옵션을 true로 설정합니다.

gcloud 명령어

알림 채널을 삭제하려면 gcloud alpha monitoring channels delete를 사용하고 삭제할 채널의 이름을 지정합니다. 예를 들어 다음 명령어는 다른 예에서 만든 email 채널을 삭제합니다.

gcloud alpha monitoring channels delete projects/a-gcp-project/notificationChannels/1355376463305411567

자세한 내용은 gcloud alpha monitoring channels delete 참조를 확인하세요.

C#

using Google.Cloud.Monitoring.V3;
using System;

partial class AlertSnippets
{
    public void DeleteNotificationChannel(
        string channelName = "projects/your-project-id/notificationChannels/123")
    {
        var client = NotificationChannelServiceClient.Create();
        client.DeleteNotificationChannel(
            name: NotificationChannelName.Parse(channelName),
            force: true);
        Console.WriteLine("Deleted {0}.", channelName);
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	monitoring "cloud.google.com/go/monitoring/apiv3"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

// deleteChannel deletes the given channel. channelName should be of the form
// "projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]".
func deleteChannel(w io.Writer, channelName string) error {
	ctx := context.Background()

	client, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}

	req := &monitoringpb.DeleteNotificationChannelRequest{
		Name: channelName,
	}

	if err := client.DeleteNotificationChannel(ctx, req); err != nil {
		return fmt.Errorf("DeleteNotificationChannel: %v", err)
	}

	fmt.Fprintf(w, "Deleted channel %q", channelName)
	return nil
}

자바

static void deleteNotificationChannel(String channelName) throws IOException {
  String projectId = System.getProperty("projectId");
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    NotificationChannelName name = NotificationChannelName.of(projectId, channelName);
    client.deleteNotificationChannel(channelName, false);
    System.out.println("Deleted notification channel " + channelName);
  }
}

PHP

use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;

/**
 * @param string $projectId Your project ID
 */
function alert_delete_channel($projectId, $channelId)
{
    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);
    $channelName = $channelClient->notificationChannelName($projectId, $channelId);

    $channelClient->deleteNotificationChannel($channelName);
    printf('Deleted notification channel %s' . PHP_EOL, $channelName);
}

Node.js

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

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

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const filter = 'A filter for selecting policies, e.g. description:"cloud"';

const request = {name: client.projectPath(projectId), filter};
const channels = await client.listNotificationChannels(request);
console.log(channels);
for (const channel of channels[0]) {
  console.log(`Deleting channel ${channel.displayName}`);
  try {
    await client.deleteNotificationChannel({
      name: channel.name,
    });
  } catch (err) {
    // ignore error
  }
}

Python

def delete_notification_channels(project_name, channel_ids, force=None):
    channel_client = monitoring_v3.NotificationChannelServiceClient()
    for channel_id in channel_ids:
        channel_name = '{}/notificationChannels/{}'.format(
            project_name, channel_id)
        try:
            channel_client.delete_notification_channel(
                channel_name, force=force)
            print('Channel {} deleted'.format(channel_name))
        except ValueError:
            print('The parameters are invalid')
        except Exception as e:
            print('API call failed: {}'.format(e))

채널 수정

알림 채널을 수정하려면 (REST API의) notificationChannels.patch 메소드를 사용합니다. 다른 API 구현 및 gcloud 인터페이스에서는 patch 대신 이 update를 호출합니다.

업데이트 작업으로는 기존 채널을 완전히 대체하거나 필드 하위 집합을 수정할 수 있습니다. 예를 들어 채널의 사용 설정 및 사용 중지가 가능합니다. 채널을 사용 중지하면 채널에 알림이 전달되지 않습니다. 임시로 변경하려는 경우에는 일반적으로 채널을 참조하는 알림 정책에서 채널을 삭제하는 것보다 채널을 사용 중지하는 편이 훨씬 더 편합니다.

gcloud 명령어

사용 정지된 알림 채널을 사용 설정하려면 gcloud alpha monitoring channels update 명령어를 사용하고 --enabled 플래그를 지정합니다. 다음 명령어는 이전 예에서 만든 사용 중지 상태의 email 알림 채널을 사용 설정합니다.

gcloud alpha monitoring channels update projects/a-gcp-project/notificationChannels/1355376463305411567 --enabled

정책을 사용 중지하려면 동일한 명령어를 사용하고 --no-enabled 플래그를 사용합니다. 자세한 내용은 gcloud alpha monitoring channels update 참조를 확인하세요. update 명령어는 REST API의 notificationChannels.patch 메소드에 해당합니다.

C#

using Google.Cloud.Monitoring.V3;
using Google.Protobuf.WellKnownTypes;
using System;

partial class AlertSnippets
{
    public NotificationChannel EnableNotificationChannel(
        string channelName = "projects/your-project-id/notificationChannels/123")
    {
        var client = NotificationChannelServiceClient.Create();
        NotificationChannel channel = new NotificationChannel();
        channel.Enabled = true;
        channel.Name = channelName;
        var fieldMask = new FieldMask { Paths = { "enabled" } };
        channel = client.UpdateNotificationChannel(
            updateMask: fieldMask,
            notificationChannel: channel);
        Console.WriteLine("Enabled {0}.", channel.Name);
        return channel;
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	monitoring "cloud.google.com/go/monitoring/apiv3"
	"github.com/golang/protobuf/ptypes/wrappers"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
	"google.golang.org/genproto/protobuf/field_mask"
)

// enableChannel enables the given channel. channelName should be of the form
// "projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]".
func enableChannel(w io.Writer, channelName string) error {
	ctx := context.Background()

	client, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}

	req := &monitoringpb.UpdateNotificationChannelRequest{
		UpdateMask: &field_mask.FieldMask{Paths: []string{"enabled"}},
		NotificationChannel: &monitoringpb.NotificationChannel{
			Name:    channelName,
			Enabled: &wrappers.BoolValue{Value: true},
		},
	}

	if _, err := client.UpdateNotificationChannel(ctx, req); err != nil {
		return fmt.Errorf("EnableNotificationChannel: %v", err)
	}

	fmt.Fprintf(w, "Enabled channel %q", channelName)
	return nil
}

Node.js

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

// Creates clients
const alertClient = new monitoring.AlertPolicyServiceClient();
const notificationClient = new monitoring.NotificationChannelServiceClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const alertPolicyId = '123456789012314';
// const channelIds = [
//   'channel-1',
//   'channel-2',
//   'channel-3',
// ];

const notificationChannels = channelIds.map(id =>
  notificationClient.notificationChannelPath(projectId, id)
);

for (const channel of notificationChannels) {
  const updateChannelRequest = {
    updateMask: {paths: ['enabled']},
    notificationChannel: {
      name: channel,
      enabled: {value: true},
    },
  };
  try {
    await notificationClient.updateNotificationChannel(updateChannelRequest);
  } catch (err) {
    const createChannelRequest = {
      notificationChannel: {
        name: channel,
        notificationChannel: {type: 'email'},
      },
    };
    const newChannel = await notificationClient.createNotificationChannel(
      createChannelRequest
    );
    notificationChannels.push(newChannel);
  }
}

const updateAlertPolicyRequest = {
  updateMask: {paths: ['notification_channels']},
  alertPolicy: {
    name: alertClient.alertPolicyPath(projectId, alertPolicyId),
    notificationChannels: notificationChannels,
  },
};
const [alertPolicy] = await alertClient.updateAlertPolicy(
  updateAlertPolicyRequest
);
console.log(`Updated ${alertPolicy.name}.`);

자바

private static Map<String, String> restoreNotificationChannels(
    String projectId,
    List<NotificationChannel> channels,
    boolean isSameProject) throws IOException {
  Map<String, String> newChannelNames = Maps.newHashMap();
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    for (NotificationChannel channel : channels) {
      // Update channel name if project ID is different.
      boolean channelUpdated = false;
      if (isSameProject) {
        try {
          NotificationChannel updatedChannel =
              client.updateNotificationChannel(NOTIFICATION_CHANNEL_UPDATE_MASK, channel);
          newChannelNames.put(channel.getName(), updatedChannel.getName());
          channelUpdated = true;
        } catch (Exception e) {
          channelUpdated = false;
        }
      }
      if (!channelUpdated) {
        NotificationChannel newChannel = client.createNotificationChannel(
            ProjectName.of(projectId),
            channel
                .toBuilder()
                .clearName()
                .clearVerificationStatus()
                .build());
        newChannelNames.put(channel.getName(), newChannel.getName());
      }
    }
  }
  return newChannelNames;
}

PHP

use Google\Cloud\Monitoring\V3\AlertPolicyServiceClient;
use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;
use Google\Cloud\Monitoring\V3\AlertPolicy;
use Google\Cloud\Monitoring\V3\NotificationChannel;
use Google\Cloud\Monitoring\V3\NotificationChannel\VerificationStatus;
use Google\ApiCore\ApiException;

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

    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);

    print('Loading alert policies and notification channels from backup.json.' . PHP_EOL);
    $projectName = $alertClient->projectName($projectId);
    $record = json_decode(file_get_contents('backup.json'), true);
    $isSameProject = $projectName == $record['project_name'];

    # Convert dicts to AlertPolicies.
    $policies = [];
    foreach ($record['policies'] as $policyArray) {
        $policy = new AlertPolicy();
        $policy->mergeFromJsonString(json_encode($policyArray));
        $policies[] = $policy;
    }

    # Convert dicts to NotificationChannels
    $channels = [];
    foreach (array_filter($record['channels']) as $channelArray) {
        $channel = new NotificationChannel();
        $channel->mergeFromJsonString(json_encode($channelArray));
        $channels[] = $channel;
    }

    # Restore the channels.
    $channelNameMap = [];
    foreach ($channels as $channel) {
        $updated = false;
        printf('Updating channel %s' . PHP_EOL, $channel->getDisplayName());

        # This field is immutable and it is illegal to specify a
        # non-default value (UNVERIFIED or VERIFIED) in the
        # Create() or Update() operations.
        $channel->setVerificationStatus(
            VerificationStatus::VERIFICATION_STATUS_UNSPECIFIED
        );

        if ($isSameProject) {
            try {
                $channelClient->updateNotificationChannel($channel);
                $updated = true;
            } catch (ApiException $e) {
                # The channel was deleted.  Create it below.
                if ($e->getStatus() !== 'NOT_FOUND') {
                    throw $e;
                }
            }
        }

        if (!$updated) {
            # The channel no longer exists.  Recreate it.
            $oldName = $channel->getName();
            $channel->setName('');
            $newChannel = $channelClient->createNotificationChannel(
                $projectName,
                $channel
            );
            $channelNameMap[$oldName] = $newChannel->getName();
        }
    }

    # Restore the alerts
    foreach ($policies as $policy) {
        printf('Updating policy %s' . PHP_EOL, $policy->getDisplayName());
        # These two fields cannot be set directly, so clear them.
        $policy->setCreationRecord(null);
        $policy->setMutationRecord(null);

        $notificationChannels = $policy->getNotificationChannels();

        # Update old channel names with new channel names.
        foreach ($notificationChannels as $i => $channel) {
            if (isset($channelNameMap[$channel])) {
                $notificationChannels[$i] = $channelNameMap[$channel];
            }
        }

        $updated = false;
        if ($isSameProject) {
            try {
                $alertClient->updateAlertPolicy($policy);
                $updated = true;
            } catch (ApiException $e) {
                # The policy was deleted.  Create it below.
                if ($e->getStatus() !== 'NOT_FOUND') {
                    throw $e;
                }
            }
        }

        if (!$updated) {
            # The policy no longer exists.  Recreate it.
            $oldName = $policy->getName();
            $policy->setName('');
            foreach ($policy->getConditions() as $condition) {
                $condition->setName('');
            }
            $policy = $alertClient->createAlertPolicy($projectName, $policy);
        }
        printf('Updated %s' . PHP_EOL, $policy->getName());
    }
    print('Restored alert policies and notification channels from backup.json.');
}

Python

def restore(project_name):
    print('Loading alert policies and notification channels from backup.json.')
    record = json.load(open('backup.json', 'rt'))
    is_same_project = project_name == record['project_name']
    # Convert dicts to AlertPolicies.
    policies_json = [json.dumps(policy) for policy in record['policies']]
    policies = [google.protobuf.json_format.Parse(
        policy_json, monitoring_v3.types.alert_pb2.AlertPolicy())
        for policy_json in policies_json]
    # Convert dicts to NotificationChannels
    channels_json = [json.dumps(channel) for channel in record['channels']]
    channels = [google.protobuf.json_format.Parse(
        channel_json, monitoring_v3.types.notification_pb2.
        NotificationChannel()) 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.enums.NotificationChannel.\
            VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED

        if is_same_project:
            try:
                channel_client.update_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
            channel.ClearField("name")
            new_channel = channel_client.create_notification_channel(
                project_name, 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.
        policy.ClearField('creation_record')
        policy.ClearField('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(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
            policy.ClearField("name")
            for condition in policy.conditions:
                condition.ClearField("name")
            policy = alert_client.create_alert_policy(project_name, policy)
        print('Updated', policy.name)

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Stackdriver Monitoring
도움이 필요하시나요? 지원 페이지를 방문하세요.