From 6e8208a92aa02b02b0f0ebcb368ef3ba4ed9e4cc Mon Sep 17 00:00:00 2001
From: Prathamesh Musale <prathamesh.musale0@gmail.com>
Date: Thu, 6 Jun 2024 19:15:52 +0530
Subject: [PATCH 1/3] Regenerate watcher with latest codegen

---
 .gitignore              |    2 +
 README.md               |    2 +-
 environments/local.toml |   32 +-
 package.json            |   13 +-
 src/indexer.ts          |    2 +-
 src/resolvers.ts        | 2462 ++++++++++++++++++++++++---------------
 6 files changed, 1580 insertions(+), 933 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0b4cc3f..549d70b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ out/
 
 .vscode
 .idea
+
+gql-logs/
diff --git a/README.md b/README.md
index 4d8410c..588dd22 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@
 
 To enable GQL requests caching:
 
-* Update the `server.gqlCache` config with required settings.
+* Update the `server.gql.cache` config with required settings.
 
 * In the GQL [schema file](./src/schema.gql), use the `cacheControl` directive to apply cache hints at schema level.
 
diff --git a/environments/local.toml b/environments/local.toml
index af716e6..1ba34d8 100644
--- a/environments/local.toml
+++ b/environments/local.toml
@@ -2,7 +2,6 @@
   host = "127.0.0.1"
   port = 3008
   kind = "active"
-  gqlPath = "/graphql"
 
   # Checkpointing state.
   checkpointing = true
@@ -22,23 +21,30 @@
   # Interval in number of blocks at which to clear entities cache.
   clearEntitiesCacheInterval = 1000
 
-  # Max block range for which to return events in eventsInRange GQL query.
-  # Use -1 for skipping check on block range.
-  maxEventsBlockRange = 1000
-
   # Flag to specify whether RPC endpoint supports block hash as block tag parameter
   rpcSupportsBlockHashParam = false
 
-  # GQL cache settings
-  [server.gqlCache]
-    enabled = true
+  # Server GQL config
+  [server.gql]
+    path = "/graphql"
 
-    # Max in-memory cache size (in bytes) (default 8 MB)
-    # maxCacheSize
+    # Max block range for which to return events in eventsInRange GQL query.
+    # Use -1 for skipping check on block range.
+    maxEventsBlockRange = 1000
 
-    # GQL cache-control max-age settings (in seconds)
-    maxAge = 15
-    timeTravelMaxAge = 86400 # 1 day
+    # Log directory for GQL requests
+    logDir = "./gql-logs"
+
+    # GQL cache settings
+    [server.gql.cache]
+      enabled = true
+
+      # Max in-memory cache size (in bytes) (default 8 MB)
+      # maxCacheSize
+
+      # GQL cache-control max-age settings (in seconds)
+      maxAge = 15
+      timeTravelMaxAge = 86400 # 1 day
 
 [metrics]
   host = "127.0.0.1"
diff --git a/package.json b/package.json
index c0f8d73..cdcb94e 100644
--- a/package.json
+++ b/package.json
@@ -39,11 +39,11 @@
   "homepage": "https://github.com/cerc-io/watcher-ts#readme",
   "dependencies": {
     "@apollo/client": "^3.3.19",
-    "@cerc-io/cli": "^0.2.93",
-    "@cerc-io/ipld-eth-client": "^0.2.93",
-    "@cerc-io/solidity-mapper": "^0.2.93",
-    "@cerc-io/util": "^0.2.93",
-    "@cerc-io/graph-node": "^0.2.93",
+    "@cerc-io/cli": "^0.2.94",
+    "@cerc-io/ipld-eth-client": "^0.2.94",
+    "@cerc-io/solidity-mapper": "^0.2.94",
+    "@cerc-io/util": "^0.2.94",
+    "@cerc-io/graph-node": "^0.2.94",
     "@ethersproject/providers": "^5.4.4",
     "debug": "^4.3.1",
     "decimal.js": "^10.3.1",
@@ -71,6 +71,7 @@
     "eslint-plugin-standard": "^5.0.0",
     "husky": "^7.0.2",
     "ts-node": "^10.2.1",
-    "typescript": "^5.0.2"
+    "typescript": "^5.0.2",
+    "winston": "^3.13.0"
   }
 }
diff --git a/src/indexer.ts b/src/indexer.ts
index 8914836..47364cd 100644
--- a/src/indexer.ts
+++ b/src/indexer.ts
@@ -657,7 +657,7 @@ export class Indexer implements IndexerInterface {
   }
 
   async getEventsInRange (fromBlockNumber: number, toBlockNumber: number): Promise<Array<Event>> {
-    return this._baseIndexer.getEventsInRange(fromBlockNumber, toBlockNumber, this._serverConfig.maxEventsBlockRange);
+    return this._baseIndexer.getEventsInRange(fromBlockNumber, toBlockNumber, this._serverConfig.gql.maxEventsBlockRange);
   }
 
   async getSyncStatus (): Promise<SyncStatus | undefined> {
diff --git a/src/resolvers.ts b/src/resolvers.ts
index d7abb1d..4a7e98f 100644
--- a/src/resolvers.ts
+++ b/src/resolvers.ts
@@ -5,10 +5,13 @@
 import assert from 'assert';
 import debug from 'debug';
 import { GraphQLResolveInfo } from 'graphql';
+import { ExpressContext } from 'apollo-server-express';
+import winston from 'winston';
 
 import {
   gqlTotalQueryCount,
   gqlQueryCount,
+  gqlQueryDuration,
   getResultState,
   IndexerInterface,
   GraphQLBigInt,
@@ -93,11 +96,57 @@ import { BurnWrap } from './entity/BurnWrap';
 
 const log = debug('vulcanize:resolver');
 
-export const createResolvers = async (indexerArg: IndexerInterface, eventWatcher: EventWatcher): Promise<any> => {
+const executeAndRecordMetrics = async (
+  indexer: Indexer,
+  gqlLogger: winston.Logger,
+  opName: string,
+  expressContext: ExpressContext,
+  operation: () => Promise<any>
+) => {
+  gqlTotalQueryCount.inc(1);
+  gqlQueryCount.labels(opName).inc(1);
+  const endTimer = gqlQueryDuration.labels(opName).startTimer();
+
+  try {
+    const [result, syncStatus] = await Promise.all([
+      operation(),
+      indexer.getSyncStatus()
+    ]);
+
+    gqlLogger.info({
+      opName,
+      query: expressContext.req.body.query,
+      variables: expressContext.req.body.variables,
+      latestIndexedBlockNumber: syncStatus?.latestIndexedBlockNumber,
+      urlPath: expressContext.req.path,
+      apiKey: expressContext.req.header('x-api-key'),
+      origin: expressContext.req.headers.origin
+    });
+    return result;
+  } catch (error) {
+    gqlLogger.error({
+      opName,
+      error,
+      query: expressContext.req.body.query,
+      variables: expressContext.req.body.variables,
+      urlPath: expressContext.req.path,
+      apiKey: expressContext.req.header('x-api-key'),
+      origin: expressContext.req.headers.origin
+    });
+  } finally {
+    endTimer();
+  }
+};
+
+export const createResolvers = async (
+  indexerArg: IndexerInterface,
+  eventWatcher: EventWatcher,
+  gqlLogger: winston.Logger
+): Promise<any> => {
   const indexer = indexerArg as Indexer;
 
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
-  const gqlCacheConfig = indexer.serverConfig.gqlCache;
+  const gqlCacheConfig = indexer.serverConfig.gql.cache;
 
   return {
     BigInt: GraphQLBigInt,
@@ -131,2619 +180,3208 @@ export const createResolvers = async (indexerArg: IndexerInterface, eventWatcher
       token: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('token', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('token').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Token, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'token',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Token, id, block, info)
+        );
       },
 
       tokens: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('tokens', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('tokens').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Token,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'tokens',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Token,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       poolFactory: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('poolFactory', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('poolFactory').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(PoolFactory, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'poolFactory',
+          expressContext,
+          async () => indexer.getSubgraphEntity(PoolFactory, id, block, info)
+        );
       },
 
       poolFactories: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('poolFactories', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('poolFactories').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          PoolFactory,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'poolFactories',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            PoolFactory,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       pool: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('pool', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('pool').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Pool, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'pool',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Pool, id, block, info)
+        );
       },
 
       pools: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('pools', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('pools').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Pool,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'pools',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Pool,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       bucket: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucket', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucket').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Bucket, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucket',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Bucket, id, block, info)
+        );
       },
 
       buckets: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('buckets', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('buckets').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Bucket,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'buckets',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Bucket,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       lend: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lend', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lend').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Lend, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lend',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Lend, id, block, info)
+        );
       },
 
       lends: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lends', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lends').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Lend,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lends',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Lend,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       loan: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('loan', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('loan').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Loan, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'loan',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Loan, id, block, info)
+        );
       },
 
       loans: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('loans', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('loans').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Loan,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'loans',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Loan,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       account: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('account', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('account').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Account, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'account',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Account, id, block, info)
+        );
       },
 
       accounts: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('accounts', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('accounts').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Account,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'accounts',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Account,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       liquidationAuction: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('liquidationAuction', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('liquidationAuction').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(LiquidationAuction, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'liquidationAuction',
+          expressContext,
+          async () => indexer.getSubgraphEntity(LiquidationAuction, id, block, info)
+        );
       },
 
       liquidationAuctions: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('liquidationAuctions', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('liquidationAuctions').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          LiquidationAuction,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'liquidationAuctions',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            LiquidationAuction,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       reserveAuction: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('reserveAuction', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('reserveAuction').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ReserveAuction, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'reserveAuction',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ReserveAuction, id, block, info)
+        );
       },
 
       reserveAuctions: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('reserveAuctions', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('reserveAuctions').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ReserveAuction,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'reserveAuctions',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ReserveAuction,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       lptransferorList: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lptransferorList', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lptransferorList').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(LPTransferorList, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lptransferorList',
+          expressContext,
+          async () => indexer.getSubgraphEntity(LPTransferorList, id, block, info)
+        );
       },
 
       lptransferorLists: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lptransferorLists', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lptransferorLists').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          LPTransferorList,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lptransferorLists',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            LPTransferorList,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       lpallowance: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lpallowance', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lpallowance').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(LPAllowance, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lpallowance',
+          expressContext,
+          async () => indexer.getSubgraphEntity(LPAllowance, id, block, info)
+        );
       },
 
       lpallowances: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lpallowances', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lpallowances').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          LPAllowance,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lpallowances',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            LPAllowance,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       lpallowanceList: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lpallowanceList', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lpallowanceList').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(LPAllowanceList, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lpallowanceList',
+          expressContext,
+          async () => indexer.getSubgraphEntity(LPAllowanceList, id, block, info)
+        );
       },
 
       lpallowanceLists: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('lpallowanceLists', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('lpallowanceLists').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          LPAllowanceList,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'lpallowanceLists',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            LPAllowanceList,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       addCollateral: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('addCollateral', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('addCollateral').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(AddCollateral, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'addCollateral',
+          expressContext,
+          async () => indexer.getSubgraphEntity(AddCollateral, id, block, info)
+        );
       },
 
       addCollaterals: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('addCollaterals', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('addCollaterals').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          AddCollateral,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'addCollaterals',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            AddCollateral,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       addQuoteToken: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('addQuoteToken', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('addQuoteToken').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(AddQuoteToken, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'addQuoteToken',
+          expressContext,
+          async () => indexer.getSubgraphEntity(AddQuoteToken, id, block, info)
+        );
       },
 
       addQuoteTokens: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('addQuoteTokens', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('addQuoteTokens').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          AddQuoteToken,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'addQuoteTokens',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            AddQuoteToken,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       auctionSettle: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('auctionSettle', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('auctionSettle').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(AuctionSettle, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'auctionSettle',
+          expressContext,
+          async () => indexer.getSubgraphEntity(AuctionSettle, id, block, info)
+        );
       },
 
       auctionSettles: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('auctionSettles', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('auctionSettles').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          AuctionSettle,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'auctionSettles',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            AuctionSettle,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       bondWithdrawn: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bondWithdrawn', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bondWithdrawn').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(BondWithdrawn, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bondWithdrawn',
+          expressContext,
+          async () => indexer.getSubgraphEntity(BondWithdrawn, id, block, info)
+        );
       },
 
       bondWithdrawns: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bondWithdrawns', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bondWithdrawns').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          BondWithdrawn,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bondWithdrawns',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            BondWithdrawn,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       bucketBankruptcy: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucketBankruptcy', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucketBankruptcy').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(BucketBankruptcy, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucketBankruptcy',
+          expressContext,
+          async () => indexer.getSubgraphEntity(BucketBankruptcy, id, block, info)
+        );
       },
 
       bucketBankruptcies: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucketBankruptcies', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucketBankruptcies').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          BucketBankruptcy,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucketBankruptcies',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            BucketBankruptcy,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       bucketTake: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucketTake', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucketTake').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(BucketTake, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucketTake',
+          expressContext,
+          async () => indexer.getSubgraphEntity(BucketTake, id, block, info)
+        );
       },
 
       bucketTakes: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucketTakes', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucketTakes').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          BucketTake,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucketTakes',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            BucketTake,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       bucketTakeLPAwarded: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucketTakeLPAwarded', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucketTakeLPAwarded').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(BucketTakeLPAwarded, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucketTakeLPAwarded',
+          expressContext,
+          async () => indexer.getSubgraphEntity(BucketTakeLPAwarded, id, block, info)
+        );
       },
 
       bucketTakeLPAwardeds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('bucketTakeLPAwardeds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('bucketTakeLPAwardeds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          BucketTakeLPAwarded,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'bucketTakeLPAwardeds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            BucketTakeLPAwarded,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       drawDebt: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('drawDebt', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('drawDebt').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DrawDebt, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'drawDebt',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DrawDebt, id, block, info)
+        );
       },
 
       drawDebts: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('drawDebts', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('drawDebts').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DrawDebt,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'drawDebts',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DrawDebt,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       flashloan: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('flashloan', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('flashloan').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Flashloan, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'flashloan',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Flashloan, id, block, info)
+        );
       },
 
       flashloans: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('flashloans', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('flashloans').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Flashloan,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'flashloans',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Flashloan,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       kick: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('kick', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('kick').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Kick, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'kick',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Kick, id, block, info)
+        );
       },
 
       kicks: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('kicks', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('kicks').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Kick,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'kicks',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Kick,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       loanStamped: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('loanStamped', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('loanStamped').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(LoanStamped, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'loanStamped',
+          expressContext,
+          async () => indexer.getSubgraphEntity(LoanStamped, id, block, info)
+        );
       },
 
       loanStampeds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('loanStampeds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('loanStampeds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          LoanStamped,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'loanStampeds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            LoanStamped,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       moveQuoteToken: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('moveQuoteToken', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('moveQuoteToken').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(MoveQuoteToken, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'moveQuoteToken',
+          expressContext,
+          async () => indexer.getSubgraphEntity(MoveQuoteToken, id, block, info)
+        );
       },
 
       moveQuoteTokens: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('moveQuoteTokens', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('moveQuoteTokens').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          MoveQuoteToken,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'moveQuoteTokens',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            MoveQuoteToken,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       removeCollateral: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('removeCollateral', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('removeCollateral').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(RemoveCollateral, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'removeCollateral',
+          expressContext,
+          async () => indexer.getSubgraphEntity(RemoveCollateral, id, block, info)
+        );
       },
 
       removeCollaterals: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('removeCollaterals', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('removeCollaterals').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          RemoveCollateral,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'removeCollaterals',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            RemoveCollateral,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       removeQuoteToken: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('removeQuoteToken', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('removeQuoteToken').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(RemoveQuoteToken, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'removeQuoteToken',
+          expressContext,
+          async () => indexer.getSubgraphEntity(RemoveQuoteToken, id, block, info)
+        );
       },
 
       removeQuoteTokens: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('removeQuoteTokens', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('removeQuoteTokens').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          RemoveQuoteToken,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'removeQuoteTokens',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            RemoveQuoteToken,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       repayDebt: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('repayDebt', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('repayDebt').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(RepayDebt, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'repayDebt',
+          expressContext,
+          async () => indexer.getSubgraphEntity(RepayDebt, id, block, info)
+        );
       },
 
       repayDebts: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('repayDebts', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('repayDebts').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          RepayDebt,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'repayDebts',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            RepayDebt,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       reserveAuctionKick: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('reserveAuctionKick', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('reserveAuctionKick').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ReserveAuctionKick, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'reserveAuctionKick',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ReserveAuctionKick, id, block, info)
+        );
       },
 
       reserveAuctionKicks: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('reserveAuctionKicks', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('reserveAuctionKicks').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ReserveAuctionKick,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'reserveAuctionKicks',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ReserveAuctionKick,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       reserveAuctionTake: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('reserveAuctionTake', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('reserveAuctionTake').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ReserveAuctionTake, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'reserveAuctionTake',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ReserveAuctionTake, id, block, info)
+        );
       },
 
       reserveAuctionTakes: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('reserveAuctionTakes', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('reserveAuctionTakes').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ReserveAuctionTake,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'reserveAuctionTakes',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ReserveAuctionTake,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       resetInterestRate: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('resetInterestRate', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('resetInterestRate').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ResetInterestRate, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'resetInterestRate',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ResetInterestRate, id, block, info)
+        );
       },
 
       resetInterestRates: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('resetInterestRates', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('resetInterestRates').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ResetInterestRate,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'resetInterestRates',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ResetInterestRate,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       settle: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('settle', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('settle').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Settle, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'settle',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Settle, id, block, info)
+        );
       },
 
       settles: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('settles', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('settles').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Settle,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'settles',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Settle,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       take: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('take', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('take').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Take, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'take',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Take, id, block, info)
+        );
       },
 
       takes: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('takes', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('takes').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Take,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'takes',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Take,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       transferLP: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('transferLP', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('transferLP').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(TransferLP, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'transferLP',
+          expressContext,
+          async () => indexer.getSubgraphEntity(TransferLP, id, block, info)
+        );
       },
 
       transferLPS: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('transferLPS', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('transferLPS').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          TransferLP,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'transferLPS',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            TransferLP,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       updateInterestRate: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('updateInterestRate', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('updateInterestRate').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(UpdateInterestRate, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'updateInterestRate',
+          expressContext,
+          async () => indexer.getSubgraphEntity(UpdateInterestRate, id, block, info)
+        );
       },
 
       updateInterestRates: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('updateInterestRates', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('updateInterestRates').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          UpdateInterestRate,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'updateInterestRates',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            UpdateInterestRate,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       approval: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('approval', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('approval').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Approval, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'approval',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Approval, id, block, info)
+        );
       },
 
       approvals: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('approvals', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('approvals').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Approval,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'approvals',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Approval,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       approvalForAll: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('approvalForAll', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('approvalForAll').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ApprovalForAll, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'approvalForAll',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ApprovalForAll, id, block, info)
+        );
       },
 
       approvalForAlls: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('approvalForAlls', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('approvalForAlls').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ApprovalForAll,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'approvalForAlls',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ApprovalForAll,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       moveLiquidity: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('moveLiquidity', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('moveLiquidity').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(MoveLiquidity, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'moveLiquidity',
+          expressContext,
+          async () => indexer.getSubgraphEntity(MoveLiquidity, id, block, info)
+        );
       },
 
       moveLiquidities: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('moveLiquidities', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('moveLiquidities').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          MoveLiquidity,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'moveLiquidities',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            MoveLiquidity,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       transfer: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('transfer', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('transfer').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Transfer, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'transfer',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Transfer, id, block, info)
+        );
       },
 
       transfers: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('transfers', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('transfers').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Transfer,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'transfers',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Transfer,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       poolCreated: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('poolCreated', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('poolCreated').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(PoolCreated, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'poolCreated',
+          expressContext,
+          async () => indexer.getSubgraphEntity(PoolCreated, id, block, info)
+        );
       },
 
       poolCreateds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('poolCreateds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('poolCreateds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          PoolCreated,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'poolCreateds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            PoolCreated,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       addCollateralNFT: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('addCollateralNFT', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('addCollateralNFT').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(AddCollateralNFT, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'addCollateralNFT',
+          expressContext,
+          async () => indexer.getSubgraphEntity(AddCollateralNFT, id, block, info)
+        );
       },
 
       addCollateralNFTS: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('addCollateralNFTS', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('addCollateralNFTS').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          AddCollateralNFT,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'addCollateralNFTS',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            AddCollateralNFT,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       auctionNFTSettle: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('auctionNFTSettle', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('auctionNFTSettle').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(AuctionNFTSettle, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'auctionNFTSettle',
+          expressContext,
+          async () => indexer.getSubgraphEntity(AuctionNFTSettle, id, block, info)
+        );
       },
 
       auctionNFTSettles: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('auctionNFTSettles', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('auctionNFTSettles').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          AuctionNFTSettle,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'auctionNFTSettles',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            AuctionNFTSettle,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       drawDebtNFT: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('drawDebtNFT', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('drawDebtNFT').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DrawDebtNFT, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'drawDebtNFT',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DrawDebtNFT, id, block, info)
+        );
       },
 
       drawDebtNFTS: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('drawDebtNFTS', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('drawDebtNFTS').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DrawDebtNFT,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'drawDebtNFTS',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DrawDebtNFT,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       mergeOrRemoveCollateralNFT: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('mergeOrRemoveCollateralNFT', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('mergeOrRemoveCollateralNFT').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(MergeOrRemoveCollateralNFT, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'mergeOrRemoveCollateralNFT',
+          expressContext,
+          async () => indexer.getSubgraphEntity(MergeOrRemoveCollateralNFT, id, block, info)
+        );
       },
 
       mergeOrRemoveCollateralNFTS: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('mergeOrRemoveCollateralNFTS', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('mergeOrRemoveCollateralNFTS').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          MergeOrRemoveCollateralNFT,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'mergeOrRemoveCollateralNFTS',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            MergeOrRemoveCollateralNFT,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       position: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('position', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('position').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Position, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'position',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Position, id, block, info)
+        );
       },
 
       positions: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('positions', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('positions').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Position,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'positions',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Position,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       positionLend: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('positionLend', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('positionLend').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(PositionLend, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'positionLend',
+          expressContext,
+          async () => indexer.getSubgraphEntity(PositionLend, id, block, info)
+        );
       },
 
       positionLends: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('positionLends', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('positionLends').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          PositionLend,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'positionLends',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            PositionLend,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       burn: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('burn', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('burn').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Burn, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'burn',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Burn, id, block, info)
+        );
       },
 
       burns: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('burns', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('burns').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Burn,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'burns',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Burn,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       memorializePosition: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('memorializePosition', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('memorializePosition').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(MemorializePosition, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'memorializePosition',
+          expressContext,
+          async () => indexer.getSubgraphEntity(MemorializePosition, id, block, info)
+        );
       },
 
       memorializePositions: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('memorializePositions', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('memorializePositions').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          MemorializePosition,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'memorializePositions',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            MemorializePosition,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       mint: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('mint', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('mint').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Mint, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'mint',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Mint, id, block, info)
+        );
       },
 
       mints: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('mints', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('mints').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Mint,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'mints',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Mint,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       redeemPosition: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('redeemPosition', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('redeemPosition').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(RedeemPosition, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'redeemPosition',
+          expressContext,
+          async () => indexer.getSubgraphEntity(RedeemPosition, id, block, info)
+        );
       },
 
       redeemPositions: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('redeemPositions', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('redeemPositions').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          RedeemPosition,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'redeemPositions',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            RedeemPosition,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       grantFund: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('grantFund', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('grantFund').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(GrantFund, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'grantFund',
+          expressContext,
+          async () => indexer.getSubgraphEntity(GrantFund, id, block, info)
+        );
       },
 
       grantFunds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('grantFunds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('grantFunds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          GrantFund,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'grantFunds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            GrantFund,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       distributionPeriod: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('distributionPeriod', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('distributionPeriod').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DistributionPeriod, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'distributionPeriod',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DistributionPeriod, id, block, info)
+        );
       },
 
       distributionPeriods: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('distributionPeriods', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('distributionPeriods').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DistributionPeriod,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'distributionPeriods',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DistributionPeriod,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       proposal: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposal', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposal').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(Proposal, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposal',
+          expressContext,
+          async () => indexer.getSubgraphEntity(Proposal, id, block, info)
+        );
       },
 
       proposals: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposals', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposals').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          Proposal,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposals',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            Proposal,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       proposalParams: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposalParams', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposalParams').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ProposalParams, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposalParams',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ProposalParams, id, block, info)
+        );
       },
 
       proposalParamss: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposalParamss', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposalParamss').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ProposalParams,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposalParamss',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ProposalParams,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       distributionPeriodVote: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('distributionPeriodVote', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('distributionPeriodVote').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DistributionPeriodVote, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'distributionPeriodVote',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DistributionPeriodVote, id, block, info)
+        );
       },
 
       distributionPeriodVotes: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('distributionPeriodVotes', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('distributionPeriodVotes').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DistributionPeriodVote,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'distributionPeriodVotes',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DistributionPeriodVote,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       screeningVote: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('screeningVote', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('screeningVote').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ScreeningVote, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'screeningVote',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ScreeningVote, id, block, info)
+        );
       },
 
       screeningVotes: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('screeningVotes', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('screeningVotes').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ScreeningVote,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'screeningVotes',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ScreeningVote,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       fundingVote: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundingVote', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundingVote').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(FundingVote, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundingVote',
+          expressContext,
+          async () => indexer.getSubgraphEntity(FundingVote, id, block, info)
+        );
       },
 
       fundingVotes: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundingVotes', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundingVotes').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          FundingVote,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundingVotes',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            FundingVote,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       fundedSlate: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundedSlate', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundedSlate').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(FundedSlate, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundedSlate',
+          expressContext,
+          async () => indexer.getSubgraphEntity(FundedSlate, id, block, info)
+        );
       },
 
       fundedSlates: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundedSlates', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundedSlates').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          FundedSlate,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundedSlates',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            FundedSlate,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       delegateRewardClaimed: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('delegateRewardClaimed', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('delegateRewardClaimed').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DelegateRewardClaimed, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'delegateRewardClaimed',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DelegateRewardClaimed, id, block, info)
+        );
       },
 
       delegateRewardClaimeds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('delegateRewardClaimeds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('delegateRewardClaimeds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DelegateRewardClaimed,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'delegateRewardClaimeds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DelegateRewardClaimed,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       fundTreasury: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundTreasury', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundTreasury').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(FundTreasury, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundTreasury',
+          expressContext,
+          async () => indexer.getSubgraphEntity(FundTreasury, id, block, info)
+        );
       },
 
       fundTreasuries: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundTreasuries', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundTreasuries').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          FundTreasury,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundTreasuries',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            FundTreasury,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       fundedSlateUpdated: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundedSlateUpdated', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundedSlateUpdated').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(FundedSlateUpdated, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundedSlateUpdated',
+          expressContext,
+          async () => indexer.getSubgraphEntity(FundedSlateUpdated, id, block, info)
+        );
       },
 
       fundedSlateUpdateds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('fundedSlateUpdateds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('fundedSlateUpdateds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          FundedSlateUpdated,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'fundedSlateUpdateds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            FundedSlateUpdated,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       proposalCreated: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposalCreated', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposalCreated').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ProposalCreated, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposalCreated',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ProposalCreated, id, block, info)
+        );
       },
 
       proposalCreateds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposalCreateds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposalCreateds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ProposalCreated,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposalCreateds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ProposalCreated,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       proposalExecuted: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposalExecuted', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposalExecuted').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(ProposalExecuted, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposalExecuted',
+          expressContext,
+          async () => indexer.getSubgraphEntity(ProposalExecuted, id, block, info)
+        );
       },
 
       proposalExecuteds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('proposalExecuteds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('proposalExecuteds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          ProposalExecuted,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'proposalExecuteds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            ProposalExecuted,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       distributionPeriodStarted: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('distributionPeriodStarted', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('distributionPeriodStarted').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DistributionPeriodStarted, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'distributionPeriodStarted',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DistributionPeriodStarted, id, block, info)
+        );
       },
 
       distributionPeriodStarteds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('distributionPeriodStarteds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('distributionPeriodStarteds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DistributionPeriodStarted,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'distributionPeriodStarteds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DistributionPeriodStarted,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       voteCast: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('voteCast', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('voteCast').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(VoteCast, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'voteCast',
+          expressContext,
+          async () => indexer.getSubgraphEntity(VoteCast, id, block, info)
+        );
       },
 
       voteCasts: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('voteCasts', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('voteCasts').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          VoteCast,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'voteCasts',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            VoteCast,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       delegateChanged: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('delegateChanged', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('delegateChanged').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DelegateChanged, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'delegateChanged',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DelegateChanged, id, block, info)
+        );
       },
 
       delegateChangeds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('delegateChangeds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('delegateChangeds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DelegateChanged,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'delegateChangeds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DelegateChanged,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       delegateVotesChanged: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('delegateVotesChanged', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('delegateVotesChanged').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(DelegateVotesChanged, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'delegateVotesChanged',
+          expressContext,
+          async () => indexer.getSubgraphEntity(DelegateVotesChanged, id, block, info)
+        );
       },
 
       delegateVotesChangeds: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('delegateVotesChangeds', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('delegateVotesChangeds').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          DelegateVotesChanged,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'delegateVotesChangeds',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            DelegateVotesChanged,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
       burnWrap: async (
         _: any,
         { id, block = {} }: { id: string, block: BlockHeight },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('burnWrap', id, JSON.stringify(block, jsonBigIntStringReplacer));
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('burnWrap').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntity(BurnWrap, id, block, info);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'burnWrap',
+          expressContext,
+          async () => indexer.getSubgraphEntity(BurnWrap, id, block, info)
+        );
       },
 
       burnWraps: async (
         _: any,
         { block = {}, where, first, skip, orderBy, orderDirection }: { block: BlockHeight, where: { [key: string]: any }, first: number, skip: number, orderBy: string, orderDirection: OrderDirection },
-        __: any,
+        expressContext: ExpressContext,
         info: GraphQLResolveInfo
       ) => {
         log('burnWraps', JSON.stringify(block, jsonBigIntStringReplacer), JSON.stringify(where, jsonBigIntStringReplacer), first, skip, orderBy, orderDirection);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('burnWraps').inc(1);
 
         // Set cache-control hints
         // setGQLCacheHints(info, block, gqlCacheConfig);
 
-        return indexer.getSubgraphEntities(
-          BurnWrap,
-          block,
-          where,
-          { limit: first, skip, orderBy, orderDirection },
-          info
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'burnWraps',
+          expressContext,
+          async () => indexer.getSubgraphEntities(
+            BurnWrap,
+            block,
+            where,
+            { limit: first, skip, orderBy, orderDirection },
+            info
+          )
         );
       },
 
-      events: async (_: any, { blockHash, contractAddress, name }: { blockHash: string, contractAddress: string, name?: string }) => {
+      events: async (
+        _: any,
+        { blockHash, contractAddress, name }: { blockHash: string, contractAddress: string, name?: string },
+        expressContext: ExpressContext
+      ) => {
         log('events', blockHash, contractAddress, name);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('events').inc(1);
 
-        const block = await indexer.getBlockProgress(blockHash);
-        if (!block || !block.isComplete) {
-          throw new Error(`Block hash ${blockHash} number ${block?.blockNumber} not processed yet`);
-        }
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'events',
+          expressContext,
+          async () => {
+            const block = await indexer.getBlockProgress(blockHash);
+            if (!block || !block.isComplete) {
+              throw new Error(`Block hash ${blockHash} number ${block?.blockNumber} not processed yet`);
+            }
 
-        const events = await indexer.getEventsByFilter(blockHash, contractAddress, name);
-        return events.map(event => indexer.getResultEvent(event));
+            const events = await indexer.getEventsByFilter(blockHash, contractAddress, name);
+            return events.map(event => indexer.getResultEvent(event));
+          }
+        );
       },
 
-      eventsInRange: async (_: any, { fromBlockNumber, toBlockNumber }: { fromBlockNumber: number, toBlockNumber: number }) => {
+      eventsInRange: async (
+        _: any,
+        { fromBlockNumber, toBlockNumber }: { fromBlockNumber: number, toBlockNumber: number },
+        expressContext: ExpressContext
+      ) => {
         log('eventsInRange', fromBlockNumber, toBlockNumber);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('eventsInRange').inc(1);
 
-        const syncStatus = await indexer.getSyncStatus();
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'eventsInRange',
+          expressContext,
+          async () => {
+            const syncStatus = await indexer.getSyncStatus();
 
-        if (!syncStatus) {
-          throw new Error('No blocks processed yet');
-        }
+            if (!syncStatus) {
+              throw new Error('No blocks processed yet');
+            }
 
-        if ((fromBlockNumber < syncStatus.initialIndexedBlockNumber) || (toBlockNumber > syncStatus.latestProcessedBlockNumber)) {
-          throw new Error(`Block range should be between ${syncStatus.initialIndexedBlockNumber} and ${syncStatus.latestProcessedBlockNumber}`);
-        }
+            if ((fromBlockNumber < syncStatus.initialIndexedBlockNumber) || (toBlockNumber > syncStatus.latestProcessedBlockNumber)) {
+              throw new Error(`Block range should be between ${syncStatus.initialIndexedBlockNumber} and ${syncStatus.latestProcessedBlockNumber}`);
+            }
 
-        const events = await indexer.getEventsInRange(fromBlockNumber, toBlockNumber);
-        return events.map(event => indexer.getResultEvent(event));
+            const events = await indexer.getEventsInRange(fromBlockNumber, toBlockNumber);
+            return events.map(event => indexer.getResultEvent(event));
+          }
+        );
       },
 
-      getStateByCID: async (_: any, { cid }: { cid: string }) => {
+      getStateByCID: async (
+        _: any,
+        { cid }: { cid: string },
+        expressContext: ExpressContext
+      ) => {
         log('getStateByCID', cid);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('getStateByCID').inc(1);
 
-        const state = await indexer.getStateByCID(cid);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'getStateByCID',
+          expressContext,
+          async () => {
+            const state = await indexer.getStateByCID(cid);
 
-        return state && state.block.isComplete ? getResultState(state) : undefined;
+            return state && state.block.isComplete ? getResultState(state) : undefined;
+          }
+        );
       },
 
-      getState: async (_: any, { blockHash, contractAddress, kind }: { blockHash: string, contractAddress: string, kind: string }) => {
+      getState: async (
+        _: any,
+        { blockHash, contractAddress, kind }: { blockHash: string, contractAddress: string, kind: string },
+        expressContext: ExpressContext
+      ) => {
         log('getState', blockHash, contractAddress, kind);
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('getState').inc(1);
 
-        const state = await indexer.getPrevState(blockHash, contractAddress, kind);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'getState',
+          expressContext,
+          async () => {
+            const state = await indexer.getPrevState(blockHash, contractAddress, kind);
 
-        return state && state.block.isComplete ? getResultState(state) : undefined;
+            return state && state.block.isComplete ? getResultState(state) : undefined;
+          }
+        );
       },
 
       _meta: async (
         _: any,
-        { block = {} }: { block: BlockHeight }
+        { block = {} }: { block: BlockHeight },
+        expressContext: ExpressContext
       ) => {
         log('_meta');
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('_meta').inc(1);
 
-        return indexer.getMetaData(block);
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          '_meta',
+          expressContext,
+          async () => indexer.getMetaData(block)
+        );
       },
 
-      getSyncStatus: async () => {
+      getSyncStatus: async (
+        _: any,
+        __: Record<string, never>,
+        expressContext: ExpressContext
+      ) => {
         log('getSyncStatus');
-        gqlTotalQueryCount.inc(1);
-        gqlQueryCount.labels('getSyncStatus').inc(1);
 
-        return indexer.getSyncStatus();
+        return executeAndRecordMetrics(
+          indexer,
+          gqlLogger,
+          'getSyncStatus',
+          expressContext,
+          async () => indexer.getSyncStatus()
+        );
       }
     }
   };
-- 
2.45.2


From cda5114ad465e09842cebc8b55ffc792c682643a Mon Sep 17 00:00:00 2001
From: Prathamesh Musale <prathamesh.musale0@gmail.com>
Date: Thu, 6 Jun 2024 19:16:31 +0530
Subject: [PATCH 2/3] Update watcher version and repo URL

---
 package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index cdcb94e..15c2407 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@cerc-io/ajna-watcher-ts",
-  "version": "0.1.11",
+  "version": "0.1.12",
   "description": "ajna-watcher-ts",
   "private": true,
   "main": "dist/index.js",
@@ -29,7 +29,7 @@
   },
   "repository": {
     "type": "git",
-    "url": "git+https://github.com/cerc-io/watcher-ts.git"
+    "url": "https://git.vdb.to/cerc-io/ajna-watcher-ts"
   },
   "author": "",
   "license": "AGPL-3.0",
-- 
2.45.2


From dec1d9b0dbe9066662885822b4d9f8171989642c Mon Sep 17 00:00:00 2001
From: Prathamesh Musale <prathamesh.musale0@gmail.com>
Date: Thu, 6 Jun 2024 19:17:36 +0530
Subject: [PATCH 3/3] Update yarn lock file

---
 yarn.lock | 249 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 200 insertions(+), 49 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index 999bbc5..81ef1f5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -199,10 +199,10 @@
     binaryen "101.0.0-nightly.20210723"
     long "^4.0.0"
 
-"@cerc-io/cache@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fcache/-/0.2.93/cache-0.2.93.tgz#3032714167cac33957aeba16a8066c58437d7002"
-  integrity sha512-iH18oDRP40sTZkCCWvxZxvrankIJNjI3smXS4WOng1p4fUmt3N+uINCzGmNdZPpfj4ZFdoNgrFGkqeYyUiNCpA==
+"@cerc-io/cache@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fcache/-/0.2.94/cache-0.2.94.tgz#e1557bfc3c85ebe3b83f24c79b55c7324797e7ed"
+  integrity sha512-9NBMd+19aBs3lgiie0X6TJizcn7yBCfEXXlbvMvac9SgYDPcloU+ghauQephAxayRjaWkrgjjfEWR/I0x6FwqA==
   dependencies:
     canonical-json "^0.0.4"
     debug "^4.3.1"
@@ -210,19 +210,19 @@
     fs-extra "^10.0.0"
     level "^7.0.0"
 
-"@cerc-io/cli@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fcli/-/0.2.93/cli-0.2.93.tgz#ee2b22a40f358ecb5ef44301d0ab5120e75bd803"
-  integrity sha512-QTEerZn4UdYaGNGXv8UZD+T1+MnYp6l2N/dWkCJBw+8df/46ec5dVuLH1kvCk6LwBUOIKrgIsosDhTPQjDS6bA==
+"@cerc-io/cli@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fcli/-/0.2.94/cli-0.2.94.tgz#f193165a4b85174c48150051ea4b0e3df57fdf9e"
+  integrity sha512-aJGzH630bhYca74efVEU37sCjxRLmERDObzNpKIjbmYjKPg6urMbYI8gs33R2HIS/FUOMS39F5B9NMwgCQd/Vw==
   dependencies:
     "@apollo/client" "^3.7.1"
-    "@cerc-io/cache" "^0.2.93"
-    "@cerc-io/ipld-eth-client" "^0.2.93"
+    "@cerc-io/cache" "^0.2.94"
+    "@cerc-io/ipld-eth-client" "^0.2.94"
     "@cerc-io/libp2p" "^0.42.2-laconic-0.1.4"
     "@cerc-io/nitro-node" "^0.1.15"
-    "@cerc-io/peer" "^0.2.93"
-    "@cerc-io/rpc-eth-client" "^0.2.93"
-    "@cerc-io/util" "^0.2.93"
+    "@cerc-io/peer" "^0.2.94"
+    "@cerc-io/rpc-eth-client" "^0.2.94"
+    "@cerc-io/util" "^0.2.94"
     "@ethersproject/providers" "^5.4.4"
     "@graphql-tools/utils" "^9.1.1"
     "@ipld/dag-cbor" "^8.0.0"
@@ -243,16 +243,16 @@
     typeorm "0.2.37"
     yargs "^17.0.1"
 
-"@cerc-io/graph-node@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fgraph-node/-/0.2.93/graph-node-0.2.93.tgz#a310c6af84bae6f28216e4cdd439396a4e7fb555"
-  integrity sha512-EbEziMAMuOBel+f4dxJ24AOaQPV41w/1sA5d/0v3KKvOLcrtgs0EysbeJYtUY7ru3fmCcMcP1Y+4k+dsp07nAQ==
+"@cerc-io/graph-node@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fgraph-node/-/0.2.94/graph-node-0.2.94.tgz#e8d346daa9e7733098d039d27e7d575e0f978b20"
+  integrity sha512-bGqv/5dq2saBcekA/YqDcepvRaZVIMPXt/lDEcP+8lXmavImXO1sdnut7JyMDQCy3DNKXT6IGADPM/olUwnDPQ==
   dependencies:
     "@apollo/client" "^3.3.19"
     "@cerc-io/assemblyscript" "0.19.10-watcher-ts-0.1.2"
-    "@cerc-io/cache" "^0.2.93"
-    "@cerc-io/ipld-eth-client" "^0.2.93"
-    "@cerc-io/util" "^0.2.93"
+    "@cerc-io/cache" "^0.2.94"
+    "@cerc-io/ipld-eth-client" "^0.2.94"
+    "@cerc-io/util" "^0.2.94"
     "@types/json-diff" "^0.5.2"
     "@types/yargs" "^17.0.0"
     bn.js "^4.11.9"
@@ -269,14 +269,14 @@
     typeorm-naming-strategies "^2.0.0"
     yargs "^17.0.1"
 
-"@cerc-io/ipld-eth-client@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fipld-eth-client/-/0.2.93/ipld-eth-client-0.2.93.tgz#8a8a25fd6a8d9964de9211545e45ecc6d692e124"
-  integrity sha512-XT9axNOg0mr/mHWrUiadLSqx4EW/8/9flCsTBNiuZjZSv5d8BtCtsPaI5AGBYbsIiA9ffhW36pYknJU0QlHi2g==
+"@cerc-io/ipld-eth-client@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fipld-eth-client/-/0.2.94/ipld-eth-client-0.2.94.tgz#22f79eaf82da60a25d8f89f23cf45581c012d6ff"
+  integrity sha512-IOOZrryZ3M7ndhk8N9NeRaXvzC8eU2OS0z7fVL0xZ/h3Ei4D+dz8fVJbCvgGRB6mJadrMXYyhahOtEAJYxjNHg==
   dependencies:
     "@apollo/client" "^3.7.1"
-    "@cerc-io/cache" "^0.2.93"
-    "@cerc-io/util" "^0.2.93"
+    "@cerc-io/cache" "^0.2.94"
+    "@cerc-io/util" "^0.2.94"
     cross-fetch "^3.1.4"
     debug "^4.3.1"
     ethers "^5.4.4"
@@ -429,10 +429,10 @@
     unique-names-generator "^4.7.1"
     yargs "^17.0.1"
 
-"@cerc-io/peer@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fpeer/-/0.2.93/peer-0.2.93.tgz#4290d8e279f4e36d6e6673f493395a78230b5567"
-  integrity sha512-LA2x973cp4QtuBhILgX/2HYH5hQFB4su7w/gTQEzgKsnm8Zwv+dKriciJP0vxycMlZFRIDsSheYJkRPBz2vVEQ==
+"@cerc-io/peer@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fpeer/-/0.2.94/peer-0.2.94.tgz#c8776a9968b32d96fb91ed2a2c6d4b62b365e4a0"
+  integrity sha512-QQANziPnT08guAD/Nwy/HoqgIIX+w1+GS2bOUE4hfS+LJmTiZ+Zquiqcj69qGQeMQxfiUHmsBPttioF+B9rp/A==
   dependencies:
     "@cerc-io/libp2p" "^0.42.2-laconic-0.1.4"
     "@cerc-io/prometheus-metrics" "1.1.4"
@@ -471,23 +471,23 @@
     it-stream-types "^1.0.4"
     promjs "^0.4.2"
 
-"@cerc-io/rpc-eth-client@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Frpc-eth-client/-/0.2.93/rpc-eth-client-0.2.93.tgz#71a695926ce1e256beb6c5b81cc4bc45d44bcd56"
-  integrity sha512-ZMFhUk7Y5itW5B1Y1zOszdH+0LsYSwFWsmHc7Xf55jSVBMFsZYkyBJrrrcBPKdBRy/f0xfs3GsIAuCbTbG+9+g==
+"@cerc-io/rpc-eth-client@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Frpc-eth-client/-/0.2.94/rpc-eth-client-0.2.94.tgz#0c4f679abacf0aed831cbd295d21780f2a3dd17a"
+  integrity sha512-S3UvHO7Qb4Z43+fArMbrs78CP8l81D5Ootd225MQ2//TGmu9QsIK9+oqdI1CIVAQCbxI7QAStzdz76Y0px2iFA==
   dependencies:
-    "@cerc-io/cache" "^0.2.93"
-    "@cerc-io/ipld-eth-client" "^0.2.93"
-    "@cerc-io/util" "^0.2.93"
+    "@cerc-io/cache" "^0.2.94"
+    "@cerc-io/ipld-eth-client" "^0.2.94"
+    "@cerc-io/util" "^0.2.94"
     chai "^4.3.4"
     ethers "^5.4.4"
     left-pad "^1.3.0"
     mocha "^8.4.0"
 
-"@cerc-io/solidity-mapper@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fsolidity-mapper/-/0.2.93/solidity-mapper-0.2.93.tgz#ade5e2490a28255a834b9b91c6f11e8d3c4cba87"
-  integrity sha512-XVYTPHr059+LsTt+2bkQ8XD97F5gnHc9A9JhXbhT8rvDg5o0iFNKHmWzIRMUA8lys4r4BReMlT4ZOA9RpA/aGA==
+"@cerc-io/solidity-mapper@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fsolidity-mapper/-/0.2.94/solidity-mapper-0.2.94.tgz#a414653bf20fcbedd91d4a544c6a019c8a02d958"
+  integrity sha512-kO2xqyAeq2+bbxBcItsT6i8qK1F0BhaYPzV1tTNXgGbkp3j1do86mc6IeTEeV6J/8e9EaeRBsOSQOdGOHUjcDA==
   dependencies:
     dotenv "^10.0.0"
 
@@ -496,15 +496,15 @@
   resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fts-channel/-/1.0.3-ts-nitro-0.1.1/ts-channel-1.0.3-ts-nitro-0.1.1.tgz#0768781313a167295c0bf21307f47e02dc17e936"
   integrity sha512-2jFICUSyffuZ+8+qRhXuLSJq4GJ6Y02wxiXoubH0Kzv2lIKkJtWICY1ZQQhtXAvP0ncAQB85WJHqtqwH8l7J3Q==
 
-"@cerc-io/util@^0.2.93":
-  version "0.2.93"
-  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Futil/-/0.2.93/util-0.2.93.tgz#8fcca36b2f539dbfb75e54240542e29f40e87ed6"
-  integrity sha512-nvlzXfNrtPtovEOigDHEb43Q3ZzY0ZEAyjjrctLvVMSM6clPneaDJI7jdzLuUsPlKJmSphRmoGGf4up+CMcGZg==
+"@cerc-io/util@^0.2.94":
+  version "0.2.94"
+  resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Futil/-/0.2.94/util-0.2.94.tgz#5d4c8046cf44641eac39a6f6ee11f2eb8b298c1f"
+  integrity sha512-4B1RkUKZoRMVVxWK5u+5d3GEmn0IN1FoAbkfCsBXMTH+OGI+VVGg6bRozaluy7pegpwDh1KtiH0A7NFjUup4OQ==
   dependencies:
     "@apollo/utils.keyvaluecache" "^1.0.1"
     "@cerc-io/nitro-node" "^0.1.15"
-    "@cerc-io/peer" "^0.2.93"
-    "@cerc-io/solidity-mapper" "^0.2.93"
+    "@cerc-io/peer" "^0.2.94"
+    "@cerc-io/solidity-mapper" "^0.2.94"
     "@cerc-io/ts-channel" "1.0.3-ts-nitro-0.1.1"
     "@ethersproject/properties" "^5.7.0"
     "@ethersproject/providers" "^5.4.4"
@@ -546,6 +546,7 @@
     toml "^3.0.0"
     typeorm "0.2.37"
     typeorm-naming-strategies "^2.0.0"
+    winston "^3.13.0"
     ws "^8.11.0"
     yargs "^17.0.1"
 
@@ -631,6 +632,11 @@
   dependencies:
     "@chainsafe/is-ip" "^2.0.1"
 
+"@colors/colors@1.6.0", "@colors/colors@^1.6.0":
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0"
+  integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==
+
 "@cspotcode/source-map-support@^0.8.0":
   version "0.8.1"
   resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
@@ -638,6 +644,15 @@
   dependencies:
     "@jridgewell/trace-mapping" "0.3.9"
 
+"@dabh/diagnostics@^2.0.2":
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
+  integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==
+  dependencies:
+    colorspace "1.1.x"
+    enabled "2.0.x"
+    kuler "^2.0.0"
+
 "@eslint-community/eslint-utils@^4.2.0":
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -2267,6 +2282,11 @@
     "@types/mime" "*"
     "@types/node" "*"
 
+"@types/triple-beam@^1.3.2":
+  version "1.3.5"
+  resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
+  integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
+
 "@types/yargs-parser@*":
   version "21.0.3"
   resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
@@ -2796,6 +2816,11 @@ async-retry@^1.2.1:
   dependencies:
     retry "0.13.1"
 
+async@^3.2.3:
+  version "3.2.5"
+  resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66"
+  integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==
+
 asyncify-wasm@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/asyncify-wasm/-/asyncify-wasm-1.2.1.tgz#a15c0480e858619a4f971e44e6fc05c49015d9e8"
@@ -3113,7 +3138,7 @@ cliui@^8.0.1:
     strip-ansi "^6.0.1"
     wrap-ansi "^7.0.0"
 
-color-convert@^1.9.0:
+color-convert@^1.9.0, color-convert@^1.9.3:
   version "1.9.3"
   resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
   integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
@@ -3132,11 +3157,35 @@ color-name@1.1.3:
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
   integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
 
-color-name@~1.1.4:
+color-name@^1.0.0, color-name@~1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
   integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
 
+color-string@^1.6.0:
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
+  integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
+  dependencies:
+    color-name "^1.0.0"
+    simple-swizzle "^0.2.2"
+
+color@^3.1.3:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
+  integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
+  dependencies:
+    color-convert "^1.9.3"
+    color-string "^1.6.0"
+
+colorspace@1.1.x:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243"
+  integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==
+  dependencies:
+    color "^3.1.3"
+    text-hex "1.0.x"
+
 commander@^2.20.3:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@@ -3488,6 +3537,11 @@ emoji-regex@^8.0.0:
   resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
   integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
 
+enabled@2.0.x:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
+  integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
+
 encodeurl@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@@ -3990,6 +4044,11 @@ fastq@^1.6.0:
   dependencies:
     reusify "^1.0.4"
 
+fecha@^4.2.0:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
+  integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
+
 figlet@^1.1.1:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.7.0.tgz#46903a04603fd19c3e380358418bb2703587a72e"
@@ -4049,6 +4108,11 @@ flatted@^3.2.9:
   resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
   integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
 
+fn.name@1.x.x:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
+  integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
+
 follow-redirects@^1.0.0:
   version "1.15.5"
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020"
@@ -4690,6 +4754,11 @@ is-array-buffer@^3.0.4:
     call-bind "^1.0.2"
     get-intrinsic "^1.2.1"
 
+is-arrayish@^0.3.1:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
+  integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
+
 is-bigint@^1.0.1:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
@@ -4844,6 +4913,11 @@ is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3:
   dependencies:
     call-bind "^1.0.7"
 
+is-stream@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
+  integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+
 is-stream@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac"
@@ -5234,6 +5308,11 @@ keyv@^4.5.3:
   dependencies:
     json-buffer "3.0.1"
 
+kuler@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
+  integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
+
 left-pad@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
@@ -5384,6 +5463,18 @@ log-symbols@4.0.0:
   dependencies:
     chalk "^4.0.0"
 
+logform@^2.3.2, logform@^2.4.0:
+  version "2.6.0"
+  resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5"
+  integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==
+  dependencies:
+    "@colors/colors" "1.6.0"
+    "@types/triple-beam" "^1.3.2"
+    fecha "^4.2.0"
+    ms "^2.1.1"
+    safe-stable-stringify "^2.3.1"
+    triple-beam "^1.3.0"
+
 loglevel@^1.6.8:
   version "1.9.1"
   resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.1.tgz#d63976ac9bcd03c7c873116d41c2a85bafff1be7"
@@ -5904,6 +5995,13 @@ once@^1.3.0:
   dependencies:
     wrappy "1"
 
+one-time@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45"
+  integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
+  dependencies:
+    fn.name "1.x.x"
+
 onetime@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4"
@@ -6597,6 +6695,11 @@ safe-regex-test@^1.0.3:
     es-errors "^1.3.0"
     is-regex "^1.1.4"
 
+safe-stable-stringify@^2.3.1:
+  version "2.4.3"
+  resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886"
+  integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==
+
 "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -6739,6 +6842,13 @@ signal-exit@^3.0.7:
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
   integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
 
+simple-swizzle@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
+  integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
+  dependencies:
+    is-arrayish "^0.3.1"
+
 slash@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
@@ -6780,6 +6890,11 @@ sprintf-js@1.1.2:
   resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
   integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
 
+stack-trace@0.0.x:
+  version "0.0.10"
+  resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
+  integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
+
 statuses@2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
@@ -6934,6 +7049,11 @@ tdigest@^0.1.1:
   dependencies:
     bintrees "1.0.2"
 
+text-hex@1.0.x:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
+  integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
+
 text-table@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -6990,6 +7110,11 @@ tr46@~0.0.3:
   resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
   integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
 
+triple-beam@^1.3.0:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984"
+  integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==
+
 truncate-utf8-bytes@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b"
@@ -7400,6 +7525,32 @@ wide-align@1.1.3:
   dependencies:
     string-width "^1.0.2 || 2"
 
+winston-transport@^4.7.0:
+  version "4.7.0"
+  resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.0.tgz#e302e6889e6ccb7f383b926df6936a5b781bd1f0"
+  integrity sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==
+  dependencies:
+    logform "^2.3.2"
+    readable-stream "^3.6.0"
+    triple-beam "^1.3.0"
+
+winston@^3.13.0:
+  version "3.13.0"
+  resolved "https://registry.yarnpkg.com/winston/-/winston-3.13.0.tgz#e76c0d722f78e04838158c61adc1287201de7ce3"
+  integrity sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==
+  dependencies:
+    "@colors/colors" "^1.6.0"
+    "@dabh/diagnostics" "^2.0.2"
+    async "^3.2.3"
+    is-stream "^2.0.0"
+    logform "^2.4.0"
+    one-time "^1.0.0"
+    readable-stream "^3.4.0"
+    safe-stable-stringify "^2.3.1"
+    stack-trace "0.0.x"
+    triple-beam "^1.3.0"
+    winston-transport "^4.7.0"
+
 wordwrap@>=0.0.2:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
-- 
2.45.2