Skip to content

Commit cbd6af0

Browse files
committed
reworked the metrics examples
1 parent 3ee1a2a commit cbd6af0

13 files changed

Lines changed: 275 additions & 225 deletions

File tree

metrics-examples/.ceignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
target/
3+
vendor/

metrics-examples/README.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Code Engine custom metrics examples
2+
3+
The following samples demonstrate how to emit custom metrics in Code Engine jobs and apps.
4+
5+
Use the following command to build and deploy all examples to the Code Engine project of your choice.
6+
```
7+
ibmcloud ce project select --name <your-project-name>
8+
9+
./run all
10+
```
11+
12+
## Metrics
13+
14+
The application provided in this example expose Prometheus metrics at `/metrics` (port 2112). All metric names are prefixed with a configurable value set via the `METRICS_NAME_PREFIX` environment variable (default: `mymetrics_`).
15+
16+
17+
Once custom metrics scraping is enabled (see asset [metrics-collector](../metrics-collector/README.md)), the following command can be used to import the "My custom Code Engine Metrics" dashboard into IBM Cloud Monitoring:
18+
19+
```bash
20+
# Load the custom metric dashboard configuration
21+
CE_CUSTOM_METRICS_DASHBOARD=$(curl -sL https://raw.githubusercontent.com/IBM/CodeEngine/main/metrics-examples/my-custom-code-engine-metrics-dashboard.json)
22+
23+
# Import the dashboard
24+
curl -X POST https://$REGION.monitoring.cloud.ibm.com/api/v3/dashboards \
25+
-H "Authorization: $(ibmcloud iam oauth-tokens --output JSON|jq -r '.iam_token')" \
26+
-H "IBMInstanceID: $MONITORING_INSTANCE_GUID" \
27+
-H "Content-Type: application/json" \
28+
-d "{\"dashboard\": $CE_CUSTOM_METRICS_DASHBOARD}"
29+
```
30+
31+
To customize the prefix, set the environment variable when starting the application:
32+
33+
```bash
34+
METRICS_NAME_PREFIX=myapp_ node app.mjs
35+
```
36+
37+
On Code Engine set the environment variable in the application configuration:
38+
39+
```bash
40+
ibmcloud ce app update "metrics-example-app-node" --env METRICS_NAME_PREFIX=myapp_
41+
```
42+
43+
Following metrics are emitted by the metrics-example-app-node:
44+
45+
**Request Metrics**
46+
- `mymetrics_requests_total`: Total requests by method and path
47+
48+
**Outbound Call Metrics**
49+
- `mymetrics_outbound_request_duration_seconds`: Histogram of outbound request durations
50+
- `mymetrics_outbound_requests_total`: Total outbound requests by target, method, and status
51+
52+
**Database Metrics**
53+
- `mymetrics_db_query_duration_seconds`: Histogram of query durations by operation and table
54+
- `mymetrics_db_queries_total`: Total queries by operation, table, and status
55+
- `mymetrics_db_connections_active`: Active database connections gauge
56+
57+
**Compute Metrics**
58+
- `mymetrics_compute_duration_seconds`: Histogram of compute operation durations
59+
60+
61+
## Put some load on your app
62+
63+
## Load Testing
64+
65+
Generate test traffic using the included script:
66+
67+
```bash
68+
# Local testing
69+
./load-test.sh
70+
71+
# IBM Cloud Code Engine deployment
72+
TARGET_URL=https://your-app.example.com ./load-test.sh
73+
74+
# Custom configuration
75+
TARGET_URL=https://your-app.example.com DURATION=120 CONCURRENT_REQUESTS=10 ./load-test.sh
76+
```
77+
78+
Configuration options:
79+
- `TARGET_URL`: Application endpoint (default: http://localhost:8080)
80+
- `DURATION`: Test duration in seconds (default: 60)
81+
- `CONCURRENT_REQUESTS`: Number of concurrent workers (default: 5)
82+
83+
84+
### Deploying httpbin Backend
85+
86+
To deploy your own httpbin instance on IBM Cloud Code Engine instead of using the public service, use the following command with an image from a registry other than docker.io:
87+
88+
```bash
89+
ibmcloud ce application update \
90+
--name httpbin \
91+
--src https://github.com/mark-sivill/httpbin \
92+
--memory 0.5G \
93+
--cpu 0.25 \
94+
--min-scale 1 \
95+
--max-scale 3 \
96+
--concurrency 100 \
97+
--port 9000
98+
```
99+
100+
After deployment, get the application URL:
101+
102+
```bash
103+
ibmcloud ce application get --name httpbin --output url
104+
```
105+
106+
Then configure the network-test-app to use your httpbin instance:
107+
108+
```bash
109+
ibmcloud ce application update \
110+
--name network-test-app \
111+
--env HTTPBIN_BASE_URL=https://httpbin.your-project.us-south.codeengine.appdomain.cloud
112+
```
113+
114+
The httpbin image from GitHub Container Registry (ghcr.io) is the official Postman-maintained implementation that works well in Code Engine environments.
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ set -ex
1313
export REGISTRY=${REGISTRY:-icr.io/codeengine}
1414

1515
# First build the app's image and push it
16-
docker build ${NOCACHE} -t ${REGISTRY}/network-test-app -f Dockerfile . --platform linux/amd64
17-
docker push ${REGISTRY}/network-test-app
16+
cd node
17+
docker build ${NOCACHE} -t ${REGISTRY}/metrics-example-app-node -f Dockerfile . --platform linux/amd64
18+
docker push ${REGISTRY}/metrics-example-app-node
19+
cd ..

network-test-app/my-custom-code-engine-metrics-dashboard.json renamed to metrics-examples/my-custom-code-engine-metrics-dashboard.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"links": null,
2323
"advancedQueries": [
2424
{
25-
"query": "rate(mymetrics_node_requests_total{$__scope}[5m])",
25+
"query": "rate(mymetrics_requests_total{$__scope}[5m])",
2626
"enabled": true,
2727
"displayInfo": {
2828
"displayName": "Request Rate",
@@ -102,7 +102,7 @@
102102
"links": null,
103103
"advancedQueries": [
104104
{
105-
"query": "sum(mymetrics_node_requests_total{$__scope})",
105+
"query": "sum(mymetrics_requests_total{$__scope})",
106106
"enabled": true,
107107
"displayInfo": {
108108
"displayName": "Total Requests",
@@ -143,7 +143,7 @@
143143
"links": null,
144144
"advancedQueries": [
145145
{
146-
"query": "histogram_quantile(0.95, rate(mymetrics_node_outbound_request_duration_seconds_bucket{$__scope}[5m]))",
146+
"query": "histogram_quantile(0.95, rate(mymetrics_outbound_request_duration_seconds_bucket{$__scope}[5m]))",
147147
"enabled": true,
148148
"displayInfo": {
149149
"displayName": "P95 Duration",
@@ -236,7 +236,7 @@
236236
"links": null,
237237
"advancedQueries": [
238238
{
239-
"query": "rate(mymetrics_node_outbound_request_duration_seconds_sum{$__scope}[5m]) / rate(mymetrics_node_outbound_request_duration_seconds_count{$__scope}[5m])",
239+
"query": "rate(mymetrics_outbound_request_duration_seconds_sum{$__scope}[5m]) / rate(mymetrics_outbound_request_duration_seconds_count{$__scope}[5m])",
240240
"enabled": true,
241241
"displayInfo": {
242242
"displayName": "Avg Duration",
@@ -316,7 +316,7 @@
316316
"links": null,
317317
"advancedQueries": [
318318
{
319-
"query": "rate(mymetrics_node_outbound_requests_total{$__scope}[5m])",
319+
"query": "rate(mymetrics_outbound_requests_total{$__scope}[5m])",
320320
"enabled": true,
321321
"displayInfo": {
322322
"displayName": "Request Rate",
@@ -396,7 +396,7 @@
396396
"links": null,
397397
"advancedQueries": [
398398
{
399-
"query": "mymetrics_node_db_connections_active{$__scope}",
399+
"query": "mymetrics_db_connections_active{$__scope}",
400400
"enabled": true,
401401
"displayInfo": {
402402
"displayName": "Active Connections",
@@ -450,7 +450,7 @@
450450
"links": null,
451451
"advancedQueries": [
452452
{
453-
"query": "mymetrics_node_db_connections_active{$__scope}",
453+
"query": "mymetrics_db_connections_active{$__scope}",
454454
"enabled": true,
455455
"displayInfo": {
456456
"displayName": "Active Connections",
@@ -537,7 +537,7 @@
537537
"links": null,
538538
"advancedQueries": [
539539
{
540-
"query": "histogram_quantile(0.95, rate(mymetrics_node_compute_duration_seconds_bucket{$__scope}[5m]))",
540+
"query": "histogram_quantile(0.95, rate(mymetrics_compute_duration_seconds_bucket{$__scope}[5m]))",
541541
"enabled": true,
542542
"displayInfo": {
543543
"displayName": "P95 Duration",
@@ -630,7 +630,7 @@
630630
"links": null,
631631
"advancedQueries": [
632632
{
633-
"query": "rate(mymetrics_node_compute_duration_seconds_sum{$__scope}[5m]) / rate(mymetrics_node_compute_duration_seconds_count{$__scope}[5m])",
633+
"query": "rate(mymetrics_compute_duration_seconds_sum{$__scope}[5m]) / rate(mymetrics_compute_duration_seconds_count{$__scope}[5m])",
634634
"enabled": true,
635635
"displayInfo": {
636636
"displayName": "Avg Duration",

metrics-examples/node/README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# # Code Engine custom metrics examples for Node.js
2+
3+
This application helps debug connectivity issues for IBM Cloud Services and provides comprehensive monitoring through Prometheus metrics. It includes outbound HTTP call simulation, database connectivity testing, and compute-intensive workload simulation.
4+
5+
## Features
6+
7+
- **Outbound HTTP Calls**: Configurable endpoints that simulate delays and error responses to httpbin.org-compatible backends
8+
- **Database Testing**: PostgreSQL connectivity verification with instrumented queries
9+
- **Prometheus Metrics**: Comprehensive instrumentation for requests, outbound calls, database operations, and compute workloads
10+
- **Load Testing**: Included shell script for generating realistic traffic patterns
11+
12+
## Quick Start
13+
14+
### Deploy to IBM Cloud Code Engine
15+
16+
Deploy the application with recommended resource settings:
17+
18+
```bash
19+
ibmcloud ce application create \
20+
--name metrics-example-app-node \
21+
--src "." \
22+
--memory 0.5G \
23+
--cpu 0.25 \
24+
--port 8080
25+
```
26+
27+
The `--concurrency 5` setting limits each instance to handle a maximum of 5 concurrent requests, ensuring stable performance given the compute-intensive operations.
28+
29+
To configure environment variables during deployment:
30+
31+
```bash
32+
ibmcloud ce application create \
33+
--name metrics-example-app-node \
34+
--src "." \
35+
--memory 0.5G \
36+
--cpu 0.25 \
37+
--env HTTPBIN_BASE_URL=https://httpbin.org \
38+
--env METRICS_COLLECT_NODE_METRICS_ENABLED=true
39+
```
40+
41+
Update an existing application:
42+
43+
```bash
44+
ibmcloud ce application update \
45+
--name metrics-example-app-node \
46+
--env HTTPBIN_BASE_URL=https://custom-backend.example.com
47+
```
48+
49+
### Run Locally
50+
51+
Pull and run with Docker:
52+
```bash
53+
docker pull icr.io/codeengine/metrics-example-app-node
54+
docker run -p 8080:8080 -p 2112:2112 icr.io/codeengine/metrics-example-app-node
55+
```
56+
57+
Or run from source:
58+
```bash
59+
npm install
60+
node app.mjs
61+
```
62+
63+
The application exposes two servers:
64+
- Main application: `http://localhost:8080`
65+
- Metrics endpoint: `http://localhost:2112/metrics`
66+
67+
## Configuration
68+
69+
### Environment Variables
70+
71+
- `PORT`: Application server port (default: 8080)
72+
- `HTTPBIN_BASE_URL`: Backend URL for outbound calls (default: `https://httpbin.org`)
73+
- `METRICS_NAME_PREFIX`: Prefix for all Prometheus metrics (default: `mymetrics_`)
74+
- `METRICS_COLLECT_NODE_METRICS_ENABLED`: Enable Node.js runtime metrics (set to "true")
75+
- `DATABASES_FOR_POSTGRESQL_CONNECTION`: PostgreSQL connection credentials (JSON format)
76+
77+
### Service Bindings
78+
79+
For database connectivity, create a Code Engine service binding between your project and the IBM Cloud service. See [Working with service bindings](https://cloud.ibm.com/docs/codeengine?topic=codeengine-service-binding) for details.
80+
81+
## API Endpoints
82+
83+
- `GET /` - Health check
84+
- `GET /test-db` - Test PostgreSQL connectivity
85+
- `GET /outbound/delay` - Outbound call with random delay (0-2s) and 5% error rate
86+
- `GET /outbound/get` - Simple outbound GET request
87+
- `POST /outbound/post` - Outbound POST request
88+
- `GET /outbound/status/:code` - Request specific HTTP status code
89+
90+
All outbound endpoints include simulated compute-intensive data processing (0-3s duration, 40-80% CPU intensity).
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const HTTPBIN_BASE_URL = process.env.HTTPBIN_BASE_URL || "https://httpbin.org";
1010
// ====================================
1111
// Initialize Prometheus metrics
1212
// ====================================
13-
const METRICS_NAME_PREFIX = process.env.METRICS_NAME_PREFIX || "mymetrics_node_";
13+
const METRICS_NAME_PREFIX = process.env.METRICS_NAME_PREFIX || "mymetrics_";
1414
// Create a registry to register the metrics
1515
const register = new promClient.Registry();
1616

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "network-test-app",
2+
"name": "metrics-example",
33
"version": "1.0.0",
44
"description": "App to test connectivity to IBM Cloud Services",
55
"main": "app.mjs",

0 commit comments

Comments
 (0)