diff --git a/package.json b/package.json index c09e276..c6511ed 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@ethersproject/bytes": "^5.5.0", "@ethersproject/contracts": "^5.5.0", "@ethersproject/hash": "^5.5.0", + "@snapshot-labs/snapshot-metrics": "^1.0.0", "@snapshot-labs/snapshot-sentry": "^1.1.0", "@snapshot-labs/snapshot.js": "^0.5.4", "bluebird": "^3.7.2", diff --git a/src/check.ts b/src/check.ts index 88309b7..340ede7 100644 --- a/src/check.ts +++ b/src/check.ts @@ -3,6 +3,7 @@ import fetch from 'node-fetch'; import db from './mysql'; // TODO: remove when all environments are updated import constants from './constants.json'; +import { timeMessageProcess } from './metrics'; import { capture } from '@snapshot-labs/snapshot-sentry'; const delay = 60 * 60 * 24 * 3; @@ -59,6 +60,7 @@ async function processSig(address, safeHash, network) { async function checkSignedMessages(messages, network) { if (messages.length > 0) { + const end = timeMessageProcess.startTimer({ network }); const provider = snapshot.utils.getProvider(network); const abi = ['function signedMessages(bytes32) view returns (uint256)']; try { @@ -84,6 +86,8 @@ async function checkSignedMessages(messages, network) { } catch (e) { capture(e); console.log(`multicall error for network: ${network}`, e); + } finally { + end(); } } } diff --git a/src/index.ts b/src/index.ts index 6f77860..2224d21 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,12 +5,15 @@ import cors from 'cors'; import { initLogger, fallbackLogger } from '@snapshot-labs/snapshot-sentry'; import api from './api'; import './check'; +import initMetrics from './metrics'; const app = express(); const PORT = process.env.PORT || 3000; initLogger(app); +initMetrics(app); +app.disable('x-powered-by'); app.use(bodyParser.json({ limit: '4mb' })); app.use(bodyParser.urlencoded({ limit: '4mb', extended: false })); app.use(cors({ maxAge: 86400 })); diff --git a/src/metrics.ts b/src/metrics.ts new file mode 100644 index 0000000..25bcf0e --- /dev/null +++ b/src/metrics.ts @@ -0,0 +1,31 @@ +import init, { client } from '@snapshot-labs/snapshot-metrics'; +import { Express } from 'express'; +import db from './mysql'; + +export default function initMetrics(app: Express) { + init(app, { + normalizedPath: [['^/api/messages/.+', '/api/messages/#hash']], + whitelistedPath: [/^\/$/, /^\/api$/, /^\/api\/msg$/, /^\/api\/messages\/.+$/] + }); +} + +new client.Gauge({ + name: 'messages_per_network_count', + help: 'Total number of messages per network', + labelNames: ['network'], + async collect() { + const results = await db.queryAsync( + 'SELECT COUNT(*) as count, network FROM messages GROUP BY network' + ); + + results.forEach(result => { + this.set({ network: result.network }, result.count); + }); + } +}); + +export const timeMessageProcess = new client.Histogram({ + name: 'message_process_duration_seconds', + help: 'Duration in seconds of each batch messages process', + labelNames: ['network'] +}); diff --git a/yarn.lock b/yarn.lock index a726434..6206b75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -490,6 +490,14 @@ resolved "https://registry.yarnpkg.com/@snapshot-labs/prettier-config/-/prettier-config-0.1.0-beta.7.tgz#c8e07e7e9baabee245020a72ac05835b65139823" integrity sha512-k/FUf4VWhwLFUmKuWs2mNvmPe691hqhvCJuujD4TfbIivWysmL1TqthwfdQUrQEAQUqVQ2ZKEiGkbufp5J27eQ== +"@snapshot-labs/snapshot-metrics@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@snapshot-labs/snapshot-metrics/-/snapshot-metrics-1.0.0.tgz#1f88a6aacc81f639f7059c153b53c550934cd3b3" + integrity sha512-6T8a2NX6Qo6zVAoNIWV8eSJCukCynI/HCLp37VZTzX8jwU/ahGsiDTQC3I/MDus+LDB+8pI5nju33NwM8Q7n2g== + dependencies: + express-prom-bundle "^6.6.0" + prom-client "^14.2.0" + "@snapshot-labs/snapshot-sentry@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@snapshot-labs/snapshot-sentry/-/snapshot-sentry-1.1.0.tgz#b357d4789ffd287f90fb70e7f0b207b47627cf24" @@ -838,6 +846,11 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bintrees@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8" + integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw== + bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -1386,6 +1399,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +express-prom-bundle@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/express-prom-bundle/-/express-prom-bundle-6.6.0.tgz#9c33c1bd1478d70e3961a53aed2d17f15ef821ca" + integrity sha512-tZh2P2p5a8/yxQ5VbRav011Poa4R0mHqdFwn9Swe/obXDe5F0jY9wtRAfNYnqk4LXY7akyvR/nrvAHxQPWUjsQ== + dependencies: + on-finished "^2.3.0" + url-value-parser "^2.0.0" + express@^4.18.1: version "4.18.1" resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" @@ -2165,7 +2186,7 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== -on-finished@2.4.1: +on-finished@2.4.1, on-finished@^2.3.0: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -2296,6 +2317,13 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +prom-client@^14.2.0: + version "14.2.0" + resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-14.2.0.tgz#ca94504e64156f6506574c25fb1c34df7812cf11" + integrity sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA== + dependencies: + tdigest "^0.1.1" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -2662,6 +2690,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +tdigest@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.2.tgz#96c64bac4ff10746b910b0e23b515794e12faced" + integrity sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA== + dependencies: + bintrees "1.0.2" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -2820,6 +2855,11 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +url-value-parser@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/url-value-parser/-/url-value-parser-2.2.0.tgz#f38ae8cd24604ec69bc219d66929ddbbd93a2b32" + integrity sha512-yIQdxJpgkPamPPAPuGdS7Q548rLhny42tg8d4vyTNzFqvOnwqrgHXvgehT09U7fwrzxi3RxCiXjoNUNnNOlQ8A== + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"