feat(nest-profiler-event-emitter): profile @nestjs/event-emitter domain events - #229
Draft
fpasquet wants to merge 1 commit into
Draft
feat(nest-profiler-event-emitter): profile @nestjs/event-emitter domain events#229fpasquet wants to merge 1 commit into
fpasquet wants to merge 1 commit into
Conversation
…in events packages: - add @eleven-labs/nest-profiler-event-emitter, the 14th collector, in the lockstep release group - add an Events panel: one row per emit/emitAsync, with listeners, duration, async flag and payload - add an `event` entrypoint so each @onevent execution gets its own profile, logs and queries - add an Event Listeners group to the Routes panel, scanning providers and controllers - tag emissions under a dedicated `event` domain, so thresholds never inherit the query ones - support configurable error classification, with the status layer off so `exceptions` applies - restore the patched emit/emitAsync and the wrapped handlers on shutdown, avoiding e2e leaks - ignore an `emitterToken` resolving to a non-emitter, which would otherwise crash bootstrap examples: - add an in-process EventPublisher adapter and make it the default over the unwired no-op one - emit `product.created` from ProductService so the collector has data with zero infrastructure - cover the panel, the event entrypoint and both profiler views in a new e2e spec docs: - add the package README, its packages/api-reference pages and a tutorial, all in the navigation - list the collector in the docs index, the API reference index and the profiler UI tour chore: - register the package in the changeset group, codecov, labels, labeler and issue templates - document the collector in both consumer skills and declare its screenshots in the generator
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
@eleven-labs/nest-profiler-event-emitter, the 14th publishable collector, closing the last blind spot around first-party NestJS integrations: domain events dispatched through@nestjs/event-emitter. Today a controller answers, the request profile closes, and whatever the@OnEventlisteners did is never recorded anywhere.The collector contributes three surfaces:
Eventspanel on the emitting profile — one row peremit/emitAsynccall with the event name, listener count (0 · no listenerflagged in amber), duration, async flag and redacted payload. Entries feed the performance-rule engine under their owneventtag domain, soslow/n-plus-one/chattythresholds never inherit the query ones.evententrypoint — each@OnEventexecution becomes a first-class profile carrying its own logs, queries and sub-requests, in a dedicatedEventslist view withStatus/Eventfilters and anEventdetail tab. Same philosophy asnest-profiler-commanderfor CLI commands; opt out withprofileListeners: false.Event Listenersgroup in the Routes panel, scanning providers and controllers.The implementation started from a collector prototyped outside the repo. Porting it to the monorepo conventions (CommonJS +
repo-build,@repo/*presets,ConfigurableModuleBuilder+buildCollectorModule, Jest at the 90 % gate) surfaced several defects, fixed here:@OnEventon controllers was ignored — the scan only walkedgetProviders(), while@nestjs/event-emitter's own loader also scans controllers. Those listeners were missing from both the Routes panel and the profiling wrapper.emit/emitAsyncnor the wrapped handlers, leaking across apps in e2e suites that create and destroy several.priority: 25collided with the validator collector./gRegExp inignoreEventsmatched every other event (RegExp.testadvanceslastIndex).emitterTokenresolving to a non-emitter crashed bootstrap — found while writing the tests; now guarded structurally.Two deliberate additions on top: configurable error classification (
error?: ProfilerErrorOptions, with the status layer off by default so anexceptionsoverride is actually meaningful — the GraphQL kind does the same) andTaggableCollectorsupport.Two limitations are documented rather than solved: request-scoped subscribers cannot be profiled (
@nestjs/event-emitterresolves a fresh instance per event, so there is no stable handler to wrap), andEventEntry.erroris rarely populated (@OnEventdefaults tosuppressErrors: true; the handler's owneventprofile records the failure either way).Demonstration in
example-apiThe
notificationscontext gains a thirdEventPublisheradapter, backed byEventEmitter2. Since it needs no infrastructure, it becomes the default in place of the no-op adapter, andPOST /api/v1/productsnow publishesproduct.created— so the collector has data out of the box, with no Docker.NotificationsNoopModuleis kept as the minimal reference implementation of the port but is no longer wired; its docblocks say so explicitly.Verified
Beyond CI: the full e2e suite (11 suites, 71 tests, including 6 new ones), plus a manual run against the example app confirming the Events panel (1 listener, 25 ms, redacted payload), the
?view=eventlist, theEvent ListenersRoutes group, a clean boot withPROFILER_ENABLED=false, and the absence of the spurious storage warning under in-memory storage.Screenshots are declared in
scripts/generate-profiler-screenshots.ts(events.png,events-list.png) but not generated in this PR — nothing references them yet, so there are no broken links.Related issue
Closes #228
Checklist
majorchangeset with aBREAKING:noteBreaking changes
New package only — nothing existing changes shape. The one consumer-visible shift is confined to
example-api, where the defaultEventPublisheradapter moves from the no-op to the in-process emitter.