@openstatus/health-redis 0.1.4-dev.0
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/README.md +73 -0
- package/dist/_virtual/rolldown_runtime.cjs +30 -0
- package/dist/mod.cjs +31 -0
- package/dist/mod.d.cts +22 -0
- package/dist/mod.d.cts.map +1 -0
- package/dist/mod.d.ts +22 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +30 -0
- package/dist/mod.js.map +1 -0
- package/package.json +74 -0
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# @openstatus/health-redis
|
|
2
|
+
|
|
3
|
+
[Redis](https://redis.io/) / [Valkey](https://valkey.io/) probe for
|
|
4
|
+
[`@openstatus/health`](https://jsr.io/@openstatus/health). Sends `PING`
|
|
5
|
+
through the client you already have — [`redis`](https://github.com/redis/node-redis)
|
|
6
|
+
(node-redis), [`ioredis`](https://github.com/redis/ioredis),
|
|
7
|
+
[`@upstash/redis`](https://github.com/upstash/redis-js) or `@vercel/kv` — and
|
|
8
|
+
fails the check unless the server answers `PONG`.
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
deno add jsr:@openstatus/health jsr:@openstatus/health-redis
|
|
12
|
+
npm install @openstatus/health @openstatus/health-redis
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Redis } from "ioredis";
|
|
17
|
+
import { createHealthHandler } from "@openstatus/health";
|
|
18
|
+
import { redisProbe } from "@openstatus/health-redis";
|
|
19
|
+
|
|
20
|
+
const redis = new Redis(env.REDIS_URL);
|
|
21
|
+
|
|
22
|
+
Deno.serve(
|
|
23
|
+
createHealthHandler({ probes: [redisProbe({ client: redis })] }),
|
|
24
|
+
);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Any object with `ping()` works, so the probe covers TCP clients against a
|
|
28
|
+
self-hosted Redis, Valkey, Railway, Fly or ElastiCache instance as well as
|
|
29
|
+
the HTTP clients from Upstash and Vercel. For an Upstash database without a
|
|
30
|
+
client, `@openstatus/health-upstash` pings the REST endpoint with `fetch`
|
|
31
|
+
alone.
|
|
32
|
+
|
|
33
|
+
With node-redis, connect the client before it is probed: `createClient()`
|
|
34
|
+
does not connect until `await client.connect()`, and a `ping()` on a closed
|
|
35
|
+
client rejects — which the probe reports as a failed check.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
redisProbe({
|
|
39
|
+
client: redis,
|
|
40
|
+
// optional overrides from the Probe contract
|
|
41
|
+
name: "cache",
|
|
42
|
+
critical: true,
|
|
43
|
+
timeoutMs: 1000,
|
|
44
|
+
skip: () => env.REDIS_URL == null,
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Non-critical by default: a Redis used as a cache degrades the report instead
|
|
49
|
+
of taking the service down. Set `critical: true` when Redis holds sessions,
|
|
50
|
+
queues or rate limits that requests cannot proceed without.
|
|
51
|
+
|
|
52
|
+
The client is typed structurally as `{ ping(): PromiseLike<...> }`, so
|
|
53
|
+
`redis` and `ioredis` are optional peer dependencies for their types only
|
|
54
|
+
and the probe adds no runtime import of either. The factory throws
|
|
55
|
+
`ProbeConfigError` at construction when the client has no `ping()`.
|
|
56
|
+
|
|
57
|
+
## About openstatus
|
|
58
|
+
|
|
59
|
+
[openstatus](https://www.openstatus.dev/) is the open-source uptime monitoring
|
|
60
|
+
and status page platform. This package is part of
|
|
61
|
+
[`@openstatus/health`](https://github.com/openstatusHQ/health), the `/health`
|
|
62
|
+
endpoints behind openstatus's own services, extracted so any JavaScript server
|
|
63
|
+
can expose one. Point an
|
|
64
|
+
[openstatus monitor](https://www.openstatus.dev/docs/reference/http-monitor)
|
|
65
|
+
at the endpoint and assert on `status` in the body to be alerted on
|
|
66
|
+
`degraded` before it becomes `unhealthy`.
|
|
67
|
+
|
|
68
|
+
Source: [github.com/openstatusHQ/health](https://github.com/openstatusHQ/health).
|
|
69
|
+
Issues and PRs welcome.
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
[MIT](https://github.com/openstatusHQ/health/blob/main/LICENSE)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
|
|
25
|
+
Object.defineProperty(exports, '__toESM', {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return __toESM;
|
|
29
|
+
}
|
|
30
|
+
});
|
package/dist/mod.cjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const __openstatus_health = require_rolldown_runtime.__toESM(require("@openstatus/health"));
|
|
3
|
+
|
|
4
|
+
//#region src/mod.ts
|
|
5
|
+
/** Probe name when `name` is unset. */
|
|
6
|
+
const redisDefaultName = "redis";
|
|
7
|
+
/** A probe that sends `PING` and expects `PONG`; non-critical by default. Throws `ProbeConfigError` without `ping()`. */
|
|
8
|
+
function redisProbe(options) {
|
|
9
|
+
const client = options.client;
|
|
10
|
+
if (typeof client?.ping !== "function") throw new __openstatus_health.ProbeConfigError("redisProbe", "client", `must expose ping(), got ${describe(client)}`);
|
|
11
|
+
return {
|
|
12
|
+
name: options.name ?? redisDefaultName,
|
|
13
|
+
critical: options.critical ?? false,
|
|
14
|
+
timeoutMs: options.timeoutMs,
|
|
15
|
+
skip: options.skip,
|
|
16
|
+
run: async () => {
|
|
17
|
+
const reply = await client.ping();
|
|
18
|
+
if (typeof reply === "string" && reply.toUpperCase() !== "PONG") throw new Error(`unexpected reply ${JSON.stringify(reply)}`);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function describe(client) {
|
|
23
|
+
if (client == null) return String(client);
|
|
24
|
+
if (typeof client !== "object") return typeof client;
|
|
25
|
+
const keys = Object.keys(client);
|
|
26
|
+
return keys.length === 0 ? "an object with no keys" : `an object with keys ${keys.slice(0, 8).join(", ")}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
exports.redisDefaultName = redisDefaultName;
|
|
31
|
+
exports.redisProbe = redisProbe;
|
package/dist/mod.d.cts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Probe, ProbeOverrides, ProbeResult } from "@openstatus/health";
|
|
2
|
+
|
|
3
|
+
//#region src/mod.d.ts
|
|
4
|
+
|
|
5
|
+
/** Probe name when `name` is unset. */
|
|
6
|
+
declare const redisDefaultName = "redis";
|
|
7
|
+
/** The subset of a Redis client the probe uses. */
|
|
8
|
+
interface RedisLikeClient {
|
|
9
|
+
/** Send `PING`; resolves with the server's reply, normally `"PONG"`. */
|
|
10
|
+
ping(): PromiseLike<ProbeResult>;
|
|
11
|
+
}
|
|
12
|
+
/** Options for `redisProbe()`. */
|
|
13
|
+
interface RedisProbeOptions extends ProbeOverrides {
|
|
14
|
+
/** A node-redis, ioredis or Upstash client. */
|
|
15
|
+
readonly client: RedisLikeClient;
|
|
16
|
+
}
|
|
17
|
+
/** A probe that sends `PING` and expects `PONG`; non-critical by default. Throws `ProbeConfigError` without `ping()`. */
|
|
18
|
+
declare function redisProbe(options: RedisProbeOptions): Probe;
|
|
19
|
+
//# sourceMappingURL=mod.d.ts.map
|
|
20
|
+
//#endregion
|
|
21
|
+
export { RedisLikeClient, RedisProbeOptions, redisDefaultName, redisProbe };
|
|
22
|
+
//# sourceMappingURL=mod.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;AAqCA;AAA0B,cAfb,gBAAA,GAea,OAAA;;AAA8B,UAZvC,eAAA,CAYuC;EAAK;UAVnD,YAAY;;;UAIL,iBAAA,SAA0B;;mBAExB;;;iBAIH,UAAA,UAAoB,oBAAoB"}
|
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Probe, ProbeOverrides, ProbeResult } from "@openstatus/health";
|
|
2
|
+
|
|
3
|
+
//#region src/mod.d.ts
|
|
4
|
+
|
|
5
|
+
/** Probe name when `name` is unset. */
|
|
6
|
+
declare const redisDefaultName = "redis";
|
|
7
|
+
/** The subset of a Redis client the probe uses. */
|
|
8
|
+
interface RedisLikeClient {
|
|
9
|
+
/** Send `PING`; resolves with the server's reply, normally `"PONG"`. */
|
|
10
|
+
ping(): PromiseLike<ProbeResult>;
|
|
11
|
+
}
|
|
12
|
+
/** Options for `redisProbe()`. */
|
|
13
|
+
interface RedisProbeOptions extends ProbeOverrides {
|
|
14
|
+
/** A node-redis, ioredis or Upstash client. */
|
|
15
|
+
readonly client: RedisLikeClient;
|
|
16
|
+
}
|
|
17
|
+
/** A probe that sends `PING` and expects `PONG`; non-critical by default. Throws `ProbeConfigError` without `ping()`. */
|
|
18
|
+
declare function redisProbe(options: RedisProbeOptions): Probe;
|
|
19
|
+
//# sourceMappingURL=mod.d.ts.map
|
|
20
|
+
//#endregion
|
|
21
|
+
export { RedisLikeClient, RedisProbeOptions, redisDefaultName, redisProbe };
|
|
22
|
+
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;AAqCA;AAA0B,cAfb,gBAAA,GAea,OAAA;;AAA8B,UAZvC,eAAA,CAYuC;EAAK;UAVnD,YAAY;;;UAIL,iBAAA,SAA0B;;mBAExB;;;iBAIH,UAAA,UAAoB,oBAAoB"}
|
package/dist/mod.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ProbeConfigError } from "@openstatus/health";
|
|
2
|
+
|
|
3
|
+
//#region src/mod.ts
|
|
4
|
+
/** Probe name when `name` is unset. */
|
|
5
|
+
const redisDefaultName = "redis";
|
|
6
|
+
/** A probe that sends `PING` and expects `PONG`; non-critical by default. Throws `ProbeConfigError` without `ping()`. */
|
|
7
|
+
function redisProbe(options) {
|
|
8
|
+
const client = options.client;
|
|
9
|
+
if (typeof client?.ping !== "function") throw new ProbeConfigError("redisProbe", "client", `must expose ping(), got ${describe(client)}`);
|
|
10
|
+
return {
|
|
11
|
+
name: options.name ?? redisDefaultName,
|
|
12
|
+
critical: options.critical ?? false,
|
|
13
|
+
timeoutMs: options.timeoutMs,
|
|
14
|
+
skip: options.skip,
|
|
15
|
+
run: async () => {
|
|
16
|
+
const reply = await client.ping();
|
|
17
|
+
if (typeof reply === "string" && reply.toUpperCase() !== "PONG") throw new Error(`unexpected reply ${JSON.stringify(reply)}`);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function describe(client) {
|
|
22
|
+
if (client == null) return String(client);
|
|
23
|
+
if (typeof client !== "object") return typeof client;
|
|
24
|
+
const keys = Object.keys(client);
|
|
25
|
+
return keys.length === 0 ? "an object with no keys" : `an object with keys ${keys.slice(0, 8).join(", ")}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { redisDefaultName, redisProbe };
|
|
30
|
+
//# sourceMappingURL=mod.js.map
|
package/dist/mod.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","names":["options: RedisProbeOptions","client: RedisLikeClient"],"sources":["../src/mod.ts"],"sourcesContent":["/**\n * Redis probe for `@openstatus/health`: sends `PING` through `redis`\n * (node-redis), `ioredis`, `@upstash/redis` or any client with `ping()`.\n *\n * ```ts\n * import { Redis } from \"ioredis\";\n * import { redisProbe } from \"@openstatus/health-redis\";\n *\n * const probe = redisProbe({ client: new Redis(env.REDIS_URL) });\n * ```\n *\n * @module\n */\n\nimport {\n type Probe,\n ProbeConfigError,\n type ProbeOverrides,\n type ProbeResult,\n} from \"@openstatus/health\";\n\n/** Probe name when `name` is unset. */\nexport const redisDefaultName = \"redis\";\n\n/** The subset of a Redis client the probe uses. */\nexport interface RedisLikeClient {\n /** Send `PING`; resolves with the server's reply, normally `\"PONG\"`. */\n ping(): PromiseLike<ProbeResult>;\n}\n\n/** Options for `redisProbe()`. */\nexport interface RedisProbeOptions extends ProbeOverrides {\n /** A node-redis, ioredis or Upstash client. */\n readonly client: RedisLikeClient;\n}\n\n/** A probe that sends `PING` and expects `PONG`; non-critical by default. Throws `ProbeConfigError` without `ping()`. */\nexport function redisProbe(options: RedisProbeOptions): Probe {\n const client = options.client;\n if (typeof client?.ping !== \"function\") {\n throw new ProbeConfigError(\n \"redisProbe\",\n \"client\",\n `must expose ping(), got ${describe(client)}`,\n );\n }\n return {\n name: options.name ?? redisDefaultName,\n critical: options.critical ?? false,\n timeoutMs: options.timeoutMs,\n skip: options.skip,\n run: async () => {\n const reply = await client.ping();\n if (typeof reply === \"string\" && reply.toUpperCase() !== \"PONG\") {\n throw new Error(`unexpected reply ${JSON.stringify(reply)}`);\n }\n },\n };\n}\n\nfunction describe(client: RedisLikeClient): string {\n if (client == null) return String(client);\n if (typeof client !== \"object\") return typeof client;\n const keys = Object.keys(client);\n return keys.length === 0\n ? \"an object with no keys\"\n : `an object with keys ${keys.slice(0, 8).join(\", \")}`;\n}\n"],"mappings":";;;;AAsBA,MAAa,mBAAmB;;AAehC,SAAgB,WAAWA,SAAmC;CAC5D,MAAM,SAAS,QAAQ;AACvB,YAAW,QAAQ,SAAS,WAC1B,OAAM,IAAI,iBACR,cACA,WACC,0BAA0B,SAAS,OAAO,CAAC;AAGhD,QAAO;EACL,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,WAAW,QAAQ;EACnB,MAAM,QAAQ;EACd,KAAK,YAAY;GACf,MAAM,QAAQ,MAAM,OAAO,MAAM;AACjC,cAAW,UAAU,YAAY,MAAM,aAAa,KAAK,OACvD,OAAM,IAAI,OAAO,mBAAmB,KAAK,UAAU,MAAM,CAAC;EAE7D;CACF;AACF;AAED,SAAS,SAASC,QAAiC;AACjD,KAAI,UAAU,KAAM,QAAO,OAAO,OAAO;AACzC,YAAW,WAAW,SAAU,eAAc;CAC9C,MAAM,OAAO,OAAO,KAAK,OAAO;AAChC,QAAO,KAAK,WAAW,IACnB,4BACC,sBAAsB,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC;AACxD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openstatus/health-redis",
|
|
3
|
+
"version": "0.1.4-dev.0",
|
|
4
|
+
"description": "Redis PING probe for @openstatus/health",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"openstatus",
|
|
7
|
+
"health",
|
|
8
|
+
"healthcheck",
|
|
9
|
+
"redis",
|
|
10
|
+
"ioredis",
|
|
11
|
+
"valkey",
|
|
12
|
+
"cache"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "openstatus",
|
|
17
|
+
"url": "https://www.openstatus.dev/"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/openstatusHQ/health",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/openstatusHQ/health.git",
|
|
23
|
+
"directory": "packages/redis/"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/openstatusHQ/health/issues"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"module": "./dist/mod.js",
|
|
30
|
+
"main": "./dist/mod.cjs",
|
|
31
|
+
"types": "./dist/mod.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": {
|
|
35
|
+
"import": "./dist/mod.d.ts",
|
|
36
|
+
"require": "./dist/mod.d.cts"
|
|
37
|
+
},
|
|
38
|
+
"import": "./dist/mod.js",
|
|
39
|
+
"require": "./dist/mod.cjs"
|
|
40
|
+
},
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"files": [
|
|
45
|
+
"dist/"
|
|
46
|
+
],
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=22"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@openstatus/health": "^0.1.4-dev.0",
|
|
52
|
+
"redis": ">=4.0.0",
|
|
53
|
+
"ioredis": ">=5.0.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"redis": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"ioredis": {
|
|
60
|
+
"optional": true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"redis": "^5.5.0",
|
|
65
|
+
"ioredis": "^5.6.0",
|
|
66
|
+
"tsdown": "^0.12.7",
|
|
67
|
+
"typescript": "^5.8.3"
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "tsdown",
|
|
71
|
+
"prepack": "tsdown",
|
|
72
|
+
"test": "node --experimental-transform-types --test"
|
|
73
|
+
}
|
|
74
|
+
}
|