@specific.dev/cli 0.1.161 → 0.1.163
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/404/index.html +1 -1
- package/dist/admin/404.html +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +2 -2
- package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/__next._full.txt +2 -2
- package/dist/admin/__next._head.txt +1 -1
- package/dist/admin/__next._index.txt +1 -1
- package/dist/admin/__next._tree.txt +1 -1
- package/dist/admin/_next/static/chunks/{d5bf905a3d3f005b.js → 03b7f2d1ca0f0722.js} +1 -1
- package/dist/admin/_next/static/chunks/{7e5c5b91b30c68a0.js → 6623aba8114d9978.js} +2 -2
- package/dist/admin/_not-found/__next._full.txt +1 -1
- package/dist/admin/_not-found/__next._head.txt +1 -1
- package/dist/admin/_not-found/__next._index.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.txt +1 -1
- package/dist/admin/_not-found/__next._tree.txt +1 -1
- package/dist/admin/_not-found/index.html +1 -1
- package/dist/admin/_not-found/index.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/databases/__next._full.txt +1 -1
- package/dist/admin/databases/__next._head.txt +1 -1
- package/dist/admin/databases/__next._index.txt +1 -1
- package/dist/admin/databases/__next._tree.txt +1 -1
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +1 -1
- package/dist/admin/fullscreen/__next._full.txt +2 -2
- package/dist/admin/fullscreen/__next._head.txt +1 -1
- package/dist/admin/fullscreen/__next._index.txt +1 -1
- package/dist/admin/fullscreen/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +2 -2
- package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/index.html +1 -1
- package/dist/admin/fullscreen/databases/index.txt +1 -1
- package/dist/admin/fullscreen/index.html +1 -1
- package/dist/admin/fullscreen/index.txt +2 -2
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +2 -2
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/mail/__next._full.txt +1 -1
- package/dist/admin/mail/__next._head.txt +1 -1
- package/dist/admin/mail/__next._index.txt +1 -1
- package/dist/admin/mail/__next._tree.txt +1 -1
- package/dist/admin/mail/index.html +1 -1
- package/dist/admin/mail/index.txt +1 -1
- package/dist/admin/services/__next.!KGRlZmF1bHQp.services.__PAGE__.txt +1 -1
- package/dist/admin/services/__next.!KGRlZmF1bHQp.services.txt +1 -1
- package/dist/admin/services/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/services/__next._full.txt +1 -1
- package/dist/admin/services/__next._head.txt +1 -1
- package/dist/admin/services/__next._index.txt +1 -1
- package/dist/admin/services/__next._tree.txt +1 -1
- package/dist/admin/services/index.html +1 -1
- package/dist/admin/services/index.txt +1 -1
- package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.__PAGE__.txt +2 -2
- package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.txt +1 -1
- package/dist/admin/storage/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/storage/__next._full.txt +2 -2
- package/dist/admin/storage/__next._head.txt +1 -1
- package/dist/admin/storage/__next._index.txt +1 -1
- package/dist/admin/storage/__next._tree.txt +1 -1
- package/dist/admin/storage/index.html +1 -1
- package/dist/admin/storage/index.txt +2 -2
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
- package/dist/admin/workflows/__next._full.txt +1 -1
- package/dist/admin/workflows/__next._head.txt +1 -1
- package/dist/admin/workflows/__next._index.txt +1 -1
- package/dist/admin/workflows/__next._tree.txt +1 -1
- package/dist/admin/workflows/index.html +1 -1
- package/dist/admin/workflows/index.txt +1 -1
- package/dist/cli.js +12 -3
- package/dist/docs/index.md +1 -0
- package/dist/docs/observability.md +192 -0
- package/package.json +1 -1
- /package/dist/admin/_next/static/{4_42SkCjqmgu0V3Wfnmok → EbVmgKWgDvW4075VZ1PdS}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{4_42SkCjqmgu0V3Wfnmok → EbVmgKWgDvW4075VZ1PdS}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{4_42SkCjqmgu0V3Wfnmok → EbVmgKWgDvW4075VZ1PdS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Observability
|
|
2
|
+
|
|
3
|
+
Every deployed environment streams logs and metrics into a queryable store. Use `specific query` to run SQL against this data — useful for debugging production incidents, investigating regressions, and ad-hoc analytics.
|
|
4
|
+
|
|
5
|
+
## Running a query
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
# Inline
|
|
9
|
+
specific query "SELECT count() FROM observability.logs"
|
|
10
|
+
|
|
11
|
+
# Against a specific environment
|
|
12
|
+
specific query --environment staging "SELECT * FROM observability.logs LIMIT 5"
|
|
13
|
+
|
|
14
|
+
# From a file via stdin
|
|
15
|
+
cat queries/p99.sql | specific query
|
|
16
|
+
specific query - < queries/p99.sql
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Flags:
|
|
20
|
+
|
|
21
|
+
- `-e, --environment <name|id>` — target environment (defaults to the current one).
|
|
22
|
+
|
|
23
|
+
Queries are automatically scoped to the selected environment. You cannot see data from other environments and you do not need to filter on environment yourself.
|
|
24
|
+
|
|
25
|
+
Queries are read-only. `INSERT`, `UPDATE`, `DELETE`, and DDL are rejected. Each query is capped at 30 seconds of execution time, returns at most 100,000 rows, and the SQL string itself is limited to 50,000 characters.
|
|
26
|
+
|
|
27
|
+
## Schema
|
|
28
|
+
|
|
29
|
+
Two views are exposed in the `observability` database.
|
|
30
|
+
|
|
31
|
+
### `observability.logs`
|
|
32
|
+
|
|
33
|
+
Unified log stream from services.
|
|
34
|
+
|
|
35
|
+
| Column | Type | Notes |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `Timestamp` | DateTime64(9) | When the log was emitted; use time arithmetic directly (`Timestamp > now() - INTERVAL 1 HOUR`) |
|
|
38
|
+
| `ServiceName` | String | Name of the service that emitted the log |
|
|
39
|
+
| `SeverityText` | String | |
|
|
40
|
+
| `SeverityNumber` | UInt8 | |
|
|
41
|
+
| `Body` | String | The log message |
|
|
42
|
+
| `LogAttributes` | Map(String, String) | Per-event attributes |
|
|
43
|
+
| `ResourceAttributes` | Map(String, String) | Resource labels (e.g. `service.name`, `service.namespace`, `deployment.environment.name`) |
|
|
44
|
+
| `TraceId` | String | Distributed-tracing trace ID, if present |
|
|
45
|
+
| `SpanId` | String | Distributed-tracing span ID, if present |
|
|
46
|
+
|
|
47
|
+
Also exposed but rarely queried directly: `EnvironmentId`, `ProjectId` (already used for auto-scoping), `TraceFlags`.
|
|
48
|
+
|
|
49
|
+
Retention: up to 30 days. Your plan may further restrict how far back queries can read; when that cutoff is in effect, `specific query` prints a one-line note on stderr.
|
|
50
|
+
|
|
51
|
+
### `observability.metrics`
|
|
52
|
+
|
|
53
|
+
Unified metrics from services.
|
|
54
|
+
|
|
55
|
+
| Column | Type | Notes |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `TimeUnix` | DateTime64(9) | Measurement timestamp; use time arithmetic directly (`TimeUnix > now() - INTERVAL 1 HOUR`) |
|
|
58
|
+
| `MetricName` | String | e.g. `container.cpu.time` (see list below) |
|
|
59
|
+
| `MetricType` | String | `'gauge'` or `'sum'` |
|
|
60
|
+
| `Value` | Float64 | Measured value |
|
|
61
|
+
| `ServiceName` | String | Service that emitted the metric |
|
|
62
|
+
| `Attributes` | Map(String, String) | Metric dimensions |
|
|
63
|
+
| `ResourceAttributes` | Map(String, String) | Resource labels |
|
|
64
|
+
|
|
65
|
+
Also exposed but rarely queried directly: `StartTimeUnix` (DateTime64(9)), `EnvironmentId`, `ProjectId`, `Source`.
|
|
66
|
+
|
|
67
|
+
Retention: up to 90 days. Your plan may further restrict how far back queries can read; when that cutoff is in effect, `specific query` prints a one-line note on stderr.
|
|
68
|
+
|
|
69
|
+
#### Service metrics
|
|
70
|
+
|
|
71
|
+
Emitted for every running service container.
|
|
72
|
+
|
|
73
|
+
| Metric | Type | Notes |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `container.cpu.time` | sum | Cumulative CPU seconds consumed; rate it (`avg(Value)` over a window or per-second deltas) for utilisation |
|
|
76
|
+
| `container.cpu.usage` | gauge | Current CPU usage in cores |
|
|
77
|
+
| `container.cpu.limit_utilization` | gauge | Fraction of CPU limit used (0–1) |
|
|
78
|
+
| `container.memory.working_set` | gauge | Memory in active use (bytes) — the right number for "is this service close to OOM" |
|
|
79
|
+
| `container.memory.usage` | gauge | Total memory usage including page cache (bytes) |
|
|
80
|
+
| `container.memory.available` | gauge | Memory still available before the container limit (bytes) |
|
|
81
|
+
| `k8s.volume.available` | gauge | Free space on attached volumes (bytes) |
|
|
82
|
+
| `k8s.volume.capacity` | gauge | Total capacity of attached volumes (bytes) |
|
|
83
|
+
|
|
84
|
+
## Debugging recipes
|
|
85
|
+
|
|
86
|
+
### Recent errors for a specific service
|
|
87
|
+
|
|
88
|
+
```sql
|
|
89
|
+
SELECT Timestamp, Body
|
|
90
|
+
FROM observability.logs
|
|
91
|
+
WHERE ServiceName = 'api'
|
|
92
|
+
AND SeverityNumber >= 17
|
|
93
|
+
AND Timestamp >= now() - INTERVAL 1 HOUR
|
|
94
|
+
ORDER BY Timestamp DESC
|
|
95
|
+
LIMIT 50
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Search log bodies for a substring
|
|
99
|
+
|
|
100
|
+
```sql
|
|
101
|
+
SELECT Timestamp, ServiceName, Body
|
|
102
|
+
FROM observability.logs
|
|
103
|
+
WHERE positionCaseInsensitive(Body, 'connection refused') > 0
|
|
104
|
+
AND Timestamp >= now() - INTERVAL 6 HOUR
|
|
105
|
+
ORDER BY Timestamp DESC
|
|
106
|
+
LIMIT 100
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Warning-or-worse rate by service
|
|
110
|
+
|
|
111
|
+
```sql
|
|
112
|
+
SELECT ServiceName, count() AS errs
|
|
113
|
+
FROM observability.logs
|
|
114
|
+
WHERE SeverityNumber >= 13
|
|
115
|
+
AND Timestamp >= now() - INTERVAL 1 HOUR
|
|
116
|
+
GROUP BY ServiceName
|
|
117
|
+
ORDER BY errs DESC
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Service CPU timeseries (1-minute buckets)
|
|
121
|
+
|
|
122
|
+
```sql
|
|
123
|
+
SELECT
|
|
124
|
+
toStartOfMinute(TimeUnix) AS bucket,
|
|
125
|
+
avg(Value) AS cpu_cores
|
|
126
|
+
FROM observability.metrics
|
|
127
|
+
WHERE MetricName = 'container.cpu.usage'
|
|
128
|
+
AND ServiceName = 'api'
|
|
129
|
+
AND TimeUnix >= now() - INTERVAL 1 HOUR
|
|
130
|
+
GROUP BY bucket
|
|
131
|
+
ORDER BY bucket
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Memory headroom over time
|
|
135
|
+
|
|
136
|
+
```sql
|
|
137
|
+
SELECT
|
|
138
|
+
TimeUnix,
|
|
139
|
+
ServiceName,
|
|
140
|
+
Value AS working_set_bytes
|
|
141
|
+
FROM observability.metrics
|
|
142
|
+
WHERE MetricName = 'container.memory.working_set'
|
|
143
|
+
AND TimeUnix >= now() - INTERVAL 30 MINUTE
|
|
144
|
+
ORDER BY TimeUnix
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Correlate all logs belonging to one trace
|
|
148
|
+
|
|
149
|
+
```sql
|
|
150
|
+
SELECT Timestamp, ServiceName, Body
|
|
151
|
+
FROM observability.logs
|
|
152
|
+
WHERE TraceId = '<trace-id>'
|
|
153
|
+
ORDER BY Timestamp
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Performance
|
|
157
|
+
|
|
158
|
+
Both views are partitioned and ordered to make environment-scoped, time-bounded queries fast. To stay within the 30-second limit on large environments:
|
|
159
|
+
|
|
160
|
+
- **Always filter by time** — `Timestamp >=` for logs, `TimeUnix >=` for metrics. Unbounded scans across 30/90 days will time out.
|
|
161
|
+
- **Add `ServiceName` and/or `MetricName`** to narrow the partition further whenever you can.
|
|
162
|
+
- **`SELECT` only the columns you need** rather than `SELECT *`; `Body`, `LogAttributes`, and `ResourceAttributes` are the heavyweight columns.
|
|
163
|
+
- **`LIMIT` exploratory queries** while you're shaping them.
|
|
164
|
+
|
|
165
|
+
## Discovering data
|
|
166
|
+
|
|
167
|
+
When you don't know what's there, ask the database:
|
|
168
|
+
|
|
169
|
+
```sql
|
|
170
|
+
SHOW TABLES FROM observability;
|
|
171
|
+
DESCRIBE observability.logs;
|
|
172
|
+
|
|
173
|
+
SELECT DISTINCT ServiceName FROM observability.logs LIMIT 50;
|
|
174
|
+
SELECT DISTINCT MetricName FROM observability.metrics LIMIT 100;
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Useful ClickHouse functions
|
|
178
|
+
|
|
179
|
+
The store is ClickHouse, so the full ClickHouse SQL dialect is available. A few commonly needed functions:
|
|
180
|
+
|
|
181
|
+
- `now()`, `now64()` — current time
|
|
182
|
+
- `toStartOfMinute(t)`, `toStartOfFiveMinutes(t)`, `toStartOfHour(t)` — bucket timestamps for time-series aggregation
|
|
183
|
+
- `positionCaseInsensitive(haystack, needle)` — case-insensitive substring search
|
|
184
|
+
- `JSONExtractString(s, 'field')`, `JSONExtractInt`, `JSONExtractFloat` — pull fields out of JSON-formatted log bodies
|
|
185
|
+
- `LogAttributes['key']`, `Attributes['key']`, `ResourceAttributes['key']` — read map columns
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
Related topics:
|
|
190
|
+
|
|
191
|
+
- Run `specific docs services` for how services are defined
|
|
192
|
+
- Run `specific docs postgres` for connecting to your application database (use `specific psql` for application data, not `specific query`)
|
package/package.json
CHANGED
/package/dist/admin/_next/static/{4_42SkCjqmgu0V3Wfnmok → EbVmgKWgDvW4075VZ1PdS}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/admin/_next/static/{4_42SkCjqmgu0V3Wfnmok → EbVmgKWgDvW4075VZ1PdS}/_ssgManifest.js
RENAMED
|
File without changes
|