Add query time tracking to IO Events.

This commit is contained in:
Patrick Fic
2021-04-22 10:16:49 -07:00
parent cdf99a16fe
commit 08faff4d8e
11 changed files with 112 additions and 3 deletions

View File

@@ -1,11 +1,18 @@
import { ApolloClient, ApolloLink, InMemoryCache, split } from "@apollo/client"; import {
ApolloClient,
ApolloLink,
InMemoryCache,
operationName,
split,
} from "@apollo/client";
import { setContext } from "@apollo/client/link/context"; import { setContext } from "@apollo/client/link/context";
import { HttpLink } from "@apollo/client/link/http"; //"apollo-link-http"; import { HttpLink } from "@apollo/client/link/http"; //"apollo-link-http";
import { RetryLink } from "@apollo/client/link/retry"; import { RetryLink } from "@apollo/client/link/retry";
import { WebSocketLink } from "@apollo/client/link/ws"; import { WebSocketLink } from "@apollo/client/link/ws";
import { getMainDefinition } from "@apollo/client/utilities";
//import { split } from "apollo-link"; //import { split } from "apollo-link";
import apolloLogger from "apollo-link-logger"; import apolloLogger from "apollo-link-logger";
import { getMainDefinition } from "@apollo/client/utilities"; import axios from "axios";
import { auth } from "../firebase/firebase.utils"; import { auth } from "../firebase/firebase.utils";
import errorLink from "../graphql/apollo-error-handling"; import errorLink from "../graphql/apollo-error-handling";
@@ -31,6 +38,25 @@ const wsLink = new WebSocketLink({
}, },
}); });
const roundTripLink = new ApolloLink((operation, forward) => {
// Called before operation is sent to server
operation.setContext({ start: new Date() });
return forward(operation).map((data) => {
// Called after server responds
const time = new Date() - operation.getContext().start;
console.log(
`Operation ${operation.operationName} took ${time} to complete`
);
TrackExecutionTime(operation.operationName, time);
return data;
});
});
const TrackExecutionTime = async (operationName, time) => {
await axios.post("/ioevent", { operationName, time, dbevent: true });
};
const subscriptionMiddleware = { const subscriptionMiddleware = {
applyMiddleware: async (options, next) => { applyMiddleware: async (options, next) => {
options.authToken = options.authToken =
@@ -96,7 +122,11 @@ if (process.env.NODE_ENV === "development") {
middlewares.push(apolloLogger); middlewares.push(apolloLogger);
} }
middlewares.push(retryLink.concat(errorLink.concat(authLink.concat(link)))); middlewares.push(
roundTripLink.concat(
retryLink.concat(errorLink.concat(authLink.concat(link)))
)
);
const cache = new InMemoryCache({}); const cache = new InMemoryCache({});

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: DROP TABLE "public"."ioevents";
type: run_sql

View File

@@ -0,0 +1,11 @@
- args:
cascade: false
read_only: false
sql: CREATE TABLE "public"."ioevents"("id" bigserial NOT NULL, "created_at" timestamptz
NOT NULL DEFAULT now(), "operationname" text NOT NULL, "time" numeric, PRIMARY
KEY ("id") );
type: run_sql
- args:
name: ioevents
schema: public
type: add_existing_table_or_view

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."ioevents" DROP COLUMN "variables";
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."ioevents" ADD COLUMN "variables" jsonb NULL;
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."ioevents" DROP COLUMN "dbevent";
type: run_sql

View File

@@ -0,0 +1,6 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."ioevents" ADD COLUMN "dbevent" Boolean NOT NULL DEFAULT
false;
type: run_sql

View File

@@ -1814,6 +1814,9 @@ tables:
- active: - active:
_eq: true _eq: true
allow_aggregations: true allow_aggregations: true
- table:
schema: public
name: ioevents
- table: - table:
schema: public schema: public
name: job_conversations name: job_conversations

View File

@@ -136,6 +136,9 @@ app.get("/qbo/callback", qbo.callback);
var data = require("./server/data/data"); var data = require("./server/data/data");
app.get("/data/ah", data.autohouse); app.get("/data/ah", data.autohouse);
var ioevent = require("./server/ioevent/ioevent");
app.post("/ioevent", ioevent.default);
app.get("/", async function (req, res) { app.get("/", async function (req, res) {
res.status(200).send("Access Forbidden."); res.status(200).send("Access Forbidden.");
}); });

View File

@@ -778,3 +778,10 @@ exports.QUERY_JOB_COSTING_DETAILS_MULTI = ` query QUERY_JOB_COSTING_DETAILS_MULT
} }
} }
`; `;
exports.INSERT_IOEVENT = ` mutation INSERT_IOEVENT($event: ioevents_insert_input!) {
insert_ioevents_one(object: $event) {
id
}
}
`;

29
server/ioevent/ioevent.js Normal file
View File

@@ -0,0 +1,29 @@
const client = require("../graphql-client/graphql-client").client;
const queries = require("../graphql-client/queries");
const path = require("path");
require("dotenv").config({
path: path.resolve(
process.cwd(),
`.env.${process.env.NODE_ENV || "development"}`
),
});
exports.default = async (req, res) => {
const { operationName, time, dbevent } = req.body;
try {
await client.request(queries.INSERT_IOEVENT, {
event: {
operationname: operationName,
time,
dbevent,
},
});
res.sendStatus(200);
} catch (error) {
console.log("error", error);
res.status(400).send(error);
}
};