Add initial client version tracking (#2710) bruception

* Add initial client version tracking

* Make headers optional

* Add client version

* Add client version on build

* header fix

Co-authored-by: Miodec <bartnikjack@gmail.com>
This commit is contained in:
Bruce Berrios 2022-03-16 11:53:11 -04:00 committed by GitHub
parent b0a32f37b7
commit 64f06231cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 104 additions and 103 deletions

View file

@ -10,6 +10,7 @@ import leaderboards from "./leaderboards";
import addSwaggerMiddlewares from "./swagger";
import { asyncHandler } from "../../middlewares/api-utils";
import { MonkeyResponse } from "../../utils/monkey-response";
import { recordClientVersion } from "../../utils/prometheus";
import { Application, NextFunction, Response, Router } from "express";
const pathOverride = process.env.API_PATH_OVERRIDE;
@ -46,6 +47,11 @@ function addApiRoutes(app: Application): void {
return;
}
const clientVersion = req.headers["client-version"];
if (clientVersion) {
recordClientVersion(clientVersion.toString());
}
requestsProcessed++;
next();
}

View file

@ -144,3 +144,13 @@ export function incrementResult(
resultDuration.observe(res.testDuration);
}
const clientVersionsCounter = new Counter({
name: "api_client_versions",
help: "Records frequency of client versions",
labelNames: ["version"],
});
export function recordClientVersion(version: string) : void {
clientVersionsCounter.inc({ version });
}

View file

@ -1,19 +1,15 @@
const { task, src, dest, series, watch } = require("gulp");
// const axios = require("axios");
const concat = require("gulp-concat");
const del = require("del");
const vinylPaths = require("vinyl-paths");
const eslint = require("gulp-eslint-new");
const sass = require("gulp-sass")(require("dart-sass"));
const concat = require("gulp-concat");
const { webpack } = require("webpack");
const eslint = require("gulp-eslint-new");
const vinylPaths = require("vinyl-paths");
const sass = require("gulp-sass")(require("dart-sass"));
const { task, src, dest, series, watch } = require("gulp");
const webpackDevConfig = require("./webpack.config.dev.js");
const webpackProdConfig = require("./webpack.config.prod.js");
const ts = require("gulp-typescript");
const JSONValidation = require("./json-validation");
const eslintConfig = "../.eslintrc.json";
const tsProject = ts.createProject("tsconfig.json");
task("clean", function () {
return src(["./public/"], { allowEmpty: true }).pipe(vinylPaths(del));
@ -41,10 +37,6 @@ task("copy-src-contents", function () {
return src("./src/scripts/**").pipe(dest("./dist/"));
});
task("transpile-ts", function () {
return tsProject.src().pipe(tsProject()).js.pipe(dest("dist"));
});
task("webpack", async function () {
return new Promise((resolve, reject) => {
webpack(webpackDevConfig, (err, stats) => {

View file

@ -44,10 +44,10 @@
"gulp-concat": "^2.6.1",
"gulp-eslint-new": "^1.3.0",
"gulp-sass": "^5.0.0",
"gulp-typescript": "^6.0.0-alpha.1",
"html2canvas": "^1.4.1",
"madge": "5.0.1",
"stream-browserify": "^3.0.0",
"string-replace-loader": "3.1.0",
"ts-loader": "9.2.6",
"tsify": "^5.0.4",
"typescript": "^4.5.5",
@ -6643,54 +6643,6 @@
"node": ">=12"
}
},
"node_modules/gulp-typescript": {
"version": "6.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-6.0.0-alpha.1.tgz",
"integrity": "sha512-KoT0TTfjfT7w3JItHkgFH1T/zK4oXWC+a8xxKfniRfVcA0Fa1bKrIhztYelYmb+95RB80OLMBreknYkdwzdi2Q==",
"dev": true,
"dependencies": {
"ansi-colors": "^4.1.1",
"plugin-error": "^1.0.1",
"source-map": "^0.7.3",
"through2": "^3.0.1",
"vinyl": "^2.2.0",
"vinyl-fs": "^3.0.3"
},
"engines": {
"node": ">= 8"
},
"peerDependencies": {
"typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev "
}
},
"node_modules/gulp-typescript/node_modules/ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/gulp-typescript/node_modules/source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"node_modules/gulp-typescript/node_modules/through2": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
"dev": true,
"dependencies": {
"inherits": "^2.0.4",
"readable-stream": "2 || 3"
}
},
"node_modules/gulplog": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
@ -10652,6 +10604,33 @@
"safe-buffer": "~5.2.0"
}
},
"node_modules/string-replace-loader": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-replace-loader/-/string-replace-loader-3.1.0.tgz",
"integrity": "sha512-5AOMUZeX5HE/ylKDnEa/KKBqvlnFmRZudSOjVJHxhoJg9QYTwl1rECx7SLR8BBH7tfxb4Rp7EM2XVfQFxIhsbQ==",
"dev": true,
"dependencies": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"peerDependencies": {
"webpack": "^5"
}
},
"node_modules/string-replace-loader/node_modules/loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@ -17214,44 +17193,6 @@
"vinyl-sourcemaps-apply": "^0.2.1"
}
},
"gulp-typescript": {
"version": "6.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-6.0.0-alpha.1.tgz",
"integrity": "sha512-KoT0TTfjfT7w3JItHkgFH1T/zK4oXWC+a8xxKfniRfVcA0Fa1bKrIhztYelYmb+95RB80OLMBreknYkdwzdi2Q==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.1",
"plugin-error": "^1.0.1",
"source-map": "^0.7.3",
"through2": "^3.0.1",
"vinyl": "^2.2.0",
"vinyl-fs": "^3.0.3"
},
"dependencies": {
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
},
"through2": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
"dev": true,
"requires": {
"inherits": "^2.0.4",
"readable-stream": "2 || 3"
}
}
}
},
"gulplog": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
@ -20303,6 +20244,29 @@
"safe-buffer": "~5.2.0"
}
},
"string-replace-loader": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-replace-loader/-/string-replace-loader-3.1.0.tgz",
"integrity": "sha512-5AOMUZeX5HE/ylKDnEa/KKBqvlnFmRZudSOjVJHxhoJg9QYTwl1rECx7SLR8BBH7tfxb4Rp7EM2XVfQFxIhsbQ==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"dependencies": {
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",

View file

@ -37,10 +37,10 @@
"gulp-concat": "^2.6.1",
"gulp-eslint-new": "^1.3.0",
"gulp-sass": "^5.0.0",
"gulp-typescript": "^6.0.0-alpha.1",
"html2canvas": "^1.4.1",
"madge": "5.0.1",
"stream-browserify": "^3.0.0",
"string-replace-loader": "3.1.0",
"ts-loader": "9.2.6",
"tsify": "^5.0.4",
"typescript": "^4.5.5",

View file

@ -1,10 +1,16 @@
import { CLIENT_VERSION } from "../../version";
const BASE_PATH = "/psas";
export default function getPsasEndpoints(
apeClient: Ape.Client
): Ape.Endpoints["psas"] {
async function get(): Ape.EndpointData {
return await apeClient.get(BASE_PATH);
return await apeClient.get(BASE_PATH, {
headers: {
"Client-Version": CLIENT_VERSION,
},
});
}
return { get };

View file

@ -20,6 +20,7 @@ async function adaptRequestOptions(
params: options.searchQuery,
data: options.payload,
headers: {
...options.headers,
Accept: "application/json",
"Content-Type": "application/json",
...(idToken && { Authorization: `Bearer ${idToken}` }),

View file

@ -20,6 +20,7 @@ declare namespace Ape {
type MethodTypes = keyof Client;
interface RequestOptions {
headers?: Record<string, string>;
searchQuery?: Record<string, any>;
payload?: any;
}

View file

@ -0,0 +1 @@
export const CLIENT_VERSION = "DEVELOPMENT-CLIENT";

View file

@ -16,10 +16,30 @@ module.exports = {
},
module: {
rules: [
{
test: /version\.ts$/,
loader: "string-replace-loader",
options: {
search: /^export const CLIENT_VERSION =.*/,
replace(_match, _p1, _offset, _string) {
const date = new Date();
const dateString = [
date.getFullYear(),
date.getMonth() + 1,
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
].join("-");
return `export const CLIENT_VERSION = "${dateString}";`;
},
flags: "g",
},
},
{ test: /\.tsx?$/, loader: "ts-loader" },
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {