Skip to content

Commit

Permalink
feat: logging via pino and logtail
Browse files Browse the repository at this point in the history
  • Loading branch information
jaybuidl committed Oct 9, 2023
1 parent 788a48b commit a54c071
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 9 deletions.
31 changes: 22 additions & 9 deletions web/netlify/functions/update-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { createClient } from "@supabase/supabase-js";
import { Database } from "../../src/types/supabase-notification";
import messages from "../../src/consts/eip712-messages";
import { EMAIL_REGEX, TELEGRAM_REGEX, ETH_ADDRESS_REGEX, ETH_SIGNATURE_REGEX } from "../../src/consts/index";
import { createLogger, throwNewError } from "../../src/utils/logger";
import dotenv from "dotenv";

dotenv.config();

type NotificationSettings = {
email?: string;
Expand All @@ -13,12 +17,15 @@ type NotificationSettings = {
signature: string;
};

const logger = createLogger(process.env.LOGTAIL_TOKEN).child({ function: "update-settings" });
const logAndThrowNewError = (message: string, error?: any) => throwNewError(logger, message, error);

const parse = (inputString: string): NotificationSettings => {
let input;
try {
input = JSON.parse(inputString);
} catch (err) {
throw new Error("Invalid JSON format");
logAndThrowNewError("Invalid JSON format", err);
}

const requiredKeys: (keyof NotificationSettings)[] = ["nonce", "address", "signature"];
Expand All @@ -27,37 +34,37 @@ const parse = (inputString: string): NotificationSettings => {

for (const key of requiredKeys) {
if (!receivedKeys.includes(key)) {
throw new Error(`Missing key: ${key}`);
logAndThrowNewError(`Missing key: ${key}`);
}
}

const allExpectedKeys = [...requiredKeys, ...optionalKeys];
for (const key of receivedKeys) {
if (!allExpectedKeys.includes(key as keyof NotificationSettings)) {
throw new Error(`Unexpected key: ${key}`);
logAndThrowNewError(`Unexpected key: ${key}`);
}
}

const email = input.email ? input.email.trim() : "";
if (email && !EMAIL_REGEX.test(email)) {
throw new Error("Invalid email format");
logAndThrowNewError("Invalid email format");
}

const telegram = input.telegram ? input.telegram.trim() : "";
if (telegram && !TELEGRAM_REGEX.test(telegram)) {
throw new Error("Invalid Telegram username format");
logAndThrowNewError("Invalid Telegram username format");
}

if (!/^\d+$/.test(input.nonce)) {
throw new Error("Invalid nonce format. Expected an integer as a string.");
logAndThrowNewError("Invalid nonce format. Expected an integer as a string.");
}

if (!ETH_ADDRESS_REGEX.test(input.address)) {
throw new Error("Invalid Ethereum address format");
logAndThrowNewError("Invalid Ethereum address format");
}

if (!ETH_SIGNATURE_REGEX.test(input.signature)) {
throw new Error("Invalid signature format");
logAndThrowNewError("Invalid signature format");
}

return {
Expand All @@ -72,7 +79,7 @@ const parse = (inputString: string): NotificationSettings => {
export const handler: Handler = async (event) => {
try {
if (!event.body) {
throw new Error("No body provided");
logAndThrowNewError("No body provided");
}
const { email, telegram, nonce, address, signature } = parse(event.body);
const lowerCaseAddress = address.toLowerCase() as `0x${string}`;
Expand All @@ -85,6 +92,7 @@ export const handler: Handler = async (event) => {
});
if (!isValid) {
// If the recovered address does not match the provided address, return an error
logAndThrowNewError("Signature verification failed");
throw new Error("Signature verification failed");
}

Expand All @@ -94,6 +102,7 @@ export const handler: Handler = async (event) => {
if (email === "" && telegram === "") {
const { error } = await supabase.from("users").delete().match({ address: lowerCaseAddress });
if (error) throw error;
logger.info("Record deleted successfully.");
return { statusCode: 200, body: JSON.stringify({ message: "Record deleted successfully." }) };
}

Expand All @@ -105,8 +114,12 @@ export const handler: Handler = async (event) => {
if (error) {
throw error;
}
logger.info("Record updated successfully.");
return { statusCode: 200, body: JSON.stringify({ message: "Record updated successfully." }) };
} catch (err) {
logger.error(err);
return { statusCode: 500, body: JSON.stringify({ message: `Error: ${err}` }) };
} finally {
logger.flush();
}
};
3 changes: 3 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"@filebase/client": "^0.0.5",
"@kleros/kleros-v2-contracts": "workspace:^",
"@kleros/ui-components-library": "^2.6.2",
"@logtail/pino": "^0.4.12",
"@sentry/react": "^7.55.2",
"@sentry/tracing": "^7.55.2",
"@supabase/supabase-js": "^2.33.1",
Expand All @@ -87,6 +88,8 @@
"moment": "^2.29.4",
"overlayscrollbars": "^2.3.0",
"overlayscrollbars-react": "^0.5.2",
"pino": "^8.16.0",
"pino-pretty": "^10.2.3",
"react": "^18.2.0",
"react-chartjs-2": "^4.3.1",
"react-dom": "^18.2.0",
Expand Down
40 changes: 40 additions & 0 deletions web/src/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pino, { TransportTargetOptions } from "pino";

// Intended for Netlify functions
export const createLogger = (logtailToken?: string): pino.Logger => {
const targets: TransportTargetOptions[] = [
{
target: "pino-pretty",
options: {},
level: "info",
},
];
if (logtailToken) {
targets.push({
target: "@logtail/pino",
options: { sourceToken: logtailToken },
level: "info",
});
}
return pino(
{
level: "info",
timestamp: pino.stdTimeFunctions.isoTime,
},
pino.transport({ targets: targets })
);
};

export const throwNewError = (logger: pino.Logger, message: string, error?: any) => {
if (!error) {
logger.error(message);
throw new Error(message);
}
if (typeof error === "string") {
logger.error(error, message);
throw new Error(message + ": " + error);
} else if (error instanceof Error) {
logger.error(error, message);
throw new Error(message + ": " + error.name + ": " + error.message);
}
};
123 changes: 123 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5365,6 +5365,7 @@ __metadata:
"@kleros/kleros-v2-prettier-config": "workspace:^"
"@kleros/kleros-v2-tsconfig": "workspace:^"
"@kleros/ui-components-library": ^2.6.2
"@logtail/pino": ^0.4.12
"@netlify/functions": ^1.6.0
"@parcel/transformer-svg-react": 2.8.3
"@parcel/watcher": ~2.2.0
Expand Down Expand Up @@ -5401,6 +5402,8 @@ __metadata:
overlayscrollbars: ^2.3.0
overlayscrollbars-react: ^0.5.2
parcel: 2.8.3
pino: ^8.16.0
pino-pretty: ^10.2.3
react: ^18.2.0
react-chartjs-2: ^4.3.1
react-dom: ^18.2.0
Expand Down Expand Up @@ -5663,6 +5666,16 @@ __metadata:
languageName: node
linkType: hard

"@logtail/core@npm:^0.4.12":
version: 0.4.12
resolution: "@logtail/core@npm:0.4.12"
dependencies:
"@logtail/tools": ^0.4.12
"@logtail/types": ^0.4.11
checksum: 615874d456ed732d650d4a022bd14e2a400198b26dfd07cb512a365e8369a8ab1d48b74657c7bc1a77e03b430778f652d41c84638c3efe9de2ef91cfe6f4dd29
languageName: node
linkType: hard

"@logtail/node@npm:^0.4.0":
version: 0.4.0
resolution: "@logtail/node@npm:0.4.0"
Expand All @@ -5678,6 +5691,21 @@ __metadata:
languageName: node
linkType: hard

"@logtail/node@npm:^0.4.12":
version: 0.4.12
resolution: "@logtail/node@npm:0.4.12"
dependencies:
"@logtail/core": ^0.4.12
"@logtail/types": ^0.4.11
"@msgpack/msgpack": ^2.5.1
"@types/stack-trace": ^0.0.29
cross-fetch: ^3.0.4
minimatch: ^3.0.4
stack-trace: ^0.0.10
checksum: d2799eb561e4bdee4fb9875350983cb5f7ede2ab6c368bf3673cbcfdc7df3c16616d6b881edf60dfe64e0bafc6c6a63d96455bb0a4d34328ed3414fd94d47c5f
languageName: node
linkType: hard

"@logtail/pino@npm:^0.4.0":
version: 0.4.0
resolution: "@logtail/pino@npm:0.4.0"
Expand All @@ -5691,6 +5719,19 @@ __metadata:
languageName: node
linkType: hard

"@logtail/pino@npm:^0.4.12":
version: 0.4.12
resolution: "@logtail/pino@npm:0.4.12"
dependencies:
"@logtail/node": ^0.4.12
"@logtail/types": ^0.4.11
pino-abstract-transport: ^1.0.0
peerDependencies:
pino: ^7.0.0 || ^8.0.0
checksum: 1b6ee658ad5e60c65cc0bd50aaf1e99b26150e2b26622a13c09fcb4e15f33dd8979aa58401d06524d82a5ea19511c96871bbdb57aaa4166586dc76159b01110e
languageName: node
linkType: hard

"@logtail/tools@npm:^0.4.0":
version: 0.4.0
resolution: "@logtail/tools@npm:0.4.0"
Expand All @@ -5700,6 +5741,15 @@ __metadata:
languageName: node
linkType: hard

"@logtail/tools@npm:^0.4.12":
version: 0.4.12
resolution: "@logtail/tools@npm:0.4.12"
dependencies:
"@logtail/types": ^0.4.11
checksum: b0a8391a763b7f7f7d889446ed857715f158288f615b089f125471582efd8bb2a9525e37bb58f88f166224529ce3bc74799807ff768905e79ac1c92d5877aa1e
languageName: node
linkType: hard

"@logtail/types@npm:^0.4.0":
version: 0.4.0
resolution: "@logtail/types@npm:0.4.0"
Expand All @@ -5709,6 +5759,15 @@ __metadata:
languageName: node
linkType: hard

"@logtail/types@npm:^0.4.11":
version: 0.4.11
resolution: "@logtail/types@npm:0.4.11"
dependencies:
js: ^0.1.0
checksum: 0102a079d0ba89efc70770f6d853f0b205784a73abe570ab056f830d4ab031f95a1d80e2a3dfa54ebf53193d20fd9b61d52c2be03032d28572ce9fcb3be89144
languageName: node
linkType: hard

"@metamask/eth-sig-util@npm:^4.0.0":
version: 4.0.1
resolution: "@metamask/eth-sig-util@npm:4.0.1"
Expand Down Expand Up @@ -24731,6 +24790,16 @@ __metadata:
languageName: node
linkType: hard

"pino-abstract-transport@npm:v1.1.0":
version: 1.1.0
resolution: "pino-abstract-transport@npm:1.1.0"
dependencies:
readable-stream: ^4.0.0
split2: ^4.0.0
checksum: cc84caabee5647b5753ae484d5f63a1bca0f6e1791845e2db2b6d830a561c2b5dd1177720f68d78994c8a93aecc69f2729e6ac2bc871a1bf5bb4b0ec17210668
languageName: node
linkType: hard

"pino-pretty@npm:^10.0.0":
version: 10.0.0
resolution: "pino-pretty@npm:10.0.0"
Expand All @@ -24755,6 +24824,30 @@ __metadata:
languageName: node
linkType: hard

"pino-pretty@npm:^10.2.3":
version: 10.2.3
resolution: "pino-pretty@npm:10.2.3"
dependencies:
colorette: ^2.0.7
dateformat: ^4.6.3
fast-copy: ^3.0.0
fast-safe-stringify: ^2.1.1
help-me: ^4.0.1
joycon: ^3.1.1
minimist: ^1.2.6
on-exit-leak-free: ^2.1.0
pino-abstract-transport: ^1.0.0
pump: ^3.0.0
readable-stream: ^4.0.0
secure-json-parse: ^2.4.0
sonic-boom: ^3.0.0
strip-json-comments: ^3.1.1
bin:
pino-pretty: bin.js
checksum: 9182886855515000df2ef381762c69fc29dbdd9014a76839cc3d8a7a94ac96d4ce17423adb9ddd61eae78986bb0ff3a1d9e6e7aa55476c096a3dd4a0c89440e8
languageName: node
linkType: hard

"pino-std-serializers@npm:^4.0.0":
version: 4.0.0
resolution: "pino-std-serializers@npm:4.0.0"
Expand Down Expand Up @@ -24811,6 +24904,27 @@ __metadata:
languageName: node
linkType: hard

"pino@npm:^8.16.0":
version: 8.16.0
resolution: "pino@npm:8.16.0"
dependencies:
atomic-sleep: ^1.0.0
fast-redact: ^3.1.1
on-exit-leak-free: ^2.1.0
pino-abstract-transport: v1.1.0
pino-std-serializers: ^6.0.0
process-warning: ^2.0.0
quick-format-unescaped: ^4.0.3
real-require: ^0.2.0
safe-stable-stringify: ^2.3.1
sonic-boom: ^3.7.0
thread-stream: ^2.0.0
bin:
pino: bin.js
checksum: c3af0d1d80d0a7ec59530e6c3668895ac813762829ea0b7e316057370f58011d09e128e67289665652904367a1f27f87cca4e564eb3ff2a0d46219f12fcf896e
languageName: node
linkType: hard

"pirates@npm:^4.0.1, pirates@npm:^4.0.4":
version: 4.0.6
resolution: "pirates@npm:4.0.6"
Expand Down Expand Up @@ -28387,6 +28501,15 @@ __metadata:
languageName: node
linkType: hard

"sonic-boom@npm:^3.7.0":
version: 3.7.0
resolution: "sonic-boom@npm:3.7.0"
dependencies:
atomic-sleep: ^1.0.0
checksum: 528f0f7f7e09dcdb02ad5985039f66554266cbd8813f9920781607c9248e01f468598c1334eab2cc740c016a63c8b2a20e15c3f618cddb08ea1cfb4a390a796e
languageName: node
linkType: hard

"source-list-map@npm:^2.0.0, source-list-map@npm:^2.0.1":
version: 2.0.1
resolution: "source-list-map@npm:2.0.1"
Expand Down

0 comments on commit a54c071

Please sign in to comment.