Skip to content

Commit

Permalink
Opt-in per-line logging (#958)
Browse files Browse the repository at this point in the history
* Opt-in per-line logging

* ci: increase timeout for tests

* feat: add latencyLogging to CF
  • Loading branch information
ogzhanolguncu authored Mar 22, 2024
1 parent babdc47 commit 8895aca
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 66 deletions.
Binary file modified bun.lockb
Binary file not shown.
31 changes: 9 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,11 @@
"type": "git",
"url": "git+https://github.com/upstash/upstash-redis.git"
},
"keywords": [
"redis",
"database",
"serverless",
"edge",
"upstash"
],
"files": [
"./**"
],
"keywords": ["redis", "database", "serverless", "edge", "upstash"],
"files": ["./**"],
"scripts": {
"build": "tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/",
"test": "bun test pkg --coverage",
"test": "bun test pkg --coverage --timeout 20000",
"fmt": "bunx @biomejs/biome check --apply ./pkg",
"prepare": "husky install"
},
Expand All @@ -57,23 +49,18 @@
"homepage": "https://github.com/upstash/upstash-redis#readme",
"typesVersions": {
"*": {
"nodejs": [
"./nodejs.d.ts"
],
"cloudflare": [
"./cloudflare.d.ts"
],
"fastly": [
"./fastly.d.ts"
]
"nodejs": ["./nodejs.d.ts"],
"cloudflare": ["./cloudflare.d.ts"],
"fastly": ["./fastly.d.ts"]
}
},
"devDependencies": {
"@types/crypto-js": "^4.1.3",
"bun-types": "^1.0.6",
"bun-types": "1.0.33",
"tsup": "^7.2.0",
"@biomejs/biome": "latest",
"husky": "^8.0.3"
"husky": "^8.0.3",
"typescript": "latest"
},
"dependencies": {
"crypto-js": "^4.2.0"
Expand Down
17 changes: 17 additions & 0 deletions pkg/commands/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type CommandOptions<TResult, TData> = {
* @default true
*/
automaticDeserialization?: boolean;
latencyLogging?: boolean;
};
/**
* Command offers default (de)serialization and the exec method to all commands.
Expand Down Expand Up @@ -55,6 +56,22 @@ export class Command<TResult, TData> {
: (x) => x as unknown as TData;

this.command = command.map((c) => this.serialize(c));

if (opts?.latencyLogging) {
const originalExec = this.exec.bind(this);
this.exec = async (client: Requester): Promise<TData> => {
const start = performance.now();
const result = await originalExec(client);
const end = performance.now();
const loggerResult = (end - start).toFixed(2);
console.log(
`Latency for \x1b[38;2;19;185;39m${this.command[0]
.toString()
.toUpperCase()}\x1b[0m: \x1b[38;2;0;255;255m${loggerResult} ms\x1b[0m`,
);
return result;
};
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions pkg/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export class HttpClient implements Requester {

public async request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> {
const requestOptions: RequestInit & { backend?: string; agent?: any } = {
//@ts-expect-error this should throw due to bun regression
cache: this.options.cache,
method: "POST",
headers: this.headers,
Expand Down
11 changes: 11 additions & 0 deletions pkg/redis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,14 @@ test("disable base64 encoding", () => {
expect(res).toEqual(value);
});
});

describe("tests with latency logging", () => {
test("test should return OK with latency logs", async () => {
const redis = new Redis(client, { latencyLogging: true });
const key = newKey();
const value = "OK";
await redis.set(key, value);
const res = await redis.get(key);
expect(res).toEqual(value);
});
});
2 changes: 1 addition & 1 deletion pkg/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ export type RedisOptions = {
* @default true
*/
automaticDeserialization?: boolean;

latencyLogging?: boolean;
enableTelemetry?: boolean;
};
27 changes: 8 additions & 19 deletions platforms/cloudflare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,11 @@ export class Redis extends core.Redis {
* ```
*/
constructor(config: RedisConfigCloudflare, env?: Env) {
if (
config.url.startsWith(" ") ||
config.url.endsWith(" ") ||
/\r|\n/.test(config.url)
) {
console.warn(
"The redis url contains whitespace or newline, which can cause errors!"
);
if (config.url.startsWith(" ") || config.url.endsWith(" ") || /\r|\n/.test(config.url)) {
console.warn("The redis url contains whitespace or newline, which can cause errors!");
}
if (
config.token.startsWith(" ") ||
config.token.endsWith(" ") ||
/\r|\n/.test(config.token)
) {
console.warn(
"The redis token contains whitespace or newline, which can cause errors!"
);
if (config.token.startsWith(" ") || config.token.endsWith(" ") || /\r|\n/.test(config.token)) {
console.warn("The redis token contains whitespace or newline, which can cause errors!");
}

const client = new HttpClient({
Expand All @@ -77,6 +65,7 @@ export class Redis extends core.Redis {
super(client, {
enableTelemetry: !env?.UPSTASH_DISABLE_TELEMETRY,
automaticDeserialization: config.automaticDeserialization,
latencyLogging: config.latencyLogging,
});
// This is only added of the user has not disabled telemetry
this.addTelemetry({
Expand All @@ -102,7 +91,7 @@ export class Redis extends core.Redis {
UPSTASH_REDIS_REST_TOKEN: string;
UPSTASH_DISABLE_TELEMETRY?: string;
},
opts?: Omit<RedisConfigCloudflare, "url" | "token">
opts?: Omit<RedisConfigCloudflare, "url" | "token">,
): Redis {
// @ts-ignore These will be defined by cloudflare
const url = env?.UPSTASH_REDIS_REST_URL ?? UPSTASH_REDIS_REST_URL;
Expand All @@ -112,12 +101,12 @@ export class Redis extends core.Redis {

if (!url) {
throw new Error(
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_URL`"
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_URL`",
);
}
if (!token) {
throw new Error(
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`"
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`",
);
}
return new Redis({ ...opts, url, token }, env);
Expand Down
34 changes: 10 additions & 24 deletions platforms/nodejs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import { VERSION } from "../version";
* Workaround for nodejs 14, where atob is not included in the standardlib
*/
if (typeof atob === "undefined") {
global.atob = function (b64: string) {
return Buffer.from(b64, "base64").toString("utf-8");
};
global.atob = (b64: string) => Buffer.from(b64, "base64").toString("utf-8");
}
export type * from "../pkg/commands/types";
export type { Requester, UpstashRequest, UpstashResponse };
Expand Down Expand Up @@ -55,6 +53,7 @@ export type RedisConfigNodejs = {
* For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
*/
signal?: AbortSignal;
latencyLogging?: boolean;
agent?: any;
} & core.RedisOptions &
RequesterConfig;
Expand Down Expand Up @@ -104,18 +103,14 @@ export class Redis extends core.Redis {
configOrRequester.url.endsWith(" ") ||
/\r|\n/.test(configOrRequester.url)
) {
console.warn(
"The redis url contains whitespace or newline, which can cause errors!"
);
console.warn("The redis url contains whitespace or newline, which can cause errors!");
}
if (
configOrRequester.token.startsWith(" ") ||
configOrRequester.token.endsWith(" ") ||
/\r|\n/.test(configOrRequester.token)
) {
console.warn(
"The redis token contains whitespace or newline, which can cause errors!"
);
console.warn("The redis token contains whitespace or newline, which can cause errors!");
}

const client = new HttpClient({
Expand All @@ -131,19 +126,14 @@ export class Redis extends core.Redis {
super(client, {
automaticDeserialization: configOrRequester.automaticDeserialization,
enableTelemetry: !process.env.UPSTASH_DISABLE_TELEMETRY,
latencyLogging: configOrRequester.latencyLogging,
});

this.addTelemetry({
runtime:
// @ts-ignore
typeof EdgeRuntime === "string"
? "edge-light"
: `node@${process.version}`,
platform: process.env.VERCEL
? "vercel"
: process.env.AWS_REGION
? "aws"
: "unknown",
typeof EdgeRuntime === "string" ? "edge-light" : `node@${process.version}`,
platform: process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : "unknown",
sdk: `@upstash/redis@${VERSION}`,
});
}
Expand All @@ -161,22 +151,18 @@ export class Redis extends core.Redis {
// @ts-ignore process will be defined in node
if (typeof process?.env === "undefined") {
throw new Error(
'Unable to get environment variables, `process.env` is undefined. If you are deploying to cloudflare, please import from "@upstash/redis/cloudflare" instead'
'Unable to get environment variables, `process.env` is undefined. If you are deploying to cloudflare, please import from "@upstash/redis/cloudflare" instead',
);
}
// @ts-ignore process will be defined in node
const url = process?.env.UPSTASH_REDIS_REST_URL;
if (!url) {
throw new Error(
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`"
);
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_URL`");
}
// @ts-ignore process will be defined in node
const token = process?.env.UPSTASH_REDIS_REST_TOKEN;
if (!token) {
throw new Error(
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`"
);
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`");
}
return new Redis({ ...config, url, token });
}
Expand Down

0 comments on commit 8895aca

Please sign in to comment.