logger-plugin.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { URL } from 'node:url';
  2. import { getLogger } from '../../logger.js';
  3. import { createUrl } from '../../utils/create-url.js';
  4. import { getPort } from '../../utils/logger-plugin.js';
  5. import { definePlugin } from '../define-plugin.js';
  6. export const loggerPlugin = definePlugin((proxyServer, options) => {
  7. const logger = getLogger(options);
  8. proxyServer.on('error', (err, req, res, target) => {
  9. const hostname = req?.headers?.host;
  10. const requestHref = `${hostname}${req?.url}`;
  11. const targetHref = `${target?.href}`; // target is undefined when websocket errors
  12. const errorMessage = '[HPM] Error occurred while proxying request %s to %s [%s] (%s)';
  13. const errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
  14. logger.error(errorMessage, requestHref, targetHref, err.code || err, errReference);
  15. });
  16. /**
  17. * Log request and response
  18. * @example
  19. * ```shell
  20. * [HPM] GET /users/ -> http://jsonplaceholder.typicode.com/users/ [304]
  21. * ```
  22. */
  23. proxyServer.on('proxyRes', (proxyRes, req, res) => {
  24. // BrowserSync uses req.originalUrl
  25. // Next.js doesn't have req.baseUrl
  26. const originalUrl = req.originalUrl ?? `${req.baseUrl || ''}${req.url}`;
  27. // construct targetUrl
  28. let target;
  29. try {
  30. const port = getPort(proxyRes.req?.agent?.sockets);
  31. const { protocol, host, path } = proxyRes.req;
  32. target = createUrl({ protocol, host, port, path });
  33. }
  34. catch (err) {
  35. // should not error. keeping fallback just in case
  36. console.error('[HPM] Unexpected error while creating target URL', err);
  37. // fallback to old implementation (less correct - without port)
  38. target = new URL(options.target);
  39. target.pathname = proxyRes.req.path;
  40. }
  41. const targetUrl = target.toString();
  42. const exchange = `[HPM] ${req.method} ${originalUrl} -> ${targetUrl} [${proxyRes.statusCode}]`;
  43. logger.info(exchange);
  44. });
  45. /**
  46. * When client opens WebSocket connection
  47. */
  48. proxyServer.on('open', (socket) => {
  49. logger.info('[HPM] Client connected: %o', socket.address());
  50. });
  51. /**
  52. * When client closes WebSocket connection
  53. */
  54. proxyServer.on('close', (req, proxySocket, proxyHead) => {
  55. logger.info('[HPM] Client disconnected: %o', proxySocket.address());
  56. });
  57. });