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: Breadcrumbs #210

Merged
merged 38 commits into from
May 15, 2024
Merged

feat: Breadcrumbs #210

merged 38 commits into from
May 15, 2024

Conversation

miquelbeltran
Copy link
Contributor

@miquelbeltran miquelbeltran commented May 10, 2024

feat: Breadcrumbs

Description 📝

  • Purpose: Add breadcrumbs support
  • Approach: Took the work on the old branch breadcrumbs and ported it to the latest codebase.
  • Closes No breadcrumb support? #74

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Updates

The main idea is that breadcrumbs are automatically scoped to the current request in ExpressJS.
Breadcrumbs are also added automatically with the request information.
For that, users must add the expressHandlerBreadcrumbs middleware to their ExpressJS app:

app.use(raygun.expressHandlerBreadcrumbs);

Then, users can also add their own custom breadcrumbs calling to addBreadcrumb() in the scope of a request.

app.get("/endpoint", (req, res) => {
  // ... inside a request ...
  raygun.addBreadcrumb("My custom breadcrumb");
  // ...

As well, users can continue using the Raygun ExpressJS handler:

app.use(raygunClient.expressHandler);

When an error is captured by the expressHandler, or the user calls to raygun.send(), the breadcrumbs in the current scope will be attached to the message details payload automatically.

At any point in time, users have the option to discard all the stored breadcrumbs if they so desire:

raygun.clearBreadcrumbs();

Besides supporting scope by request, breadcrumbs are added to a global scope when calling addBreadcrumb() outside the scope, and will be included in any error sent outside of request scopes.

Internally, the implementation uses AsyncLocalStorage to handle scopes within requests.
Quoting the original PR:

Currently built on top of AsyncLocalStorage, which means that we can run a section of code with a particular scope for breadcrumbs, which allows us to process multiple requests in parallel and still attribute breadcrumbs correctly without a great deal of user intervention.

Expanded Express example

The ExpressJS example has been expanded this way:

  • Added breadcrumbs to project setup.
  • Created a /send endpoint which sends a custom Raygun error.
  • Added breadcrumbs to /error endpoint.

Example of how Breadcrumbs appear:

image

As raw data:

"breadcrumbs": [
        {
            "category": "http",
            "message": "GET /send",
            "level": "info",
            "timestamp": 1715668231800,
            "type": "request"
        },
        {
            "level": "debug",
            "category": "Example",
            "message": "Breadcrumb in /send endpoint",
            "customData": {
                "custom-data": "data"
            },
            "timestamp": 1715668231804,
            "type": "manual",
            "className": "/home/miquel/dev/projects/raygun/raygun4node/examples/express-sample/routes/index.js",
            "methodName": "<anonymous>",
            "lineNumber": 14
        }
    ],

Test plan 🧪

  • Added tests in test/raygun_breadcrumbs_test.js.
  • Added breadcrumbs to ExpressJS example project.
  • Extended the ExpressJS example project.
  • Added breadcrumbs to domains test.

Author to check 👓

  • Project and all contained modules builds successfully
  • Self-/dev-tested
  • Unit/UI/Automation/Integration tests provided where applicable
  • Code is written to standards
  • Appropriate documentation written (code comments, internal docs)

Reviewer to check ✔️

  • Project and all contained modules builds successfully
  • Change has been dev-/reviewer-tested, where possible
  • Unit/UI/Automation/Integration tests provided where applicable
  • Code is written to standards
  • Appropriate documentation written (code comments, internal docs)

@miquelbeltran miquelbeltran requested review from a team, TheRealAgentK, PanosNB and sumitramanga and removed request for a team May 13, 2024 09:21
@miquelbeltran
Copy link
Contributor Author

Hi @MindscapeHQ/kai-miquel-and-friends I'd like you to take a look at the current implementation while I am finishing documentation and examples, and get some feedback and questions from you.

@miquelbeltran
Copy link
Contributor Author

No, that's different, isn't it. [breadcrumbs] is the tag for the debug module and that can be quite generic. Express adds something to it for instance that is not related to the file at all. I added the filename as an additional information for folks to easily find the file a debug statement from within the provider comes from.

The output looks correct to me:

2024-05-14T12:21:08.984Z raygun [raygun.ts] Client initialized
2024-05-14T12:21:08.989Z raygun [raygun.breadcrumbs.ts] enter with new store

Nevertheless, I will change it to follow the rest of the files.

@miquelbeltran miquelbeltran marked this pull request as ready for review May 14, 2024 14:07
@miquelbeltran miquelbeltran changed the title feat: Breadcrumbs (WIP) feat: Breadcrumbs May 14, 2024
@miquelbeltran
Copy link
Contributor Author

Did some more cleanup, updated README with Breadcrumb documentation, and applied many of the suggestions from Kai.

I mark this now as ready for review, I think it is in a state which is usable and good enough to go as first implementation.

@TheRealAgentK
Copy link
Contributor

No, that's different, isn't it. [breadcrumbs] is the tag for the debug module and that can be quite generic. Express adds something to it for instance that is not related to the file at all. I added the filename as an additional information for folks to easily find the file a debug statement from within the provider comes from.

The output looks correct to me:

2024-05-14T12:21:08.984Z raygun [raygun.ts] Client initialized
2024-05-14T12:21:08.989Z raygun [raygun.breadcrumbs.ts] enter with new store

Nevertheless, I will change it to follow the rest of the files.

Yeah that output does look like I'd expect it to be.

@TheRealAgentK
Copy link
Contributor

Did some more cleanup, updated README with Breadcrumb documentation, and applied many of the suggestions from Kai.

I mark this now as ready for review, I think it is in a state which is usable and good enough to go as first implementation.

I just gave it another look and I think it's good and my concerns/remarks are all addressed!

Copy link
Contributor

@TheRealAgentK TheRealAgentK left a comment

Choose a reason for hiding this comment

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

LGTM

@miquelbeltran
Copy link
Contributor Author

Thanks for the review!

I'll go ahead and merge to develop, if we want to do any changes, we can do it before the release in a new PR

@miquelbeltran miquelbeltran merged commit 57ceec3 into develop May 15, 2024
8 checks passed
@miquelbeltran miquelbeltran deleted the miquelbeltran/breadcrumbs branch May 15, 2024 11:07
app.use("/", routes);
```

This middleware can be user together with the provided ExpressJS error handler `expressHandler`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

"used" instead of "user"

Comment on lines 26 to 27
// uncomment after placing your favicon in /public
// app.use(favicon(__dirname + '/public/favicon.ico'));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The favicon was missing in the /public folder, this should be cleaned up, or we need a favicon. I'll see if we can get a raygun one.

@@ -58,7 +47,9 @@ app.use(express.static(path.join(__dirname, "public")));
app.use("/", routes);
app.use("/users", users);

// Add the Raygun Express handler
// Add the Raygun error Express handler
app.use(raygunClient.expressHandler);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that it (express naming usage) is too tightly coupled at the moment. But until we see popular requests for other frameworks, I'm happy with the current implementation until we implement support for other frameworks. I think the new approach looks good (moving to raygun.breadcrumbs.express.ts).

But does a standalone node app need breadcrumbs tracked manually?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But does a standalone node app need breadcrumbs tracked manually?

Yes, users would need to manually add breadcrumbs.

The expressBreadcrumbsHandler only adds a single breadcrumb for requests, so it isn't a big difference nevertheless.

@miquelbeltran
Copy link
Contributor Author

@sumitramanga I will submit the suggestions in a new PR

This was referenced May 17, 2024
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.

No breadcrumb support?
3 participants