Skip to main contentSkip to headerSkip to footer
Integrating Vercel with GCP Cloud Logging: A Complete Guide
14 Apr 2022
5 min read
Praveen Thirumurugan

Integrating Vercel with GCP Cloud Logging: A Complete Guide

Learn how to implement a custom log drain solution to send Vercel application logs to Google Cloud Platform's Cloud Logging service, complete with authentication setup and reusable code examples.

Vercel's serverless architecture provides an excellent developer experience with its simplicity and deployment efficiency. However, as your application scales from a hobby project to production, implementing robust logging becomes crucial for monitoring, debugging, and maintaining system reliability.

While Vercel offers built-in log drain integrations with popular services like Datadog and LogDNA, Google Cloud Platform's Cloud Logging isn't available as a native integration. This guide will walk you through implementing a custom solution to stream your Vercel logs directly to GCP Cloud Logging.

Prerequisites and Important Considerations

Before implementing this solution, please note the following requirements and limitations:

Authentication Requirements:

  • • A GCP service account with the necessary credentials (client_email, private_key, and project_id).
  • • Appropriate IAM permissions for Cloud Logging.

Technical Limitations:

  • Synchronous Operations: Due to Vercel's serverless architecture, logging operations must be awaited to prevent premature function termination.
  • Edge Functions Incompatibility: This implementation cannot be used with Vercel Edge Functions (such as _middleware.ts) because the Edge Runtime operates in a browser-like environment that doesn't support Node.js dependencies like fs.

Setting Up GCP Service Account

To authenticate with Google Cloud Logging, you'll need to create a service account with appropriate permissions:

Step 1: Create the Service Account

  1. Navigate to the Google Cloud Console
  2. Go to IAM & AdminService Accounts
  3. Click Create Service Account
  4. Provide a descriptive name (e.g., "vercel-logging-service")
  5. Assign the Logging Admin role to ensure proper write permissions

Step 2: Generate Authentication Keys

  1. Select your newly created service account
  2. Navigate to the Keys tab
  3. Click Add KeyCreate new key
  4. Choose JSON format and download the key file

The downloaded JSON file contains the essential credentials we'll use:

  • client_email: Service account email address
  • private_key: Private key for authentication
  • project_id: Your GCP project identifier

Implementation: Creating the CloudLogging Class

Now let's implement a reusable TypeScript class that handles the integration with GCP Cloud Logging.

Step 1: Install Dependencies

1yarn add @google-cloud/logging
2# or
3npm install @google-cloud/logging

Step 2: Environment Setup

Store your service account credentials as an environment variable in Vercel:

  • GOOGLE_SERVICE_ACCOUNT: The entire JSON key file contents as a string
  • VERCEL_ENV: Automatically provided by Vercel (production, preview, or development)

Step 3: CloudLogging Class Implementation

1import { Logging } from '@google-cloud/logging';
2
3export class CloudLogging {
4 private logging: Logging;
5 private log: any;
6
7 constructor() {
8 // Parse the service account credentials from environment
9 const credentials = JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT!);
10
11 // Initialize the Google Cloud Logging client
12 this.logging = new Logging({
13 projectId: credentials.project_id,
14 credentials: {
15 client_email: credentials.client_email,
16 private_key: credentials.private_key,
17 }
18 });
19
20 // Create a log instance with environment-specific naming
21 this.log = this.logging.log(`vercel-${process.env.VERCEL_ENV}`, {
22 removeCircular: true
23 });
24 }
25
26 /**
27 * Logs data to GCP Cloud Logging with specified severity level
28 * @param severity - Log severity (INFO, WARNING, ERROR, etc.)
29 * @param data - Data to log (string, object, or any serializable type)
30 * @param labels - Optional custom labels for log organization
31 */
32 async logData(
33 severity: string,
34 data: string | object | any,
35 labels: Record<string, string> = {}
36 ): Promise<void> {
37 try {
38 const entry = this.log.entry({
39 resource: {
40 type: 'global',
41 },
42 labels: {
43 environment: process.env.VERCEL_ENV || 'unknown',
44 source: 'vercel',
45 ...labels
46 },
47 severity: severity.toUpperCase(),
48 }, data);
49
50 await this.log.write(entry);
51 } catch (error) {
52 // Fallback to console logging if GCP logging fails
53 console.error('Failed to write to GCP Cloud Logging:', error);
54 console.log('Original log data:', { severity, data });
55 }
56 }
57
58 /**
59 * Convenience methods for common log levels
60 */
61 async info(data: any, labels?: Record<string, string>): Promise<void> {
62 return this.logData('INFO', data, labels);
63 }
64
65 async warn(data: any, labels?: Record<string, string>): Promise<void> {
66 return this.logData('WARNING', data, labels);
67 }
68
69 async error(data: any, labels?: Record<string, string>): Promise<void> {
70 return this.logData('ERROR', data, labels);
71 }
72}

Usage Examples

With our CloudLogging class implemented, let's explore various ways to integrate it into your Vercel application.

Basic Usage

1import { CloudLogging } from '@/lib/gcp/logging';
2
3const logger = new CloudLogging();
4
5// API Route Example
6export default async function handler(req: NextApiRequest, res: NextApiResponse) {
7 try {
8 // Your business logic here
9 const result = await processUserData(req.body);
10
11 // Log successful operation
12 await logger.info({
13 message: 'User data processed successfully',
14 userId: req.body.userId,
15 timestamp: new Date().toISOString()
16 }, { operation: 'user-processing' });
17
18 res.status(200).json(result);
19 } catch (error) {
20 // Log error with context
21 await logger.error({
22 message: 'Failed to process user data',
23 error: error.message,
24 stack: error.stack,
25 requestBody: req.body
26 }, { operation: 'user-processing' });
27
28 res.status(500).json({ error: 'Processing failed' });
29 }
30}

Advanced Usage with Custom Labels

1class UserService {
2 private logger = new CloudLogging();
3
4 async createUser(userData: any) {
5 try {
6 const user = await this.saveToDatabase(userData);
7
8 await this.logger.info({
9 message: 'New user created',
10 userId: user.id,
11 email: user.email
12 }, {
13 service: 'user-service',
14 operation: 'create-user',
15 version: 'v1'
16 });
17
18 return user;
19 } catch (error) {
20 await this.logger.error({
21 message: 'User creation failed',
22 error: error.message,
23 userData: { ...userData, password: '[REDACTED]' }
24 }, {
25 service: 'user-service',
26 operation: 'create-user'
27 });
28
29 throw error;
30 }
31 }
32}

Serverless Function Example

1import { VercelRequest, VercelResponse } from '@vercel/node';
2import { CloudLogging } from '../lib/gcp/logging';
3
4const logger = new CloudLogging();
5
6export default async function handler(req: VercelRequest, res: VercelResponse) {
7 const startTime = Date.now();
8
9 try {
10 // Log request start
11 await logger.info({
12 message: 'Processing webhook',
13 method: req.method,
14 url: req.url,
15 headers: req.headers
16 }, { type: 'webhook', stage: 'start' });
17
18 // Process webhook
19 const result = await processWebhook(req.body);
20
21 // Log success with performance metrics
22 await logger.info({
23 message: 'Webhook processed successfully',
24 duration: Date.now() - startTime,
25 result: result
26 }, { type: 'webhook', stage: 'complete' });
27
28 res.status(200).json({ success: true });
29
30 } catch (error) {
31 await logger.error({
32 message: 'Webhook processing failed',
33 duration: Date.now() - startTime,
34 error: error.message
35 }, { type: 'webhook', stage: 'error' });
36
37 res.status(500).json({ error: 'Webhook failed' });
38 }
39}

Viewing Your Logs

Once implemented, your logs will be available in the Google Cloud Console:

  1. Navigate to LoggingLogs Explorer
  2. Filter by your log name (e.g., vercel-production)
  3. Use labels and severity levels to organize and query your logs
  4. Set up log-based metrics and alerts for monitoring