Skip to main content

Overview

Every workload on Control Plane arrives with its logs, metrics, and traces already collected. The sidecar in front of each replica writes a log line for every request it receives and every request it sends, reports request rate and latency as metrics, and, once tracing is on, records a span for each hop, so a request that crosses from the frontend to the API shows up as one trace. This part reads all three for the system you built, from every location in one place. What you’ll do:
  • Enable tracing on quickstart-gvc, sampling every request.
  • Follow one waitlist signup through the logs of both workloads by its request id.
  • Read the request rate and latency of the three workloads, in the Console and with a PromQL query.
  • Open one trace that spans frontend and api in Grafana.
A POST from your browser gets an id at the frontend, whose sidecar logs the request in and the call out and starts the trace; the frontend calls the api with POST /signups under the same id and the same trace, and the api's sidecar logs the call in and adds its span. Control Plane collects logs, metrics, and traces from both. One request id in every log line, and one trace across both workloads.
Each workload has three log streams per replica, all queried with LogQL:The sidecar stamps every request with an x-request-id header and writes the id into both log lines. The quickstart frontend forwards that header, together with the W3C traceparent header, on its call to the API, which is what ties the two workloads’ lines and spans together.

Prerequisites

  • Completed 4. Add a database and wire its secret, with frontend and api running and the waitlist stored in PostgreSQL.
  • For the CLI and AI Agent paths: the CLI installed and logged in, as in part 2.

Step 1: Enable tracing on the GVC

Tracing is configured on the GVC or on the org, and a GVC setting takes precedence over the org’s. The Control Plane provider stores the traces for you.
1

Open the tracing settings

Click GVCs in the left menu, open quickstart-gvc, and click Tracing in the left pane.
2

Turn it on

Switch on Enable Tracing, keep Control Plane as the Provider, and set Sampling Percentage to 100, so every request is traced while you look.
3

Update

Click Update and reload the page. A Traces link appears in the left pane. A replica reads the tracing setting when it starts, so force a redeployment of frontend and api: open each workload, click Actions, then Force Redeployment.

Step 2: Make a few requests

Once frontend and api report Ready again, open the frontend’s canonical endpoint, reload it a couple of times, and join the waitlist with a new address. Every page load is one request to frontend and one call from frontend to api, and the signup is one more of each.

Step 3: Follow the signup through the logs

The signup was one request from your browser that the frontend turned into calls to the API. The sidecar gave that request an id and wrote it into every line it logged for it, in both workloads, so one id finds the whole path of one user action. That is the search to run when a user reports that something failed.
1

Read the API's own log

Open the api workload and click Logs in the left pane. Click Settings and switch on Show Labels, so every line shows its location and replica. Select api under Container, add |= "POST" to the end of the query so it reads {gvc="quickstart-gvc", workload="api", container="api"} |= "POST", and click Query. One line per signup comes back, written by the API in the location that served it:
Remove the filter to see the rest of what the API writes: a GET /signups 200 2ms line per page load and, first in every replica’s log, api 5 listening on port 8080 in aws-us-west-2, storage: postgres at db-postgres.quickstart-db.cpln.local, where the number is the workload’s version.
2

Find the same call in the frontend's request log

Open the frontend workload, click Logs, select Request Log under Container, add |= "POST" to the end of the query, and click Query. One line comes back, the frontend’s sidecar logging the call it made to the API for your signup:
After the status come the bytes received and sent and the duration in milliseconds, then in quotes the address the call came from, the user agent (node, the frontend’s server-side fetch), the request id, the host called, and the replica that answered. Copy the request id.
3

Search the whole GVC for that id

Replace the query with {gvc="quickstart-gvc"} |= "d9c301d7-a9e9-90ec-a508-326ffe5dd4fb", using your id, select Any Container, make sure Show Labels is on under Settings, and click Query. Five lines come back, and the labels column names the workload and container of each:The two API lines each carry two addresses at the end, the frontend replica that called and the API replica that answered; the frontend’s request-log lines carry only the replica they called.

Step 4: Read the metrics

Open the api workload and click Metrics in the left pane. The Summary group charts Request Latency 90th Percentile, Replica Count, CPU Used, and Memory Used, per location; the groups below it, such as Request Data, CPU, and Memory, hold the rest of the default metrics. Metrics under Analyze in the left menu shows the same charts for the whole org, filtered by GVC, workload, and location.

Step 5: Open the trace

Open quickstart-gvc and click Traces in the left pane. Grafana opens in a new tab on the traces of the GVC from the last hour. Below the charts, the structure lists the path every request took: frontend, under it the call to api.quickstart-gvc.cpln.local:8080/*, and under that api serving it, each with the time it spent. That is one trace with three spans, two from the frontend’s sidecar (the request it received and the call it made) and one from the API’s sidecar. Your AI agent reads the same trace:
The agent searches the GVC’s traces and summarizes the one it finds: the frontend’s span for the request it received, its call to api.quickstart-gvc.cpln.local:8080, and the API’s span, each with its duration.
The sidecars join hops through the W3C traceparent header. The frontend forwards it on its call to the API, so the API’s span lands in the same trace. A call made without it starts a new trace, and B3 headers such as x-b3-traceid are not read.

Verify

  • The GVC-wide log search for one request id returns five lines from frontend and api.
  • The request-rate query lists web, frontend, and api in both locations.
  • The trace structure in Grafana shows api beneath frontend.
You followed one user action across two workloads by its request id, read the metrics every workload publishes, and opened a trace that spans the frontend and the API.

What you’ve learned

  • Three log streams per workload: the container’s own output, the access log of requests it received, and the request log of requests it sent, queried with LogQL from every location in one place.
  • One request id across the hop: the sidecar stamps x-request-id on every request, and an application that forwards it lets one id find every line a user action produced in both workloads.
  • Metrics without an agent: request rate, latency, errors, CPU, memory, and replica counts are collected for every workload and queried with PromQL.
  • Tracing is a GVC setting: enable it once with a sampling percentage, and every sidecar in the GVC records a span per hop from the moment its replica starts. Set it on the org instead to cover every GVC.
  • Trace context is traceparent: an application that forwards traceparent and tracestate keeps its outgoing calls in the caller’s trace.

Next steps

The system is complete: a frontend, an API, and a database across two clouds, with logs, metrics, and traces for all of it. One part is left, and it is optional.

6. Configure a custom domain

Optional. Put your own domain in front of the frontend, with a certificate Control Plane issues and renews. It needs a domain you own, and nothing else in the series depends on it.

Learn more

Logs

LogQL, filters, live tail, and the queries behind the Logs page.

Default Metrics

Every metric Control Plane publishes for orgs, workloads, volumes, and domains.

Tracing

Sampling, custom tags, and sending traces to your own OpenTelemetry collector.

External logging

Ship the same logs to your own logging provider.

Clean up

To remove everything the series has created:
1

Delete the domain, if you did part 6

Open Domains, select your domain, click Actions, then Delete, and confirm.
2

Delete the policy

Open Policies, select api-db-policy, click Actions, then Delete, and confirm.
3

Uninstall the database release

Under Templates, click Releases, open db, click Actions, then Uninstall, and confirm.
4

Delete the database GVC

Open quickstart-db, click Actions, then Delete, type the GVC name to confirm, and click Delete.
5

Delete the application GVC

Open quickstart-gvc, click Actions, then Delete, type the GVC name to confirm, and click Delete. web, frontend, api, api-identity, and the tracing setting go with it.
6

Delete the secret

Open Secrets, select db-credentials, click Actions, then Delete, and confirm.
7

Delete the images

Open Images, select frontend, and click Actions, then Delete to remove all its tags. Repeat for api.
Uninstalling the release removes its volume set and the data on it. If you did part 6, remove the DNS records from your DNS provider after deleting the domain. A --remote build also pushes the build cache images frontend-cache:latest and api-cache:latest; delete those too if you built without Docker.