Get started with Managed ClickStack
This guide takes you from an empty Managed ClickStack service all the way to logs, metrics, traces, and session replays flowing from a real application. You'll deploy a new OpenTelemetry collector (or adapt an existing one if you have one) against your service, instrument a sample Node.js application with no changes to its business logic, then explore the telemetry in the ClickStack UI.
If you're setting up a new collector, or using your own, it should run as a gateway: a single OTLP endpoint that your applications, SDKs, and agent collectors send to. The gateway batches events, applies any processing you've configured, and writes them to ClickHouse via the ClickHouse exporter.
The application we'll instrument is the HackerNews Analyzer, a Node.js app that queries the HackerNews dataset hosted in the public ClickHouse demo. Every chart, table, and search box is backed by a real ClickHouse query, so every interaction produces a trace whose main span is the HTTPS call from the backend out to ClickHouse.
Prerequisites
- A Managed ClickStack service in ClickHouse Cloud.
- Node 18+ and npm to run the sample application.
- Docker, if you don't already have a collector and want to follow the new-collector path below.
Gather your credentials
You'll need:
- The HTTPS endpoint of your ClickHouse Cloud service, including protocol and port, for example
https://abc123xyz.us-central1.gcp.clickhouse.cloud:8443. - A ClickHouse username and password for ingestion.
If you don't have these recorded, open your service in the ClickHouse Cloud console and select Connect. Record the url from the subsequent dialog. We will create a dedicated user for ingestion below.
Create an ingestion user
We recommend creating a dedicated user for the collector rather than reusing default. Connect to your service via the SQL console and run:
Replace the password in the snippet above with a strong value.
The collector creates the schema for logs, traces, and metrics inside the otel database on first use. For more guidance on production user setup, see Going to production.
Deploy the collector
Pick the option that matches your situation.
If you're using an existing OpenTelemetry collector, we assume it's already configured in a gateway role. We don't recommend using this process for reconfiguring collectors in the agent role.
- I don't have a collector
- I have a collector
Deploy the ClickStack distribution of the OpenTelemetry collector, which is preconfigured for Managed ClickStack. In the example below, we run the collector locally for simplicity.
In production, you would typically deploy the collector in a Kubernetes cluster, or on a virtual machine that can be reached by your OpenTelemetry SDKs, agents, and other collectors. This allows telemetry from across your environment to be centrally collected and forwarded to ClickStack.
Pick a shared secret to authenticate clients sending data to the collector, then export it alongside your connection details and chosen password for the hyperdx_ingest user:
Run the ClickStack OTel collector:
The collector now exposes OTLP gRPC on 4317 and OTLP HTTP on 4318. Applications, SDKs, and agent collectors should send to these ports with authorization: $OTLP_AUTH_TOKEN in the request headers. Keep the OTLP endpoint and the OTLP_AUTH_TOKEN to hand, you'll point the application at them in the next steps.
For production, we recommend enabling TLS on the OTLP endpoint. See Securing the collector.
Extend your existing collector configuration to write to Managed ClickStack via the ClickHouse exporter.
If you're using your own distribution, ensure it includes the ClickHouse exporter. The upstream contrib image already does.
Below is an example configuration that uses the ClickHouse exporter with the receivers, processors, and pipelines expected by the ClickStack UI. It matches the behavior of the ClickStack distribution, including the Session Replay (rrweb) routing path. Substitute <clickhouse_cloud_endpoint> and <your_password_here> with the credentials for the hyperdx_ingest user created above:
A few things to note:
- The
otlp/hyperdxreceiver listens on both gRPC (4317) and HTTP (4318); applications and agents should target these ports on your collector host. - The
clickhouseexporter writes logs, traces, and metrics into theoteldatabase, matching the layout the ClickStack UI expects. Theclickhouse/rrwebexporter handles Session Replay events routed by therouting/logsconnector intootel.hyperdx_sessions. - Authentication on the OTLP receivers is left to your existing setup. Configure it via collector extensions (for example
bearertokenauth) or a TLS-fronted reverse proxy if you need to require an ingestion token.
Reload your collector with the new configuration. Keep the OTLP endpoint and whatever auth header your setup expects to hand, you'll point the application at them in the next steps.
For further details on configuring OpenTelemetry collectors against Managed ClickStack, see Ingesting with OpenTelemetry.
Clone and run the application
Clone the repository, install dependencies, and create your .env file:
The ClickHouse data source defaults to the public read-only demo cluster, so the app runs without any further configuration. Start it:
Open http://localhost:5001. You will see a year selector, summary statistics, an activity chart, top users and domains tables, and a search box. Click around: switch years, drill into stories.
At this point the application is running but uninstrumented. ClickStack shows no data: it is waiting for telemetry. This is the "before" state.
Connect the application to your collector
The application needs two values to reach the collector you deployed above:
OTEL_EXPORTER_OTLP_ENDPOINT: the OTLP endpoint your collector exposes (commonly port4318for OTLP over HTTP).OTEL_EXPORTER_OTLP_HEADERS: the authorization header carrying your ingestion token, in the formauthorization=<token>. Use theOTLP_AUTH_TOKENyou set on the collector above, or whatever auth header your existing collector expects.
Open .env and set them:
The SDK uses OTEL_EXPORTER_OTLP_HEADERS to set the authorization header for all three signals: traces, metrics, and logs. If your collector runs locally and doesn't enforce auth, you can leave the value empty (OTEL_EXPORTER_OTLP_HEADERS=authorization=), but the variable must be present; the SDK skips initialization entirely if it's unset or fully empty.
Instrument the application
Instrumentation has three parts: install the SDKs, switch the launch command, and enable the browser SDK. None of it changes the application's business logic.
Install the SDKs
Install both the backend and browser OpenTelemetry SDKs:
Use the opentelemetry-instrument CLI
The application is launched by run.sh, which has two exec lines at the bottom: one active, one commented. Switch which one is active so Node is wrapped by opentelemetry-instrument:
That is the entire backend change. The auto-instrumentation is loaded by opentelemetry-instrument at process start.
Enable the browser SDK
To capture distributed traces (browser to backend) and session replays, enable the browser SDK in src/web/telemetry.ts. Uncomment the import and the HyperDX.init({...}) block:
No extra .env edits are required. __OTLP_ENDPOINT__ and __OTLP_AUTH_TOKEN__ are compile-time constants injected by vite.config.ts: the endpoint is OTEL_EXPORTER_OTLP_ENDPOINT and the token is parsed out of OTEL_EXPORTER_OTLP_HEADERS, the same values the backend uses.
The ingestion token is baked into the public browser bundle and is readable by anyone inspecting the network tab.
Generate traffic
Restart the application so the new launch command and freshly built browser bundle take effect:
Reload the browser tab so Vite serves the updated bundle, then refresh the app a few times, switch years, and click into stories to generate traffic. Each interaction sends logs, metrics, traces, and session replay events through your collector and into ClickStack.
Launch ClickStack and explore your telemetry
Open your service in the ClickHouse Cloud console and select ClickStack from the left menu, then Start Ingestion.
The next step can be skipped, as you've already configured your collector. Click Launch ClickStack to continue.
ClickStack will open in a new tab and you should be automatically directed to the Getting Started page. If not, select Getting Started from the left-hand menu, then click Start Ingestion followed by Next.
ClickStack should automatically detect your tables and telemetry data, allowing you to proceed. Select Start Exploring to begin exploring your data.
Now view the data the application is producing:
- Go to Search and filter to the last 5 minutes. Logs for
hn-analyzer-apistream in.
- Click into a request and walk up the trace. You will see the Express handler span, a child HTTP span pointing at the ClickHouse cluster with real network duration, and correlated
console.logrecords on the same trace.
- Open Session Replay to play back a scrubbable video of a browser session, synced to the trace timeline.
Logs, metrics, traces, and session replays all land in the same UI, share the same query language, and are correlated automatically.
If nothing shows up:
- Confirm the auth header value set in
OTEL_EXPORTER_OTLP_HEADERSmatches the one your collector expects. - Tail your collector's logs and look for export errors.
- Verify the ClickHouse endpoint configured on the collector includes both the protocol and port (
https://...:8443).
Further reading
- Monitoring Kubernetes: collect logs, infra metrics, and Kubernetes events from a cluster.
- Monitoring AWS CloudWatch logs: forward CloudWatch logs via the OpenTelemetry CloudWatch receiver.
- Tuning Managed ClickStack: refine your schema for query performance and storage efficiency.
- Securing the collector with TLS on the OTLP endpoint and least-privilege ingestion users.
- Going to production for recommendations when going to production.