diagnostics.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. 'use strict'
  2. const diagnosticsChannel = require('node:diagnostics_channel')
  3. const util = require('node:util')
  4. const undiciDebugLog = util.debuglog('undici')
  5. const fetchDebuglog = util.debuglog('fetch')
  6. const websocketDebuglog = util.debuglog('websocket')
  7. let isClientSet = false
  8. const channels = {
  9. // Client
  10. beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'),
  11. connected: diagnosticsChannel.channel('undici:client:connected'),
  12. connectError: diagnosticsChannel.channel('undici:client:connectError'),
  13. sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'),
  14. // Request
  15. create: diagnosticsChannel.channel('undici:request:create'),
  16. bodySent: diagnosticsChannel.channel('undici:request:bodySent'),
  17. headers: diagnosticsChannel.channel('undici:request:headers'),
  18. trailers: diagnosticsChannel.channel('undici:request:trailers'),
  19. error: diagnosticsChannel.channel('undici:request:error'),
  20. // WebSocket
  21. open: diagnosticsChannel.channel('undici:websocket:open'),
  22. close: diagnosticsChannel.channel('undici:websocket:close'),
  23. socketError: diagnosticsChannel.channel('undici:websocket:socket_error'),
  24. ping: diagnosticsChannel.channel('undici:websocket:ping'),
  25. pong: diagnosticsChannel.channel('undici:websocket:pong')
  26. }
  27. if (undiciDebugLog.enabled || fetchDebuglog.enabled) {
  28. const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog
  29. // Track all Client events
  30. diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => {
  31. const {
  32. connectParams: { version, protocol, port, host }
  33. } = evt
  34. debuglog(
  35. 'connecting to %s using %s%s',
  36. `${host}${port ? `:${port}` : ''}`,
  37. protocol,
  38. version
  39. )
  40. })
  41. diagnosticsChannel.channel('undici:client:connected').subscribe(evt => {
  42. const {
  43. connectParams: { version, protocol, port, host }
  44. } = evt
  45. debuglog(
  46. 'connected to %s using %s%s',
  47. `${host}${port ? `:${port}` : ''}`,
  48. protocol,
  49. version
  50. )
  51. })
  52. diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => {
  53. const {
  54. connectParams: { version, protocol, port, host },
  55. error
  56. } = evt
  57. debuglog(
  58. 'connection to %s using %s%s errored - %s',
  59. `${host}${port ? `:${port}` : ''}`,
  60. protocol,
  61. version,
  62. error.message
  63. )
  64. })
  65. diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => {
  66. const {
  67. request: { method, path, origin }
  68. } = evt
  69. debuglog('sending request to %s %s/%s', method, origin, path)
  70. })
  71. // Track Request events
  72. diagnosticsChannel.channel('undici:request:headers').subscribe(evt => {
  73. const {
  74. request: { method, path, origin },
  75. response: { statusCode }
  76. } = evt
  77. debuglog(
  78. 'received response to %s %s/%s - HTTP %d',
  79. method,
  80. origin,
  81. path,
  82. statusCode
  83. )
  84. })
  85. diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => {
  86. const {
  87. request: { method, path, origin }
  88. } = evt
  89. debuglog('trailers received from %s %s/%s', method, origin, path)
  90. })
  91. diagnosticsChannel.channel('undici:request:error').subscribe(evt => {
  92. const {
  93. request: { method, path, origin },
  94. error
  95. } = evt
  96. debuglog(
  97. 'request to %s %s/%s errored - %s',
  98. method,
  99. origin,
  100. path,
  101. error.message
  102. )
  103. })
  104. isClientSet = true
  105. }
  106. if (websocketDebuglog.enabled) {
  107. if (!isClientSet) {
  108. const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog
  109. diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => {
  110. const {
  111. connectParams: { version, protocol, port, host }
  112. } = evt
  113. debuglog(
  114. 'connecting to %s%s using %s%s',
  115. host,
  116. port ? `:${port}` : '',
  117. protocol,
  118. version
  119. )
  120. })
  121. diagnosticsChannel.channel('undici:client:connected').subscribe(evt => {
  122. const {
  123. connectParams: { version, protocol, port, host }
  124. } = evt
  125. debuglog(
  126. 'connected to %s%s using %s%s',
  127. host,
  128. port ? `:${port}` : '',
  129. protocol,
  130. version
  131. )
  132. })
  133. diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => {
  134. const {
  135. connectParams: { version, protocol, port, host },
  136. error
  137. } = evt
  138. debuglog(
  139. 'connection to %s%s using %s%s errored - %s',
  140. host,
  141. port ? `:${port}` : '',
  142. protocol,
  143. version,
  144. error.message
  145. )
  146. })
  147. diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => {
  148. const {
  149. request: { method, path, origin }
  150. } = evt
  151. debuglog('sending request to %s %s/%s', method, origin, path)
  152. })
  153. }
  154. // Track all WebSocket events
  155. diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => {
  156. const {
  157. address: { address, port }
  158. } = evt
  159. websocketDebuglog('connection opened %s%s', address, port ? `:${port}` : '')
  160. })
  161. diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => {
  162. const { websocket, code, reason } = evt
  163. websocketDebuglog(
  164. 'closed connection to %s - %s %s',
  165. websocket.url,
  166. code,
  167. reason
  168. )
  169. })
  170. diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => {
  171. websocketDebuglog('connection errored - %s', err.message)
  172. })
  173. diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => {
  174. websocketDebuglog('ping received')
  175. })
  176. diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => {
  177. websocketDebuglog('pong received')
  178. })
  179. }
  180. module.exports = {
  181. channels
  182. }