---
title: "Google Cloud Run"
description: "Configure Middleware APM for Google Cloud Run to track container performance, monitor requests, and analyze function behavior."
section: "Cloud Platform"
breadcrumb: "Cloud Platform > Google Cloud Run"
canonical: "https://docs.middleware.io/get-started/agent/google-cloud-run"
---
# Google Cloud Run

Middleware application instrumentation collects traces, metrics, and logs from services running on Google Cloud Run. This gives you request-level visibility into a containerized service without deploying a separate host agent.

Use this telemetry to investigate slow requests, application errors, and calls between services, for example when an API response becomes slower after a deployment.

Middleware supports Cloud Run instrumentation for Node.js, .NET, and Python applications.

## How it works

Middleware uses application-level instrumentation to collect telemetry from Cloud Run containers.

Depending on the runtime, you can configure:

- **Node.js**: Initialize the Middleware APM SDK before your application starts to automatically instrument supported libraries and frameworks.
- **.NET**: Add the Middleware APM package and configure instrumentation and logging in your application.
- **Python**: Use automatic instrumentation without changing application code, or initialize the Middleware tracker manually.

Each Cloud Run container initializes the SDK when it starts and exports telemetry to your Middleware account.

## Prerequisites

Before configuring Middleware, make sure you have:

- A Google Cloud project with Cloud Run and Artifact Registry enabled.
- The Google Cloud CLI (`gcloud`) installed and authenticated.
- An existing containerized application with a Dockerfile.
- A Middleware account with an API key and target URL.
- Outbound HTTPS connectivity from Cloud Run to your Middleware target on port 443.

For Node.js, use version 18 or later. For .NET, use version 6 or later.

### Supported telemetry

| Capability | Node.js | .NET |
| --- | --- | --- |
| Traces | ✅ | ✅ |
| Metrics | ✅ | ✅ |
| Application logs | ✅ | ✅ |
| Custom logs | ✅ | ✅ |
| Profiling | ✅ | ✖ |

Python instrumentation is also available; telemetry support depends on the SDK configuration.

## Installation

#### Node.js

Install the Middleware Node.js APM SDK and initialize it before loading your application modules.

#### 1 Install the Middleware APM package

Run the following command in your application directory:

```bash
npm install @middleware.io/node-apm --save
```

Ensure the package is included in `package.json` so it is installed when your Cloud Run container builds.

#### 2 Initialize the tracker

The Middleware tracker must initialize before your application loads other modules. This allows automatic instrumentation to capture supported framework and runtime operations.

Choose the configuration that matches your application.

#### JavaScript (CommonJS)

Create a file named `instrumentation.js`:

```js
// instrumentation.js
const tracker = require('@middleware.io/node-apm');

tracker.track({
  serviceName: '<MW_SERVICE_NAME>',
  accessToken: 'your-initial-token',
  target: 'your-initial-uid',
  // Optional
  projectName: '<MW_PROJECT_NAME>',
});
```

Start your application using Node.js preload:

```bash
node --require ./instrumentation.js app.js
```

This loads Middleware instrumentation before `app.js`.

#### JavaScript (ESM)

For applications using ECMAScript modules, create `instrumentation.mjs`:

```js
// instrumentation.mjs
import * as tracker from '@middleware.io/node-apm';

tracker.track({
  serviceName: '<MW_SERVICE_NAME>',
  accessToken: 'your-initial-token',
  target: 'your-initial-uid',
  projectName: '<MW_PROJECT_NAME>',
});
```

Start the application using the ESM import hook:

```bash
node --import ./instrumentation.mjs app.mjs
```

**Note**: Use `--import` for ESM applications rather than CommonJS `--require`.

#### TypeScript

Create `instrumentation.ts`:

```js
// instrumentation.ts
import * as tracker from '@middleware.io/node-apm';

tracker.track({
  serviceName: '<MW_SERVICE_NAME>',
  accessToken: 'your-initial-token',
  target: 'your-initial-uid',
  projectName: '<MW_PROJECT_NAME>',
});
```

For local development using ts-node:

```bash
npx ts-node --require ./instrumentation.ts app.ts
```

For ESM TypeScript:

```bash
node --loader ts-node/esm --import ./instrumentation.ts app.ts
```

For production, compile TypeScript to JavaScript and start the compiled application:

```bash
npx tsc
node --require ./instrumentation.js dist/app.js
```

**Note**: Adjust the preload path to match the output location of your compiled instrumentation file.

Replace the placeholders with your Middleware account details and service name.

#### 3 Configure Cloud Run environment variables

Open **Google Cloud Console → Cloud Run → Your Service → Edit & deploy new revision → Variables & Secrets**.

Add the following environment variable:

```bash
OTEL_NODE_RESOURCE_DETECTORS=all
```

To reduce the chance of losing spans during container shutdown, set:

```bash
OTEL_BSP_SCHEDULE_DELAY=500
```

This configures the batch span processor to export telemetry more frequently.

**Note**: A shorter export interval can increase the number of export requests.

#### 4 Configure graceful shutdown (recommended)

Cloud Run sends `SIGTERM` before terminating a container instance. Configure the Middleware SDK to flush telemetry before the process exits.

Add the following shutdown handler to your application:

```js
// main app (Node.js)
const tracker = require('@middleware.io/node-apm');

process.on('SIGTERM', async () => {
  console.log('SIGTERM received -- flushing Middleware telemetry...');

  try {
    await tracker.sdkShutdown();
  } finally {
    process.exit(0);
  }
});
```

This allows the SDK to export pending telemetry when Cloud Run terminates the container.

For local development, you can also handle `SIGINT`.

#### 5 Add custom logs and errors (optional)

Use the Middleware SDK to record custom application logs:

```js
const tracker = require('@middleware.io/node-apm');

tracker.info('Info sample');
tracker.warn('Warning sample');
tracker.debug('Debugging sample');
tracker.error('Error sample');
```

To record an exception with its stack trace:

```js
try {
  throw new Error('oh error!');
} catch (e) {
  tracker.errorRecord(e);
}
```

#### 6 Deploy and verify

Build and deploy the updated container to Cloud Run using your existing deployment workflow.

Make sure the container startup command loads the instrumentation file before the application.

After deployment, send a few requests to your service and verify telemetry in Middleware under [**APM → Services**](https://app.middleware.io/apm/services).

#### .NET

Use the Middleware APM package to collect traces, metrics, and logs from .NET applications running on Cloud Run.

#### 1 Install the Middleware APM package

Run the following command in your .NET project:

```bash
dotnet add package MW.APM
```

Alternatively, install `MW.APM` using Visual Studio:

**Tools → NuGet Package Manager → Manage NuGet Packages for Solution → Browse → MW.APM → Install**

#### 2 Configure instrumentation and logging

Open `Program.cs` and initialize Middleware instrumentation.

```js
var builder = WebApplication.CreateBuilder(args);

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables()
    .Build();

builder.Services.ConfigureMWInstrumentation(configuration);

builder.Logging.AddConfiguration(configuration.GetSection("Logging"));
builder.Logging.AddConsole();
builder.Logging.SetMinimumLevel(LogLevel.Debug);

var app = builder.Build();

// Initialize Middleware logging after app creation
Logger.Init(app.Services.GetRequiredService<ILoggerFactory>());

app.MapGet("/health", () => Results.Ok("ok"));

app.Run();
```

This configures Middleware APM and logging when the application starts.

#### 3 Configure Middleware credentials

Add the following configuration to `appsettings.json`:

```json
{
  "MW": {
    "ApiKey": "your-initial-token",
    "TargetURL": "your-initial-uid",
    "ServiceName": "<MW_SERVICE_NAME>",
    "ProjectName": "<MW_PROJECT_NAME>",
    "ConsoleExporter": "true",
    "ExcludeLinks": "[\"/health\"]",
    "ApmCollectMetrics": "true",
    "ApmCollectTraces": "true",
    "ApmCollectLogs": "true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}
```

Replace the placeholders with your Middleware account details.

#### Configuration reference

| Setting | Description |
| --- | --- |
| `ApiKey` | Middleware API key |
| `TargetURL` | Middleware telemetry endpoint |
| `ServiceName` | Name displayed in Middleware APM |
| `ProjectName` | Middleware project name |
| `ConsoleExporter` | Enables console telemetry output |
| `ExcludeLinks` | Excludes specified routes, such as `/health` |
| `ApmCollectMetrics` | Enables metric collection |
| `ApmCollectTraces` | Enables trace collection |
| `ApmCollectLogs` | Enables log collection |

**Security note**: For production deployments, supply credentials through Cloud Run secrets or environment-based configuration rather than committing an API key to source control.

#### 4 Deploy and verify

Build and deploy your .NET application to Cloud Run.

Each container instance initializes Middleware instrumentation when the application starts.

Send requests to your service and verify traces, metrics, and logs in Middleware.

#### Python

Middleware supports two instrumentation methods for Python applications:

- **Auto-instrumentation**: Automatically instrument supported frameworks and libraries without modifying application code.
- **Manual instrumentation**: Initialize the Middleware tracker in your application for additional configuration control.

#### Auto-instrumentation

#### 1 Install the Middleware package

Add the following dependencies to `requirements.txt`:

```bash
middleware-io>=2.4.1
setuptools
```

Install the dependencies:

```bash
pip install -r requirements.txt
```

For local development, you can create a virtual environment:

```bash
python -m venv myenv
source myenv/bin/activate
```

#### 2 Install automatic instrumentation libraries

Run:

```bash
middleware-bootstrap -a install
```

This command detects supported packages installed in your Python environment and installs the corresponding OpenTelemetry instrumentation libraries.

For example, if Flask is installed, the bootstrap command installs its supported instrumentation package.

Verify the installation:

```bash
pip list | grep -i flask
```

Expected packages include:

```text
Flask
opentelemetry-instrumentation-flask
```

#### 3 Configure the Dockerfile

For a containerized application, add the bootstrap command to your Dockerfile after installing Python dependencies:

```bash
RUN middleware-bootstrap -a install
```

Ensure the application starts through `middleware-run` rather than calling Python directly.

#### 4 Configure Middleware environment variables

Set the following environment variables in your Cloud Run service configuration:

```bash
MW_API_KEY='your-initial-token'
MW_TARGET='your-initial-uid'
MW_SERVICE_NAME='MyFlaskServer'
```

Start your application with:

```bash
middleware-run python app.py
```

For Cloud Run, configure this as the container startup command or entrypoint.

**Note**: The application must still listen on the port provided by Cloud Run through the `PORT` environment variable.

#### 5 Deploy and verify

Build and deploy the updated Python container.

Send requests to your application and verify that the service appears under [**APM → Services**](https://app.middleware.io/apm/services) in Middleware.

#### Manual instrumentation

Use manual instrumentation when you want to initialize Middleware directly in your Python application.

#### 1 Enable the Middleware tracker

Set the following environment variable:

```bash
MW_TRACKER=True
```

#### 2 Initialize the tracker

Add the Middleware tracker before creating your Flask application:

```py
from flask import Flask

from middleware import mw_tracker, MWOptions, record_exception, DETECT_GCP

mw_tracker(
    MWOptions(
        access_token="your-initial-token",
        target="your-initial-uid",
        console_exporter=True,
        debug_log_file=True,
        service_name="MyPythonServer",
        otel_propagators="b3,tracecontext",
        custom_resource_attributes="call_id=12345678, request_id=987654321",
        detectors=[DETECT_GCP]
    )
)

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello, World!"

if __name__ == "__main__":
    app.run()
```

This example configures the Middleware tracker with service metadata, trace propagation, and Google Cloud resource detection.

For additional options, see the [Python APM configuration](/get-started/apm/python#advanced-configuration) documentation.

#### 3 Add custom instrumentation (optional)

You can create custom spans and attributes to capture application-specific operations.

See the [Python APM configuration guide](/get-started/apm/python#-capture-application-data) for additional instrumentation examples.

#### 4 Deploy and verify

Deploy your updated application to Cloud Run.

Generate application traffic and verify that traces appear under [**APM → Services**](https://app.middleware.io/apm/services).

## Verify data collection

After deploying the instrumented application, allow a few minutes for telemetry to appear.

#### 1 Generate application traffic

Open your Cloud Run service URL or send requests to one of its endpoints.

For example:

```bash
curl https://<CLOUD_RUN_SERVICE_URL>
```

#### 2 Verify application traces

1. Log in to Middleware.
2. Go to [APM → Services](https://app.middleware.io/apm/services).
3. Find the service configured using `MW_SERVICE_NAME` or the SDK's service name.
4. Open the service to view request traces, latency, and errors.

#### 3 Verify logs

Go to [Log Monitoring → Log Explorer](https://app.middleware.io/logs) and filter by the service name.

If logs do not appear, verify that log collection is enabled in your SDK configuration.

#### 4 Verify metrics

Open the relevant service in APM to review available application metrics, including request rate, latency, and error rate.

## Troubleshooting

### No traces in Middleware

If the application is running but traces do not appear:

- Verify that your Middleware API key and target URL are correct.
- Check that the application initializes the Middleware SDK before other instrumented modules.
- Confirm that the Cloud Run container starts with the required instrumentation command.
- Verify outbound HTTPS connectivity to your Middleware target.
- Check Cloud Run logs for SDK initialization or export errors.

### Node.js instrumentation is not loading

If Node.js traces are missing:

- Confirm that Node.js 18 or later is installed.
- Verify that `instrumentation.js` or `instrumentation.mjs` is included in the container image.
- Check that the startup command uses `--require` for CommonJS or `--import` for ESM.
- Verify the Node.js startup arguments using `process.execArgv`.

### TypeScript instrumentation works locally but not on Cloud Run

If instrumentation works locally but not after deployment:

- Compile TypeScript to JavaScript during the container build.
- Confirm that the compiled instrumentation file is included in the image.
- Update the startup command to reference the compiled JavaScript file.

### Spans are missing during shutdown

Cloud Run may terminate container instances before all buffered telemetry is exported.

For Node.js:

- Set `OTEL_BSP_SCHEDULE_DELAY=500`.
- Configure a `SIGTERM` handler.
- Call `tracker.sdkShutdown()` before the process exits.

### Python auto-instrumentation is not working

If Python traces are missing:

- Verify that `middleware-io` is installed.
- Run `middleware-bootstrap -a install` during the container build.
- Confirm that the required framework instrumentation packages are installed.
- Verify that the container starts using `middleware-run`.

### No telemetry from Cloud Run

If the SDK is configured correctly but data does not appear:

- Verify outbound connectivity to the Middleware target URL.
- Check Cloud Run VPC egress and firewall settings.
- Confirm that the service is receiving requests.
- Review Cloud Run logs for connection or authentication errors.

If the issue persists, contact Middleware Support at support@middleware.io.

Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us page or join our Slack channel.
