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#
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:
1npm install @middleware.io/node-apm --saveEnsure 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.
Create a file named instrumentation.js:
1// instrumentation.js
2const tracker = require('@middleware.io/node-apm');
3
4tracker.track({
5 serviceName: '<MW_SERVICE_NAME>',
6 accessToken: '<MW_API_KEY>',
7 target: 'https://<MW_UID>.middleware.io:443',
8 // Optional
9 projectName: '<MW_PROJECT_NAME>',
10});Start your application using Node.js preload:
1node --require ./instrumentation.js app.jsThis loads Middleware instrumentation before app.js.
For applications using ECMAScript modules, create instrumentation.mjs:
1// instrumentation.mjs
2import * as tracker from '@middleware.io/node-apm';
3
4tracker.track({
5 serviceName: '<MW_SERVICE_NAME>',
6 accessToken: '<MW_API_KEY>',
7 target: 'https://<MW_UID>.middleware.io:443',
8 projectName: '<MW_PROJECT_NAME>',
9});Start the application using the ESM import hook:
1node --import ./instrumentation.mjs app.mjsNote: Use --import for ESM applications rather than CommonJS --require.
Create instrumentation.ts:
1// instrumentation.ts
2import * as tracker from '@middleware.io/node-apm';
3
4tracker.track({
5 serviceName: '<MW_SERVICE_NAME>',
6 accessToken: '<MW_API_KEY>',
7 target: 'https://<MW_UID>.middleware.io:443',
8 projectName: '<MW_PROJECT_NAME>',
9});For local development using ts-node:
1npx ts-node --require ./instrumentation.ts app.tsFor ESM TypeScript:
1node --loader ts-node/esm --import ./instrumentation.ts app.tsFor production, compile TypeScript to JavaScript and start the compiled application:
1npx tsc
2node --require ./instrumentation.js dist/app.jsNote: 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:
1OTEL_NODE_RESOURCE_DETECTORS=allTo reduce the chance of losing spans during container shutdown, set:
1OTEL_BSP_SCHEDULE_DELAY=500This 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:
1// main app (Node.js)
2const tracker = require('@middleware.io/node-apm');
3
4process.on('SIGTERM', async () => {
5 console.log('SIGTERM received -- flushing Middleware telemetry...');
6
7 try {
8 await tracker.sdkShutdown();
9 } finally {
10 process.exit(0);
11 }
12});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:
1const tracker = require('@middleware.io/node-apm');
2
3tracker.info('Info sample');
4tracker.warn('Warning sample');
5tracker.debug('Debugging sample');
6tracker.error('Error sample');To record an exception with its stack trace:
1try {
2 throw new Error('oh error!');
3} catch (e) {
4 tracker.errorRecord(e);
5}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.
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:
1dotnet add package MW.APMAlternatively, 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.
1var builder = WebApplication.CreateBuilder(args);
2
3var configuration = new ConfigurationBuilder()
4 .SetBasePath(Directory.GetCurrentDirectory())
5 .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
6 .AddEnvironmentVariables()
7 .Build();
8
9builder.Services.ConfigureMWInstrumentation(configuration);
10
11builder.Logging.AddConfiguration(configuration.GetSection("Logging"));
12builder.Logging.AddConsole();
13builder.Logging.SetMinimumLevel(LogLevel.Debug);
14
15var app = builder.Build();
16
17// Initialize Middleware logging after app creation
18Logger.Init(app.Services.GetRequiredService<ILoggerFactory>());
19
20app.MapGet("/health", () => Results.Ok("ok"));
21
22app.Run();This configures Middleware APM and logging when the application starts.
3 Configure Middleware credentials#
Add the following configuration to appsettings.json:
1{
2 "MW": {
3 "ApiKey": "<MW_API_KEY>",
4 "TargetURL": "https://<MW_UID>.middleware.io:443",
5 "ServiceName": "<MW_SERVICE_NAME>",
6 "ProjectName": "<MW_PROJECT_NAME>",
7 "ConsoleExporter": "true",
8 "ExcludeLinks": "[\"/health\"]",
9 "ApmCollectMetrics": "true",
10 "ApmCollectTraces": "true",
11 "ApmCollectLogs": "true"
12 },
13 "Logging": {
14 "LogLevel": {
15 "Default": "Information",
16 "Microsoft.AspNetCore": "Warning"
17 }
18 }
19}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.
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.
1 Install the Middleware package#
Add the following dependencies to requirements.txt:
1middleware-io>=2.4.1
2setuptoolsInstall the dependencies:
1pip install -r requirements.txtFor local development, you can create a virtual environment:
1python -m venv myenv
2source myenv/bin/activate2 Install automatic instrumentation libraries#
Run:
1middleware-bootstrap -a installThis 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:
1pip list | grep -i flaskExpected packages include:
1Flask
2opentelemetry-instrumentation-flask3 Configure the Dockerfile#
For a containerized application, add the bootstrap command to your Dockerfile after installing Python dependencies:
1RUN middleware-bootstrap -a installEnsure 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:
1MW_API_KEY='<MW_API_KEY>'
2MW_TARGET='https://<MW_UID>.middleware.io:443'
3MW_SERVICE_NAME='MyFlaskServer'Start your application with:
1middleware-run python app.pyFor 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 in Middleware.
Use manual instrumentation when you want to initialize Middleware directly in your Python application.
1 Enable the Middleware tracker#
Set the following environment variable:
1MW_TRACKER=True2 Initialize the tracker#
Add the Middleware tracker before creating your Flask application:
1from flask import Flask
2
3from middleware import mw_tracker, MWOptions, record_exception, DETECT_GCP
4
5mw_tracker(
6 MWOptions(
7 access_token="<MW_API_KEY>",
8 target="https://<MW_UID>.middleware.io:443",
9 console_exporter=True,
10 debug_log_file=True,
11 service_name="MyPythonServer",
12 otel_propagators="b3,tracecontext",
13 custom_resource_attributes="call_id=12345678, request_id=987654321",
14 detectors=[DETECT_GCP]
15 )
16)
17
18app = Flask(__name__)
19
20@app.route('/')
21def index():
22 return "Hello, World!"
23
24if __name__ == "__main__":
25 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 documentation.
3 Add custom instrumentation (optional)#
You can create custom spans and attributes to capture application-specific operations.
See the Python APM configuration guide 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.
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:
1curl https://<CLOUD_RUN_SERVICE_URL>2 Verify application traces#
- Log in to Middleware.
- Go to APM → Services.
- Find the service configured using
MW_SERVICE_NAMEor the SDK's service name. - Open the service to view request traces, latency, and errors.
3 Verify logs#
Go to Log Monitoring → Log Explorer 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.jsorinstrumentation.mjsis included in the container image. - Check that the startup command uses
--requirefor CommonJS or--importfor 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
SIGTERMhandler. - Call
tracker.sdkShutdown()before the process exits.
Python auto-instrumentation is not working#
If Python traces are missing:
- Verify that
middleware-iois installed. - Run
middleware-bootstrap -a installduring 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 [email protected].
Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us or join our Slack channel.
What did you think of this content?