How to log all Axios external http requests in NestJS

霸气de小男生 提交于 2020-06-29 06:08:10

问题


I want to be able to log each axios request with full url, headers, etc but currently didn't find a way to do so.

What I did achieve so far is to writhe an Http Interceptor based on this answer

export class HttpLoggerInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    return call$.pipe(
      map(data => {
        // pipe call to add / modify header(s) after remote method
        const req = context.switchToHttp().getRequest();
        return data;
      }),
    );
  }
}

Now I browse through the objects req and context props on debug but could not see Asios request url, etc. Unless I missed that.

My controller route (api/data in that case) have N number of http external calls taking place but interceptor intercepts only controller controller call not Axios calls.

Any thoughts?

That is context object:

args:Array(2) [IncomingMessage, ServerResponse]
constructorRef:class AppController { … }
getRequest:() => …
getResponse:() => …
handler:data() { … }
__proto__:Object {constructor: , getClass: , getHandler: , …}

that is req:

_dumped:false
_events:Object {}
_eventsCount:0
_maxListeners:undefined
_parsedOriginalUrl:Url {protocol: null, slashes: null, auth: null, …}
_parsedUrl:Url {protocol: null, slashes: null, auth: null, …}
_readableState:ReadableState {objectMode: false, highWaterMark: 16384, buffer: BufferList, …}
baseUrl:""
body:Object {}
client:Socket {connecting: false, _hadError: false, _handle: TCP, …}
complete:true
connection:Socket {connecting: false, _hadError: false, _handle: TCP, …}
destroyed:false
fresh:false
headers:Object {accept: "application/json, text/plain, */*", user-agent: "axios/0.18.0", host: "localhost:3000", …}
host:"localhost"
hostname:"localhost"
httpVersion:"1.1"
httpVersionMajor:1
httpVersionMinor:1
ip:"::ffff:127.0.0.1"
ips:Array(0)
method:"GET"
next:function next(err) { … }
originalUrl:"/api/data"
params:Object {}
__proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
path:"/api/data"
protocol:"http"
query:Object {}
rawHeaders:Array(8) ["Accept", "application/json, text/plain, */*", "User-Agent", …]
rawTrailers:Array(0) []
readable:true
readableBuffer:BufferList
readableFlowing:null
readableHighWaterMark:16384
readableLength:0
res:ServerResponse {_events: Object, _eventsCount: 1, _maxListeners: undefined, …}
route:Route {path: "/api/data", stack: Array(1), methods: Object}
secure:false
socket:Socket {connecting: false, _hadError: false, _handle: TCP, …}
stale:true
statusCode:null
statusMessage:null
subdomains:Array(0)
trailers:Object {}
upgrade:false
url:"/api/data"
xhr:false

回答1:


Nest.js-Interceptors only process the request handled by your controller and the response going out. If you make http requests with Axios while you handle a controller request, they won't be processed by an interceptor.


Axios Interceptor

The HttpService exposes its axios instance directly via get axiosRef(). With it, you can add an axios interceptor:

this.httpService.axiosRef.interceptors.request.use(config => console.log(config));

You can for example do that in the onModuleInit() of your AppModule.


Delegate to Facade

As an alternative, you can create an HttpService facade, that logs the request and delegates all calls to the built-in HttpService:

@Injectable()
export class MyHttpService {
  private logger: Logger = new Logger(MyHttpService.name);

  constructor (private httpService: HttpService) {}

  public get<T = any>(url: string, config?: AxiosRequestConfig): Observable<AxiosResponse<T>> {
    this.logger.log({url, config});
    return this.httpService.get(url, config)
       .pipe(tap(response => this.logger.log(response)));
  }

  // ... all the other methods you need.

}

You can create your own LoggingHttpModule that imports the built-in HttpModule and exports your MyHttpService.




回答2:


npm i @types/morgan

npm i morgan

then

import * as morgan from 'morgan';

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(morgan('combined'))
      .forRoutes('*');
  }
}


来源:https://stackoverflow.com/questions/54229131/how-to-log-all-axios-external-http-requests-in-nestjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!