Cloud Logging でのセカンド パーティ トリガー

多くの Google Cloud Platform イベントが Cloud Audit Logs に記録されます。これらのログをフィルタリングし、シンクを使用して Pub/Sub トピックに転送できます。これらの Pub/Sub トピックは、Cloud Functions をトリガーする通知を送信します。これにより、監査ログを生成する Google Cloud Platform サービスからカスタム イベントを作成できます。

構成

以下のサンプルを実行するには、Pub/Sub トピックCloud Logging シンクが必要です。 サンプルでは、これらを使用して Cloud Audit Logs を Cloud Functions の関数に転送します。

イベントの構造

すべての Pub/Sub トリガー関数と同様に、Cloud ログエントリからトリガーされる関数は PubsubMessage オブジェクトを受信します。このオブジェクトのdata パラメータに base64 でエンコーディングされた文字列が格納されます。Cloud ログイベントの場合、この値をデコードすると、関連するログエントリが JSON 文字列として返されます。

サンプルコード

以下のような Pub/Sub トリガー関数を使用すると、エクスポートされた Cloud ログを検出して応答できます。

Node.js

exports.processLogEntry = (data) => {
  const dataBuffer = Buffer.from(data.data, 'base64');

  const logEntry = JSON.parse(dataBuffer.toString('ascii')).protoPayload;
  console.log(`Method: ${logEntry.methodName}`);
  console.log(`Resource: ${logEntry.resourceName}`);
  console.log(`Initiator: ${logEntry.authenticationInfo.principalEmail}`);
};

Python

import base64
import json

def process_log_entry(data, context):
    data_buffer = base64.b64decode(data['data'])
    log_entry = json.loads(data_buffer)['protoPayload']

    print(f"Method: {log_entry['methodName']}")
    print(f"Resource: {log_entry['resourceName']}")
    print(f"Initiator: {log_entry['authenticationInfo']['principalEmail']}")

Go


// Package log contains examples for handling Cloud Functions logs.
package log

import (
	"context"
	"log"
)

// PubSubMessage is the payload of a Pub/Sub event.
type PubSubMessage struct {
	Data []byte `json:"data"`
}

// ProcessLogEntry processes a Pub/Sub message from Cloud Logging.
func ProcessLogEntry(ctx context.Context, m PubSubMessage) error {
	log.Printf("Log entry data: %s", string(m.Data))
	return nil
}

Java


import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import functions.eventpojos.PubSubMessage;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.logging.Logger;

public class StackdriverLogging implements BackgroundFunction<PubSubMessage> {
  private static final Logger logger = Logger.getLogger(StackdriverLogging.class.getName());

  @Override
  public void accept(PubSubMessage message, Context context) {
    String name = "World";

    if (!message.getData().isEmpty()) {
      name = new String(Base64.getDecoder().decode(
          message.getData().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
    }
    String res = String.format("Hello, %s", name);
    logger.info(res);
  }
}

関数のデプロイ

関数をデプロイするには、次のコマンドを使用します。

Node.js

gcloud functions deploy processLogEntry \
--runtime nodejs10 \
--trigger-topic YOUR_PUBSUB_TOPIC
優先する Node.js のバージョンを指定するには、--runtime フラグに次の値を使用します。
  • nodejs10
  • nodejs12

Python

gcloud functions deploy process_log_entry \
--runtime python37 \
--trigger-topic YOUR_PUBSUB_TOPIC
優先する Python バージョンを指定するには、--runtime フラグに次の値を使用します。
  • python37
  • python38

Go

gcloud functions deploy ProcessLogEntry \
--runtime go111 \
--trigger-topic YOUR_PUBSUB_TOPIC
優先する Go バージョンを指定するには、--runtime フラグに次の値を使用します。
  • go111
  • go113

Java

gcloud functions deploy java-log-function \
--entry-point StackdriverLogging \
--runtime java11 \
--memory 512MB \
--trigger-topic YOUR_PUBSUB_TOPIC

関数のトリガー

フィルタに一致する Cloud ログエントリが作成されると、関数でも対応するログエントリを確認できます。

Method: METHOD
Resource: projects/YOUR_GCLOUD_PROJECT/...
Initiator: YOUR_EMAIL_ADDRESS