Trigger functions from log entries

Many Google Cloud events are logged in Cloud Audit Logs. You can filter these logs and forward them to Pub/Sub topics using sinks. These Pub/Sub topics can then send notifications that trigger Cloud Run functions. You can create custom events from any Google Cloud service that produces audit logs.

This page shows an example of how to trigger functions from log entries routed to a Pub/Sub topic.

Event structure of Pub/Sub-triggered functions

Like all Pub/Sub-triggered functions, functions triggered by Cloud Logging log entries receive a PubsubMessage object whose data parameter is a base64-encoded string. For Cloud Logging log events, decoding this value returns the relevant log entry as a JSON string.

Before you begin

The sample code forwards Cloud Audit Logs to a Cloud Run function. Before you run the sample code, you'll need the following:

See the Pub/Sub triggers guide for the APIs to enable and the required roles for deploying functions that are triggered by Pub/Sub.

Sample code

You can use a Pub/Sub-triggered function to detect and respond to exported Cloud Logging logs:

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.
// See the documentation for more details:
// https://cloud.google.com/pubsub/docs/reference/rest/v1/PubsubMessage
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);
  }
}

Deploy and trigger a function

To configure a trigger during function deployment:

  1. Run the following command in the directory that contains the sample code to deploy your function:

    Node.js

    gcloud beta run deploy nodejs-log-function \
          --source . \
          --function processLogEntry \
          --base-image nodejs20 \
          --region REGION
    

    Python

    gcloud beta run deploy python-log-function \
          --source . \
          --function process_log_entry \
          --base-image python312 \
          --region REGION
    

    Go

    gcloud beta run deploy go-log-function \
          --source . \
          --function ProcessLogEntry \
          --base-image go122 \
          --region REGION
    

    Java

    gcloud beta run deploy java-log-function \
          --source . \
          --function StackdriverLogging \
          --base-image java21 \
          --region REGION
    

    Replace:

    • REGION with the Google Cloud region where you want to deploy your function. For example, us-central1.

    • The --function flag specifies the entry point to the function in example source code. This is the code Cloud Run executes when your function runs. The value of this flag must be a function name or fully-qualified class name that exists in your source code.

    • The --base-image flag specifies the base image environment for your function. For more details about base images and the packages included in each image, see Runtimes base images.

  2. Run the following command to create a trigger that filters events:

    gcloud eventarc triggers create TRIGGER_NAME  \
        --location=EVENTARC_TRIGGER_LOCATION \
        --destination-run-service=SERVICE  \
        --destination-run-region=REGION \
        --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
        --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
    

    Replace:

    • TRIGGER_NAME with the name for your trigger.

    • EVENTARC_TRIGGER_LOCATION with the location for the Eventarc trigger. In general, the location of an Eventarc trigger should match the location of the Google Cloud resource that you want to monitor for events. In most scenarios, you should also deploy your function in the same region. See Understand Eventarc locations for more details about Eventarc trigger locations.

    • SERVICE with the name of the function you are deploying.

    • REGION with the Cloud Run region of the function.

    • PROJECT_NUMBER with your Google Cloud project number. Eventarc triggers are linked to service accounts to use as an identity when invoking your function. Your Eventarc trigger's service account must have the permission to invoke your function. By default, Cloud Run uses the Default compute service account.

    • The --event-filters flag specifies the event filters that the trigger monitors. An event that matches all the event-filters, filters triggers calls to your function. Each trigger must have a supported event type. You can't change the event filter type after creation. To change the event filter type, you must create a new trigger and delete the old one. Optionally, you can repeat the --event-filters flag with a supported filter in the form ATTRIBUTE=VALUE to add more filters.

Cloud log entry

When a Cloud log entry that matches one of your filters is created, the corresponding log entries for your function in the Google Cloud console should look as follows:

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