diff --git a/arcjet/index.ts b/arcjet/index.ts index 0ab303cf3..8e397f3f9 100644 --- a/arcjet/index.ts +++ b/arcjet/index.ts @@ -40,7 +40,7 @@ import { } from "@arcjet/protocol/proto.js"; import * as analyze from "@arcjet/analyze"; import * as duration from "@arcjet/duration"; -import { Logger } from "@arcjet/logger"; +import logger from "@arcjet/logger"; export * from "@arcjet/protocol"; @@ -324,7 +324,7 @@ export function createRemoteClient( rules: rules.map(ArcjetRuleToProtocol), }); - context.log.debug("Decide request to %s", baseUrl); + logger.debug("Decide request to %s", baseUrl); const response = await client.decide(decideRequest, { headers: { Authorization: `Bearer ${context.key}` }, @@ -333,7 +333,7 @@ export function createRemoteClient( const decision = ArcjetDecisionFromProtocol(response.decision); - context.log.debug("Decide response", { + logger.debug("Decide response", { id: decision.id, fingerprint: context.fingerprint, path: details.path, @@ -375,7 +375,7 @@ export function createRemoteClient( receivedAt: Timestamp.now(), }); - context.log.debug("Report request to %s", baseUrl); + logger.debug("Report request to %s", baseUrl); // We use the promise API directly to avoid returning a promise from this function so execution can't be paused with `await` client @@ -384,7 +384,7 @@ export function createRemoteClient( timeoutMs: 2_000, // 2 seconds }) .then((response) => { - context.log.debug("Report response", { + logger.debug("Report response", { id: response.decision?.id, fingerprint: context.fingerprint, path: details.path, @@ -393,7 +393,7 @@ export function createRemoteClient( }); }) .catch((err: unknown) => { - context.log.log( + logger.log( "Encountered problem sending report: %s", errorMessage(err), ); @@ -1046,8 +1046,6 @@ export interface Arcjet { export default function arcjet< const Rules extends [...(Primitive | Product)[]] = [], >(options: ArcjetOptions): Arcjet>> { - const log = new Logger(); - // We destructure here to make the function signature neat when viewed by consumers const { key, rules, client } = options; @@ -1094,24 +1092,24 @@ export default function arcjet< email: typeof request.email === "string" ? request.email : undefined, }); - log.time("local"); + logger.time("local"); - log.time("fingerprint"); + logger.time("fingerprint"); let ip = ""; if (typeof details.ip === "string") { ip = details.ip; } if (details.ip === "") { - log.warn("generateFingerprint: ip is empty"); + logger.warn("generateFingerprint: ip is empty"); } const fingerprint = await analyze.generateFingerprint(ip); - log.debug("fingerprint (%s): %s", runtime(), fingerprint); - log.timeEnd("fingerprint"); + logger.debug("fingerprint (%s): %s", runtime(), fingerprint); + logger.timeEnd("fingerprint"); - const context: ArcjetContext = { key, fingerprint, log }; + const context: ArcjetContext = { key, fingerprint }; if (rules.length > 10) { - log.error("Failure running rules. Only 10 rules may be specified."); + logger.error("Failure running rules. Only 10 rules may be specified."); const decision = new ArcjetErrorDecision({ ttl: 0, @@ -1148,15 +1146,15 @@ export default function arcjet< // serverless environments where every request is isolated, but there may be // some instances where the instance is not recycled immediately. If so, we // can take advantage of that. - log.time("cache"); + logger.time("cache"); const existingBlockReason = blockCache.get(fingerprint); - log.timeEnd("cache"); + logger.timeEnd("cache"); // If already blocked then we can async log to the API and return the // decision immediately. if (existingBlockReason) { - log.timeEnd("local"); - log.debug("decide: alreadyBlocked", { + logger.timeEnd("local"); + logger.debug("decide: alreadyBlocked", { fingerprint, existingBlockReason, }); @@ -1169,7 +1167,7 @@ export default function arcjet< remoteClient.report(context, details, decision, rules); - log.debug("decide: already blocked", { + logger.debug("decide: already blocked", { id: decision.id, conclusion: decision.conclusion, fingerprint, @@ -1190,13 +1188,13 @@ export default function arcjet< continue; } - log.time(rule.type); + logger.time(rule.type); try { localRule.validate(context, details); results[idx] = await localRule.protect(context, details); - log.debug("Local rule result:", { + logger.debug("Local rule result:", { id: results[idx].ruleId, rule: rule.type, fingerprint, @@ -1207,7 +1205,7 @@ export default function arcjet< reason: results[idx].reason, }); } catch (err) { - log.error( + logger.error( "Failure running rule: %s due to %s", rule.type, errorMessage(err), @@ -1221,10 +1219,10 @@ export default function arcjet< }); } - log.timeEnd(rule.type); + logger.timeEnd(rule.type); if (results[idx].isDenied()) { - log.timeEnd("local"); + logger.timeEnd("local"); const decision = new ArcjetDenyDecision({ ttl: results[idx].ttl, @@ -1241,7 +1239,7 @@ export default function arcjet< // and return this DENY decision. if (rule.mode !== "DRY_RUN") { if (results[idx].ttl > 0) { - log.debug("Caching decision for %d seconds", decision.ttl, { + logger.debug("Caching decision for %d seconds", decision.ttl, { fingerprint, conclusion: decision.conclusion, reason: decision.reason, @@ -1257,7 +1255,7 @@ export default function arcjet< return decision; } - log.warn( + logger.warn( `Dry run mode is enabled for "%s" rule. Overriding decision. Decision was: %s`, rule.type, decision.conclusion, @@ -1265,20 +1263,23 @@ export default function arcjet< } } - log.timeEnd("local"); - log.time("remote"); + logger.timeEnd("local"); + logger.time("remote"); // With no cached values, we take a decision remotely. We use a timeout to // fail open. try { - log.time("decideApi"); + logger.time("decideApi"); const decision = await remoteClient.decide(context, details, rules); - log.timeEnd("decideApi"); + logger.timeEnd("decideApi"); // If the decision is to block and we have a non-zero TTL, we cache the // block locally if (decision.isDenied() && decision.ttl > 0) { - log.debug("decide: Caching block locally for %d seconds", decision.ttl); + logger.debug( + "decide: Caching block locally for %d seconds", + decision.ttl, + ); blockCache.set( fingerprint, @@ -1289,7 +1290,7 @@ export default function arcjet< return decision; } catch (err) { - log.error( + logger.error( "Encountered problem getting remote decision: %s", errorMessage(err), ); @@ -1299,11 +1300,11 @@ export default function arcjet< results, }); - remoteClient.report({ key, fingerprint, log }, details, decision, rules); + remoteClient.report(context, details, decision, rules); return decision; } finally { - log.timeEnd("remote"); + logger.timeEnd("remote"); } } diff --git a/arcjet/test/index.node.test.ts b/arcjet/test/index.node.test.ts index 726253879..2d7c49174 100644 --- a/arcjet/test/index.node.test.ts +++ b/arcjet/test/index.node.test.ts @@ -24,7 +24,7 @@ import { RuleResult, RuleState, } from "@arcjet/protocol/proto"; -import { Logger } from "@arcjet/logger"; +import logger from "@arcjet/logger"; import arcjet, { ArcjetDecision, @@ -245,7 +245,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -300,7 +299,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -356,7 +354,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -410,7 +407,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -465,7 +461,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -525,7 +520,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -567,7 +561,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -608,7 +601,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -649,7 +641,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -693,7 +684,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -743,7 +733,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -785,7 +774,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const receivedAt = Timestamp.now(); const details = { @@ -853,7 +841,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const receivedAt = Timestamp.now(); const details = { @@ -920,7 +907,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const receivedAt = Timestamp.now(); const details = { @@ -994,7 +980,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const receivedAt = Timestamp.now(); const details = { @@ -1061,7 +1046,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const receivedAt = Timestamp.now(); const details = { @@ -1124,7 +1108,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const receivedAt = Timestamp.now(); const details = { @@ -1213,7 +1196,6 @@ describe("createRemoteClient", () => { const context = { key, fingerprint, - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1229,7 +1211,7 @@ describe("createRemoteClient", () => { const [promise, resolve] = deferred(); - const logSpy = jest.spyOn(context.log, "log").mockImplementation(() => { + const logSpy = jest.spyOn(logger, "log").mockImplementation(() => { resolve(); }); @@ -1543,7 +1525,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { headers: new Headers(), @@ -1561,7 +1542,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { headers: undefined, @@ -1579,7 +1559,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1623,7 +1602,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1677,7 +1655,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1731,7 +1708,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1772,7 +1748,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1835,7 +1810,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1883,7 +1857,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -1930,7 +1903,6 @@ describe("Primitive > detectBot", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2745,7 +2717,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { email: "abc@example.com", @@ -2763,7 +2734,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { email: undefined, @@ -2781,7 +2751,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2813,7 +2782,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2845,7 +2813,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2877,7 +2844,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2911,7 +2877,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2943,7 +2908,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -2975,7 +2939,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -3009,7 +2972,6 @@ describe("Primitive > validateEmail", () => { const context = { key: "test-key", fingerprint: "test-fingerprint", - log: new Logger(), }; const details = { ip: "172.100.1.1", @@ -4161,7 +4123,7 @@ describe("SDK", () => { "extra-test": "extra-test-value", }; - let errorLogSpy; + const errorLogSpy = jest.spyOn(logger, "error"); function testRuleLocalThrowString(): ArcjetLocalRule { return { @@ -4170,7 +4132,6 @@ describe("SDK", () => { priority: 1, validate: jest.fn(), async protect(context, details) { - errorLogSpy = jest.spyOn(context.log, "error"); throw "Local rule protect failed"; }, }; @@ -4214,7 +4175,7 @@ describe("SDK", () => { "extra-test": "extra-test-value", }; - let errorLogSpy; + const errorLogSpy = jest.spyOn(logger, "error"); function testRuleLocalThrowNull(): ArcjetLocalRule { return { @@ -4223,7 +4184,6 @@ describe("SDK", () => { priority: 1, validate: jest.fn(), async protect(context, details) { - errorLogSpy = jest.spyOn(context.log, "error"); throw null; }, }; diff --git a/protocol/index.ts b/protocol/index.ts index 7c799935a..927e2780e 100644 --- a/protocol/index.ts +++ b/protocol/index.ts @@ -1,6 +1,5 @@ import { typeid } from "typeid-js"; import { Reason } from "./gen/es/decide/v1alpha1/decide_pb.js"; -import type { Logger } from "@arcjet/logger"; type ArcjetEnum = { readonly [Key in T]: T }; @@ -463,5 +462,4 @@ export interface ArcjetBotRule export type ArcjetContext = { key: string; fingerprint: string; - log: Logger; }; diff --git a/protocol/package.json b/protocol/package.json index 8f5cc0ae2..2539fe3df 100644 --- a/protocol/package.json +++ b/protocol/package.json @@ -41,7 +41,6 @@ "test": "NODE_OPTIONS=--experimental-vm-modules jest" }, "dependencies": { - "@arcjet/logger": "1.0.0-alpha.8", "@bufbuild/protobuf": "1.7.2", "@connectrpc/connect": "1.3.0", "typeid-js": "0.5.0"