lograil 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +40 -0
  4. package/dist/cjs/context/async-context.browser.d.ts +16 -0
  5. package/dist/cjs/context/async-context.browser.d.ts.map +1 -0
  6. package/dist/cjs/context/async-context.browser.js +29 -0
  7. package/dist/cjs/context/async-context.browser.js.map +1 -0
  8. package/dist/cjs/context/async-context.d.ts +10 -0
  9. package/dist/cjs/context/async-context.d.ts.map +1 -0
  10. package/dist/cjs/context/async-context.js +37 -0
  11. package/dist/cjs/context/async-context.js.map +1 -0
  12. package/dist/cjs/context/context.d.ts +33 -0
  13. package/dist/cjs/context/context.d.ts.map +1 -0
  14. package/dist/cjs/context/context.js +57 -0
  15. package/dist/cjs/context/context.js.map +1 -0
  16. package/dist/cjs/context/index.d.ts +3 -0
  17. package/dist/cjs/context/index.d.ts.map +1 -0
  18. package/dist/cjs/context/index.js +19 -0
  19. package/dist/cjs/context/index.js.map +1 -0
  20. package/dist/cjs/core/entry.d.ts +30 -0
  21. package/dist/cjs/core/entry.d.ts.map +1 -0
  22. package/dist/cjs/core/entry.js +37 -0
  23. package/dist/cjs/core/entry.js.map +1 -0
  24. package/dist/cjs/core/index.d.ts +7 -0
  25. package/dist/cjs/core/index.d.ts.map +1 -0
  26. package/dist/cjs/core/index.js +24 -0
  27. package/dist/cjs/core/index.js.map +1 -0
  28. package/dist/cjs/core/level.d.ts +12 -0
  29. package/dist/cjs/core/level.d.ts.map +1 -0
  30. package/dist/cjs/core/level.js +31 -0
  31. package/dist/cjs/core/level.js.map +1 -0
  32. package/dist/cjs/core/logger.d.ts +271 -0
  33. package/dist/cjs/core/logger.d.ts.map +1 -0
  34. package/dist/cjs/core/logger.js +751 -0
  35. package/dist/cjs/core/logger.js.map +1 -0
  36. package/dist/cjs/core/printf.d.ts +34 -0
  37. package/dist/cjs/core/printf.d.ts.map +1 -0
  38. package/dist/cjs/core/printf.js +133 -0
  39. package/dist/cjs/core/printf.js.map +1 -0
  40. package/dist/cjs/index.d.ts +40 -0
  41. package/dist/cjs/index.d.ts.map +1 -0
  42. package/dist/cjs/index.js +56 -0
  43. package/dist/cjs/index.js.map +1 -0
  44. package/dist/cjs/package.json +1 -0
  45. package/dist/cjs/pipeline/filter.d.ts +10 -0
  46. package/dist/cjs/pipeline/filter.d.ts.map +1 -0
  47. package/dist/cjs/pipeline/filter.js +16 -0
  48. package/dist/cjs/pipeline/filter.js.map +1 -0
  49. package/dist/cjs/pipeline/formatter.d.ts +19 -0
  50. package/dist/cjs/pipeline/formatter.d.ts.map +1 -0
  51. package/dist/cjs/pipeline/formatter.js +183 -0
  52. package/dist/cjs/pipeline/formatter.js.map +1 -0
  53. package/dist/cjs/pipeline/index.d.ts +6 -0
  54. package/dist/cjs/pipeline/index.d.ts.map +1 -0
  55. package/dist/cjs/pipeline/index.js +22 -0
  56. package/dist/cjs/pipeline/index.js.map +1 -0
  57. package/dist/cjs/pipeline/pipeline.d.ts +45 -0
  58. package/dist/cjs/pipeline/pipeline.d.ts.map +1 -0
  59. package/dist/cjs/pipeline/pipeline.js +80 -0
  60. package/dist/cjs/pipeline/pipeline.js.map +1 -0
  61. package/dist/cjs/pipeline/processor.d.ts +67 -0
  62. package/dist/cjs/pipeline/processor.d.ts.map +1 -0
  63. package/dist/cjs/pipeline/processor.js +284 -0
  64. package/dist/cjs/pipeline/processor.js.map +1 -0
  65. package/dist/cjs/pipeline/sampler.d.ts +45 -0
  66. package/dist/cjs/pipeline/sampler.d.ts.map +1 -0
  67. package/dist/cjs/pipeline/sampler.js +62 -0
  68. package/dist/cjs/pipeline/sampler.js.map +1 -0
  69. package/dist/cjs/plugin/index.d.ts +4 -0
  70. package/dist/cjs/plugin/index.d.ts.map +1 -0
  71. package/dist/cjs/plugin/index.js +20 -0
  72. package/dist/cjs/plugin/index.js.map +1 -0
  73. package/dist/cjs/plugin/manager.d.ts +38 -0
  74. package/dist/cjs/plugin/manager.d.ts.map +1 -0
  75. package/dist/cjs/plugin/manager.js +79 -0
  76. package/dist/cjs/plugin/manager.js.map +1 -0
  77. package/dist/cjs/plugin/otel-trace.d.ts +19 -0
  78. package/dist/cjs/plugin/otel-trace.d.ts.map +1 -0
  79. package/dist/cjs/plugin/otel-trace.js +91 -0
  80. package/dist/cjs/plugin/otel-trace.js.map +1 -0
  81. package/dist/cjs/plugin/plugin.d.ts +41 -0
  82. package/dist/cjs/plugin/plugin.d.ts.map +1 -0
  83. package/dist/cjs/plugin/plugin.js +3 -0
  84. package/dist/cjs/plugin/plugin.js.map +1 -0
  85. package/dist/cjs/runtime/adapter.d.ts +81 -0
  86. package/dist/cjs/runtime/adapter.d.ts.map +1 -0
  87. package/dist/cjs/runtime/adapter.js +3 -0
  88. package/dist/cjs/runtime/adapter.js.map +1 -0
  89. package/dist/cjs/runtime/defaults.d.ts +27 -0
  90. package/dist/cjs/runtime/defaults.d.ts.map +1 -0
  91. package/dist/cjs/runtime/defaults.js +30 -0
  92. package/dist/cjs/runtime/defaults.js.map +1 -0
  93. package/dist/cjs/runtime/electron-binding.browser.d.ts +10 -0
  94. package/dist/cjs/runtime/electron-binding.browser.d.ts.map +1 -0
  95. package/dist/cjs/runtime/electron-binding.browser.js +18 -0
  96. package/dist/cjs/runtime/electron-binding.browser.js.map +1 -0
  97. package/dist/cjs/runtime/electron-binding.d.ts +24 -0
  98. package/dist/cjs/runtime/electron-binding.d.ts.map +1 -0
  99. package/dist/cjs/runtime/electron-binding.js +49 -0
  100. package/dist/cjs/runtime/electron-binding.js.map +1 -0
  101. package/dist/cjs/runtime/electron-lifecycle.d.ts +17 -0
  102. package/dist/cjs/runtime/electron-lifecycle.d.ts.map +1 -0
  103. package/dist/cjs/runtime/electron-lifecycle.js +47 -0
  104. package/dist/cjs/runtime/electron-lifecycle.js.map +1 -0
  105. package/dist/cjs/runtime/electron-main.d.ts +24 -0
  106. package/dist/cjs/runtime/electron-main.d.ts.map +1 -0
  107. package/dist/cjs/runtime/electron-main.js +102 -0
  108. package/dist/cjs/runtime/electron-main.js.map +1 -0
  109. package/dist/cjs/runtime/electron-renderer.d.ts +26 -0
  110. package/dist/cjs/runtime/electron-renderer.d.ts.map +1 -0
  111. package/dist/cjs/runtime/electron-renderer.js +33 -0
  112. package/dist/cjs/runtime/electron-renderer.js.map +1 -0
  113. package/dist/cjs/runtime/electron.d.ts +20 -0
  114. package/dist/cjs/runtime/electron.d.ts.map +1 -0
  115. package/dist/cjs/runtime/electron.js +27 -0
  116. package/dist/cjs/runtime/electron.js.map +1 -0
  117. package/dist/cjs/runtime/index.d.ts +21 -0
  118. package/dist/cjs/runtime/index.d.ts.map +1 -0
  119. package/dist/cjs/runtime/index.js +41 -0
  120. package/dist/cjs/runtime/index.js.map +1 -0
  121. package/dist/cjs/runtime/node.d.ts +27 -0
  122. package/dist/cjs/runtime/node.d.ts.map +1 -0
  123. package/dist/cjs/runtime/node.js +126 -0
  124. package/dist/cjs/runtime/node.js.map +1 -0
  125. package/dist/cjs/runtime/process-lifecycle.d.ts +13 -0
  126. package/dist/cjs/runtime/process-lifecycle.d.ts.map +1 -0
  127. package/dist/cjs/runtime/process-lifecycle.js +80 -0
  128. package/dist/cjs/runtime/process-lifecycle.js.map +1 -0
  129. package/dist/cjs/runtime/web-lifecycle.d.ts +13 -0
  130. package/dist/cjs/runtime/web-lifecycle.d.ts.map +1 -0
  131. package/dist/cjs/runtime/web-lifecycle.js +39 -0
  132. package/dist/cjs/runtime/web-lifecycle.js.map +1 -0
  133. package/dist/cjs/runtime/web.d.ts +14 -0
  134. package/dist/cjs/runtime/web.d.ts.map +1 -0
  135. package/dist/cjs/runtime/web.js +61 -0
  136. package/dist/cjs/runtime/web.js.map +1 -0
  137. package/dist/cjs/shims/index.browser.d.ts +26 -0
  138. package/dist/cjs/shims/index.browser.d.ts.map +1 -0
  139. package/dist/cjs/shims/index.browser.js +67 -0
  140. package/dist/cjs/shims/index.browser.js.map +1 -0
  141. package/dist/cjs/shims/index.d.ts +15 -0
  142. package/dist/cjs/shims/index.d.ts.map +1 -0
  143. package/dist/cjs/shims/index.js +39 -0
  144. package/dist/cjs/shims/index.js.map +1 -0
  145. package/dist/cjs/transport/cluster-ipc.d.ts +36 -0
  146. package/dist/cjs/transport/cluster-ipc.d.ts.map +1 -0
  147. package/dist/cjs/transport/cluster-ipc.js +76 -0
  148. package/dist/cjs/transport/cluster-ipc.js.map +1 -0
  149. package/dist/cjs/transport/console.d.ts +28 -0
  150. package/dist/cjs/transport/console.d.ts.map +1 -0
  151. package/dist/cjs/transport/console.js +48 -0
  152. package/dist/cjs/transport/console.js.map +1 -0
  153. package/dist/cjs/transport/electron-ipc.d.ts +69 -0
  154. package/dist/cjs/transport/electron-ipc.d.ts.map +1 -0
  155. package/dist/cjs/transport/electron-ipc.js +153 -0
  156. package/dist/cjs/transport/electron-ipc.js.map +1 -0
  157. package/dist/cjs/transport/file.d.ts +190 -0
  158. package/dist/cjs/transport/file.d.ts.map +1 -0
  159. package/dist/cjs/transport/file.js +666 -0
  160. package/dist/cjs/transport/file.js.map +1 -0
  161. package/dist/cjs/transport/index.d.ts +9 -0
  162. package/dist/cjs/transport/index.d.ts.map +1 -0
  163. package/dist/cjs/transport/index.js +25 -0
  164. package/dist/cjs/transport/index.js.map +1 -0
  165. package/dist/cjs/transport/live.d.ts +72 -0
  166. package/dist/cjs/transport/live.d.ts.map +1 -0
  167. package/dist/cjs/transport/live.js +104 -0
  168. package/dist/cjs/transport/live.js.map +1 -0
  169. package/dist/cjs/transport/otlp.d.ts +97 -0
  170. package/dist/cjs/transport/otlp.d.ts.map +1 -0
  171. package/dist/cjs/transport/otlp.js +194 -0
  172. package/dist/cjs/transport/otlp.js.map +1 -0
  173. package/dist/cjs/transport/rotating-file.d.ts +67 -0
  174. package/dist/cjs/transport/rotating-file.d.ts.map +1 -0
  175. package/dist/cjs/transport/rotating-file.js +179 -0
  176. package/dist/cjs/transport/rotating-file.js.map +1 -0
  177. package/dist/cjs/transport/transport.d.ts +35 -0
  178. package/dist/cjs/transport/transport.d.ts.map +1 -0
  179. package/dist/cjs/transport/transport.js +3 -0
  180. package/dist/cjs/transport/transport.js.map +1 -0
  181. package/dist/cjs/transport/worker-ipc.d.ts +43 -0
  182. package/dist/cjs/transport/worker-ipc.d.ts.map +1 -0
  183. package/dist/cjs/transport/worker-ipc.js +106 -0
  184. package/dist/cjs/transport/worker-ipc.js.map +1 -0
  185. package/dist/cjs/types.d.ts +72 -0
  186. package/dist/cjs/types.d.ts.map +1 -0
  187. package/dist/cjs/types.js +45 -0
  188. package/dist/cjs/types.js.map +1 -0
  189. package/dist/esm/context/async-context.browser.d.ts +16 -0
  190. package/dist/esm/context/async-context.browser.d.ts.map +1 -0
  191. package/dist/esm/context/async-context.browser.js +25 -0
  192. package/dist/esm/context/async-context.browser.js.map +1 -0
  193. package/dist/esm/context/async-context.d.ts +10 -0
  194. package/dist/esm/context/async-context.d.ts.map +1 -0
  195. package/dist/esm/context/async-context.js +33 -0
  196. package/dist/esm/context/async-context.js.map +1 -0
  197. package/dist/esm/context/context.d.ts +33 -0
  198. package/dist/esm/context/context.d.ts.map +1 -0
  199. package/dist/esm/context/context.js +52 -0
  200. package/dist/esm/context/context.js.map +1 -0
  201. package/dist/esm/context/index.d.ts +3 -0
  202. package/dist/esm/context/index.d.ts.map +1 -0
  203. package/dist/esm/context/index.js +3 -0
  204. package/dist/esm/context/index.js.map +1 -0
  205. package/dist/esm/core/entry.d.ts +30 -0
  206. package/dist/esm/core/entry.d.ts.map +1 -0
  207. package/dist/esm/core/entry.js +34 -0
  208. package/dist/esm/core/entry.js.map +1 -0
  209. package/dist/esm/core/index.d.ts +7 -0
  210. package/dist/esm/core/index.d.ts.map +1 -0
  211. package/dist/esm/core/index.js +6 -0
  212. package/dist/esm/core/index.js.map +1 -0
  213. package/dist/esm/core/level.d.ts +12 -0
  214. package/dist/esm/core/level.d.ts.map +1 -0
  215. package/dist/esm/core/level.js +25 -0
  216. package/dist/esm/core/level.js.map +1 -0
  217. package/dist/esm/core/logger.d.ts +271 -0
  218. package/dist/esm/core/logger.d.ts.map +1 -0
  219. package/dist/esm/core/logger.js +747 -0
  220. package/dist/esm/core/logger.js.map +1 -0
  221. package/dist/esm/core/printf.d.ts +34 -0
  222. package/dist/esm/core/printf.d.ts.map +1 -0
  223. package/dist/esm/core/printf.js +129 -0
  224. package/dist/esm/core/printf.js.map +1 -0
  225. package/dist/esm/index.d.ts +40 -0
  226. package/dist/esm/index.d.ts.map +1 -0
  227. package/dist/esm/index.js +38 -0
  228. package/dist/esm/index.js.map +1 -0
  229. package/dist/esm/pipeline/filter.d.ts +10 -0
  230. package/dist/esm/pipeline/filter.d.ts.map +1 -0
  231. package/dist/esm/pipeline/filter.js +11 -0
  232. package/dist/esm/pipeline/filter.js.map +1 -0
  233. package/dist/esm/pipeline/formatter.d.ts +19 -0
  234. package/dist/esm/pipeline/formatter.d.ts.map +1 -0
  235. package/dist/esm/pipeline/formatter.js +179 -0
  236. package/dist/esm/pipeline/formatter.js.map +1 -0
  237. package/dist/esm/pipeline/index.d.ts +6 -0
  238. package/dist/esm/pipeline/index.d.ts.map +1 -0
  239. package/dist/esm/pipeline/index.js +6 -0
  240. package/dist/esm/pipeline/index.js.map +1 -0
  241. package/dist/esm/pipeline/pipeline.d.ts +45 -0
  242. package/dist/esm/pipeline/pipeline.d.ts.map +1 -0
  243. package/dist/esm/pipeline/pipeline.js +76 -0
  244. package/dist/esm/pipeline/pipeline.js.map +1 -0
  245. package/dist/esm/pipeline/processor.d.ts +67 -0
  246. package/dist/esm/pipeline/processor.d.ts.map +1 -0
  247. package/dist/esm/pipeline/processor.js +277 -0
  248. package/dist/esm/pipeline/processor.js.map +1 -0
  249. package/dist/esm/pipeline/sampler.d.ts +45 -0
  250. package/dist/esm/pipeline/sampler.d.ts.map +1 -0
  251. package/dist/esm/pipeline/sampler.js +59 -0
  252. package/dist/esm/pipeline/sampler.js.map +1 -0
  253. package/dist/esm/plugin/index.d.ts +4 -0
  254. package/dist/esm/plugin/index.d.ts.map +1 -0
  255. package/dist/esm/plugin/index.js +4 -0
  256. package/dist/esm/plugin/index.js.map +1 -0
  257. package/dist/esm/plugin/manager.d.ts +38 -0
  258. package/dist/esm/plugin/manager.d.ts.map +1 -0
  259. package/dist/esm/plugin/manager.js +75 -0
  260. package/dist/esm/plugin/manager.js.map +1 -0
  261. package/dist/esm/plugin/otel-trace.d.ts +19 -0
  262. package/dist/esm/plugin/otel-trace.d.ts.map +1 -0
  263. package/dist/esm/plugin/otel-trace.js +55 -0
  264. package/dist/esm/plugin/otel-trace.js.map +1 -0
  265. package/dist/esm/plugin/plugin.d.ts +41 -0
  266. package/dist/esm/plugin/plugin.d.ts.map +1 -0
  267. package/dist/esm/plugin/plugin.js +2 -0
  268. package/dist/esm/plugin/plugin.js.map +1 -0
  269. package/dist/esm/runtime/adapter.d.ts +81 -0
  270. package/dist/esm/runtime/adapter.d.ts.map +1 -0
  271. package/dist/esm/runtime/adapter.js +2 -0
  272. package/dist/esm/runtime/adapter.js.map +1 -0
  273. package/dist/esm/runtime/defaults.d.ts +27 -0
  274. package/dist/esm/runtime/defaults.d.ts.map +1 -0
  275. package/dist/esm/runtime/defaults.js +27 -0
  276. package/dist/esm/runtime/defaults.js.map +1 -0
  277. package/dist/esm/runtime/electron-binding.browser.d.ts +10 -0
  278. package/dist/esm/runtime/electron-binding.browser.d.ts.map +1 -0
  279. package/dist/esm/runtime/electron-binding.browser.js +13 -0
  280. package/dist/esm/runtime/electron-binding.browser.js.map +1 -0
  281. package/dist/esm/runtime/electron-binding.d.ts +24 -0
  282. package/dist/esm/runtime/electron-binding.d.ts.map +1 -0
  283. package/dist/esm/runtime/electron-binding.js +44 -0
  284. package/dist/esm/runtime/electron-binding.js.map +1 -0
  285. package/dist/esm/runtime/electron-lifecycle.d.ts +17 -0
  286. package/dist/esm/runtime/electron-lifecycle.d.ts.map +1 -0
  287. package/dist/esm/runtime/electron-lifecycle.js +44 -0
  288. package/dist/esm/runtime/electron-lifecycle.js.map +1 -0
  289. package/dist/esm/runtime/electron-main.d.ts +24 -0
  290. package/dist/esm/runtime/electron-main.d.ts.map +1 -0
  291. package/dist/esm/runtime/electron-main.js +99 -0
  292. package/dist/esm/runtime/electron-main.js.map +1 -0
  293. package/dist/esm/runtime/electron-renderer.d.ts +26 -0
  294. package/dist/esm/runtime/electron-renderer.d.ts.map +1 -0
  295. package/dist/esm/runtime/electron-renderer.js +30 -0
  296. package/dist/esm/runtime/electron-renderer.js.map +1 -0
  297. package/dist/esm/runtime/electron.d.ts +20 -0
  298. package/dist/esm/runtime/electron.d.ts.map +1 -0
  299. package/dist/esm/runtime/electron.js +21 -0
  300. package/dist/esm/runtime/electron.js.map +1 -0
  301. package/dist/esm/runtime/index.d.ts +21 -0
  302. package/dist/esm/runtime/index.d.ts.map +1 -0
  303. package/dist/esm/runtime/index.js +29 -0
  304. package/dist/esm/runtime/index.js.map +1 -0
  305. package/dist/esm/runtime/node.d.ts +27 -0
  306. package/dist/esm/runtime/node.d.ts.map +1 -0
  307. package/dist/esm/runtime/node.js +123 -0
  308. package/dist/esm/runtime/node.js.map +1 -0
  309. package/dist/esm/runtime/process-lifecycle.d.ts +13 -0
  310. package/dist/esm/runtime/process-lifecycle.d.ts.map +1 -0
  311. package/dist/esm/runtime/process-lifecycle.js +77 -0
  312. package/dist/esm/runtime/process-lifecycle.js.map +1 -0
  313. package/dist/esm/runtime/web-lifecycle.d.ts +13 -0
  314. package/dist/esm/runtime/web-lifecycle.d.ts.map +1 -0
  315. package/dist/esm/runtime/web-lifecycle.js +36 -0
  316. package/dist/esm/runtime/web-lifecycle.js.map +1 -0
  317. package/dist/esm/runtime/web.d.ts +14 -0
  318. package/dist/esm/runtime/web.d.ts.map +1 -0
  319. package/dist/esm/runtime/web.js +58 -0
  320. package/dist/esm/runtime/web.js.map +1 -0
  321. package/dist/esm/shims/index.browser.d.ts +26 -0
  322. package/dist/esm/shims/index.browser.d.ts.map +1 -0
  323. package/dist/esm/shims/index.browser.js +54 -0
  324. package/dist/esm/shims/index.browser.js.map +1 -0
  325. package/dist/esm/shims/index.d.ts +15 -0
  326. package/dist/esm/shims/index.d.ts.map +1 -0
  327. package/dist/esm/shims/index.js +22 -0
  328. package/dist/esm/shims/index.js.map +1 -0
  329. package/dist/esm/transport/cluster-ipc.d.ts +36 -0
  330. package/dist/esm/transport/cluster-ipc.d.ts.map +1 -0
  331. package/dist/esm/transport/cluster-ipc.js +71 -0
  332. package/dist/esm/transport/cluster-ipc.js.map +1 -0
  333. package/dist/esm/transport/console.d.ts +28 -0
  334. package/dist/esm/transport/console.d.ts.map +1 -0
  335. package/dist/esm/transport/console.js +44 -0
  336. package/dist/esm/transport/console.js.map +1 -0
  337. package/dist/esm/transport/electron-ipc.d.ts +69 -0
  338. package/dist/esm/transport/electron-ipc.d.ts.map +1 -0
  339. package/dist/esm/transport/electron-ipc.js +146 -0
  340. package/dist/esm/transport/electron-ipc.js.map +1 -0
  341. package/dist/esm/transport/file.d.ts +190 -0
  342. package/dist/esm/transport/file.d.ts.map +1 -0
  343. package/dist/esm/transport/file.js +662 -0
  344. package/dist/esm/transport/file.js.map +1 -0
  345. package/dist/esm/transport/index.d.ts +9 -0
  346. package/dist/esm/transport/index.d.ts.map +1 -0
  347. package/dist/esm/transport/index.js +9 -0
  348. package/dist/esm/transport/index.js.map +1 -0
  349. package/dist/esm/transport/live.d.ts +72 -0
  350. package/dist/esm/transport/live.d.ts.map +1 -0
  351. package/dist/esm/transport/live.js +100 -0
  352. package/dist/esm/transport/live.js.map +1 -0
  353. package/dist/esm/transport/otlp.d.ts +97 -0
  354. package/dist/esm/transport/otlp.d.ts.map +1 -0
  355. package/dist/esm/transport/otlp.js +190 -0
  356. package/dist/esm/transport/otlp.js.map +1 -0
  357. package/dist/esm/transport/rotating-file.d.ts +67 -0
  358. package/dist/esm/transport/rotating-file.d.ts.map +1 -0
  359. package/dist/esm/transport/rotating-file.js +175 -0
  360. package/dist/esm/transport/rotating-file.js.map +1 -0
  361. package/dist/esm/transport/transport.d.ts +35 -0
  362. package/dist/esm/transport/transport.d.ts.map +1 -0
  363. package/dist/esm/transport/transport.js +2 -0
  364. package/dist/esm/transport/transport.js.map +1 -0
  365. package/dist/esm/transport/worker-ipc.d.ts +43 -0
  366. package/dist/esm/transport/worker-ipc.d.ts.map +1 -0
  367. package/dist/esm/transport/worker-ipc.js +101 -0
  368. package/dist/esm/transport/worker-ipc.js.map +1 -0
  369. package/dist/esm/types.d.ts +72 -0
  370. package/dist/esm/types.d.ts.map +1 -0
  371. package/dist/esm/types.js +39 -0
  372. package/dist/esm/types.js.map +1 -0
  373. package/package.json +128 -0
@@ -0,0 +1,747 @@
1
+ import { LOG_LEVELS, normalizeLevel, isLogLevelName } from '../types.js';
2
+ import { detectRuntime } from '../runtime/index.js';
3
+ import { Pipeline } from '../pipeline/pipeline.js';
4
+ import { createLineFormatter } from '../pipeline/formatter.js';
5
+ import { PluginManager } from '../plugin/index.js';
6
+ import { createContextStore, asyncContext, isEmptyRecord, EMPTY_RECORD } from '../context/index.js';
7
+ import { freezeEntry } from './entry.js';
8
+ import { formatMessage, hasPrintfSpecifier } from './printf.js';
9
+ // Captured at module load — before `redirectConsole` can replace `console.*` —
10
+ // so the logger's own error reporting never recurses into itself.
11
+ const RAW_CONSOLE_ERROR = typeof console !== 'undefined' && typeof console.error === 'function'
12
+ ? console.error.bind(console)
13
+ : () => { };
14
+ function pad(n, len) {
15
+ let s = String(n);
16
+ while (s.length < len)
17
+ s = `0${s}`;
18
+ return s;
19
+ }
20
+ // Reused across entries so the timestamp formatter never allocates a `Date`
21
+ // per log line (single-threaded: `setTime` + UTC reads run synchronously).
22
+ const TIME_DATE = new Date();
23
+ /**
24
+ * Format a millisecond epoch timestamp as an ISO-8601 UTC string
25
+ * (`YYYY-MM-DDTHH:mm:ss.sssZ`). A single `Date` is reused for the calendar
26
+ * decomposition, avoiding a per-entry allocation; only the string is built.
27
+ */
28
+ function isoFromMs(ms) {
29
+ TIME_DATE.setTime(ms);
30
+ return `${pad(TIME_DATE.getUTCFullYear(), 4)}-${pad(TIME_DATE.getUTCMonth() + 1, 2)}-${pad(TIME_DATE.getUTCDate(), 2)}T${pad(TIME_DATE.getUTCHours(), 2)}:${pad(TIME_DATE.getUTCMinutes(), 2)}:${pad(TIME_DATE.getUTCSeconds(), 2)}.${pad(TIME_DATE.getUTCMilliseconds(), 3)}Z`;
31
+ }
32
+ function escapeRegex(s) {
33
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
34
+ }
35
+ function toPattern(token) {
36
+ const body = token
37
+ .split('*')
38
+ .map((part) => escapeRegex(part))
39
+ .join('.*');
40
+ return { re: new RegExp(`^${body}$`) };
41
+ }
42
+ /**
43
+ * Compile a namespace filter. `input` is a comma/space-separated list of glob
44
+ * patterns (with `*` wildcards); a leading `-` excludes. An empty input yields
45
+ * `undefined` (no filtering).
46
+ */
47
+ function compileNamespaceFilter(input) {
48
+ if (!input || (Array.isArray(input) && input.length === 0))
49
+ return undefined;
50
+ const tokens = (Array.isArray(input) ? input : input.split(/[ ,]+/))
51
+ .map((t) => t.trim())
52
+ .filter(Boolean);
53
+ if (tokens.length === 0)
54
+ return undefined;
55
+ const includes = [];
56
+ const excludes = [];
57
+ for (const token of tokens) {
58
+ if (token.startsWith('-'))
59
+ excludes.push(toPattern(token.slice(1)));
60
+ else
61
+ includes.push(toPattern(token));
62
+ }
63
+ return { includes, excludes };
64
+ }
65
+ function matchesNamespace(scope, filter) {
66
+ if (!filter)
67
+ return true;
68
+ const s = scope ?? '';
69
+ for (const ex of filter.excludes) {
70
+ if (ex.re.test(s))
71
+ return false;
72
+ }
73
+ if (filter.includes.length === 0)
74
+ return true;
75
+ return filter.includes.some((inc) => inc.re.test(s));
76
+ }
77
+ /** Read an environment variable, returning `undefined` when unavailable/empty. */
78
+ function readEnvVar(name) {
79
+ if (typeof process === 'undefined' || !process.env)
80
+ return undefined;
81
+ const v = process.env[name];
82
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
83
+ }
84
+ /** Narrowing guard for {@link ChildOptions}. */
85
+ function isChildOptions(o) {
86
+ return o.__child === true;
87
+ }
88
+ function getNodeProcess() {
89
+ if (typeof process === 'undefined' || typeof process.on !== 'function') {
90
+ return undefined;
91
+ }
92
+ return process;
93
+ }
94
+ /**
95
+ * Unified logging facade. Produces {@link LogEntry} records, runs them through
96
+ * the {@link Pipeline} (filter + processors), lets {@link Plugin}s intercept,
97
+ * formats and writes them to {@link Transport}s.
98
+ *
99
+ * Instances are cheap to derive via {@link scope} or {@link child}; all
100
+ * children share the same transports, pipeline and plugins, but carry their own
101
+ * scope and context (captured from the parent at creation).
102
+ */
103
+ export class Logger {
104
+ constructor(options = {}) {
105
+ /**
106
+ * Sequences the async plugin-interception step so entries are processed in
107
+ * emit order. Transport writes fan out to their own per-transport queues
108
+ * (see `transportQueues`), so a slow/blocked transport can never stall the
109
+ * others or this front queue.
110
+ */
111
+ this.dispatchQueue = Promise.resolve();
112
+ /** Independent async-write queue per transport. */
113
+ this.transportQueues = new Map();
114
+ this.destroyed = false;
115
+ this.processHandlersAttached = false;
116
+ this.errorHandlersAttached = false;
117
+ this._exiting = false;
118
+ /** True for loggers created via `scope`/`child` (share the parent's plumbing). */
119
+ this.isChild = false;
120
+ /** Tracks whether the local level was explicitly set via setLevel(). */
121
+ this.hasExplicitLocalLevel = false;
122
+ // ---- Emitting ----
123
+ this.trace = (message, ...args) => this.emit('trace', message, args);
124
+ this.debug = (message, ...args) => this.emit('debug', message, args);
125
+ this.info = (message, ...args) => this.emit('info', message, args);
126
+ this.warn = (message, ...args) => this.emit('warn', message, args);
127
+ this.error = (message, ...args) => this.emit('error', message, args);
128
+ this.fatal = (message, ...args) => this.emit('fatal', message, args);
129
+ // Lightweight child path: reuse the parent's runtime, pipeline, plugins,
130
+ // transports and namespace filter, skipping env reads, regex compilation
131
+ // and runtime detection entirely. This keeps `scope`/`child` (used per
132
+ // request, e.g. `logger.child({ requestId })`) near-zero allocation.
133
+ if (isChildOptions(options)) {
134
+ this.isChild = true;
135
+ this.initFromParent(options);
136
+ return;
137
+ }
138
+ this.runtime = options.runtime ?? detectRuntime();
139
+ const pipelineOpts = options.pipeline instanceof Pipeline ? undefined : options.pipeline;
140
+ this.pipeline =
141
+ options.pipeline instanceof Pipeline ? options.pipeline : new Pipeline(pipelineOpts ?? {});
142
+ if (!(options.pipeline instanceof Pipeline) && !pipelineOpts?.formatter) {
143
+ this.pipeline.setFormatter(createLineFormatter());
144
+ }
145
+ this.plugins = options.plugins ?? new PluginManager(this.buildPluginContext());
146
+ this.transports = options.transports ?? this.runtime.defaultTransports();
147
+ this.context = options.context ?? createContextStore();
148
+ const envLevelName = options.levelEnvVar === null ? undefined : readEnvVar(options.levelEnvVar ?? 'LOG_LEVEL');
149
+ const levelInput = envLevelName && isLogLevelName(envLevelName) ? envLevelName : (options.level ?? 'info');
150
+ this.level = normalizeLevel(levelInput);
151
+ this.originalLevel = this.level;
152
+ this.scopeName = options.scope;
153
+ const nsInput = options.namespaceFilter ??
154
+ (options.namespaceEnvVar === null
155
+ ? undefined
156
+ : readEnvVar(options.namespaceEnvVar ?? 'LOGRAIL_DEBUG'));
157
+ this.namespaceFilter = compileNamespaceFilter(nsInput);
158
+ // On the Electron main process, receive renderer logs over IPC.
159
+ if (this.runtime.attachReceiver) {
160
+ this.detachReceiver = this.runtime.attachReceiver((entry) => this.ingestEntry(entry));
161
+ this.runtime.onLevelCommand = (level) => {
162
+ this.peerLevel = level;
163
+ };
164
+ }
165
+ if (options.autoFlushOnExit)
166
+ this.attachExitHandlers();
167
+ this.onLoggerError = options.onError;
168
+ this.writeTimeoutMs = options.writeTimeoutMs ?? 5000;
169
+ this.exitFlushTimeoutMs = options.exitFlushTimeoutMs ?? 2000;
170
+ // Wire the pipeline/plugin error sinks into the unified handler.
171
+ this.pipeline.onError = (err, info) => this.reportError(info.phase, err, info.entry);
172
+ this.plugins.onError = (name, err, entry) => this.reportError('plugin', err, entry, name);
173
+ }
174
+ /**
175
+ * Initialise a lightweight child from its parent. Reuses the parent's
176
+ * runtime, pipeline, plugins, transports and namespace filter, and shares the
177
+ * parent's error handler config so no duplicate `onError` wiring (or duplicate
178
+ * IPC receiver registration) happens.
179
+ */
180
+ initFromParent(opts) {
181
+ const parent = opts.parent;
182
+ this.parent = parent;
183
+ this.runtime = parent.runtime;
184
+ this.pipeline = parent.pipeline;
185
+ this.plugins = parent.plugins;
186
+ this.transports = parent.transports;
187
+ this.namespaceFilter = parent.namespaceFilter;
188
+ this.context = opts.context ?? createContextStore();
189
+ this.scopeName = opts.scope;
190
+ // Only a root logger owns the shared plugin error sink; children inherit it.
191
+ this.onLoggerError = parent.onLoggerError;
192
+ this.writeTimeoutMs = parent.writeTimeoutMs;
193
+ this.exitFlushTimeoutMs = parent.exitFlushTimeoutMs;
194
+ if (opts.levelOverride !== undefined)
195
+ this.levelOverride = opts.levelOverride;
196
+ }
197
+ /**
198
+ * Feed an externally produced {@link LogEntry} (e.g. received from a renderer
199
+ * process over IPC) into the pipeline/transports. Subject to the configured
200
+ * level and plugins, then written via the active transports.
201
+ */
202
+ ingestEntry(entry) {
203
+ if (this.destroyed)
204
+ return;
205
+ if (entry.level < this.getLevel())
206
+ return;
207
+ if (!matchesNamespace(entry.scope, this.namespaceFilter))
208
+ return;
209
+ this.dispatch(entry);
210
+ }
211
+ // ---- Level ----
212
+ getLevel() {
213
+ if (this.levelOverride !== undefined)
214
+ return this.levelOverride;
215
+ if (this.parent)
216
+ return this.parent.getLevel();
217
+ // If local level was explicitly set (via constructor or setLevel), use it.
218
+ // Otherwise fall back to the cached peer level.
219
+ if (this.hasExplicitLocalLevel)
220
+ return this.level;
221
+ if (this.peerLevel !== undefined)
222
+ return this.peerLevel;
223
+ return this.level;
224
+ }
225
+ setLevel(level) {
226
+ const v = normalizeLevel(level);
227
+ if (this.parent) {
228
+ this.levelOverride = v;
229
+ }
230
+ else {
231
+ this.level = v;
232
+ this.hasExplicitLocalLevel = true;
233
+ }
234
+ }
235
+ /**
236
+ * Register a callback invoked when a cross-process level command is received
237
+ * (e.g. from a renderer, worker, or cluster peer). Called automatically by
238
+ * the runtime when {@link RuntimeAdapter.onLevelCommand} is wired up; most
239
+ * users should not call this directly.
240
+ */
241
+ setOnLevelCommand(cb) {
242
+ this.runtime.onLevelCommand = cb;
243
+ }
244
+ // ---- Context ----
245
+ setContext(key, value) {
246
+ this.context.set(key, value);
247
+ }
248
+ mergeContext(values) {
249
+ this.context.merge(values);
250
+ }
251
+ // ---- Transports ----
252
+ addTransport(transport) {
253
+ this.transports.push(transport);
254
+ this.plugins.notifyTransport(transport);
255
+ }
256
+ removeTransport(name) {
257
+ const removed = this.transports.filter((t) => t.name === name);
258
+ for (const t of removed)
259
+ this.transportQueues.delete(t);
260
+ this.transports = this.transports.filter((t) => t.name !== name);
261
+ }
262
+ /** Unregister a plugin by name at runtime. */
263
+ unregisterPlugin(name) {
264
+ this.plugins.unregister(name);
265
+ }
266
+ /** Whether a plugin with the given name is currently registered. */
267
+ hasPlugin(name) {
268
+ return this.plugins.has(name);
269
+ }
270
+ /** Access the processing pipeline to add/remove filters & processors or change the formatter at runtime. */
271
+ getPipeline() {
272
+ return this.pipeline;
273
+ }
274
+ /** Build the {@link PluginContext} handed to plugins so they can reconfigure the logger. */
275
+ buildPluginContext() {
276
+ return {
277
+ addTransport: (t) => this.addTransport(t),
278
+ removeTransport: (n) => this.removeTransport(n),
279
+ pipeline: this.pipeline,
280
+ use: (p) => this.use(p),
281
+ unregisterPlugin: (n) => this.unregisterPlugin(n),
282
+ logger: this,
283
+ };
284
+ }
285
+ getTransports() {
286
+ return this.transports;
287
+ }
288
+ // ---- Plugins ----
289
+ use(plugin) {
290
+ return this.plugins.register(plugin);
291
+ }
292
+ // ---- Scoped loggers ----
293
+ /**
294
+ * Derive a scoped child logger. The child shares this logger's transports,
295
+ * pipeline, plugins and runtime, inherits its scope (joined with `:`) and
296
+ * context (captured from the parent at creation), and may carry extra
297
+ * context. The level is inherited live from the parent (see {@link child})
298
+ * unless overridden via `setLevel`.
299
+ *
300
+ * Construction is lightweight: no environment reads, regex compilation or
301
+ * runtime detection is performed — the child reuses this logger's plumbing.
302
+ */
303
+ scope(scope, context) {
304
+ const childScope = this.scopeName ? `${this.scopeName}:${scope}` : scope;
305
+ const childContext = this.context.child();
306
+ if (context) {
307
+ childContext.merge(context);
308
+ }
309
+ return new Logger({
310
+ __child: true,
311
+ parent: this,
312
+ scope: childScope,
313
+ context: childContext,
314
+ });
315
+ }
316
+ /**
317
+ * Derive a child logger that shares this logger's transports, pipeline,
318
+ * plugins and runtime. The child:
319
+ * - merges `options.context` on top of the parent's context (captured at
320
+ * creation),
321
+ * - inherits the parent's scope,
322
+ * - inherits the parent's level live, unless `options.level` overrides it
323
+ * (the override also applies to any further descendants).
324
+ *
325
+ * This is the canonical "child logger" (à la `pino.child`), ideal for
326
+ * per-request context such as `logger.child({ requestId: id })`. Construction
327
+ * is lightweight — see {@link scope}.
328
+ */
329
+ child(options = {}) {
330
+ const childContext = this.context.child();
331
+ if (options.context) {
332
+ childContext.merge(options.context);
333
+ }
334
+ return new Logger({
335
+ __child: true,
336
+ parent: this,
337
+ scope: this.scopeName,
338
+ context: childContext,
339
+ levelOverride: options.level !== undefined ? normalizeLevel(options.level) : undefined,
340
+ });
341
+ }
342
+ emit(levelName, message, args) {
343
+ if (this.destroyed)
344
+ return;
345
+ const levelValue = LOG_LEVELS[levelName];
346
+ if (levelValue < this.getLevel())
347
+ return;
348
+ if (!matchesNamespace(this.scopeName, this.namespaceFilter))
349
+ return;
350
+ const entry = this.buildEntry(levelName, levelValue, message, args);
351
+ const processed = this.pipeline.process(entry);
352
+ if (!processed)
353
+ return;
354
+ this.dispatch(processed);
355
+ }
356
+ /**
357
+ * Route a processed entry to the transports. When no plugin intercepts
358
+ * entries we can write synchronously and skip the per-call Promise + write
359
+ * queue entirely (the common case); the async path is only used when a plugin
360
+ * hook or an async transport needs it.
361
+ */
362
+ dispatch(entry) {
363
+ if (this.plugins.hasEntryInterceptors()) {
364
+ const p = this.plugins.intercept(entry).then((intercepted) => {
365
+ if (intercepted)
366
+ this.writeToTransports(intercepted);
367
+ });
368
+ this.dispatchQueue = this.dispatchQueue
369
+ .then(() => p)
370
+ .catch((err) => this.reportError('plugin', err));
371
+ return;
372
+ }
373
+ this.writeToTransports(entry);
374
+ }
375
+ /**
376
+ * Report an internal error without throwing. Routes to the user-supplied
377
+ * `onError` handler, falling back to the native `console.error` (deliberately
378
+ * not the redirected one, to avoid recursion).
379
+ */
380
+ reportError(phase, err, entry, source) {
381
+ if (this.onLoggerError) {
382
+ this.onLoggerError(err, { phase, entry, source });
383
+ return;
384
+ }
385
+ RAW_CONSOLE_ERROR(`[lograil]${source ? ` (${source})` : ''} ${phase} error:`, err);
386
+ }
387
+ buildEntry(levelName, levelValue, message, args) {
388
+ let msg;
389
+ let error;
390
+ let rest = args;
391
+ if (message instanceof Error) {
392
+ error = message;
393
+ msg = message.message;
394
+ }
395
+ else if (typeof message === 'string') {
396
+ // `printf`-style: `logger.info('user %s', name)`. Only enter the format
397
+ // path when at least one argument is present and a legal specifier
398
+ // exists, so the dominant `info('msg', {obj})` pattern stays on the
399
+ // zero-format fast path and literal `%` in messages is preserved.
400
+ if (args.length > 0 && hasPrintfSpecifier(message)) {
401
+ const [formatted, ...restArgs] = formatMessage(message, args);
402
+ msg = formatted;
403
+ rest = restArgs;
404
+ }
405
+ else {
406
+ msg = message;
407
+ }
408
+ }
409
+ else {
410
+ // Non-string / non-Error first argument (e.g. an object): preserve it as
411
+ // structured data instead of coercing to "[object Object]".
412
+ msg = '';
413
+ rest = [message, ...args];
414
+ }
415
+ if (!error) {
416
+ error = rest.find((a) => a instanceof Error);
417
+ }
418
+ const now = this.runtime.now();
419
+ const ts = typeof now === 'number' ? now : new Date(now).getTime();
420
+ // Merge the ambient (request-scoped) context on top of this logger's own
421
+ // context. Reading it is O(1); we only clone when one side is non-empty.
422
+ const base = this.context.get();
423
+ const ambient = asyncContext.get();
424
+ // NB: never hand the live AsyncLocalStorage store directly to the entry —
425
+ // the ambient object is shared across the async scope, so a later mutation
426
+ // (or `freezeEntry` below) would corrupt every entry in that scope. When
427
+ // ambient is the only source we clone it into a per-entry object; otherwise
428
+ // we reuse the frozen EMPTY_RECORD sentinel so the hot path allocates
429
+ // nothing.
430
+ const context = ambient === EMPTY_RECORD
431
+ ? base
432
+ : isEmptyRecord(base)
433
+ ? { ...ambient }
434
+ : { ...base, ...ambient };
435
+ return {
436
+ level: levelValue,
437
+ levelName,
438
+ message: msg,
439
+ args: rest,
440
+ timestamp: ts,
441
+ time: isoFromMs(ts),
442
+ scope: this.scopeName,
443
+ pid: this.runtime.pid(),
444
+ context,
445
+ // Shared frozen empty record (no per-call allocation); `freezeEntry`
446
+ // recognises it as a sentinel and skips cloning/freezing.
447
+ metadata: EMPTY_RECORD,
448
+ error,
449
+ };
450
+ }
451
+ writeToTransports(entry) {
452
+ // Freeze at the single fan-out choke point so every transport, formatter and
453
+ // plugin reads an immutable entry and can safely share it by reference
454
+ // (zero-copy within the process). Idempotent.
455
+ const frozen = freezeEntry(entry);
456
+ for (const transport of this.transports) {
457
+ const tl = transport.level;
458
+ if (tl !== undefined && frozen.level < normalizeLevel(tl))
459
+ continue;
460
+ const formatter = transport.formatter ?? this.pipeline.getFormatter();
461
+ let formatted;
462
+ try {
463
+ formatted = formatter(frozen);
464
+ }
465
+ catch (err) {
466
+ this.reportError('formatter', err, frozen);
467
+ formatted = `[formatting failed] ${frozen.message}`;
468
+ }
469
+ const onErr = transport.onError;
470
+ try {
471
+ const result = transport.write(frozen, String(formatted));
472
+ if (result && typeof result.then === 'function') {
473
+ const guarded = this.guardWrite(result);
474
+ // Chain onto THIS transport's own queue, not a shared one, so a stalled
475
+ // write here cannot block other transports (or the front dispatch queue).
476
+ const prev = this.transportQueues.get(transport) ?? Promise.resolve();
477
+ const next = prev
478
+ .then(() => guarded)
479
+ .catch((err) => this.reportTransportError(err, frozen, onErr));
480
+ this.transportQueues.set(transport, next);
481
+ }
482
+ }
483
+ catch (err) {
484
+ this.reportTransportError(err, frozen, onErr);
485
+ }
486
+ }
487
+ }
488
+ /** Await a transport's async `write`, but never let it stall the queue. */
489
+ guardWrite(p) {
490
+ if (!this.writeTimeoutMs)
491
+ return p;
492
+ let timer;
493
+ const timeout = new Promise((_, reject) => {
494
+ timer = setTimeout(() => reject(new Error(`transport write timed out after ${this.writeTimeoutMs}ms`)), this.writeTimeoutMs);
495
+ });
496
+ return Promise.race([p, timeout]).finally(() => {
497
+ if (timer)
498
+ clearTimeout(timer);
499
+ });
500
+ }
501
+ /** Await a transport's async `flush`, but never let it stall teardown. */
502
+ guardFlush(p) {
503
+ if (!this.writeTimeoutMs)
504
+ return Promise.resolve();
505
+ const result = p();
506
+ if (!result || typeof result.then !== 'function')
507
+ return Promise.resolve();
508
+ return this.guardWrite(result);
509
+ }
510
+ /** Surface a transport failure via the transport's hook, else the global handler. */
511
+ reportTransportError(err, entry, onErr) {
512
+ if (onErr)
513
+ onErr(err, entry);
514
+ else
515
+ this.reportError('transport', err, entry);
516
+ }
517
+ // ---- Lifecycle ----
518
+ async flush() {
519
+ // Let in-flight interception finish so every scheduled write has been
520
+ // enqueued onto its transport's own queue.
521
+ await this.dispatchQueue;
522
+ // Aggregate all per-transport async-write queues. `allSettled` means a
523
+ // rejected/errored transport queue never rejects flush; a stalled one is
524
+ // bounded by `writeTimeoutMs` via `guardWrite`.
525
+ await Promise.allSettled(Array.from(this.transportQueues.values()));
526
+ // Flush each transport's internal buffers with the same timeout guard so
527
+ // a stalled flush can never hang shutdown or caller code.
528
+ await Promise.allSettled(this.transports.map((t) => (t.flush ? this.guardFlush(t.flush.bind(t)) : Promise.resolve())));
529
+ }
530
+ /**
531
+ * Flush, but never wait longer than `ms`. Resolves (does not reject) once the
532
+ * flush settles or the timeout elapses, so callers can always proceed (e.g.
533
+ * exit the process) without risking a hang on a stalled transport.
534
+ */
535
+ flushWithTimeout(ms) {
536
+ if (!ms)
537
+ return this.flush();
538
+ return new Promise((resolve) => {
539
+ let settled = false;
540
+ const done = () => {
541
+ if (settled)
542
+ return;
543
+ settled = true;
544
+ resolve();
545
+ };
546
+ const timer = setTimeout(done, ms);
547
+ if (typeof timer.unref === 'function')
548
+ timer.unref();
549
+ this.flush().then(done, done);
550
+ });
551
+ }
552
+ /** Set the max time (ms) to flush on process exit before giving up. */
553
+ setExitFlushTimeout(ms) {
554
+ if (Number.isFinite(ms) && ms >= 0)
555
+ this.exitFlushTimeoutMs = ms;
556
+ return this;
557
+ }
558
+ /** Get the current exit-flush timeout (ms). */
559
+ getExitFlushTimeout() {
560
+ return this.exitFlushTimeoutMs;
561
+ }
562
+ // ---- Process integration ----
563
+ /**
564
+ * Register `beforeExit` / `SIGINT` / `SIGTERM` handlers that flush the logger
565
+ * before the process leaves. On `SIGINT` / `SIGTERM` the process exits (130 /
566
+ * 143) after the flush completes. No-op outside Node. Idempotent.
567
+ */
568
+ attachExitHandlers() {
569
+ if (this.processHandlersAttached)
570
+ return;
571
+ // Prefer runtime-provided lifecycle hooks so the logger stays
572
+ // runtime-agnostic and the runtime owns process/window event wiring and
573
+ // exit semantics. Falls back to a direct `process` binding below for
574
+ // adapters that don't supply lifecycle hooks (e.g. custom test runtimes).
575
+ const lc = this.runtime.lifecycle;
576
+ if (lc) {
577
+ const ms = this.exitFlushTimeoutMs;
578
+ const detach = lc.onFlushBeforeExit(() => {
579
+ void this.flushWithTimeout(ms);
580
+ });
581
+ const prev = this.removeProcessHandlers;
582
+ this.removeProcessHandlers = () => {
583
+ prev?.();
584
+ detach();
585
+ };
586
+ this.processHandlersAttached = true;
587
+ return;
588
+ }
589
+ const proc = getNodeProcess();
590
+ if (!proc)
591
+ return;
592
+ const ms = this.exitFlushTimeoutMs;
593
+ // On normal exit the event loop is about to empty: flush pending writes.
594
+ // `beforeExit` re-fires as long as async writes keep the loop alive, so the
595
+ // queue keeps draining until empty (bounded by `ms` if a sink stalls).
596
+ const onBeforeExit = () => {
597
+ void this.flushWithTimeout(ms);
598
+ };
599
+ // On a signal, flush what we can, then terminate — but never hang shutdown
600
+ // on a stalled transport (the timeout guarantees we still exit).
601
+ const onSignal = (code) => {
602
+ if (this._exiting)
603
+ return;
604
+ this._exiting = true;
605
+ void this.flushWithTimeout(ms).finally(() => {
606
+ try {
607
+ proc.exit(code);
608
+ }
609
+ catch {
610
+ /* ignore */
611
+ }
612
+ });
613
+ };
614
+ const onSigInt = () => onSignal(130);
615
+ const onSigTerm = () => onSignal(143);
616
+ proc.on('beforeExit', onBeforeExit);
617
+ proc.on('SIGINT', onSigInt);
618
+ proc.on('SIGTERM', onSigTerm);
619
+ this.processHandlersAttached = true;
620
+ const prev = this.removeProcessHandlers;
621
+ this.removeProcessHandlers = () => {
622
+ prev?.();
623
+ proc.removeListener('beforeExit', onBeforeExit);
624
+ proc.removeListener('SIGINT', onSigInt);
625
+ proc.removeListener('SIGTERM', onSigTerm);
626
+ };
627
+ }
628
+ /**
629
+ * Forward `uncaughtException` and `unhandledRejection` to the logger (at
630
+ * `fatal` level) and exit afterwards, so crashes are recorded before the
631
+ * process dies. No-op outside Node. Idempotent.
632
+ */
633
+ watchUncaughtErrors() {
634
+ if (this.errorHandlersAttached)
635
+ return;
636
+ // Delegate to the runtime's lifecycle hooks when present (see
637
+ // `attachExitHandlers` for the rationale). The hooks own the `process`
638
+ // events and the post-flush `exit(1)`; we only provide the fatal log +
639
+ // bounded flush. Runtimes without an `onUncaughtError` hook (e.g. web)
640
+ // fall back to the direct `process` binding below, which is a no-op there.
641
+ const lc = this.runtime.lifecycle;
642
+ if (lc?.onUncaughtError) {
643
+ const ms = this.exitFlushTimeoutMs;
644
+ const detach = lc.onUncaughtError((err) => {
645
+ this.fatal(err);
646
+ return this.flushWithTimeout(ms);
647
+ });
648
+ const prev = this.removeProcessHandlers;
649
+ this.removeProcessHandlers = () => {
650
+ prev?.();
651
+ detach();
652
+ };
653
+ this.errorHandlersAttached = true;
654
+ return;
655
+ }
656
+ const proc = getNodeProcess();
657
+ if (!proc)
658
+ return;
659
+ const onUncaught = (err) => {
660
+ this.fatal(err);
661
+ void this.flushWithTimeout(this.exitFlushTimeoutMs).finally(() => proc.exit(1));
662
+ };
663
+ const onRejection = (reason) => {
664
+ this.fatal(reason);
665
+ void this.flushWithTimeout(this.exitFlushTimeoutMs).finally(() => proc.exit(1));
666
+ };
667
+ proc.on('uncaughtException', onUncaught);
668
+ proc.on('unhandledRejection', onRejection);
669
+ this.errorHandlersAttached = true;
670
+ const prev = this.removeProcessHandlers;
671
+ this.removeProcessHandlers = () => {
672
+ prev?.();
673
+ proc.removeListener('uncaughtException', onUncaught);
674
+ proc.removeListener('unhandledRejection', onRejection);
675
+ };
676
+ }
677
+ /**
678
+ * Route `console.*` calls through this logger, so third-party `console.log`
679
+ * output is captured into the structured pipeline. The native console output
680
+ * is suppressed for those calls (the logger's own transports produce the
681
+ * visible output); if logging throws, the native console is used as a
682
+ * fallback. Returns a function that restores the original `console`.
683
+ */
684
+ redirectConsole() {
685
+ if (typeof console === 'undefined')
686
+ return () => { };
687
+ const routes = [
688
+ ['log', 'info'],
689
+ ['info', 'info'],
690
+ ['debug', 'debug'],
691
+ ['warn', 'warn'],
692
+ ['error', 'error'],
693
+ ['trace', 'trace'],
694
+ ];
695
+ const originals = {};
696
+ for (const [method, level] of routes) {
697
+ const original = console[method]?.bind(console);
698
+ if (!original)
699
+ continue;
700
+ originals[method] = original;
701
+ console[method] = (...args) => {
702
+ try {
703
+ this[level](...args);
704
+ }
705
+ catch {
706
+ original(...args);
707
+ }
708
+ };
709
+ }
710
+ return () => {
711
+ for (const key of Object.keys(originals)) {
712
+ console[key] = originals[key];
713
+ }
714
+ };
715
+ }
716
+ async destroy() {
717
+ this.destroyed = true;
718
+ // Only a root logger owns the shared resources (process handlers, plugins,
719
+ // transports, the IPC receiver). A child shares them with its parent and
720
+ // must not tear them down — destroying a child used to silently break the
721
+ // parent's transports and plugins.
722
+ if (this.isChild) {
723
+ this.transportQueues.clear();
724
+ return;
725
+ }
726
+ this.removeProcessHandlers?.();
727
+ // Flush pending writes before tearing down transports, so buffered logs
728
+ // are not lost. Bounded by the exit-flush timeout so a stalled sink can
729
+ // never hang teardown.
730
+ await this.flushWithTimeout(this.exitFlushTimeoutMs).catch(() => { });
731
+ await this.plugins.destroy().catch(() => { });
732
+ this.detachReceiver?.();
733
+ this.peerLevel = undefined;
734
+ if (this.originalLevel !== undefined) {
735
+ this.level = this.originalLevel;
736
+ this.hasExplicitLocalLevel = false;
737
+ }
738
+ for (const transport of this.transports) {
739
+ if (transport.close) {
740
+ await Promise.resolve(transport.close()).catch(() => { });
741
+ }
742
+ }
743
+ this.transportQueues.clear();
744
+ this.dispatchQueue = Promise.resolve();
745
+ }
746
+ }
747
+ //# sourceMappingURL=logger.js.map