What Nodrik investigates
Nodrik investigates whatever your own alerting policies send it. That is true, and on its own it is not much use if you are deciding whether this will work on your stack — because “investigates” covers a range, and the range has a shape.
This page is that shape. What every investigation reads, the eleven kinds of service Nodrik knows how to ask sharper questions of, and what happens to an alert that is none of them.
The short version: an alert Nodrik recognises gets specialist framing; an alert it does not still gets investigated, with everything below. Nothing is refused for being unfamiliar.
The tools
Section titled “The tools”This is the whole catalogue — every read Nodrik can make of its own accord, and there is nothing else.
| Tool | What it reads | Family |
|---|---|---|
query_logs |
Cloud Logging entries matching a filter | Every investigation |
get_metric_series |
one Cloud Monitoring time series, over a window | Every investigation |
list_error_groups |
Error Reporting groups, most-affected first | Every investigation |
list_alerts |
what else is firing in the project right now, and when each started | Every investigation |
list_alert_policies |
the alerting policies the project has configured at all | Every investigation |
list_revisions |
a Cloud Run service’s recent revisions and their configuration | Every investigation |
list_recent_commits |
recent commit metadata — sha, author, message | GitHub connected |
get_commit_diff |
the file diffs of one commit | GitHub connected |
read_code |
one source file at a ref, truncated | GitHub connected |
list_recent_changes |
the admin-activity audit log — IAM grants, config edits, deploys: who did what, when | Every investigation |
get_database_health |
connections, CPU, memory, disk and replication lag for one instance, in a single call | Cloud SQL / AlloyDB |
get_database_config |
instance settings — tier, availability, disk, database flags such as max_connections, maintenance window, replicas |
Cloud SQL / AlloyDB ‡ |
get_cache_config |
instance settings for Redis, Valkey or Memcached — memory size, eviction policy, tier, version, replicas, maintenance window | Memorystore ‡ |
get_workload_health |
container restarts, memory and CPU against limits, uptime and node conditions for a namespace or workload, in a single call | GKE |
list_cluster_events |
Kubernetes events, cluster-autoscaler decisions and node OOM kills, from Cloud Logging — never from the cluster | GKE |
get_cluster_config |
cluster settings from the GKE API — control-plane and node-pool versions, release channel, autoscaling bounds, an upgrade in progress | GKE ‡ |
get_instance_config |
instance settings — machine type, status, scheduling, its managed instance group and autoscaler bounds, recent zone operations | Compute Engine ‡ |
get_backend_health |
per-backend health with the reason, timeouts and balancing mode, health-check thresholds, and the URL-map routes to it | Load balancing ‡ |
search_gcp_docs |
Google’s published Google Cloud documentation — reference material, never anything of yours | Google’s documentation |
read_gcp_doc |
one section of a documentation page a search already listed — Google’s again, not yours | Google’s documentation |
‡ needs one of the optional configuration roles, which you may never grant. Without it the tool is not offered at all, and Nodrik says a setting would have decided the answer rather than guessing at one.
The two documentation tools are worth calling out because the names read
the wrong way round at a glance: they search and read Google’s public
documentation, to check what an error, a quota or a gcloud flag
currently means. They read nothing of yours, and whether they are offered
at all is a setting on our deployment rather than anything in your
project.
Everything else on that list is your telemetry, read through the
four viewer roles you granted:
roles/logging.viewer for the logs and the audit log,
roles/monitoring.viewer for the metrics, the alerts and the policies,
roles/errorreporting.viewer for the error groups, and roles/run.viewer
for the Cloud Run revisions. Connecting
GitHub adds the three that read commits, diffs and
source.
If the tool you need is not on that list, that is what MCP is for. Nodrik will not grow a tool per service. Every declared tool costs tokens on every investigation, for every customer — a reader of Crashlytics is dead weight for a customer with no mobile app — so the catalogue stays the size one model can hold. What is missing from it is yours to expose: connect your own tools.
The eleven families
Section titled “The eleven families”A family is a kind of thing that fails in a particular way. When an alert names one, Nodrik is told what that kind of thing fails on before it starts, so it asks about connections and replication lag on a database rather than about revisions.
The grouping is by what an investigator asks next, not by Google’s product taxonomy. Cloud SQL and AlloyDB are one family because the questions are identical; load balancing is not part of Compute Engine, because “which backend is unhealthy” has nothing to do with “is the VM up”.
| Service | What Nodrik asks of it |
|---|---|
| Cloud Run | the newest revision and its traffic split, container start failures, request concurrency, the max-instances ceiling |
| Cloud SQL and AlloyDB | connections against the instance limit, replication lag, storage headroom, long-running transactions and locks, maintenance in the window |
| Memorystore | evictions and memory pressure, connected clients against the limit, whether a failover happened |
| GKE | whether the container crashed or was never scheduled, whether a rollout or an upgrade came first, whether a probe is failing or an image cannot be pulled |
| Compute Engine | instance state and any recent stop, restart or live migration, disk pressure, managed-instance-group resizes |
| Pub/Sub and Cloud Tasks | the oldest unacknowledged message age, backlog size, dead-letter volume, whether a push endpoint is returning errors |
| Load balancing | backend health and which backend the errors come from, certificate expiry, recent URL-map or backend-service changes |
| Cloud Storage | request error rates and which operation is failing — bucket-level breakage is usually permissions or lifecycle, so the audit log gets read |
| BigQuery, Dataflow and Composer | failed jobs and their errors, slot or worker contention, quota |
| Cloud Functions and App Engine | the deployed version, cold starts, execution timeouts, memory limits |
| Firestore and Spanner | contention and hot keys, and whether the caller changed — these services have few knobs, so the change is usually upstream |
Six of those eleven buy nothing but that framing. Cloud Run,
messaging, Cloud Storage, analytics, the legacy serverless pair and the
NoSQL pair have no tool of their own: their questions are answerable from
the logs and metrics every investigation already reads, and a tool that
only rephrased get_metric_series would cost every customer tokens in
order to say so. The five that earned one — Cloud SQL and AlloyDB,
Memorystore, GKE, Compute Engine, load balancing — are the five named in
the Family column above.
GKE is the family with a stated boundary, and it is permanent rather than a rung waiting to be climbed: Nodrik never connects to your cluster. Pod phase, exit codes and an HPA’s own state are not visible from telemetry, so a verdict that needs them says so under “what would confirm it” instead of inferring it. Configuration roles has the detail, including the two roles Google offers that Nodrik will not ask for.
Four families at most
Section titled “Four families at most”One investigation may reach for four families. The declaration rides in the prompt of every step, so this is a cost control before it is anything else — and a shorter list of sharper tools beats a long list the model has to read past.
They are chosen in this order:
- The alert. Whatever its
resource.typenames. Always included: it is the thing that fired. - Anything an admin turned on in the console, for a dependency inference has no way to see.
- What the alerting service’s own configuration shows it uses — only for a Cloud Run alert, and only from the service’s static configuration: the Cloud SQL instances it mounts, and the names of its environment variables. Never their values; a variable’s value is where a connection string, and so a password, lives, and nothing in Nodrik reads one.
A family turned off in the console is dropped from (2) and (3) and never from (1). A Cloud SQL alert investigated without the Cloud SQL questions is the one outcome the whole mechanism exists to prevent, and the alert in hand knows more than a preference stored last month.
What is deliberately not on that list is the rest of your project. A Cloud SQL alert three weeks ago proves the project contains a database; it does not follow that the service in trouble now talks to it, and a step spent on a healthy database is a step not spent on the cause.
The console records the families it has seen alert, under Settings ▸ Investigating ▸ What Nodrik has seen. That census is a fact about your project, shown to you — it does not choose tools.
An alert that is none of them
Section titled “An alert that is none of them”Nothing about an unfamiliar alert is refused. It is investigated with the tools every investigation has. The difference is that nothing has said what this kind of thing tends to fail on, so the investigation works it out from the evidence — and sometimes spends a step finding out what the thing is not.
Here is a real one, and it is worth more than the abstraction.
On 21 September a Firebase Crashlytics alert from a customer’s project reached Nodrik. Crashlytics matches none of the eleven — no family recognises its monitored resource type, and none is going to — so the investigation began with no framing at all. It ran roughly a dozen calls, and this is the shape of them:
list_alerts— what else is firing. Good first move.list_revisionsfor a Cloud Run service named after the app. There is no such service. Wasted.list_recent_commits— the repository is not part of this installation. Wasted.list_recent_changes— the admin-activity audit log.query_logsfiltered onresource.type="firebase_crashlytics". That is not a monitored resource type, and Cloud Logging answered400.query_logsagain, broader. Useful.get_metric_seriesonlogging.googleapis.com/user/crashlytics_fatal_events— found it.list_alert_policies— what the project watches at all.
It reached a verdict, and it reached it through the log-based metric: Crashlytics fatal events surface in Cloud Monitoring like any other metric, so the universal tools were enough. Two calls of the dozen were spent on a Cloud Run service and a repository that do not exist, because nothing told the model this was a mobile crash rather than a service.
That is what a missing family costs. Not a failure — a couple of wasted steps out of a bounded budget, and a report with less of the specific knowledge a Crashlytics-shaped question deserves.
Where the real boundary is
Section titled “Where the real boundary is”The wasted calls are the small half. The large half is this:
Nodrik can see that Crashlytics fired. It cannot see into Crashlytics. Which issue, the stack trace, the affected build, how many users — none of that is in Cloud Monitoring, and none of the four viewer roles reaches it. The alert is investigable. The diagnosis is not.
That shape recurs. Whenever the fact that something is wrong reaches Google Cloud but the detail of what is wrong lives in a system of your own, Nodrik gets as far as the symptom and stops.
Where the line is, and why it is there
Section titled “Where the line is, and why it is there”The eleven families are what Nodrik reads by itself, and that list does not grow casually. Everything else is yours to expose.
The reason is worth stating rather than implying. A built-in tool has to earn its declaration on every investigation, for every customer, because that is where it is paid for: every tool in the catalogue above rides in the prompt of every step of every investigation we run. A Crashlytics reader is dead weight for a customer with no mobile app. A catalogue of two hundred services is one no model can hold and no person can reason about, and it would make every investigation worse for everybody in order to make a few better for somebody.
So the line is drawn at what is common enough to be worth it to everyone — and on the other side of it, you get a way in. One read Nodrik cannot reach, which everything around it already works with: an MCP server you host, or a single HTTP endpoint. It runs on your infrastructure under a credential you issued, Nodrik calls it during an investigation, and the answer still arrives as one card in Slack.
Connect your own tools has the setup, the limits and the three things Nodrik guarantees about calling it.