Skip to content

Commit 8895aca

Browse files
Opt-in per-line logging (#958)
* Opt-in per-line logging * ci: increase timeout for tests * feat: add latencyLogging to CF
1 parent babdc47 commit 8895aca

File tree

8 files changed

+57
-66
lines changed

8 files changed

+57
-66
lines changed

bun.lockb

1.46 KB
Binary file not shown.

package.json

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,11 @@
3333
"type": "git",
3434
"url": "git+https://github.com/upstash/upstash-redis.git"
3535
},
36-
"keywords": [
37-
"redis",
38-
"database",
39-
"serverless",
40-
"edge",
41-
"upstash"
42-
],
43-
"files": [
44-
"./**"
45-
],
36+
"keywords": ["redis", "database", "serverless", "edge", "upstash"],
37+
"files": ["./**"],
4638
"scripts": {
4739
"build": "tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/",
48-
"test": "bun test pkg --coverage",
40+
"test": "bun test pkg --coverage --timeout 20000",
4941
"fmt": "bunx @biomejs/biome check --apply ./pkg",
5042
"prepare": "husky install"
5143
},
@@ -57,23 +49,18 @@
5749
"homepage": "https://github.com/upstash/upstash-redis#readme",
5850
"typesVersions": {
5951
"*": {
60-
"nodejs": [
61-
"./nodejs.d.ts"
62-
],
63-
"cloudflare": [
64-
"./cloudflare.d.ts"
65-
],
66-
"fastly": [
67-
"./fastly.d.ts"
68-
]
52+
"nodejs": ["./nodejs.d.ts"],
53+
"cloudflare": ["./cloudflare.d.ts"],
54+
"fastly": ["./fastly.d.ts"]
6955
}
7056
},
7157
"devDependencies": {
7258
"@types/crypto-js": "^4.1.3",
73-
"bun-types": "^1.0.6",
59+
"bun-types": "1.0.33",
7460
"tsup": "^7.2.0",
7561
"@biomejs/biome": "latest",
76-
"husky": "^8.0.3"
62+
"husky": "^8.0.3",
63+
"typescript": "latest"
7764
},
7865
"dependencies": {
7966
"crypto-js": "^4.2.0"

pkg/commands/command.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type CommandOptions<TResult, TData> = {
2828
* @default true
2929
*/
3030
automaticDeserialization?: boolean;
31+
latencyLogging?: boolean;
3132
};
3233
/**
3334
* Command offers default (de)serialization and the exec method to all commands.
@@ -55,6 +56,22 @@ export class Command<TResult, TData> {
5556
: (x) => x as unknown as TData;
5657

5758
this.command = command.map((c) => this.serialize(c));
59+
60+
if (opts?.latencyLogging) {
61+
const originalExec = this.exec.bind(this);
62+
this.exec = async (client: Requester): Promise<TData> => {
63+
const start = performance.now();
64+
const result = await originalExec(client);
65+
const end = performance.now();
66+
const loggerResult = (end - start).toFixed(2);
67+
console.log(
68+
`Latency for \x1b[38;2;19;185;39m${this.command[0]
69+
.toString()
70+
.toUpperCase()}\x1b[0m: \x1b[38;2;0;255;255m${loggerResult} ms\x1b[0m`,
71+
);
72+
return result;
73+
};
74+
}
5875
}
5976

6077
/**

pkg/http.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ export class HttpClient implements Requester {
170170

171171
public async request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> {
172172
const requestOptions: RequestInit & { backend?: string; agent?: any } = {
173+
//@ts-expect-error this should throw due to bun regression
173174
cache: this.options.cache,
174175
method: "POST",
175176
headers: this.headers,

pkg/redis.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,14 @@ test("disable base64 encoding", () => {
237237
expect(res).toEqual(value);
238238
});
239239
});
240+
241+
describe("tests with latency logging", () => {
242+
test("test should return OK with latency logs", async () => {
243+
const redis = new Redis(client, { latencyLogging: true });
244+
const key = newKey();
245+
const value = "OK";
246+
await redis.set(key, value);
247+
const res = await redis.get(key);
248+
expect(res).toEqual(value);
249+
});
250+
});

pkg/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ export type RedisOptions = {
2828
* @default true
2929
*/
3030
automaticDeserialization?: boolean;
31-
31+
latencyLogging?: boolean;
3232
enableTelemetry?: boolean;
3333
};

platforms/cloudflare.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,11 @@ export class Redis extends core.Redis {
4747
* ```
4848
*/
4949
constructor(config: RedisConfigCloudflare, env?: Env) {
50-
if (
51-
config.url.startsWith(" ") ||
52-
config.url.endsWith(" ") ||
53-
/\r|\n/.test(config.url)
54-
) {
55-
console.warn(
56-
"The redis url contains whitespace or newline, which can cause errors!"
57-
);
50+
if (config.url.startsWith(" ") || config.url.endsWith(" ") || /\r|\n/.test(config.url)) {
51+
console.warn("The redis url contains whitespace or newline, which can cause errors!");
5852
}
59-
if (
60-
config.token.startsWith(" ") ||
61-
config.token.endsWith(" ") ||
62-
/\r|\n/.test(config.token)
63-
) {
64-
console.warn(
65-
"The redis token contains whitespace or newline, which can cause errors!"
66-
);
53+
if (config.token.startsWith(" ") || config.token.endsWith(" ") || /\r|\n/.test(config.token)) {
54+
console.warn("The redis token contains whitespace or newline, which can cause errors!");
6755
}
6856

6957
const client = new HttpClient({
@@ -77,6 +65,7 @@ export class Redis extends core.Redis {
7765
super(client, {
7866
enableTelemetry: !env?.UPSTASH_DISABLE_TELEMETRY,
7967
automaticDeserialization: config.automaticDeserialization,
68+
latencyLogging: config.latencyLogging,
8069
});
8170
// This is only added of the user has not disabled telemetry
8271
this.addTelemetry({
@@ -102,7 +91,7 @@ export class Redis extends core.Redis {
10291
UPSTASH_REDIS_REST_TOKEN: string;
10392
UPSTASH_DISABLE_TELEMETRY?: string;
10493
},
105-
opts?: Omit<RedisConfigCloudflare, "url" | "token">
94+
opts?: Omit<RedisConfigCloudflare, "url" | "token">,
10695
): Redis {
10796
// @ts-ignore These will be defined by cloudflare
10897
const url = env?.UPSTASH_REDIS_REST_URL ?? UPSTASH_REDIS_REST_URL;
@@ -112,12 +101,12 @@ export class Redis extends core.Redis {
112101

113102
if (!url) {
114103
throw new Error(
115-
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_URL`"
104+
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_URL`",
116105
);
117106
}
118107
if (!token) {
119108
throw new Error(
120-
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`"
109+
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`",
121110
);
122111
}
123112
return new Redis({ ...opts, url, token }, env);

platforms/nodejs.ts

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ import { VERSION } from "../version";
1414
* Workaround for nodejs 14, where atob is not included in the standardlib
1515
*/
1616
if (typeof atob === "undefined") {
17-
global.atob = function (b64: string) {
18-
return Buffer.from(b64, "base64").toString("utf-8");
19-
};
17+
global.atob = (b64: string) => Buffer.from(b64, "base64").toString("utf-8");
2018
}
2119
export type * from "../pkg/commands/types";
2220
export type { Requester, UpstashRequest, UpstashResponse };
@@ -55,6 +53,7 @@ export type RedisConfigNodejs = {
5553
* For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
5654
*/
5755
signal?: AbortSignal;
56+
latencyLogging?: boolean;
5857
agent?: any;
5958
} & core.RedisOptions &
6059
RequesterConfig;
@@ -104,18 +103,14 @@ export class Redis extends core.Redis {
104103
configOrRequester.url.endsWith(" ") ||
105104
/\r|\n/.test(configOrRequester.url)
106105
) {
107-
console.warn(
108-
"The redis url contains whitespace or newline, which can cause errors!"
109-
);
106+
console.warn("The redis url contains whitespace or newline, which can cause errors!");
110107
}
111108
if (
112109
configOrRequester.token.startsWith(" ") ||
113110
configOrRequester.token.endsWith(" ") ||
114111
/\r|\n/.test(configOrRequester.token)
115112
) {
116-
console.warn(
117-
"The redis token contains whitespace or newline, which can cause errors!"
118-
);
113+
console.warn("The redis token contains whitespace or newline, which can cause errors!");
119114
}
120115

121116
const client = new HttpClient({
@@ -131,19 +126,14 @@ export class Redis extends core.Redis {
131126
super(client, {
132127
automaticDeserialization: configOrRequester.automaticDeserialization,
133128
enableTelemetry: !process.env.UPSTASH_DISABLE_TELEMETRY,
129+
latencyLogging: configOrRequester.latencyLogging,
134130
});
135131

136132
this.addTelemetry({
137133
runtime:
138134
// @ts-ignore
139-
typeof EdgeRuntime === "string"
140-
? "edge-light"
141-
: `node@${process.version}`,
142-
platform: process.env.VERCEL
143-
? "vercel"
144-
: process.env.AWS_REGION
145-
? "aws"
146-
: "unknown",
135+
typeof EdgeRuntime === "string" ? "edge-light" : `node@${process.version}`,
136+
platform: process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : "unknown",
147137
sdk: `@upstash/redis@${VERSION}`,
148138
});
149139
}
@@ -161,22 +151,18 @@ export class Redis extends core.Redis {
161151
// @ts-ignore process will be defined in node
162152
if (typeof process?.env === "undefined") {
163153
throw new Error(
164-
'Unable to get environment variables, `process.env` is undefined. If you are deploying to cloudflare, please import from "@upstash/redis/cloudflare" instead'
154+
'Unable to get environment variables, `process.env` is undefined. If you are deploying to cloudflare, please import from "@upstash/redis/cloudflare" instead',
165155
);
166156
}
167157
// @ts-ignore process will be defined in node
168158
const url = process?.env.UPSTASH_REDIS_REST_URL;
169159
if (!url) {
170-
throw new Error(
171-
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`"
172-
);
160+
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_URL`");
173161
}
174162
// @ts-ignore process will be defined in node
175163
const token = process?.env.UPSTASH_REDIS_REST_TOKEN;
176164
if (!token) {
177-
throw new Error(
178-
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`"
179-
);
165+
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`");
180166
}
181167
return new Redis({ ...config, url, token });
182168
}

0 commit comments

Comments
 (0)