-
-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
Middleware for Microservices #1627
Comments
Middleware concept exists only for HTTP applications so far. |
Did someone find solution how to implement logger with context in microservice? |
I am on it :) |
@skliarovartem just saw this message, you can use an interceptor to do some request logging in interceptors. That's what I've done with Ogma. It's also got optional request scoping so that you can have the correlationId in each log if you want that too. |
I made my tracing by using nestjs-pino + nestjs-steroids/async-context. and yes, I use interceptors to set reqId to context. Thank you for the answer anyway! |
I was looking into the code, and I would like to discuss the solution I see at the moment, with the core team, to make sure that I won't spend effort needlessly. I will split the questions into sections. Interfaces Let's start from the fact that the current
Configuration Currently, we expose
And there are the same concerns regarding the extendability of both approaches if we consider adding Websockets middleware in the future. Application Current HTTP middleware relies on the underlying Adapter to mount middleware, due to that fact it is pretty easy to just path the path and handler to the adaptor, and handle Microservices transports don't have such built-in functions as middleware, so the only way to apply them will be to manually perform the mapping when we create the handler, in the same way, we do with Guards, Interceptors, and so on. This will require the creation of something like Other Thoughts I wonder whether the outcome is worth the effort. The only reasonable way to use middleware in Microservices that I see right now is to use things like |
Agree. Maybe we could just allow registering a "preRequest" (where request = event/message) hook so that you can register it for all handlers? |
Yep, I think that makes sense. That is very close to what I thought when was speaking about One note that such asyncLocalStorage.run(context, () => {
next();
}); What do you think? Also while we on that, I think it makes sense to implement similar |
Sounds good.
We could implement this in a subsequent PR |
@Ayzrian If it helps you, I have solved same problem with interceptor: @Injectable()
export class AsyncContextMsInterceptor implements NestInterceptor {
constructor(private _asyncStorage: AppAsyncLocalStorage) {
}
intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> | Promise<Observable<any>> {
const input = context.switchToRpc().getData();
const { ...some data from headers } = input.headers;
this._asyncStorage.enterWith(new AsyncContextStorage(...some data from headers));
return next.handle();
}
}
|
Hey, @slrv , the problem here is that Guards are called before Interceptors, so you won't have that async storage available in the guards. Though if you don't actually care about Guards, then yes the Interceptor solution will work. |
Hey, @Ayzrian, totally understand you. Anyway, |
Hello, is it possible to get an "onFinish" hook too? It should be triggered after the ExceptionFilters right before the response is send. I am trying to log microservices with an interceptor, which works, as long as i don't throw an exception. In that case the ExceptionFilter is the last instance (and not the interceptor) before the response is send and will modify it. I would like to use this data for my logging. |
I think that you can use |
You can try use the adapter pattern in order to make it agnostic to any outside service such as Sentry and/or Elastic or Datadog for example. |
Hope this issue will be resolved. |
Can you pls share full code as I am unable to find the |
Is it included in the nestjs. |
Hey! What's the state of this? I think it would be great have such feature for example to be able to log RPC messages trace IDs via AsyncLocalStorage |
Can't you just put this logic into a Guard then?
|
Can you share, from where AppAsyncLocalStorage dependency come from, if it is written locally in the application itself, can you share it |
This is how I am using it in the pubsub microservice. import { PinoLogger } from 'nestjs-pino';
import { storage, Store } from 'nestjs-pino/storage';
export const useLoggerAsyncStorage = (callback): unknown => {
return storage.run(new Store(PinoLogger.root), callback);
};
/**
* Pubsub Microservice
*/
@EventPattern('my-subscription')
public handlePubsubReq(
@Payload('payload')
reqMessage: any,
) {
useLoggerAsyncStorage(() => {
this.handleReq(reqMessage);
});
} I was unable to use the assign function in non http transports but using useLoggerAsyncStorage, I can use pino assign method. |
I'm submitting a...
Current behavior
Middleware exists for HTTP but not for Microservices.
Expected behavior
I would like to be able to create middleware functions for Microservices to introduce something like a request context for logging.
Example:
This is different to interceptors because it spans over all guards, interceptors and exception filters.
Or ist there already another way to do this?
Thanks in advance
Environment
The text was updated successfully, but these errors were encountered: