Skip to content

Commit ccecd24

Browse files
danielpaulusUbuntuclaude
authored
feat(cli): gRPC/SSL/Traceroute typed result rendering + IaC constructs (#1362)
* feat(reporters): per-type TRACEROUTE/GRPC/SSL result rendering (P4-CLI-RESULTS) Render failure-debug diagnostics for the three uptime monitor types across every CLI result surface, mirroring the 4.1 public check-results fields: - rest/check-results.ts: typed TracerouteCheckResult/GrpcCheckResult/ SslCheckResult interfaces + additive fields on CheckResult/CheckResultField. - formatters/check-result-detail.ts: per-type terminal + markdown diagnostic block (checks results get) keyed on the typed fields. - reporters/util.ts: GRPC/SSL/TRACEROUTE branches in formatCheckResult (checkly test terminal), sourced from the runner artifact (checkRunData). - formatters/batch-stats.ts: add the three types to TIMING_TYPES. - reporters/json.ts: emit a per-type diagnostics object in the JSON report for a failed run (checkly test --reporter json). Snapshot + assertion tests for each type across all three surfaces. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(constructs): add GrpcMonitor, SslMonitor, TracerouteMonitor IaC constructs Implement the missing CLI constructs so users can author and deploy gRPC, SSL and Traceroute uptime monitors via checkly/constructs, and so backend CLI export templates that import these classes compile. Constructs follow the DNS/TCP/ICMP monitor pattern (extend Monitor, register with Session, validate, synthesize): - GrpcMonitor / GrpcRequest / GrpcConfig / GrpcMetadata + GrpcAssertionBuilder (RESPONSE_TIME, GRPC_STATUS_CODE, GRPC_HEALTHCHECK_STATUS, GRPC_RESPONSE, GRPC_METADATA). checkType GRPC, top-level degraded/maxResponseTime (<=30000). - SslMonitor / SslRequest / SslConfig / SecurityBaseline + SslAssertionBuilder (cert expiry, chain, hostname, TLS version, cipher, key size, etc). checkType SSL; response-time limits live in sslConfig (degraded/maxResponseTimeMs). - TracerouteMonitor / TracerouteRequest + TracerouteAssertionBuilder (RESPONSE_TIME, HOP_COUNT, PACKET_LOSS). checkType TRACEROUTE, top-level degraded/maxResponseTime (<=30000); port dropped for ICMP probes. Request shapes mirror the public API (verified against checkly-go-sdk types and the p5-parity captured payloads). Wires exports in constructs/index.ts, import codegen in check-codegen.ts (GRPC/SSL/TRACEROUTE -> *MonitorCodegen), and adds the three types to constants.CheckTypes. Tests: construct synthesize/validation/grouping specs, codegen specs (incl. ICMP port-strip and assertion builders), and a regression spec asserting the backend-style export snippets compile against checkly/constructs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(deploy): skip code-bundle upload when nothing was bundled archive.store() (the 'Uploading Playwright tests' step) was called unconditionally on every deploy. For a project of only uptime monitors (GRPC/SSL/TRACEROUTE), the bundler registers no files, so this uploaded an empty Playwright bundle — an unnecessary code-bundle upload in production, and a hard failure in devenv where it 500s on the storage backend. The remote code bundle is consumed only by Playwright check suites (via bundler.marker -> playwright-check.ts); browser checks upload snapshots separately. Add Bundler.isEmpty and skip store() when no files were registered. Refs T65. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(cli): wire gRPC/SSL/Traceroute analytics paths + connection-error rendering Addresses review (Simo) new-monitor checklist gaps: - src/rest/analytics.ts: add checkTypeToPath (grpc-checks/ssl/traceroute) and defaultMetrics for the three types, matching the backend analytics routes + metric registries (gRPC total_*, SSL handshakeTimeMs_*/daysUntilExpiry_avg, TRACEROUTE finalHopLatencyAvg_*/totalHops_avg). - src/reporters/util.ts: add the Connection Error subsection to the GRPC/SSL/ TRACEROUTE result blocks, mirroring ICMP/DNS. * docs(cli): AI context references + examples for gRPC/SSL/Traceroute monitors Addresses review (Simo) new-monitor checklist Phases 5 & 7: - ai-context/references/configure-{grpc,ssl,traceroute}-monitors.md + REFERENCES and EXAMPLE_CONFIGS entries in context.ts (inline exampleConfig). - examples/advanced-project{,-js}/src/__checks__/uptime/{grpc,ssl,traceroute} TS + JS examples with group, assertions, and doc-link comments. * test(cli): e2e deploy fixtures + Create assertions for gRPC/SSL/Traceroute Addresses review (Simo) new-monitor checklist Phase 6: - e2e/__tests__/fixtures/deploy-project/{grpc,ssl,traceroute}.check.ts (activated:false) - deploy.spec.ts: assert the three logical IDs in the Create output. * feat(cli): support TEXT_BODY assertions for gRPC monitors Mirror monorepo #2730 which added TEXT_BODY to grpcMonitorAssertionSources. Adds GrpcAssertionBuilder.textBody() (source TEXT_BODY) + codegen case, matching the API check's textBody() builder. * refactor(cli): restructure SslMonitor props per review (wire shape unchanged) Per @sorccu's review: make SslMonitor ergonomics consistent with other monitors. - degradedResponseTime/maxResponseTime -> construct top level (were in sslConfig) - hostname/port/ipFamily -> request top level (were in sslConfig) - sslClientCertificateId -> into sslConfig (was on request) synthesize() remaps to the identical API wire shape (request.sslConfig.* + request.sslClientCertificateId), so the payload the backend receives is unchanged. Updated codegen (wire->construct), unit + codegen + export-snippet tests, examples (ts+js), e2e fixture, and AI context. * refactor(cli): drop Ms suffix on SslConfig.handshakeTimeout per review @sorccu: we don't suffix timeout properties with Ms even when the value is milliseconds. Renames the construct field handshakeTimeoutMs -> handshakeTimeout; synthesize() and the codegen wire interface keep the API's handshakeTimeoutMs. --------- Co-authored-by: Ubuntu <ubuntu@ip-172-31-7-108.eu-central-1.compute.internal> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e50287a commit ccecd24

55 files changed

Lines changed: 3958 additions & 10 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const { GrpcMonitor, GrpcAssertionBuilder } = require('checkly/constructs')
2+
const { uptimeGroup } = require('../utils/website-groups.check')
3+
4+
// gRPC monitors check gRPC service health or invoke unary methods to validate responses.
5+
// They support HEALTH mode (standard gRPC health-check) and BEHAVIOR mode (custom method calls).
6+
// Read more: https://www.checklyhq.com/docs/grpc-monitors/
7+
8+
new GrpcMonitor('grpc-api-health', {
9+
name: 'gRPC API Health Monitor',
10+
activated: true,
11+
group: uptimeGroup,
12+
degradedResponseTime: 2000,
13+
maxResponseTime: 5000,
14+
request: {
15+
url: 'grpc.example.com',
16+
port: 50051,
17+
grpcConfig: {
18+
mode: 'HEALTH',
19+
tls: true,
20+
},
21+
assertions: [
22+
GrpcAssertionBuilder.healthCheckStatus().equals('SERVING'),
23+
GrpcAssertionBuilder.responseTime().lessThan(1000),
24+
],
25+
},
26+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const { SslMonitor, SslAssertionBuilder } = require('checkly/constructs')
2+
const { uptimeGroup } = require('../utils/website-groups.check')
3+
4+
// SSL monitors validate TLS certificates: expiry, chain trust, TLS version, and more.
5+
// Configure alertDaysBeforeExpiry to be notified before a certificate expires.
6+
// Read more: https://www.checklyhq.com/docs/ssl-monitors/
7+
8+
new SslMonitor('example-com-ssl', {
9+
name: 'example.com SSL Certificate',
10+
activated: true,
11+
group: uptimeGroup,
12+
degradedResponseTime: 3000,
13+
maxResponseTime: 10000,
14+
request: {
15+
hostname: 'example.com',
16+
port: 443,
17+
sslConfig: {
18+
alertDaysBeforeExpiry: 30,
19+
},
20+
assertions: [
21+
SslAssertionBuilder.certExpiresInDays().greaterThan(30),
22+
SslAssertionBuilder.chainTrusted().equals(true),
23+
SslAssertionBuilder.hostnameVerified().equals(true),
24+
SslAssertionBuilder.tlsVersion().equals('TLS1.3'),
25+
],
26+
},
27+
})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const { TracerouteMonitor, TracerouteAssertionBuilder } = require('checkly/constructs')
2+
const { uptimeGroup } = require('../utils/website-groups.check')
3+
4+
// Traceroute monitors map the network path to a host and can detect routing issues,
5+
// excessive hops, or high packet loss along the path.
6+
// Read more: https://www.checklyhq.com/docs/traceroute-monitors/
7+
8+
new TracerouteMonitor('example-com-traceroute', {
9+
name: 'example.com Traceroute',
10+
activated: true,
11+
group: uptimeGroup,
12+
degradedResponseTime: 10000,
13+
maxResponseTime: 20000,
14+
request: {
15+
url: 'example.com',
16+
protocol: 'TCP',
17+
port: 443,
18+
maxHops: 30,
19+
assertions: [
20+
TracerouteAssertionBuilder.hopCount().lessThan(20),
21+
TracerouteAssertionBuilder.packetLoss().lessThan(10),
22+
],
23+
},
24+
})
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { GrpcMonitor, GrpcAssertionBuilder } from 'checkly/constructs'
2+
import { uptimeGroup } from '../utils/website-groups.check'
3+
4+
// gRPC monitors check gRPC service health or invoke unary methods to validate responses.
5+
// They support HEALTH mode (standard gRPC health-check) and BEHAVIOR mode (custom method calls).
6+
// Read more: https://www.checklyhq.com/docs/grpc-monitors/
7+
8+
new GrpcMonitor('grpc-api-health', {
9+
name: 'gRPC API Health Monitor',
10+
activated: true,
11+
group: uptimeGroup,
12+
degradedResponseTime: 2000,
13+
maxResponseTime: 5000,
14+
request: {
15+
url: 'grpc.example.com',
16+
port: 50051,
17+
grpcConfig: {
18+
mode: 'HEALTH',
19+
tls: true,
20+
},
21+
assertions: [
22+
GrpcAssertionBuilder.healthCheckStatus().equals('SERVING'),
23+
GrpcAssertionBuilder.responseTime().lessThan(1000),
24+
],
25+
},
26+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { SslMonitor, SslAssertionBuilder } from 'checkly/constructs'
2+
import { uptimeGroup } from '../utils/website-groups.check'
3+
4+
// SSL monitors validate TLS certificates: expiry, chain trust, TLS version, and more.
5+
// Configure alertDaysBeforeExpiry to be notified before a certificate expires.
6+
// Read more: https://www.checklyhq.com/docs/ssl-monitors/
7+
8+
new SslMonitor('example-com-ssl', {
9+
name: 'example.com SSL Certificate',
10+
activated: true,
11+
group: uptimeGroup,
12+
degradedResponseTime: 3000,
13+
maxResponseTime: 10000,
14+
request: {
15+
hostname: 'example.com',
16+
port: 443,
17+
sslConfig: {
18+
alertDaysBeforeExpiry: 30,
19+
},
20+
assertions: [
21+
SslAssertionBuilder.certExpiresInDays().greaterThan(30),
22+
SslAssertionBuilder.chainTrusted().equals(true),
23+
SslAssertionBuilder.hostnameVerified().equals(true),
24+
SslAssertionBuilder.tlsVersion().equals('TLS1.3'),
25+
],
26+
},
27+
})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { TracerouteMonitor, TracerouteAssertionBuilder } from 'checkly/constructs'
2+
import { uptimeGroup } from '../utils/website-groups.check'
3+
4+
// Traceroute monitors map the network path to a host and can detect routing issues,
5+
// excessive hops, or high packet loss along the path.
6+
// Read more: https://www.checklyhq.com/docs/traceroute-monitors/
7+
8+
new TracerouteMonitor('example-com-traceroute', {
9+
name: 'example.com Traceroute',
10+
activated: true,
11+
group: uptimeGroup,
12+
degradedResponseTime: 10000,
13+
maxResponseTime: 20000,
14+
request: {
15+
url: 'example.com',
16+
protocol: 'TCP',
17+
port: 443,
18+
maxHops: 30,
19+
assertions: [
20+
TracerouteAssertionBuilder.hopCount().lessThan(20),
21+
TracerouteAssertionBuilder.packetLoss().lessThan(10),
22+
],
23+
},
24+
})

packages/cli/e2e/__tests__/deploy.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,13 @@ describe('deploy', { timeout: 45_000 }, () => {
205205
DnsMonitor: dns-nonexistent-all-assertion-types
206206
DnsMonitor: dns-welcome-a
207207
DnsMonitor: dns-welcome-aaaa
208+
GrpcMonitor: grpc-monitor
208209
HeartbeatMonitor: heartbeat-monitor-1
209210
BrowserCheck: homepage-browser-check
210211
IcmpMonitor: icmp-welcome
212+
SslMonitor: ssl-monitor
211213
TcpMonitor: tcp-monitor
214+
TracerouteMonitor: traceroute-monitor
212215
CheckGroupV2: my-group-1
213216
CheckGroupV1: my-group-2-v1
214217
Dashboard: dashboard-1
@@ -227,11 +230,14 @@ describe('deploy', { timeout: 45_000 }, () => {
227230
DnsMonitor: dns-nonexistent-all-assertion-types
228231
DnsMonitor: dns-welcome-a
229232
DnsMonitor: dns-welcome-aaaa
233+
GrpcMonitor: grpc-monitor
230234
HeartbeatMonitor: heartbeat-monitor-1
231235
BrowserCheck: homepage-browser-check
232236
IcmpMonitor: icmp-welcome
233237
BrowserCheck: snapshot-test.test.ts
238+
SslMonitor: ssl-monitor
234239
TcpMonitor: tcp-monitor
240+
TracerouteMonitor: traceroute-monitor
235241
CheckGroupV2: my-group-1
236242
CheckGroupV1: my-group-2-v1
237243
Dashboard: dashboard-1
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { GrpcMonitor } from 'checkly/constructs'
2+
3+
new GrpcMonitor('grpc-monitor', {
4+
name: 'gRPC Monitor',
5+
activated: false,
6+
request: {
7+
url: 'grpc.example.com',
8+
port: 50051,
9+
grpcConfig: {
10+
mode: 'HEALTH',
11+
},
12+
},
13+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { SslMonitor } from 'checkly/constructs'
2+
3+
new SslMonitor('ssl-monitor', {
4+
name: 'SSL Monitor',
5+
activated: false,
6+
request: {
7+
hostname: 'example.com',
8+
sslConfig: {},
9+
},
10+
})
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { TracerouteMonitor } from 'checkly/constructs'
2+
3+
new TracerouteMonitor('traceroute-monitor', {
4+
name: 'Traceroute Monitor',
5+
activated: false,
6+
request: {
7+
url: 'example.com',
8+
},
9+
})

0 commit comments

Comments
 (0)