mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-23 20:25:56 +00:00
Match probe help to the current observation-location editor
Fresh editor and API inspection shows that local and remote paths can coexist, including in published v6.4.5. Explain the actual location picker, per-path uncertainty and safe canonical-versus-legacy update fields, and validate the linked target-field instructions in the Docs renderer. Contract-Neutral: Documentation, shipped mirrors and guidance verification only; existing observation and API semantics are unchanged. Change-source: pulse-maintainer
This commit is contained in:
+6
-1
@@ -1663,7 +1663,12 @@ Target payload fields:
|
||||
- `linkedResourceId` - Optional resource id hint for attaching the probe facet to an existing resource.
|
||||
- `certificateMonitoringDisabled` - Explicit HTTPS-only opt-out; certificate validity monitoring is enabled by default.
|
||||
- `certificateExpiryWarningDays` - HTTPS certificate expiry warning window; defaults to 30 days.
|
||||
- `probeAgentId` - Optional registered host-agent ID that runs the check instead of the Pulse server; requires the Pro `external_probe` entitlement. Send an explicit empty string on update to return the check to local execution.
|
||||
- `observationLocationIds` - Observation locations for this one logical check: `pulse:local` for this Pulse server and `agent:<host-agent-id>` for a connected agent. Agent locations require the Pro `external_probe` entitlement. Include `pulse:local` only when a local observation is wanted; agent-only sets do not also run locally. Each location retains separate evidence rather than treating one path failure as a universal outage.
|
||||
- `probeAgentId` - Compatibility field for single-location clients. A non-empty registered host-agent ID selects that agent; an explicit empty string selects local execution. When updating only this field, omit `observationLocationIds`. For multi-location updates, send the complete desired `observationLocationIds` set and clear `probeAgentId` to `""` so a legacy value cannot override a single-location edit.
|
||||
|
||||
External agents collect observations, but alert evaluation and notification
|
||||
delivery still depend on the Pulse server. Missing reports are not proof of a
|
||||
target outage. See [probe coverage and outage limits](CONFIGURATION.md#external-probes-pro).
|
||||
|
||||
An explicit `linkedResourceId` is authoritative and fails closed when it
|
||||
cannot resolve. Without it, Pulse correlates only on one exact normalized IP
|
||||
|
||||
+11
-6
@@ -579,20 +579,25 @@ alerts, and resource projections keep one canonical protocol value.
|
||||
|
||||
External probes change **where a check runs**, not where alerts are sent.
|
||||
By default, checks run on the Pulse server. With the Pro `external_probe`
|
||||
entitlement, assign a connected Pulse agent using **Run from** in the UI
|
||||
(`probeAgentId` in the API). An agent on a cloud VM or at another site can
|
||||
observe a service from outside its local network.
|
||||
entitlement, select one or more connected agents under **Observation locations**
|
||||
in the check editor. An agent on a cloud VM or at another site can observe a
|
||||
service from outside its local network. Keep **This Pulse server** selected if
|
||||
you also want a local observation; deselect it for agent-only checks. Pulse keeps
|
||||
each location's evidence separate, so a failure on one path is not a universal
|
||||
outage. The API uses `observationLocationIds`; see the
|
||||
[target fields](API.md#availability-checks).
|
||||
|
||||
The assigned agent receives signed configuration, runs the check and reports
|
||||
results back to Pulse. Only the currently assigned agent's results are accepted;
|
||||
an assigned check is not also run locally. **The agent does not send
|
||||
results back to Pulse. Only agents assigned to that target may submit results;
|
||||
the server runs a local check only when **This Pulse server** is selected.
|
||||
**The agent does not send
|
||||
notifications directly.** The Pulse server must be running and able to reach
|
||||
the notification destination to evaluate results and send alerts.
|
||||
|
||||
| Situation | What the check can tell you |
|
||||
| --- | --- |
|
||||
| Pulse is running and receives probe results | Target observations are evaluated through the normal alert and notification policies. |
|
||||
| Pulse is running but probe results stop arriving | The check becomes indeterminate: "no recent report from probe agent". This is missing evidence, not proof the target is down. |
|
||||
| Pulse is running but probe results stop arriving | The affected location becomes indeterminate: "no recent report from probe agent". This is missing evidence, not proof the target is down. Other locations retain their own evidence. |
|
||||
| Pulse is stopped or cannot reach its notification destination | An external agent cannot deliver Pulse alerts in its place. Use an independent external watchdog for this failure. |
|
||||
|
||||
The missing-report window is the longer of **five minutes or three check
|
||||
|
||||
+10
-6
@@ -303,11 +303,15 @@ storage nodes to avoid duplicate or ambiguously correlated readings.
|
||||
## External Probes (Pro)
|
||||
|
||||
With the Pro `external_probe` entitlement, availability checks configured in
|
||||
Pulse can be assigned to run from a specific agent instead of the Pulse
|
||||
server (Settings -> Monitoring -> Availability checks -> "Run from"). This is
|
||||
how you observe a service from outside its local network: deploy the agent on
|
||||
a machine elsewhere — a cloud VM, a Docker host at another location — and
|
||||
assign checks to it. **The agent does not send notifications directly.** The
|
||||
Pulse can run from one or more connected agents. In **Settings → Monitoring →
|
||||
Availability checks**, select the agents under **Observation locations** in the
|
||||
check editor. Keep **This Pulse server** selected for a local observation too,
|
||||
or deselect it for agent-only checks. Each location keeps its own evidence; a
|
||||
failure on one path is not a universal outage.
|
||||
|
||||
To observe a service from outside its local network, deploy the agent on a
|
||||
machine elsewhere — a cloud VM, a Docker host at another location — and assign
|
||||
checks to it. **The agent does not send notifications directly.** The
|
||||
Pulse server must be running and able to reach the notification destination;
|
||||
target failures are evaluated there through your normal alert routes.
|
||||
|
||||
@@ -317,7 +321,7 @@ configured interval, and results are delivered with its regular reports.
|
||||
Results waiting for delivery use a bounded **in-memory** queue of up to 200
|
||||
observations across the agent's checks. Oldest pending observations are dropped
|
||||
when it fills, and an agent restart loses the queue; it is not a complete outage
|
||||
record. If reports stop arriving, the check becomes indeterminate ("no recent
|
||||
record. If reports stop arriving, the affected location becomes indeterminate ("no recent
|
||||
report from probe agent"). This is missing evidence, not proof the target is
|
||||
down. The missing-report window is the
|
||||
longer of **five minutes or three check intervals**. During normal server
|
||||
|
||||
@@ -50,6 +50,7 @@ const { chromium, webkit } = require('playwright');
|
||||
const body = (await page.locator('article').innerText()).replace(/\s+/g, ' ');
|
||||
for (const text of ['The agent does not send notifications directly.',
|
||||
'Pulse server must be running and able to reach the notification destination',
|
||||
'Observation locations', 'This Pulse server', 'not a universal outage',
|
||||
'not proof the target is down', 'five minutes or three check intervals',
|
||||
'31 March 2027', 'Relay is no longer sold', 'not a permanent substitute']) {
|
||||
assert.ok(body.includes(text), text);
|
||||
@@ -96,6 +97,11 @@ const { chromium, webkit } = require('playwright');
|
||||
await page.getByRole('heading', { name: 'External Probes (Pro)', exact: true }).waitFor();
|
||||
await follow('configuration guide', '/docs/CONFIGURATION#external-probes-pro',
|
||||
'External probes (Pro)', 'external-probes-pro');
|
||||
await follow('target fields', '/docs/API#availability-checks',
|
||||
'Availability Checks', 'availability-checks');
|
||||
assert.ok((await page.locator('article').innerText()).includes('clear probeAgentId to ""'));
|
||||
await page.goBack();
|
||||
await page.getByRole('heading', { name: 'External probes (Pro)', exact: true }).waitFor();
|
||||
await follow('external watchdog', '/docs/TROUBLESHOOTING#no-alert-when-pulse-power-or-internet-goes-down',
|
||||
'No alert when Pulse, power or internet goes down', 'no-alert-when-pulse-power-or-internet-goes-down');
|
||||
assert.deepEqual(errors, []);
|
||||
@@ -104,11 +110,11 @@ const { chromium, webkit } = require('playwright');
|
||||
serverDependencyVisible: true, semanticContainedCoverageTable: true,
|
||||
noDocumentOverflow: true, queueAndRetirementLimitsVisible: true,
|
||||
keyboardAgentGuide: true, keyboardConfigurationGuide: true,
|
||||
keyboardWatchdogLinks: 2, keyboardRetirementLink: true, errors });
|
||||
keyboardWatchdogLinks: 2, keyboardRetirementLink: true, keyboardCanonicalApiFields: true, errors });
|
||||
await browser.close();
|
||||
browser = undefined;
|
||||
}
|
||||
const files = ['public/docs/CONFIGURATION.md', 'public/docs/UNIFIED_AGENT.md',
|
||||
const files = ['public/docs/CONFIGURATION.md', 'public/docs/UNIFIED_AGENT.md', 'public/docs/API.md',
|
||||
'browser-tests/probe-guidance.cjs', 'browser-tests/docs-fragment-navigation.tsx',
|
||||
'src/features/docs/docMarkdown.ts', 'src/pages/Docs.tsx'].map((file) => ({ file,
|
||||
sha256: crypto.createHash('sha256').update(fs.readFileSync(path.join(root, file))).digest('hex') }));
|
||||
|
||||
@@ -1663,7 +1663,12 @@ Target payload fields:
|
||||
- `linkedResourceId` - Optional resource id hint for attaching the probe facet to an existing resource.
|
||||
- `certificateMonitoringDisabled` - Explicit HTTPS-only opt-out; certificate validity monitoring is enabled by default.
|
||||
- `certificateExpiryWarningDays` - HTTPS certificate expiry warning window; defaults to 30 days.
|
||||
- `probeAgentId` - Optional registered host-agent ID that runs the check instead of the Pulse server; requires the Pro `external_probe` entitlement. Send an explicit empty string on update to return the check to local execution.
|
||||
- `observationLocationIds` - Observation locations for this one logical check: `pulse:local` for this Pulse server and `agent:<host-agent-id>` for a connected agent. Agent locations require the Pro `external_probe` entitlement. Include `pulse:local` only when a local observation is wanted; agent-only sets do not also run locally. Each location retains separate evidence rather than treating one path failure as a universal outage.
|
||||
- `probeAgentId` - Compatibility field for single-location clients. A non-empty registered host-agent ID selects that agent; an explicit empty string selects local execution. When updating only this field, omit `observationLocationIds`. For multi-location updates, send the complete desired `observationLocationIds` set and clear `probeAgentId` to `""` so a legacy value cannot override a single-location edit.
|
||||
|
||||
External agents collect observations, but alert evaluation and notification
|
||||
delivery still depend on the Pulse server. Missing reports are not proof of a
|
||||
target outage. See [probe coverage and outage limits](CONFIGURATION.md#external-probes-pro).
|
||||
|
||||
An explicit `linkedResourceId` is authoritative and fails closed when it
|
||||
cannot resolve. Without it, Pulse correlates only on one exact normalized IP
|
||||
|
||||
@@ -579,20 +579,25 @@ alerts, and resource projections keep one canonical protocol value.
|
||||
|
||||
External probes change **where a check runs**, not where alerts are sent.
|
||||
By default, checks run on the Pulse server. With the Pro `external_probe`
|
||||
entitlement, assign a connected Pulse agent using **Run from** in the UI
|
||||
(`probeAgentId` in the API). An agent on a cloud VM or at another site can
|
||||
observe a service from outside its local network.
|
||||
entitlement, select one or more connected agents under **Observation locations**
|
||||
in the check editor. An agent on a cloud VM or at another site can observe a
|
||||
service from outside its local network. Keep **This Pulse server** selected if
|
||||
you also want a local observation; deselect it for agent-only checks. Pulse keeps
|
||||
each location's evidence separate, so a failure on one path is not a universal
|
||||
outage. The API uses `observationLocationIds`; see the
|
||||
[target fields](API.md#availability-checks).
|
||||
|
||||
The assigned agent receives signed configuration, runs the check and reports
|
||||
results back to Pulse. Only the currently assigned agent's results are accepted;
|
||||
an assigned check is not also run locally. **The agent does not send
|
||||
results back to Pulse. Only agents assigned to that target may submit results;
|
||||
the server runs a local check only when **This Pulse server** is selected.
|
||||
**The agent does not send
|
||||
notifications directly.** The Pulse server must be running and able to reach
|
||||
the notification destination to evaluate results and send alerts.
|
||||
|
||||
| Situation | What the check can tell you |
|
||||
| --- | --- |
|
||||
| Pulse is running and receives probe results | Target observations are evaluated through the normal alert and notification policies. |
|
||||
| Pulse is running but probe results stop arriving | The check becomes indeterminate: "no recent report from probe agent". This is missing evidence, not proof the target is down. |
|
||||
| Pulse is running but probe results stop arriving | The affected location becomes indeterminate: "no recent report from probe agent". This is missing evidence, not proof the target is down. Other locations retain their own evidence. |
|
||||
| Pulse is stopped or cannot reach its notification destination | An external agent cannot deliver Pulse alerts in its place. Use an independent external watchdog for this failure. |
|
||||
|
||||
The missing-report window is the longer of **five minutes or three check
|
||||
|
||||
@@ -303,11 +303,15 @@ storage nodes to avoid duplicate or ambiguously correlated readings.
|
||||
## External Probes (Pro)
|
||||
|
||||
With the Pro `external_probe` entitlement, availability checks configured in
|
||||
Pulse can be assigned to run from a specific agent instead of the Pulse
|
||||
server (Settings -> Monitoring -> Availability checks -> "Run from"). This is
|
||||
how you observe a service from outside its local network: deploy the agent on
|
||||
a machine elsewhere — a cloud VM, a Docker host at another location — and
|
||||
assign checks to it. **The agent does not send notifications directly.** The
|
||||
Pulse can run from one or more connected agents. In **Settings → Monitoring →
|
||||
Availability checks**, select the agents under **Observation locations** in the
|
||||
check editor. Keep **This Pulse server** selected for a local observation too,
|
||||
or deselect it for agent-only checks. Each location keeps its own evidence; a
|
||||
failure on one path is not a universal outage.
|
||||
|
||||
To observe a service from outside its local network, deploy the agent on a
|
||||
machine elsewhere — a cloud VM, a Docker host at another location — and assign
|
||||
checks to it. **The agent does not send notifications directly.** The
|
||||
Pulse server must be running and able to reach the notification destination;
|
||||
target failures are evaluated there through your normal alert routes.
|
||||
|
||||
@@ -317,7 +321,7 @@ configured interval, and results are delivered with its regular reports.
|
||||
Results waiting for delivery use a bounded **in-memory** queue of up to 200
|
||||
observations across the agent's checks. Oldest pending observations are dropped
|
||||
when it fills, and an agent restart loses the queue; it is not a complete outage
|
||||
record. If reports stop arriving, the check becomes indeterminate ("no recent
|
||||
record. If reports stop arriving, the affected location becomes indeterminate ("no recent
|
||||
report from probe agent"). This is missing evidence, not proof the target is
|
||||
down. The missing-report window is the
|
||||
longer of **five minutes or three check intervals**. During normal server
|
||||
|
||||
@@ -117,6 +117,31 @@ describe('docsLinks', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('matches the existing observation-location editor and compatibility fields', () => {
|
||||
for (const guide of probeGuides()) {
|
||||
expect(guide).toContain('Observation locations');
|
||||
expect(guide).toContain('This Pulse server');
|
||||
expect(guide).toContain('not a universal outage');
|
||||
expect(guide).not.toContain('Run from');
|
||||
expect(guide).not.toContain('an assigned check is not also run locally');
|
||||
}
|
||||
const api = readFileSync(path.join(repoRoot, 'docs', 'API.md'), 'utf8');
|
||||
expect(api).toContain('`observationLocationIds` - Observation locations');
|
||||
expect(api).toContain('`pulse:local` for this Pulse server');
|
||||
expect(api).toContain('`agent:<host-agent-id>` for a connected agent');
|
||||
expect(api).toContain('omit `observationLocationIds`');
|
||||
expect(api).toContain('clear `probeAgentId` to `""`');
|
||||
const editor = readFileSync(path.join(frontendRoot, 'src', 'components', 'Settings',
|
||||
'ConnectionEditor', 'CredentialSlots', 'AvailabilityTargetSlot.tsx'), 'utf8');
|
||||
expect(editor).toContain('Observation locations</legend>');
|
||||
expect(editor).toContain('observationLocationIds: [...form.observationLocationIds]');
|
||||
const handler = readFileSync(
|
||||
path.join(repoRoot, 'internal', 'api', 'availability_handlers.go'), 'utf8',
|
||||
);
|
||||
expect(handler).toContain('compatibility.ObservationLocationIDs == nil && compatibility.ProbeAgentID != nil');
|
||||
expect(handler).toContain('agentID != "" && len(*compatibility.ObservationLocationIDs) == 1');
|
||||
});
|
||||
|
||||
it('separates server removal from persistent-data erasure', () => {
|
||||
const installation = readFileSync(path.join(repoRoot, 'docs', 'INSTALL.md'), 'utf8');
|
||||
const removal = installation.split('## 🗑️ Uninstall')[1];
|
||||
|
||||
Reference in New Issue
Block a user