Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

refactor: migrating metrics server to Fastify #803

Merged
merged 35 commits into from
Sep 2, 2022

Conversation

giulianok
Copy link
Member

@giulianok giulianok commented Aug 10, 2022

Migrating Metrics Server from ExpressJS to Fastify

Description

This PR includes the migration of Metrics Server routes to Fastify + converting logging middleware into a fastify plugin

Metrics Server

All routes have been moved to Fastify

Logging

The logging middleware has been converted into a Fastify plugin. It required some refactoring in order to leverage fastify hooks.

To calculate ttfb (time to first byte), instead of monkey patching writeHead function from the raw/nodejs response, I leveraged the onSend fastify hook which is called right before writeHead is called, providing the same time (technically isn't the same but we are using Math.round when logging, so "it's the same").

Besides logging the full request duration and ttfb, I also added extra timers to calculate things like how long it took to start resolving a route, how long it took to resolved a route handler, etc.

Here's an example of a request that's taking 500ms to resolve things before fastify can start resolving the route handler, and the route handler takes 1000ms to resolved.

Screen Shot 2022-08-10 at 11 53 13 AM

I achieved this by adding a sleep function to create the delay

Screen Shot 2022-08-10 at 11 53 28 AM

Screen Shot 2022-08-10 at 11 53 33 AM

These are real metrics from /metrics and /im-up, where we can see that /im-up is a bit slower because of the healthcheck fn

/metrics
Screen Shot 2022-08-10 at 11 58 40 AM

/im-up
Screen Shot 2022-08-10 at 11 58 32 AM

As we can see, we do not have an overhead on the request (pre route handler) and on the response builder

Motivation and Context

Allows us to run Metrics Server in Fastify without the need of Express

How Has This Been Tested?

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (adding or updating documentation)
  • Dependency update
  • Security update

Checklist:

  • My change requires a change to the documentation and I have updated the documentation accordingly.
  • These changes should be applied to a maintenance branch.
  • This change requires cross browser checks.
  • Performance tests should be ran against the server prior to merging.
  • This change impacts caching for client browsers.
  • This change impacts HTTP headers.
  • This change adds additional environment variable requirements for One App users.
  • I have added the Apache 2.0 license header to any new files created.

What is the Impact to Developers Using One App?

10xLaCroixDrinker and others added 27 commits June 28, 2022 15:49
BREAKING CHANGE: Upgrade from React 16 to 17
BREAKING CHANGE: minimum supported node version is 16
* chore(babel): update packages

* chore(commitlint): update

* chore(rollup-plugins): update

* chore(acorn): uninstall

* chore(babel-preset-amex): update to 4

* chore(body-parser): update

* chore(dev-deps): update

* chore(holocron): update 1.3.0

* chore(redux): update 4.2.0

* chore(core-js): update 3.23.3

* chore(deps): run npm update

* chore(husky): update to 8.x

* chore(chalk): downgrade to non esm version

* chore(webdriverio): update 7.x

* feat(dockerfile): update node version to 16.15.1

* chore(deps): update supertest

* fix(node): set min version 16.15.1

* chore(deps): dedupe

* test(createRequestHtmlFragment): more reliable error message

* chore(jest): upgrade 28.1.2
BREAKING CHANGE: Upgrade from React 16 to 17
BREAKING CHANGE: minimum supported node version is 16
* chore(babel): update packages

* chore(commitlint): update

* chore(rollup-plugins): update

* chore(acorn): uninstall

* chore(babel-preset-amex): update to 4

* chore(body-parser): update

* chore(dev-deps): update

* chore(holocron): update 1.3.0

* chore(redux): update 4.2.0

* chore(core-js): update 3.23.3

* chore(deps): run npm update

* chore(husky): update to 8.x

* chore(chalk): downgrade to non esm version

* chore(webdriverio): update 7.x

* feat(dockerfile): update node version to 16.15.1

* chore(deps): update supertest

* fix(node): set min version 16.15.1

* chore(deps): dedupe

* test(createRequestHtmlFragment): more reliable error message

* chore(jest): upgrade 28.1.2
@github-actions
Copy link
Contributor

github-actions bot commented Aug 10, 2022

Size Change: -299 B (0%)

Total Size: 680 kB

Filename Size Change
./build/app/vendors.js 114 kB -299 B (0%)
ℹ️ View Unchanged
Filename Size
./build/app/app.js 165 kB
./build/app/app~vendors.js 386 kB
./build/app/runtime.js 7.07 kB
./build/app/service-worker-client.js 7.26 kB

compressed-size-action

@giulianok giulianok marked this pull request as ready for review August 16, 2022 14:13
@giulianok giulianok requested review from a team as code owners August 16, 2022 14:13
@giulianok giulianok changed the title refactor: migrating metrics server to Fastify [DO NOT MERGE] refactor: migrating metrics server to Fastify Aug 16, 2022
};

const getLocale = (req) => {
// TODO: Verify if `store` is available
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only affects the locale in logger

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not longer a blocker, the Metrics Server does not inject the store, only the SSR Server which is being migrated in a separate PR

@@ -1,5 +1,5 @@
/*
* Copyright 2019 American Express Travel Related Services Company, Inc.
* Copyright 2022 American Express Travel Related Services Company, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

years in existing files can stay the same

});
await fastify.register(fp(logging));
await fastify.register(helmet);
await fastify.register(healthCheck);
Copy link
Contributor

@JAdshead JAdshead Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sold on having the route abstracted into the plugin. I would have to do into each plugin to understand what routes this serves. can you provide your reasoning ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's true. We could pass the url through the options but still hides the route. Best option would be to create a reply decorator so we can implement the route outside the plugin

@@ -1,5 +1,5 @@
/*
* Copyright 2019 American Express Travel Related Services Company, Inc.
* Copyright 2022 American Express Travel Related Services Company, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be reverted

@@ -0,0 +1,179 @@
/*
* Copyright 2019 American Express Travel Related Services Company, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new file so should be this year.

Suggested change
* Copyright 2019 American Express Travel Related Services Company, Inc.
* Copyright 2022 American Express Travel Related Services Company, Inc.

export const $RouteHandler = Symbol('$RouteHandler');
export const $ResponseBuilder = Symbol('$ResponseBuilder');

const TIMERS = {};
Copy link
Contributor

@JAdshead JAdshead Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could one instance of this be shared across multiple requests ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just looking through the code, this is not really needed, i'll remove it

@giulianok giulianok changed the title [DO NOT MERGE] refactor: migrating metrics server to Fastify refactor: migrating metrics server to Fastify Aug 17, 2022
@giulianok giulianok requested review from JAdshead and a team August 17, 2022 15:45
src/server/utils/logging/fastifyPlugin.js Outdated Show resolved Hide resolved
src/server/utils/logging/fastifyPlugin.js Outdated Show resolved Hide resolved
__tests__/server/plugins/healthCheck.spec.js Show resolved Hide resolved
__tests__/server/ssrServer.spec.js Outdated Show resolved Hide resolved
@JAdshead JAdshead requested review from a team August 30, 2022 22:20
@giulianok giulianok merged commit a0fc9ed into main Sep 2, 2022
@giulianok giulianok deleted the refactor/ONE-8301-metrics-fastify-migration branch September 2, 2022 00:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants