Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add slow query logging #7867

Closed
wants to merge 5 commits into from

Conversation

dblythy
Copy link
Member

@dblythy dblythy commented Mar 19, 2022

New Pull Request Checklist

Issue Description

There's no way to know if your Parse Server has slow endpoints without using a third party tool. Slow Queries was a feature in the original Parse.com, and in fact the component still exists in Parse Dashboard

Related issue: #7038

Approach

Add an express listener to detect when routes take longer than the threshold. Pretty simple really.

TODOs before merging

  • Add tests
  • Add changes to documentation (guides, repository pages, in-code descriptions)
  • Add security check
  • A changelog entry is created automatically using the pull request title (do not manually add a changelog entry)

@parse-github-assistant
Copy link

Thanks for opening this pull request!

  • 🎉 We are excited about your hands-on contribution!

@codecov
Copy link

codecov bot commented Mar 19, 2022

Codecov Report

Merging #7867 (7935bf8) into alpha (62c8715) will decrease coverage by 9.17%.
The diff coverage is 95.83%.

@@            Coverage Diff             @@
##            alpha    #7867      +/-   ##
==========================================
- Coverage   94.18%   85.00%   -9.18%     
==========================================
  Files         182      183       +1     
  Lines       13617    13641      +24     
==========================================
- Hits        12825    11596    -1229     
- Misses        792     2045    +1253     
Impacted Files Coverage Δ
src/Options/index.js 100.00% <ø> (ø)
src/rest.js 98.86% <ø> (ø)
src/SlowQuery.js 94.73% <94.73%> (ø)
src/Controllers/SchemaController.js 97.18% <100.00%> (-0.19%) ⬇️
src/Options/Definitions.js 100.00% <100.00%> (ø)
src/ParseServer.js 90.21% <100.00%> (+0.16%) ⬆️
...dapters/Storage/Postgres/PostgresStorageAdapter.js 2.42% <0.00%> (-93.05%) ⬇️
src/Adapters/Storage/Postgres/PostgresClient.js 5.00% <0.00%> (-65.00%) ⬇️
src/Controllers/UserController.js 95.34% <0.00%> (-2.33%) ⬇️
src/Controllers/FilesController.js 92.00% <0.00%> (-2.00%) ⬇️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 62c8715...7935bf8. Read the comment docs.

Comment on lines +24 to +25
body: req.body,
query: req.query,
Copy link
Member

@Moumouls Moumouls Mar 19, 2022

Choose a reason for hiding this comment

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

Here i'm wondering about security, i can suggest some little improvements (inspired from Sentry):

  • If body size is huge the _SlowQuery collection could be heavy, sentry currently limit the body size, may be we can splice the body at a defined size after a JSON.stringify (this size option could be added in the config).
  • As i understand this hook will be triggered on all endpoints (create, update, get, find, login, signup etc...), here it's required to clean the body and remove sensitve data (like password, etc...), if i'm not wrong the logger already has this feature. May be a little package exists.

Comment on lines +31 to +37
it('needs masterKey for slow queries', async () => {
await reconfigureServer({
slowQuery: {
enable: true,
threshold: 300,
log: true,
},
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to add a test to check that Parse.Cloud.beforeSave("_SlowQuery") works correctly. It could help developers to manipulate the body and remove sensitive data (we should add documentation suggestion about that)

I think we need to ensure/cover that this is supported.

@Moumouls
Copy link
Member

@dblythy nice work 🚀
i'm just wondering about security details

@dblythy
Copy link
Member Author

dblythy commented Mar 19, 2022

Yes I was thinking that too, it's obviously going to be problematic to store req.body on the _User class for example. I was thinking we could add a securityCheck and warn against using it in prod, and possibly try to strip out sensitive data.

@Moumouls
Copy link
Member

Moumouls commented Mar 19, 2022

As i understand the current implementation rely on a middleware for all app endpoints.

Benefits: Easily cover all endpoints
Cons: It's hard to detect details on the query, what class, graphql endpoint ?, create ?, update ?

By design it will be hard to add some future options to helps developers in production to disable for example a specific class slow query tracking for security purpose (health data, and more).

In other hand in dev env it's not a problem, but this kind of feature is also really useful on production env.

i can may be suggest to implement this feature in RestWrite, RestQuery system to be able to give some config options to disable SlowQuery on sensitive classes. A trigger should also added before cloud functions.
GraphQL API use under the hood the rest API, so it will be auto tracked, if implementation is moved into RestWrite/RestQuery

What do you think about this @dblythy ?

@dblythy
Copy link
Member Author

dblythy commented Mar 19, 2022

Thanks for your feedback @Moumouls! Personally I think that your suggestion is the end goal of slowQuery logging. I would in-vision that one day we would have logs of SlowQueries as well as logs of how long each async task took, so users could diagnose what caused the slow query (e’g whether it was a beforeSave, afterSave, auth). However, I think before that we should refactor the codebase (RestRead/RestWrite$ to async/await so the new SlowQuery code can be nice and clean. I think for a v1 of a new feature, recording path and body should be enough for users to replicate the slow query, and then we can evolve it in the future to include more analytics.

I do agree though that this is more of a production feature, so we would have to ensure that we clean the output.

@mtrezza
Copy link
Member

mtrezza commented Mar 19, 2022

See #7038 (comment)

@Moumouls
Copy link
Member

Moumouls commented Mar 19, 2022

@mtrezza you are right i think in this case, some 3rd party services are may be more appropriate. Here i think it's a good idea to redirect developers to just plug their 3rd party lib on top of express (like this implementation).

For example sentry has some example (i know that they have a performance utility): https://docs.sentry.io/platforms/node/guides/express/

here @dblythy i'm scared about security/performance issue of the system. Listening also the full express app, in case of graphql queries/mutations, it will be hard to replace sensitive informations.

In another hand i understand the fast/YAGNI/POC methodology, but we saw also for example on the GraphQL implementation that we need to check widely the scope/standards/common used tools , (in graphql case: Relay API). The first implementation was ok, but after a quick check, it led us to rewrite/migrate all the system to Relay spec.

Here a good idea is may to add some interface to allow developers to plug their favorite performance tool.

Last thinking: This feature will be also useless in some case when developers use mongo atlas. They provide a good performance monitoring tool :)

@mtrezza
Copy link
Member

mtrezza commented Mar 19, 2022

I will comment in #7038 (comment) to give some conceptual suggestions.

@mtrezza mtrezza added the type:feature New feature or improvement of existing feature label Mar 22, 2022
@parse-github-assistant parse-github-assistant bot removed the type:feature New feature or improvement of existing feature label Mar 22, 2022
@dblythy dblythy closed this May 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants