@spinajs/log 2.0.481 → 2.0.482

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 (304) hide show
  1. package/README.md +744 -0
  2. package/lib/cjs/archive/LogArchiveService.d.ts +75 -0
  3. package/lib/cjs/archive/LogArchiveService.d.ts.map +1 -0
  4. package/lib/cjs/archive/LogArchiveService.js +189 -0
  5. package/lib/cjs/archive/LogArchiveService.js.map +1 -0
  6. package/lib/cjs/archive/archive-strategy.d.ts +32 -0
  7. package/lib/cjs/archive/archive-strategy.d.ts.map +1 -0
  8. package/lib/cjs/archive/archive-strategy.js +43 -0
  9. package/lib/cjs/archive/archive-strategy.js.map +1 -0
  10. package/lib/cjs/archive/context.d.ts +50 -0
  11. package/lib/cjs/archive/context.d.ts.map +1 -0
  12. package/lib/cjs/archive/context.js +3 -0
  13. package/lib/cjs/archive/context.js.map +1 -0
  14. package/lib/cjs/archive/index.d.ts +10 -0
  15. package/lib/cjs/archive/index.d.ts.map +1 -0
  16. package/lib/cjs/archive/index.js +26 -0
  17. package/lib/cjs/archive/index.js.map +1 -0
  18. package/lib/cjs/archive/retention-strategy.d.ts +26 -0
  19. package/lib/cjs/archive/retention-strategy.d.ts.map +1 -0
  20. package/lib/cjs/archive/retention-strategy.js +42 -0
  21. package/lib/cjs/archive/retention-strategy.js.map +1 -0
  22. package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.d.ts +10 -0
  23. package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.d.ts.map +1 -0
  24. package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.js +46 -0
  25. package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.js.map +1 -0
  26. package/lib/cjs/archive/strategies/CountLogRetentionStrategy.d.ts +10 -0
  27. package/lib/cjs/archive/strategies/CountLogRetentionStrategy.d.ts.map +1 -0
  28. package/lib/cjs/archive/strategies/CountLogRetentionStrategy.js +42 -0
  29. package/lib/cjs/archive/strategies/CountLogRetentionStrategy.js.map +1 -0
  30. package/lib/cjs/archive/strategies/CronLogArchiveStrategy.d.ts +15 -0
  31. package/lib/cjs/archive/strategies/CronLogArchiveStrategy.d.ts.map +1 -0
  32. package/lib/cjs/archive/strategies/CronLogArchiveStrategy.js +52 -0
  33. package/lib/cjs/archive/strategies/CronLogArchiveStrategy.js.map +1 -0
  34. package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.d.ts +18 -0
  35. package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.d.ts.map +1 -0
  36. package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.js +63 -0
  37. package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.js.map +1 -0
  38. package/lib/cjs/archive/strategies/util.d.ts +28 -0
  39. package/lib/cjs/archive/strategies/util.d.ts.map +1 -0
  40. package/lib/cjs/archive/strategies/util.js +59 -0
  41. package/lib/cjs/archive/strategies/util.js.map +1 -0
  42. package/lib/cjs/bootstrap.d.ts.map +1 -1
  43. package/lib/cjs/bootstrap.js +24 -1
  44. package/lib/cjs/bootstrap.js.map +1 -1
  45. package/lib/cjs/callsite.d.ts +26 -0
  46. package/lib/cjs/callsite.d.ts.map +1 -0
  47. package/lib/cjs/callsite.js +60 -0
  48. package/lib/cjs/callsite.js.map +1 -0
  49. package/lib/cjs/config/log.d.ts +96 -0
  50. package/lib/cjs/config/log.d.ts.map +1 -0
  51. package/lib/cjs/config/log.js +75 -0
  52. package/lib/cjs/config/log.js.map +1 -0
  53. package/lib/cjs/context.browser.d.ts +46 -0
  54. package/lib/cjs/context.browser.d.ts.map +1 -0
  55. package/lib/cjs/context.browser.js +85 -0
  56. package/lib/cjs/context.browser.js.map +1 -0
  57. package/lib/cjs/context.d.ts +61 -0
  58. package/lib/cjs/context.d.ts.map +1 -0
  59. package/lib/cjs/context.js +92 -0
  60. package/lib/cjs/context.js.map +1 -0
  61. package/lib/cjs/filters/LevelFilter.d.ts +24 -0
  62. package/lib/cjs/filters/LevelFilter.d.ts.map +1 -0
  63. package/lib/cjs/filters/LevelFilter.js +39 -0
  64. package/lib/cjs/filters/LevelFilter.js.map +1 -0
  65. package/lib/cjs/filters/MatchFilter.d.ts +30 -0
  66. package/lib/cjs/filters/MatchFilter.d.ts.map +1 -0
  67. package/lib/cjs/filters/MatchFilter.js +65 -0
  68. package/lib/cjs/filters/MatchFilter.js.map +1 -0
  69. package/lib/cjs/filters/RateLimitFilter.d.ts +37 -0
  70. package/lib/cjs/filters/RateLimitFilter.d.ts.map +1 -0
  71. package/lib/cjs/filters/RateLimitFilter.js +70 -0
  72. package/lib/cjs/filters/RateLimitFilter.js.map +1 -0
  73. package/lib/cjs/filters/index.d.ts +4 -0
  74. package/lib/cjs/filters/index.d.ts.map +1 -0
  75. package/lib/cjs/filters/index.js +20 -0
  76. package/lib/cjs/filters/index.js.map +1 -0
  77. package/lib/cjs/index.browser.d.ts +14 -0
  78. package/lib/cjs/index.browser.d.ts.map +1 -0
  79. package/lib/cjs/index.browser.js +46 -0
  80. package/lib/cjs/index.browser.js.map +1 -0
  81. package/lib/cjs/index.d.ts +8 -0
  82. package/lib/cjs/index.d.ts.map +1 -1
  83. package/lib/cjs/index.js +8 -0
  84. package/lib/cjs/index.js.map +1 -1
  85. package/lib/cjs/log.d.ts +60 -1
  86. package/lib/cjs/log.d.ts.map +1 -1
  87. package/lib/cjs/log.js +294 -32
  88. package/lib/cjs/log.js.map +1 -1
  89. package/lib/cjs/perf/LogMetricSink.d.ts +28 -0
  90. package/lib/cjs/perf/LogMetricSink.d.ts.map +1 -0
  91. package/lib/cjs/perf/LogMetricSink.js +120 -0
  92. package/lib/cjs/perf/LogMetricSink.js.map +1 -0
  93. package/lib/cjs/perf/measure.d.ts +9 -0
  94. package/lib/cjs/perf/measure.d.ts.map +1 -0
  95. package/lib/cjs/perf/measure.js +21 -0
  96. package/lib/cjs/perf/measure.js.map +1 -0
  97. package/lib/cjs/perf.d.ts +9 -0
  98. package/lib/cjs/perf.d.ts.map +1 -0
  99. package/lib/cjs/perf.js +18 -0
  100. package/lib/cjs/perf.js.map +1 -0
  101. package/lib/cjs/schemas/log.configuration.d.ts +151 -18
  102. package/lib/cjs/schemas/log.configuration.d.ts.map +1 -1
  103. package/lib/cjs/schemas/log.configuration.js +154 -21
  104. package/lib/cjs/schemas/log.configuration.js.map +1 -1
  105. package/lib/cjs/targets/BrowserConsoleTarget.d.ts +48 -0
  106. package/lib/cjs/targets/BrowserConsoleTarget.d.ts.map +1 -0
  107. package/lib/cjs/targets/BrowserConsoleTarget.js +48 -0
  108. package/lib/cjs/targets/BrowserConsoleTarget.js.map +1 -0
  109. package/lib/cjs/targets/ColoredConsoleTarget.d.ts.map +1 -1
  110. package/lib/cjs/targets/ColoredConsoleTarget.js +21 -12
  111. package/lib/cjs/targets/ColoredConsoleTarget.js.map +1 -1
  112. package/lib/cjs/targets/FileTarget.d.ts +96 -20
  113. package/lib/cjs/targets/FileTarget.d.ts.map +1 -1
  114. package/lib/cjs/targets/FileTarget.js +188 -225
  115. package/lib/cjs/targets/FileTarget.js.map +1 -1
  116. package/lib/cjs/targets/JsonFileTarget.d.ts +19 -0
  117. package/lib/cjs/targets/JsonFileTarget.d.ts.map +1 -0
  118. package/lib/cjs/targets/JsonFileTarget.js +44 -0
  119. package/lib/cjs/targets/JsonFileTarget.js.map +1 -0
  120. package/lib/cjs/targets/JsonTarget.d.ts +27 -0
  121. package/lib/cjs/targets/JsonTarget.d.ts.map +1 -0
  122. package/lib/cjs/targets/JsonTarget.js +46 -0
  123. package/lib/cjs/targets/JsonTarget.js.map +1 -0
  124. package/lib/cjs/targets/MemoryTarget.d.ts +33 -0
  125. package/lib/cjs/targets/MemoryTarget.d.ts.map +1 -0
  126. package/lib/cjs/targets/MemoryTarget.js +63 -0
  127. package/lib/cjs/targets/MemoryTarget.js.map +1 -0
  128. package/lib/cjs/targets/index.d.ts +7 -0
  129. package/lib/cjs/targets/index.d.ts.map +1 -1
  130. package/lib/cjs/targets/index.js +7 -0
  131. package/lib/cjs/targets/index.js.map +1 -1
  132. package/lib/cjs/targets/wrappers/AutoFlushTarget.d.ts +37 -0
  133. package/lib/cjs/targets/wrappers/AutoFlushTarget.d.ts.map +1 -0
  134. package/lib/cjs/targets/wrappers/AutoFlushTarget.js +48 -0
  135. package/lib/cjs/targets/wrappers/AutoFlushTarget.js.map +1 -0
  136. package/lib/cjs/targets/wrappers/FallbackGroupTarget.d.ts +45 -0
  137. package/lib/cjs/targets/wrappers/FallbackGroupTarget.d.ts.map +1 -0
  138. package/lib/cjs/targets/wrappers/FallbackGroupTarget.js +94 -0
  139. package/lib/cjs/targets/wrappers/FallbackGroupTarget.js.map +1 -0
  140. package/lib/cjs/targets/wrappers/RetryingTarget.d.ts +44 -0
  141. package/lib/cjs/targets/wrappers/RetryingTarget.d.ts.map +1 -0
  142. package/lib/cjs/targets/wrappers/RetryingTarget.js +61 -0
  143. package/lib/cjs/targets/wrappers/RetryingTarget.js.map +1 -0
  144. package/lib/cjs/targets/wrappers/SplitGroupTarget.d.ts +30 -0
  145. package/lib/cjs/targets/wrappers/SplitGroupTarget.d.ts.map +1 -0
  146. package/lib/cjs/targets/wrappers/SplitGroupTarget.js +52 -0
  147. package/lib/cjs/targets/wrappers/SplitGroupTarget.js.map +1 -0
  148. package/lib/cjs/traceparent.d.ts +63 -0
  149. package/lib/cjs/traceparent.d.ts.map +1 -0
  150. package/lib/cjs/traceparent.js +107 -0
  151. package/lib/cjs/traceparent.js.map +1 -0
  152. package/lib/mjs/archive/LogArchiveService.d.ts +75 -0
  153. package/lib/mjs/archive/LogArchiveService.d.ts.map +1 -0
  154. package/lib/mjs/archive/LogArchiveService.js +186 -0
  155. package/lib/mjs/archive/LogArchiveService.js.map +1 -0
  156. package/lib/mjs/archive/archive-strategy.d.ts +32 -0
  157. package/lib/mjs/archive/archive-strategy.d.ts.map +1 -0
  158. package/lib/mjs/archive/archive-strategy.js +39 -0
  159. package/lib/mjs/archive/archive-strategy.js.map +1 -0
  160. package/lib/mjs/archive/context.d.ts +50 -0
  161. package/lib/mjs/archive/context.d.ts.map +1 -0
  162. package/lib/mjs/archive/context.js +2 -0
  163. package/lib/mjs/archive/context.js.map +1 -0
  164. package/lib/mjs/archive/index.d.ts +10 -0
  165. package/lib/mjs/archive/index.d.ts.map +1 -0
  166. package/lib/mjs/archive/index.js +10 -0
  167. package/lib/mjs/archive/index.js.map +1 -0
  168. package/lib/mjs/archive/retention-strategy.d.ts +26 -0
  169. package/lib/mjs/archive/retention-strategy.d.ts.map +1 -0
  170. package/lib/mjs/archive/retention-strategy.js +38 -0
  171. package/lib/mjs/archive/retention-strategy.js.map +1 -0
  172. package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.d.ts +10 -0
  173. package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.d.ts.map +1 -0
  174. package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.js +43 -0
  175. package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.js.map +1 -0
  176. package/lib/mjs/archive/strategies/CountLogRetentionStrategy.d.ts +10 -0
  177. package/lib/mjs/archive/strategies/CountLogRetentionStrategy.d.ts.map +1 -0
  178. package/lib/mjs/archive/strategies/CountLogRetentionStrategy.js +39 -0
  179. package/lib/mjs/archive/strategies/CountLogRetentionStrategy.js.map +1 -0
  180. package/lib/mjs/archive/strategies/CronLogArchiveStrategy.d.ts +15 -0
  181. package/lib/mjs/archive/strategies/CronLogArchiveStrategy.d.ts.map +1 -0
  182. package/lib/mjs/archive/strategies/CronLogArchiveStrategy.js +49 -0
  183. package/lib/mjs/archive/strategies/CronLogArchiveStrategy.js.map +1 -0
  184. package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.d.ts +18 -0
  185. package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.d.ts.map +1 -0
  186. package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.js +60 -0
  187. package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.js.map +1 -0
  188. package/lib/mjs/archive/strategies/util.d.ts +28 -0
  189. package/lib/mjs/archive/strategies/util.d.ts.map +1 -0
  190. package/lib/mjs/archive/strategies/util.js +54 -0
  191. package/lib/mjs/archive/strategies/util.js.map +1 -0
  192. package/lib/mjs/bootstrap.d.ts.map +1 -1
  193. package/lib/mjs/bootstrap.js +25 -2
  194. package/lib/mjs/bootstrap.js.map +1 -1
  195. package/lib/mjs/callsite.d.ts +26 -0
  196. package/lib/mjs/callsite.d.ts.map +1 -0
  197. package/lib/mjs/callsite.js +57 -0
  198. package/lib/mjs/callsite.js.map +1 -0
  199. package/lib/mjs/config/log.d.ts +96 -0
  200. package/lib/mjs/config/log.d.ts.map +1 -0
  201. package/lib/mjs/config/log.js +72 -0
  202. package/lib/mjs/config/log.js.map +1 -0
  203. package/lib/mjs/context.browser.d.ts +46 -0
  204. package/lib/mjs/context.browser.d.ts.map +1 -0
  205. package/lib/mjs/context.browser.js +81 -0
  206. package/lib/mjs/context.browser.js.map +1 -0
  207. package/lib/mjs/context.d.ts +61 -0
  208. package/lib/mjs/context.d.ts.map +1 -0
  209. package/lib/mjs/context.js +88 -0
  210. package/lib/mjs/context.js.map +1 -0
  211. package/lib/mjs/filters/LevelFilter.d.ts +24 -0
  212. package/lib/mjs/filters/LevelFilter.d.ts.map +1 -0
  213. package/lib/mjs/filters/LevelFilter.js +36 -0
  214. package/lib/mjs/filters/LevelFilter.js.map +1 -0
  215. package/lib/mjs/filters/MatchFilter.d.ts +30 -0
  216. package/lib/mjs/filters/MatchFilter.d.ts.map +1 -0
  217. package/lib/mjs/filters/MatchFilter.js +62 -0
  218. package/lib/mjs/filters/MatchFilter.js.map +1 -0
  219. package/lib/mjs/filters/RateLimitFilter.d.ts +37 -0
  220. package/lib/mjs/filters/RateLimitFilter.d.ts.map +1 -0
  221. package/lib/mjs/filters/RateLimitFilter.js +67 -0
  222. package/lib/mjs/filters/RateLimitFilter.js.map +1 -0
  223. package/lib/mjs/filters/index.d.ts +4 -0
  224. package/lib/mjs/filters/index.d.ts.map +1 -0
  225. package/lib/mjs/filters/index.js +4 -0
  226. package/lib/mjs/filters/index.js.map +1 -0
  227. package/lib/mjs/index.browser.d.ts +14 -0
  228. package/lib/mjs/index.browser.d.ts.map +1 -0
  229. package/lib/mjs/index.browser.js +30 -0
  230. package/lib/mjs/index.browser.js.map +1 -0
  231. package/lib/mjs/index.d.ts +8 -0
  232. package/lib/mjs/index.d.ts.map +1 -1
  233. package/lib/mjs/index.js +8 -0
  234. package/lib/mjs/index.js.map +1 -1
  235. package/lib/mjs/log.d.ts +60 -1
  236. package/lib/mjs/log.d.ts.map +1 -1
  237. package/lib/mjs/log.js +295 -33
  238. package/lib/mjs/log.js.map +1 -1
  239. package/lib/mjs/perf/LogMetricSink.d.ts +28 -0
  240. package/lib/mjs/perf/LogMetricSink.d.ts.map +1 -0
  241. package/lib/mjs/perf/LogMetricSink.js +117 -0
  242. package/lib/mjs/perf/LogMetricSink.js.map +1 -0
  243. package/lib/mjs/perf/measure.d.ts +9 -0
  244. package/lib/mjs/perf/measure.d.ts.map +1 -0
  245. package/lib/mjs/perf/measure.js +18 -0
  246. package/lib/mjs/perf/measure.js.map +1 -0
  247. package/lib/mjs/perf.d.ts +9 -0
  248. package/lib/mjs/perf.d.ts.map +1 -0
  249. package/lib/mjs/perf.js +15 -0
  250. package/lib/mjs/perf.js.map +1 -0
  251. package/lib/mjs/schemas/log.configuration.d.ts +151 -18
  252. package/lib/mjs/schemas/log.configuration.d.ts.map +1 -1
  253. package/lib/mjs/schemas/log.configuration.js +154 -21
  254. package/lib/mjs/schemas/log.configuration.js.map +1 -1
  255. package/lib/mjs/targets/BrowserConsoleTarget.d.ts +48 -0
  256. package/lib/mjs/targets/BrowserConsoleTarget.d.ts.map +1 -0
  257. package/lib/mjs/targets/BrowserConsoleTarget.js +45 -0
  258. package/lib/mjs/targets/BrowserConsoleTarget.js.map +1 -0
  259. package/lib/mjs/targets/ColoredConsoleTarget.d.ts.map +1 -1
  260. package/lib/mjs/targets/ColoredConsoleTarget.js +21 -9
  261. package/lib/mjs/targets/ColoredConsoleTarget.js.map +1 -1
  262. package/lib/mjs/targets/FileTarget.d.ts +96 -20
  263. package/lib/mjs/targets/FileTarget.d.ts.map +1 -1
  264. package/lib/mjs/targets/FileTarget.js +191 -192
  265. package/lib/mjs/targets/FileTarget.js.map +1 -1
  266. package/lib/mjs/targets/JsonFileTarget.d.ts +19 -0
  267. package/lib/mjs/targets/JsonFileTarget.d.ts.map +1 -0
  268. package/lib/mjs/targets/JsonFileTarget.js +41 -0
  269. package/lib/mjs/targets/JsonFileTarget.js.map +1 -0
  270. package/lib/mjs/targets/JsonTarget.d.ts +27 -0
  271. package/lib/mjs/targets/JsonTarget.d.ts.map +1 -0
  272. package/lib/mjs/targets/JsonTarget.js +43 -0
  273. package/lib/mjs/targets/JsonTarget.js.map +1 -0
  274. package/lib/mjs/targets/MemoryTarget.d.ts +33 -0
  275. package/lib/mjs/targets/MemoryTarget.d.ts.map +1 -0
  276. package/lib/mjs/targets/MemoryTarget.js +60 -0
  277. package/lib/mjs/targets/MemoryTarget.js.map +1 -0
  278. package/lib/mjs/targets/index.d.ts +7 -0
  279. package/lib/mjs/targets/index.d.ts.map +1 -1
  280. package/lib/mjs/targets/index.js +7 -0
  281. package/lib/mjs/targets/index.js.map +1 -1
  282. package/lib/mjs/targets/wrappers/AutoFlushTarget.d.ts +37 -0
  283. package/lib/mjs/targets/wrappers/AutoFlushTarget.d.ts.map +1 -0
  284. package/lib/mjs/targets/wrappers/AutoFlushTarget.js +45 -0
  285. package/lib/mjs/targets/wrappers/AutoFlushTarget.js.map +1 -0
  286. package/lib/mjs/targets/wrappers/FallbackGroupTarget.d.ts +45 -0
  287. package/lib/mjs/targets/wrappers/FallbackGroupTarget.d.ts.map +1 -0
  288. package/lib/mjs/targets/wrappers/FallbackGroupTarget.js +91 -0
  289. package/lib/mjs/targets/wrappers/FallbackGroupTarget.js.map +1 -0
  290. package/lib/mjs/targets/wrappers/RetryingTarget.d.ts +44 -0
  291. package/lib/mjs/targets/wrappers/RetryingTarget.d.ts.map +1 -0
  292. package/lib/mjs/targets/wrappers/RetryingTarget.js +58 -0
  293. package/lib/mjs/targets/wrappers/RetryingTarget.js.map +1 -0
  294. package/lib/mjs/targets/wrappers/SplitGroupTarget.d.ts +30 -0
  295. package/lib/mjs/targets/wrappers/SplitGroupTarget.d.ts.map +1 -0
  296. package/lib/mjs/targets/wrappers/SplitGroupTarget.js +49 -0
  297. package/lib/mjs/targets/wrappers/SplitGroupTarget.js.map +1 -0
  298. package/lib/mjs/traceparent.d.ts +63 -0
  299. package/lib/mjs/traceparent.d.ts.map +1 -0
  300. package/lib/mjs/traceparent.js +100 -0
  301. package/lib/mjs/traceparent.js.map +1 -0
  302. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  303. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  304. package/package.json +25 -15
@@ -0,0 +1,44 @@
1
+ import { ICommonTargetOptions, ILogEntry, ITargetsOption, LogTarget } from "@spinajs/log-common";
2
+ import { ResiliencePipeline } from "@spinajs/util";
3
+ /**
4
+ * Options for {@link RetryingTarget}.
5
+ */
6
+ export interface IRetryingTargetOptions extends ICommonTargetOptions {
7
+ options: {
8
+ /**
9
+ * Inline child target this wrapper decorates. Resolved through DI exactly
10
+ * like a top-level target.
11
+ */
12
+ target: ITargetsOption;
13
+ /**
14
+ * Total number of write attempts ( the first try plus retries ). Default 3.
15
+ */
16
+ maxAttempts?: number;
17
+ /**
18
+ * Base delay in milliseconds between retries ( exponential backoff + jitter
19
+ * is applied on top ). Default 100.
20
+ */
21
+ delayMs?: number;
22
+ };
23
+ }
24
+ /**
25
+ * Wraps ONE inner target and RETRIES its `write` when it REJECTS, using the
26
+ * `@spinajs/util` resilience pipeline ( exponential backoff + jitter ). Only
27
+ * useful for targets that surface failure by rejecting ( console / custom /
28
+ * strict ) — self-healing targets ( File / Loki / OTLP ) own their reliability
29
+ * and resolve, so wrapping them is a no-op. See the write() rejection contract
30
+ * on {@link LogTarget.write}.
31
+ *
32
+ * The inner target is declared inline and owned by this wrapper ( resolve /
33
+ * flush / dispose ). Pure / browser-safe - just delegates to its child.
34
+ */
35
+ export declare class RetryingTarget extends LogTarget<IRetryingTargetOptions> {
36
+ protected Inner: LogTarget<ICommonTargetOptions>;
37
+ /** Reusable retry pipeline guarding the inner write. */
38
+ protected RetryPipeline: ResiliencePipeline<void>;
39
+ resolve(): void;
40
+ write(entry: ILogEntry): Promise<void>;
41
+ forceFlush(): Promise<void>;
42
+ dispose(): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=RetryingTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetryingTarget.d.ts","sourceRoot":"","sources":["../../../../src/targets/wrappers/RetryingTarget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAe,kBAAkB,EAAuC,MAAM,eAAe,CAAC;AAErG;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,OAAO,EAAE;QACP;;;WAGG;QACH,MAAM,EAAE,cAAc,CAAC;QAEvB;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;;;;;;;;GAUG;AACH,qBAEa,cAAe,SAAQ,SAAS,CAAC,sBAAsB,CAAC;IACnE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAEjD,wDAAwD;IACxD,SAAS,CAAC,aAAa,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAE3C,OAAO,IAAI,IAAI;IAoBf,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RetryingTarget = void 0;
10
+ const log_common_1 = require("@spinajs/log-common");
11
+ const di_1 = require("@spinajs/di");
12
+ const util_1 = require("@spinajs/util");
13
+ /**
14
+ * Wraps ONE inner target and RETRIES its `write` when it REJECTS, using the
15
+ * `@spinajs/util` resilience pipeline ( exponential backoff + jitter ). Only
16
+ * useful for targets that surface failure by rejecting ( console / custom /
17
+ * strict ) — self-healing targets ( File / Loki / OTLP ) own their reliability
18
+ * and resolve, so wrapping them is a no-op. See the write() rejection contract
19
+ * on {@link LogTarget.write}.
20
+ *
21
+ * The inner target is declared inline and owned by this wrapper ( resolve /
22
+ * flush / dispose ). Pure / browser-safe - just delegates to its child.
23
+ */
24
+ let RetryingTarget = class RetryingTarget extends log_common_1.LogTarget {
25
+ resolve() {
26
+ this.Inner = di_1.DI.resolve(this.Options.options.target.type, [this.Options.options.target]);
27
+ const maxAttempts = this.Options.options.maxAttempts ?? 3;
28
+ const delayMs = this.Options.options.delayMs ?? 100;
29
+ // MaxRetryAttempts counts RETRIES ( on top of the first attempt ), so
30
+ // subtract one from the total attempt budget.
31
+ this.RetryPipeline = new util_1.ResiliencePipelineBuilder()
32
+ .addRetry({
33
+ MaxRetryAttempts: Math.max(0, maxAttempts - 1),
34
+ Delay: util_1.TimeSpan.fromMilliseconds(delayMs),
35
+ BackoffType: util_1.BackoffType.Exponential,
36
+ UseJitter: true,
37
+ })
38
+ .build();
39
+ super.resolve();
40
+ }
41
+ write(entry) {
42
+ if (!this.Options.enabled) {
43
+ return Promise.resolve();
44
+ }
45
+ // wrap in Promise.resolve because some targets' write is sync / void. The
46
+ // pipeline retries whenever the inner write REJECTS.
47
+ return this.RetryPipeline.execute(() => Promise.resolve(this.Inner.write(entry)).then(() => undefined));
48
+ }
49
+ forceFlush() {
50
+ return this.Inner.forceFlush();
51
+ }
52
+ async dispose() {
53
+ await this.Inner.dispose?.();
54
+ }
55
+ };
56
+ exports.RetryingTarget = RetryingTarget;
57
+ exports.RetryingTarget = RetryingTarget = __decorate([
58
+ (0, di_1.Singleton)(),
59
+ (0, di_1.Injectable)("RetryingTarget")
60
+ ], RetryingTarget);
61
+ //# sourceMappingURL=RetryingTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetryingTarget.js","sourceRoot":"","sources":["../../../../src/targets/wrappers/RetryingTarget.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAiG;AACjG,oCAAwD;AACxD,wCAAqG;AA0BrG;;;;;;;;;;GAUG;AAGI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,sBAAiC;IAM5D,OAAO;QACZ,IAAI,CAAC,KAAK,GAAG,OAAE,CAAC,OAAO,CAAkC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAE1H,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,GAAG,CAAC;QAEpD,sEAAsE;QACtE,8CAA8C;QAC9C,IAAI,CAAC,aAAa,GAAG,IAAI,gCAAyB,EAAQ;aACvD,QAAQ,CAAC;YACR,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC;YAC9C,KAAK,EAAE,eAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACzC,WAAW,EAAE,kBAAW,CAAC,WAAW;YACpC,SAAS,EAAE,IAAI;SAChB,CAAC;aACD,KAAK,EAAE,CAAC;QAEX,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,KAAgB;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,0EAA0E;QAC1E,qDAAqD;QACrD,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1G,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,OAAO;QAClB,MAAO,IAAI,CAAC,KAAa,CAAC,OAAO,EAAE,EAAE,CAAC;IACxC,CAAC;CACF,CAAA;AA3CY,wCAAc;yBAAd,cAAc;IAF1B,IAAA,cAAS,GAAE;IACX,IAAA,eAAU,EAAC,gBAAgB,CAAC;GAChB,cAAc,CA2C1B"}
@@ -0,0 +1,30 @@
1
+ import { ICommonTargetOptions, ILogEntry, ITargetsOption, LogTarget } from "@spinajs/log-common";
2
+ /**
3
+ * Options for {@link SplitGroupTarget}.
4
+ */
5
+ export interface ISplitGroupTargetOptions extends ICommonTargetOptions {
6
+ options: {
7
+ /**
8
+ * Inline child target definitions this group fans out to. Each is resolved
9
+ * through DI exactly like a top-level target, so any registered target type
10
+ * ( File, Json, Loki, another wrapper ... ) can be nested here.
11
+ */
12
+ targets: ITargetsOption[];
13
+ };
14
+ }
15
+ /**
16
+ * Fan-out wrapper: one configured target name that writes every entry to MANY
17
+ * inner targets. The inner targets are declared inline under `options.targets`
18
+ * and are owned by this wrapper ( they are NOT part of the logger's Targets
19
+ * list ), so the wrapper resolves, flushes and disposes them.
20
+ *
21
+ * Pure / browser-safe - just delegates to its children.
22
+ */
23
+ export declare class SplitGroupTarget extends LogTarget<ISplitGroupTargetOptions> {
24
+ protected Inner: LogTarget<ICommonTargetOptions>[];
25
+ resolve(): void;
26
+ write(entry: ILogEntry): Promise<void>;
27
+ forceFlush(): Promise<void>;
28
+ dispose(): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=SplitGroupTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SplitGroupTarget.d.ts","sourceRoot":"","sources":["../../../../src/targets/wrappers/SplitGroupTarget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGjG;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IACpE,OAAO,EAAE;QACP;;;;WAIG;QACH,OAAO,EAAE,cAAc,EAAE,CAAC;KAC3B,CAAC;CACH;AAED;;;;;;;GAOG;AACH,qBAEa,gBAAiB,SAAQ,SAAS,CAAC,wBAAwB,CAAC;IACvE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAM;IAEjD,OAAO,IAAI,IAAI;IAQf,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAStC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAKtC"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SplitGroupTarget = void 0;
10
+ const log_common_1 = require("@spinajs/log-common");
11
+ const di_1 = require("@spinajs/di");
12
+ /**
13
+ * Fan-out wrapper: one configured target name that writes every entry to MANY
14
+ * inner targets. The inner targets are declared inline under `options.targets`
15
+ * and are owned by this wrapper ( they are NOT part of the logger's Targets
16
+ * list ), so the wrapper resolves, flushes and disposes them.
17
+ *
18
+ * Pure / browser-safe - just delegates to its children.
19
+ */
20
+ let SplitGroupTarget = class SplitGroupTarget extends log_common_1.LogTarget {
21
+ constructor() {
22
+ super(...arguments);
23
+ this.Inner = [];
24
+ }
25
+ resolve() {
26
+ // resolve each child via DI exactly like FrameworkLogger.resolveLogTargets
27
+ // does - the child's ITargetsOption is passed as the single ctor arg.
28
+ this.Inner = this.Options.options.targets.map((t) => di_1.DI.resolve(t.type, [t]));
29
+ super.resolve();
30
+ }
31
+ write(entry) {
32
+ if (!this.Options.enabled) {
33
+ return Promise.resolve();
34
+ }
35
+ // wrap in Promise.resolve because some targets' write is sync / void.
36
+ return Promise.allSettled(this.Inner.map((t) => Promise.resolve(t.write(entry)))).then(() => undefined);
37
+ }
38
+ forceFlush() {
39
+ return Promise.allSettled(this.Inner.map((t) => t.forceFlush())).then(() => undefined);
40
+ }
41
+ async dispose() {
42
+ // the wrapper owns its children ( they are not in the logger's Targets list )
43
+ // so it drives their teardown.
44
+ await Promise.allSettled(this.Inner.map((t) => t.dispose?.()));
45
+ }
46
+ };
47
+ exports.SplitGroupTarget = SplitGroupTarget;
48
+ exports.SplitGroupTarget = SplitGroupTarget = __decorate([
49
+ (0, di_1.Singleton)(),
50
+ (0, di_1.Injectable)("SplitGroupTarget")
51
+ ], SplitGroupTarget);
52
+ //# sourceMappingURL=SplitGroupTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SplitGroupTarget.js","sourceRoot":"","sources":["../../../../src/targets/wrappers/SplitGroupTarget.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAiG;AACjG,oCAAwD;AAgBxD;;;;;;;GAOG;AAGI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,sBAAmC;IAAlE;;QACK,UAAK,GAAsC,EAAE,CAAC;IA4B1D,CAAC;IA1BQ,OAAO;QACZ,2EAA2E;QAC3E,sEAAsE;QACtE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAE,CAAC,OAAO,CAAkC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/G,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,KAAgB;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,sEAAsE;QACtE,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC1G,CAAC;IAEM,UAAU;QACf,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACzF,CAAC;IAEM,KAAK,CAAC,OAAO;QAClB,8EAA8E;QAC9E,+BAA+B;QAC/B,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;CACF,CAAA;AA7BY,4CAAgB;2BAAhB,gBAAgB;IAF5B,IAAA,cAAS,GAAE;IACX,IAAA,eAAU,EAAC,kBAAkB,CAAC;GAClB,gBAAgB,CA6B5B"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * W3C Trace Context ( traceparent ) utilities.
3
+ *
4
+ * Pure, dependency-free and cross-platform ( Node 20+ and browsers ) — randomness
5
+ * is sourced from the WHATWG `crypto.getRandomValues`, available on `globalThis`
6
+ * in both environments, so this module deliberately does NOT import
7
+ * `node:crypto` and stays safe to bundle for the browser.
8
+ *
9
+ * A W3C `traceparent` header has the shape:
10
+ *
11
+ * version "-" trace-id "-" parent-id "-" trace-flags
12
+ * 00 - 32 hex - 16 hex - 2 hex
13
+ *
14
+ * See https://www.w3.org/TR/trace-context/#traceparent-header.
15
+ */
16
+ /**
17
+ * Minimal trace context this service carries on the ambient store and emits on
18
+ * the outbound `traceparent` header.
19
+ */
20
+ export interface ITraceContext {
21
+ /** 32-hex-char trace id, shared by every span across services in one trace. */
22
+ traceId: string;
23
+ /** 16-hex-char span id identifying this service's span within the trace. */
24
+ spanId: string;
25
+ /** Whether the trace is sampled ( low bit of the trace-flags ). */
26
+ sampled: boolean;
27
+ }
28
+ /**
29
+ * Parse & validate an inbound `traceparent` header value.
30
+ *
31
+ * @returns the decomposed parts ( plus the derived `sampled` flag ), or `null`
32
+ * when the value is missing / malformed / forbidden by the spec
33
+ * ( all-zero trace-id, all-zero parent-id, or version `ff` ).
34
+ */
35
+ export declare function parseTraceparent(value: string | undefined | null): {
36
+ version: string;
37
+ traceId: string;
38
+ parentId: string;
39
+ flags: string;
40
+ sampled: boolean;
41
+ } | null;
42
+ /**
43
+ * A fresh random trace id ( 16 bytes -> 32 lowercase hex chars ).
44
+ */
45
+ export declare function randomTraceId(): string;
46
+ /**
47
+ * A fresh random span id ( 8 bytes -> 16 lowercase hex chars ).
48
+ */
49
+ export declare function randomSpanId(): string;
50
+ /**
51
+ * Render a {@link ITraceContext} as a W3C `traceparent` header value.
52
+ */
53
+ export declare function formatTraceparent(ctx: ITraceContext): string;
54
+ /**
55
+ * Derive this service's trace context for a request.
56
+ *
57
+ * When `inboundTraceparent` is a valid header we CONTINUE the trace: the trace
58
+ * id and sampled decision are inherited, and a fresh span id is minted for this
59
+ * service's own span ( its parent being the inbound `parent-id` ). Otherwise a
60
+ * brand-new, sampled trace is STARTED.
61
+ */
62
+ export declare function newTraceContext(inboundTraceparent?: string | null): ITraceContext;
63
+ //# sourceMappingURL=traceparent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceparent.d.ts","sourceRoot":"","sources":["../../src/traceparent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAwBjK;AAgBD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAE5D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,CAejF"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /**
3
+ * W3C Trace Context ( traceparent ) utilities.
4
+ *
5
+ * Pure, dependency-free and cross-platform ( Node 20+ and browsers ) — randomness
6
+ * is sourced from the WHATWG `crypto.getRandomValues`, available on `globalThis`
7
+ * in both environments, so this module deliberately does NOT import
8
+ * `node:crypto` and stays safe to bundle for the browser.
9
+ *
10
+ * A W3C `traceparent` header has the shape:
11
+ *
12
+ * version "-" trace-id "-" parent-id "-" trace-flags
13
+ * 00 - 32 hex - 16 hex - 2 hex
14
+ *
15
+ * See https://www.w3.org/TR/trace-context/#traceparent-header.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.parseTraceparent = parseTraceparent;
19
+ exports.randomTraceId = randomTraceId;
20
+ exports.randomSpanId = randomSpanId;
21
+ exports.formatTraceparent = formatTraceparent;
22
+ exports.newTraceContext = newTraceContext;
23
+ const TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
24
+ const ZERO_TRACE_ID = "00000000000000000000000000000000";
25
+ const ZERO_SPAN_ID = "0000000000000000";
26
+ /**
27
+ * Parse & validate an inbound `traceparent` header value.
28
+ *
29
+ * @returns the decomposed parts ( plus the derived `sampled` flag ), or `null`
30
+ * when the value is missing / malformed / forbidden by the spec
31
+ * ( all-zero trace-id, all-zero parent-id, or version `ff` ).
32
+ */
33
+ function parseTraceparent(value) {
34
+ if (!value) {
35
+ return null;
36
+ }
37
+ const match = TRACEPARENT_RE.exec(value.toLowerCase());
38
+ if (!match) {
39
+ return null;
40
+ }
41
+ const [, version, traceId, parentId, flags] = match;
42
+ // Spec-forbidden values: version ff is reserved, and all-zero ids are invalid.
43
+ if (version === "ff" || traceId === ZERO_TRACE_ID || parentId === ZERO_SPAN_ID) {
44
+ return null;
45
+ }
46
+ return {
47
+ version,
48
+ traceId,
49
+ parentId,
50
+ flags,
51
+ sampled: (parseInt(flags, 16) & 0x01) === 1,
52
+ };
53
+ }
54
+ /**
55
+ * Cross-platform `n` random bytes rendered as lowercase hex.
56
+ */
57
+ function randomHex(bytes) {
58
+ const buffer = new Uint8Array(bytes);
59
+ globalThis.crypto.getRandomValues(buffer);
60
+ let out = "";
61
+ for (const b of buffer) {
62
+ out += b.toString(16).padStart(2, "0");
63
+ }
64
+ return out;
65
+ }
66
+ /**
67
+ * A fresh random trace id ( 16 bytes -> 32 lowercase hex chars ).
68
+ */
69
+ function randomTraceId() {
70
+ return randomHex(16);
71
+ }
72
+ /**
73
+ * A fresh random span id ( 8 bytes -> 16 lowercase hex chars ).
74
+ */
75
+ function randomSpanId() {
76
+ return randomHex(8);
77
+ }
78
+ /**
79
+ * Render a {@link ITraceContext} as a W3C `traceparent` header value.
80
+ */
81
+ function formatTraceparent(ctx) {
82
+ return `00-${ctx.traceId}-${ctx.spanId}-${ctx.sampled ? "01" : "00"}`;
83
+ }
84
+ /**
85
+ * Derive this service's trace context for a request.
86
+ *
87
+ * When `inboundTraceparent` is a valid header we CONTINUE the trace: the trace
88
+ * id and sampled decision are inherited, and a fresh span id is minted for this
89
+ * service's own span ( its parent being the inbound `parent-id` ). Otherwise a
90
+ * brand-new, sampled trace is STARTED.
91
+ */
92
+ function newTraceContext(inboundTraceparent) {
93
+ const parsed = parseTraceparent(inboundTraceparent);
94
+ if (parsed) {
95
+ return {
96
+ traceId: parsed.traceId,
97
+ spanId: randomSpanId(),
98
+ sampled: parsed.sampled,
99
+ };
100
+ }
101
+ return {
102
+ traceId: randomTraceId(),
103
+ spanId: randomSpanId(),
104
+ sampled: true,
105
+ };
106
+ }
107
+ //# sourceMappingURL=traceparent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceparent.js","sourceRoot":"","sources":["../../src/traceparent.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AA0BH,4CAwBC;AAmBD,sCAEC;AAKD,oCAEC;AAKD,8CAEC;AAUD,0CAeC;AA/FD,MAAM,cAAc,GAAG,6DAA6D,CAAC;AACrF,MAAM,aAAa,GAAG,kCAAkC,CAAC;AACzD,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,KAAgC;IAC/D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;IAEpD,+EAA+E;IAC/E,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,aAAa,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO;QACP,OAAO;QACP,QAAQ;QACR,KAAK;QACL,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;KAC5C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa;IAC3B,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY;IAC1B,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,GAAkB;IAClD,OAAO,MAAM,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACxE,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,eAAe,CAAC,kBAAkC;IAChE,MAAM,MAAM,GAAG,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IACpD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,YAAY,EAAE;YACtB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,aAAa,EAAE;QACxB,MAAM,EAAE,YAAY,EAAE;QACtB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { AsyncService, Class } from "@spinajs/di";
2
+ import { Log } from "@spinajs/log-common";
3
+ import { LogArchiveStrategy } from "./archive-strategy.js";
4
+ import { LogRetentionStrategy } from "./retention-strategy.js";
5
+ import { ILogArchiveContext } from "./context.js";
6
+ /**
7
+ * Orchestrates rotation + retention for a single file log target.
8
+ *
9
+ * It owns nothing schedule-wise itself: it resolves ONE rotation strategy
10
+ * ( `archiveStrategy` ) and a LIST of retention strategies
11
+ * ( `retentionStrategies` ) by class name from DI, delegates start / stop to the
12
+ * rotation strategy, and provides the shared `rotate()` routine every rotation
13
+ * ( interval, cron or manual ) funnels through.
14
+ *
15
+ * `@NewInstance()` - each file target gets its own service ( per-target
16
+ * scheduling and strategy state ).
17
+ */
18
+ export declare class LogArchiveService extends AsyncService {
19
+ protected Logger: Log;
20
+ protected ArchiveStrategy: LogArchiveStrategy;
21
+ protected RetentionStrategies: LogRetentionStrategy[];
22
+ /**
23
+ * Resolves the configured rotation + retention strategies by class name.
24
+ * Follows the fs temp-provider mechanism: look the class up in the DI
25
+ * registry by name, then resolve an instance.
26
+ */
27
+ resolve(): Promise<void>;
28
+ /**
29
+ * Wires strategies for the given context and starts the rotation schedule.
30
+ */
31
+ start(ctx: ILogArchiveContext): Promise<void>;
32
+ /**
33
+ * Stops the rotation schedule. Safe to call multiple times.
34
+ */
35
+ stop(): void;
36
+ /**
37
+ * Single rotation routine, shared by every scheduling strategy:
38
+ *
39
+ * 1. acquire the target write-lock so no append runs while we rename,
40
+ * 2. rename the active file to a sequenced archive name in the archive dir,
41
+ * 3. compress ( zip into archiveFs, drop the raw file ) OR move cross-fs,
42
+ * 4. run every retention strategy in order,
43
+ * 5. release the lock ( always, even on failure ).
44
+ *
45
+ * The whole routine is guarded so a failed rotation neither crashes the
46
+ * scheduler nor leaves the lock held.
47
+ */
48
+ rotate(ctx: ILogArchiveContext): Promise<void>;
49
+ /**
50
+ * Renames the active log file into the archive dir under a unique
51
+ * `archived_<name>_<seq><ext>` name. When `archiveFs` differs from `fs` the
52
+ * file is first renamed within `fs` then moved across.
53
+ *
54
+ * Returns the archive path relative to `archiveFs`.
55
+ */
56
+ protected moveToArchive(ctx: ILogArchiveContext): Promise<string>;
57
+ /**
58
+ * Zips `archived` into `archiveFs` and removes the raw archived file, so the
59
+ * archive dir only ever holds the compressed copy.
60
+ */
61
+ protected compress(ctx: ILogArchiveContext, archived: string): Promise<void>;
62
+ /**
63
+ * Next archive sequence number for a given base name. Uses existing archive
64
+ * file names first, falling back to a timestamp so two rotations in the same
65
+ * tick never collide.
66
+ */
67
+ protected nextSequence(ctx: ILogArchiveContext, name: string, ext: string): Promise<number>;
68
+ /**
69
+ * Resolves a strategy instance by class name, mirroring the fs temp-provider
70
+ * mechanism: look the class up in the DI registry by name, then resolve an
71
+ * instance ( `@NewInstance()` gives a fresh per-target instance ).
72
+ */
73
+ protected resolveStrategy<T>(base: Class<T>, className: string): T;
74
+ }
75
+ //# sourceMappingURL=LogArchiveService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogArchiveService.d.ts","sourceRoot":"","sources":["../../../src/archive/LogArchiveService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAiD,MAAM,aAAa,CAAC;AACjG,OAAO,EAAU,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD;;;;;;;;;;;GAWG;AACH,qBAEa,iBAAkB,SAAQ,YAAY;IAEjD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAEtB,SAAS,CAAC,eAAe,EAAE,kBAAkB,CAAC;IAC9C,SAAS,CAAC,mBAAmB,EAAE,oBAAoB,EAAE,CAAM;IAE3D;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;OAEG;IACU,KAAK,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1D;;OAEG;IACI,IAAI,IAAI,IAAI;IAInB;;;;;;;;;;;OAWG;IACU,MAAM,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB3D;;;;;;OAMG;cACa,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBvE;;;OAGG;cACa,QAAQ,CAAC,GAAG,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlF;;;;OAIG;cACa,YAAY,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoCjG;;;;OAIG;IACH,SAAS,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC;CAcnE"}
@@ -0,0 +1,186 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { AsyncService, DI, Injectable, NewInstance, ResolveException } from "@spinajs/di";
11
+ import { Logger, Log } from "@spinajs/log-common";
12
+ import { DateTime } from "luxon";
13
+ import { parse, posix } from "path";
14
+ import { LogArchiveStrategy } from "./archive-strategy.js";
15
+ import { LogRetentionStrategy } from "./retention-strategy.js";
16
+ import { ARCHIVE_PREFIX, archivePath } from "./strategies/util.js";
17
+ /**
18
+ * Orchestrates rotation + retention for a single file log target.
19
+ *
20
+ * It owns nothing schedule-wise itself: it resolves ONE rotation strategy
21
+ * ( `archiveStrategy` ) and a LIST of retention strategies
22
+ * ( `retentionStrategies` ) by class name from DI, delegates start / stop to the
23
+ * rotation strategy, and provides the shared `rotate()` routine every rotation
24
+ * ( interval, cron or manual ) funnels through.
25
+ *
26
+ * `@NewInstance()` - each file target gets its own service ( per-target
27
+ * scheduling and strategy state ).
28
+ */
29
+ let LogArchiveService = class LogArchiveService extends AsyncService {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.RetentionStrategies = [];
33
+ }
34
+ /**
35
+ * Resolves the configured rotation + retention strategies by class name.
36
+ * Follows the fs temp-provider mechanism: look the class up in the DI
37
+ * registry by name, then resolve an instance.
38
+ */
39
+ async resolve() {
40
+ await super.resolve();
41
+ }
42
+ /**
43
+ * Wires strategies for the given context and starts the rotation schedule.
44
+ */
45
+ async start(ctx) {
46
+ // archiveStrategy / retentionStrategies are populated from the logger.file
47
+ // config defaults ( see FileTarget.resolve ), so no inline fallback here -
48
+ // the config is the single source of truth for what runs.
49
+ this.ArchiveStrategy = this.resolveStrategy(LogArchiveStrategy, ctx.options.archiveStrategy);
50
+ const retentionNames = ctx.options.retentionStrategies ?? [];
51
+ this.RetentionStrategies = retentionNames.map((n) => this.resolveStrategy(LogRetentionStrategy, n));
52
+ this.ArchiveStrategy.start(ctx);
53
+ }
54
+ /**
55
+ * Stops the rotation schedule. Safe to call multiple times.
56
+ */
57
+ stop() {
58
+ this.ArchiveStrategy?.stop();
59
+ }
60
+ /**
61
+ * Single rotation routine, shared by every scheduling strategy:
62
+ *
63
+ * 1. acquire the target write-lock so no append runs while we rename,
64
+ * 2. rename the active file to a sequenced archive name in the archive dir,
65
+ * 3. compress ( zip into archiveFs, drop the raw file ) OR move cross-fs,
66
+ * 4. run every retention strategy in order,
67
+ * 5. release the lock ( always, even on failure ).
68
+ *
69
+ * The whole routine is guarded so a failed rotation neither crashes the
70
+ * scheduler nor leaves the lock held.
71
+ */
72
+ async rotate(ctx) {
73
+ await ctx.withWriteLock(async () => {
74
+ // nothing written yet - nothing to rotate
75
+ if (!(await ctx.fs.exists(ctx.activePath))) {
76
+ return;
77
+ }
78
+ const archived = await this.moveToArchive(ctx);
79
+ if (ctx.options.compress) {
80
+ await this.compress(ctx, archived);
81
+ }
82
+ });
83
+ // retention runs OUTSIDE the write-lock - it only touches archive files,
84
+ // never the active log, so it must not block appends.
85
+ for (const strategy of this.RetentionStrategies) {
86
+ await strategy.safePrune(ctx);
87
+ }
88
+ }
89
+ /**
90
+ * Renames the active log file into the archive dir under a unique
91
+ * `archived_<name>_<seq><ext>` name. When `archiveFs` differs from `fs` the
92
+ * file is first renamed within `fs` then moved across.
93
+ *
94
+ * Returns the archive path relative to `archiveFs`.
95
+ */
96
+ async moveToArchive(ctx) {
97
+ const { name, ext } = parse(posix.basename(ctx.activePath.replace(/\\/g, "/")));
98
+ const seq = await this.nextSequence(ctx, name, ext);
99
+ const archiveName = `${ARCHIVE_PREFIX}${name}_${seq}${ext}`;
100
+ const archiveRel = archivePath(ctx, archiveName);
101
+ if (ctx.archiveFs === ctx.fs) {
102
+ await ctx.fs.rename(ctx.activePath, archiveRel);
103
+ return archiveRel;
104
+ }
105
+ // cross-fs: rename to a temp name inside `fs`, then move into archiveFs
106
+ const stagingRel = `${ARCHIVE_PREFIX}${name}_${seq}${ext}`;
107
+ await ctx.fs.rename(ctx.activePath, stagingRel);
108
+ await ctx.fs.move(stagingRel, archiveRel, ctx.archiveFs);
109
+ return archiveRel;
110
+ }
111
+ /**
112
+ * Zips `archived` into `archiveFs` and removes the raw archived file, so the
113
+ * archive dir only ever holds the compressed copy.
114
+ */
115
+ async compress(ctx, archived) {
116
+ const zipRel = `${archived}.zip`;
117
+ // zip() honors a non-temp dstFs / dstFile - output lands directly in archiveFs
118
+ await ctx.archiveFs.zip(archived, ctx.archiveFs, zipRel);
119
+ await ctx.archiveFs.rm(archived);
120
+ this.Logger.trace(`Compressed archive ${archived} -> ${zipRel}`);
121
+ }
122
+ /**
123
+ * Next archive sequence number for a given base name. Uses existing archive
124
+ * file names first, falling back to a timestamp so two rotations in the same
125
+ * tick never collide.
126
+ */
127
+ async nextSequence(ctx, name, ext) {
128
+ let existing = [];
129
+ try {
130
+ existing = await ctx.archiveFs.list(ctx.archiveDir || "/");
131
+ }
132
+ catch {
133
+ existing = [];
134
+ }
135
+ const prefix = `${ARCHIVE_PREFIX}${name}_`;
136
+ // prefix is escaped via escapeRegExp before interpolation
137
+ // eslint-disable-next-line security/detect-non-literal-regexp
138
+ const seqReg = new RegExp(`^${escapeRegExp(prefix)}(\\d+)`);
139
+ let max = 0;
140
+ for (const f of existing) {
141
+ const m = seqReg.exec(f);
142
+ if (m) {
143
+ const n = parseInt(m[1], 10);
144
+ if (n > max) {
145
+ max = n;
146
+ }
147
+ }
148
+ }
149
+ const next = max + 1;
150
+ // guard against a name clash ( eg. same-second cron + size rotation ) by
151
+ // appending a millisecond timestamp only when the computed name already exists
152
+ const candidate = archivePath(ctx, `${ARCHIVE_PREFIX}${name}_${next}${ext}`);
153
+ if (await ctx.archiveFs.exists(candidate)) {
154
+ return DateTime.now().toMillis();
155
+ }
156
+ return next;
157
+ }
158
+ /**
159
+ * Resolves a strategy instance by class name, mirroring the fs temp-provider
160
+ * mechanism: look the class up in the DI registry by name, then resolve an
161
+ * instance ( `@NewInstance()` gives a fresh per-target instance ).
162
+ */
163
+ resolveStrategy(base, className) {
164
+ const types = DI.RootContainer.Registry.getTypes(base);
165
+ const type = types.find((x) => x.name === className);
166
+ if (!type) {
167
+ const baseName = base.name;
168
+ throw new ResolveException(`Log archive strategy ${className} ( ${baseName} ) not registered, make sure it is imported and registered in DI container`);
169
+ }
170
+ // strategies are plain ( non-async ) services, so resolve is synchronous
171
+ return DI.resolve(type);
172
+ }
173
+ };
174
+ __decorate([
175
+ Logger("LogFileTarget"),
176
+ __metadata("design:type", Log)
177
+ ], LogArchiveService.prototype, "Logger", void 0);
178
+ LogArchiveService = __decorate([
179
+ Injectable(),
180
+ NewInstance()
181
+ ], LogArchiveService);
182
+ export { LogArchiveService };
183
+ function escapeRegExp(s) {
184
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
185
+ }
186
+ //# sourceMappingURL=LogArchiveService.js.map