@nx-ddd/logging 19.42.0 → 19.44.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.
@@ -3,6 +3,35 @@ import { BaseLogger, LogLevel, LOGGER } from '@nx-ddd/logging/base';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable } from '@angular/core';
5
5
 
6
+ /**
7
+ * `process.stdout` / `process.stderr` の write を wrap し、書き込み内容を
8
+ * `stream` にも tee する。foreground 起動時に `console.log` 直書きを含む
9
+ * 全 stdout/stderr 出力をログファイルへ流すために使う。
10
+ *
11
+ * 戻り値の `restore()` で元の write 関数に戻せる。
12
+ */
13
+ function pipeStdioToStream(stream) {
14
+ // bind すると同一性比較 (process.stdout.write === origStdoutWrite) が壊れるので、
15
+ // 元の参照をそのまま保持し、wrap 内で apply(thisArg, args) で this を補う
16
+ const origStdoutWrite = process.stdout.write;
17
+ const origStderrWrite = process.stderr.write;
18
+ const wrap = (orig, thisArg) => ((...args) => {
19
+ try {
20
+ stream.write(args[0]);
21
+ }
22
+ catch {
23
+ // ファイル書き込みエラーは黙殺し、stdio 出力を妨げない
24
+ }
25
+ return orig.apply(thisArg, args);
26
+ });
27
+ process.stdout.write = wrap(origStdoutWrite, process.stdout);
28
+ process.stderr.write = wrap(origStderrWrite, process.stderr);
29
+ return () => {
30
+ process.stdout.write = origStdoutWrite;
31
+ process.stderr.write = origStderrWrite;
32
+ };
33
+ }
34
+
6
35
  /**
7
36
  * TeeLogger - ファイルとコンソール両方にログを出力(BaseLogger継承版)
8
37
  *
@@ -16,9 +45,15 @@ import { Injectable } from '@angular/core';
16
45
  class TeeLogger extends BaseLogger {
17
46
  logStream = null;
18
47
  enableConsoleOutput = true;
48
+ restoreStdio = null;
49
+ pipeStdioActive = false;
19
50
  initialize(logFilePath, forceConsole = false, options) {
20
51
  this.logStream = fs.createWriteStream(logFilePath, { flags: 'a' });
21
52
  this.enableConsoleOutput = forceConsole || !options?.isE2e;
53
+ this.pipeStdioActive = options?.pipeStdio === true;
54
+ if (this.pipeStdioActive) {
55
+ this.restoreStdio = pipeStdioToStream(this.logStream);
56
+ }
22
57
  }
23
58
  log(level, message) {
24
59
  const levelStr = LogLevel[level] ?? 'LOG';
@@ -29,12 +64,18 @@ class TeeLogger extends BaseLogger {
29
64
  : console.log;
30
65
  method(`[${time}][${levelStr}] ${message}`);
31
66
  }
32
- if (this.logStream) {
67
+ // pipeStdio mode は console.* → stdio pipe 経由でファイル書き込みされるため、
68
+ // logStream への直接 JSON write は省略して 2 重書き込みを回避する
69
+ if (this.logStream && !this.pipeStdioActive) {
33
70
  const ts = new Date().toISOString();
34
71
  this.logStream.write(JSON.stringify({ ts, lvl: levelStr, msg: message }) + '\n');
35
72
  }
36
73
  }
37
74
  close() {
75
+ if (this.restoreStdio) {
76
+ this.restoreStdio();
77
+ this.restoreStdio = null;
78
+ }
38
79
  if (this.logStream) {
39
80
  this.logStream.end();
40
81
  this.logStream = null;
@@ -57,5 +98,5 @@ function provideTeeLogger() {
57
98
  * Generated bundle index. Do not edit.
58
99
  */
59
100
 
60
- export { TeeLogger, provideTeeLogger };
101
+ export { TeeLogger, pipeStdioToStream, provideTeeLogger };
61
102
  //# sourceMappingURL=nx-ddd-logging-tee.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nx-ddd-logging-tee.mjs","sources":["../../../../../packages/@nx-ddd/logging/src/lib/tee/tee.logger.ts","../../../../../packages/@nx-ddd/logging/src/lib/tee/nx-ddd-logging-tee.ts"],"sourcesContent":["import * as fs from 'fs';\nimport { BaseLogger, LOGGER, LogLevel } from '@nx-ddd/logging/base';\nimport { Injectable, Provider } from '@angular/core';\n\n/**\n * TeeLogger - ファイルとコンソール両方にログを出力(BaseLogger継承版)\n *\n * BaseLoggerを継承することでLoggingServiceのmulti-providerチェーンに統合可能。\n * console.logのオーバーライドを廃止し、正規のLoggingService経由でログレベルを保持する。\n *\n * - initialize() なし: コンソールのみ出力(ConsoleLogger と同等)\n * - initialize(logFile): コンソール + ファイル出力\n * - E2E 時は FileLogger を使用するため、TeeLogger は常にコンソール出力が有効\n */\n@Injectable()\nexport class TeeLogger extends BaseLogger {\n private logStream: fs.WriteStream | null = null;\n private enableConsoleOutput = true;\n\n initialize(logFilePath: string, forceConsole = false, options?: { isE2e?: boolean }): void {\n this.logStream = fs.createWriteStream(logFilePath, { flags: 'a' });\n this.enableConsoleOutput = forceConsole || !options?.isE2e;\n }\n\n log(level: LogLevel, message: string): void {\n const levelStr = LogLevel[level] ?? 'LOG';\n\n if (this.enableConsoleOutput) {\n const time = new Date().toTimeString().slice(0, 8);\n const method = level >= LogLevel.ERROR ? console.error\n : level >= LogLevel.WARN ? console.warn\n : console.log;\n method(`[${time}][${levelStr}] ${message}`);\n }\n\n if (this.logStream) {\n const ts = new Date().toISOString();\n this.logStream.write(JSON.stringify({ ts, lvl: levelStr, msg: message }) + '\\n');\n }\n }\n\n close(): void {\n if (this.logStream) {\n this.logStream.end();\n this.logStream = null;\n }\n }\n}\n\nexport function provideTeeLogger(): Provider[] {\n return [\n { provide: TeeLogger, useClass: TeeLogger },\n { provide: LOGGER, multi: true, useExisting: TeeLogger },\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAIA;;;;;;;;;AASG;AAEG,MAAO,SAAU,SAAQ,UAAU,CAAA;IAC/B,SAAS,GAA0B,IAAI;IACvC,mBAAmB,GAAG,IAAI;AAElC,IAAA,UAAU,CAAC,WAAmB,EAAE,YAAY,GAAG,KAAK,EAAE,OAA6B,EAAA;AACjF,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,iBAAiB,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAClE,IAAI,CAAC,mBAAmB,GAAG,YAAY,IAAI,CAAC,OAAO,EAAE,KAAK;IAC5D;IAEA,GAAG,CAAC,KAAe,EAAE,OAAe,EAAA;QAClC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK;AAEzC,QAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE;AAC5B,YAAA,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AAClD,YAAA,MAAM,MAAM,GAAG,KAAK,IAAI,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC;kBAClC,KAAK,IAAI,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC;AACnC,sBAAE,OAAO,CAAC,GAAG;YAC1B,MAAM,CAAC,IAAI,IAAI,CAAA,EAAA,EAAK,QAAQ,CAAA,EAAA,EAAK,OAAO,CAAA,CAAE,CAAC;QAC7C;AAEA,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;QAClF;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;AACpB,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;QACvB;IACF;uGA/BW,SAAS,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAT,SAAS,EAAA,CAAA;;2FAAT,SAAS,EAAA,UAAA,EAAA,CAAA;kBADrB;;SAmCe,gBAAgB,GAAA;IAC9B,OAAO;AACL,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE;QAC3C,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE;KACzD;AACH;;ACtDA;;AAEG;;;;"}
1
+ {"version":3,"file":"nx-ddd-logging-tee.mjs","sources":["../../../../../packages/@nx-ddd/logging/src/lib/tee/pipe-stdio.ts","../../../../../packages/@nx-ddd/logging/src/lib/tee/tee.logger.ts","../../../../../packages/@nx-ddd/logging/src/lib/tee/nx-ddd-logging-tee.ts"],"sourcesContent":["import type * as fs from 'fs';\n\nexport type RestoreStdioFn = () => void;\n\ntype WriteFn = typeof process.stdout.write;\n\n/**\n * `process.stdout` / `process.stderr` の write を wrap し、書き込み内容を\n * `stream` にも tee する。foreground 起動時に `console.log` 直書きを含む\n * 全 stdout/stderr 出力をログファイルへ流すために使う。\n *\n * 戻り値の `restore()` で元の write 関数に戻せる。\n */\nexport function pipeStdioToStream(stream: fs.WriteStream): RestoreStdioFn {\n // bind すると同一性比較 (process.stdout.write === origStdoutWrite) が壊れるので、\n // 元の参照をそのまま保持し、wrap 内で apply(thisArg, args) で this を補う\n const origStdoutWrite = process.stdout.write as WriteFn;\n const origStderrWrite = process.stderr.write as WriteFn;\n\n const wrap = (orig: WriteFn, thisArg: NodeJS.WriteStream): WriteFn =>\n ((...args: unknown[]) => {\n try {\n stream.write(args[0] as Parameters<typeof stream.write>[0]);\n } catch {\n // ファイル書き込みエラーは黙殺し、stdio 出力を妨げない\n }\n return (orig as (...a: unknown[]) => boolean).apply(thisArg, args);\n }) as WriteFn;\n\n process.stdout.write = wrap(origStdoutWrite, process.stdout);\n process.stderr.write = wrap(origStderrWrite, process.stderr);\n\n return () => {\n process.stdout.write = origStdoutWrite;\n process.stderr.write = origStderrWrite;\n };\n}\n","import * as fs from 'fs';\nimport { BaseLogger, LOGGER, LogLevel } from '@nx-ddd/logging/base';\nimport { Injectable, Provider } from '@angular/core';\nimport { pipeStdioToStream, RestoreStdioFn } from './pipe-stdio';\n\n/**\n * TeeLogger - ファイルとコンソール両方にログを出力(BaseLogger継承版)\n *\n * BaseLoggerを継承することでLoggingServiceのmulti-providerチェーンに統合可能。\n * console.logのオーバーライドを廃止し、正規のLoggingService経由でログレベルを保持する。\n *\n * - initialize() なし: コンソールのみ出力(ConsoleLogger と同等)\n * - initialize(logFile): コンソール + ファイル出力\n * - E2E 時は FileLogger を使用するため、TeeLogger は常にコンソール出力が有効\n */\n@Injectable()\nexport class TeeLogger extends BaseLogger {\n private logStream: fs.WriteStream | null = null;\n private enableConsoleOutput = true;\n private restoreStdio: RestoreStdioFn | null = null;\n private pipeStdioActive = false;\n\n initialize(\n logFilePath: string,\n forceConsole = false,\n options?: { isE2e?: boolean; pipeStdio?: boolean },\n ): void {\n this.logStream = fs.createWriteStream(logFilePath, { flags: 'a' });\n this.enableConsoleOutput = forceConsole || !options?.isE2e;\n this.pipeStdioActive = options?.pipeStdio === true;\n if (this.pipeStdioActive) {\n this.restoreStdio = pipeStdioToStream(this.logStream);\n }\n }\n\n log(level: LogLevel, message: string): void {\n const levelStr = LogLevel[level] ?? 'LOG';\n\n if (this.enableConsoleOutput) {\n const time = new Date().toTimeString().slice(0, 8);\n const method = level >= LogLevel.ERROR ? console.error\n : level >= LogLevel.WARN ? console.warn\n : console.log;\n method(`[${time}][${levelStr}] ${message}`);\n }\n\n // pipeStdio mode は console.* → stdio pipe 経由でファイル書き込みされるため、\n // logStream への直接 JSON write は省略して 2 重書き込みを回避する\n if (this.logStream && !this.pipeStdioActive) {\n const ts = new Date().toISOString();\n this.logStream.write(JSON.stringify({ ts, lvl: levelStr, msg: message }) + '\\n');\n }\n }\n\n close(): void {\n if (this.restoreStdio) {\n this.restoreStdio();\n this.restoreStdio = null;\n }\n if (this.logStream) {\n this.logStream.end();\n this.logStream = null;\n }\n }\n}\n\nexport function provideTeeLogger(): Provider[] {\n return [\n { provide: TeeLogger, useClass: TeeLogger },\n { provide: LOGGER, multi: true, useExisting: TeeLogger },\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx-ddd/logging",
3
- "version": "19.42.0",
3
+ "version": "19.44.0",
4
4
  "license": "MIT",
5
5
  "peerDependencies": {
6
6
  "@angular/core": "19.1.4"
@@ -1,6 +1,7 @@
1
1
  import { BaseLogger, LogLevel } from '@nx-ddd/logging/base';
2
2
  import * as i0 from '@angular/core';
3
3
  import { Provider } from '@angular/core';
4
+ import * as fs from 'fs';
4
5
 
5
6
  /**
6
7
  * TeeLogger - ファイルとコンソール両方にログを出力(BaseLogger継承版)
@@ -15,8 +16,11 @@ import { Provider } from '@angular/core';
15
16
  declare class TeeLogger extends BaseLogger {
16
17
  private logStream;
17
18
  private enableConsoleOutput;
19
+ private restoreStdio;
20
+ private pipeStdioActive;
18
21
  initialize(logFilePath: string, forceConsole?: boolean, options?: {
19
22
  isE2e?: boolean;
23
+ pipeStdio?: boolean;
20
24
  }): void;
21
25
  log(level: LogLevel, message: string): void;
22
26
  close(): void;
@@ -25,5 +29,16 @@ declare class TeeLogger extends BaseLogger {
25
29
  }
26
30
  declare function provideTeeLogger(): Provider[];
27
31
 
28
- export { TeeLogger, provideTeeLogger };
32
+ type RestoreStdioFn = () => void;
33
+ /**
34
+ * `process.stdout` / `process.stderr` の write を wrap し、書き込み内容を
35
+ * `stream` にも tee する。foreground 起動時に `console.log` 直書きを含む
36
+ * 全 stdout/stderr 出力をログファイルへ流すために使う。
37
+ *
38
+ * 戻り値の `restore()` で元の write 関数に戻せる。
39
+ */
40
+ declare function pipeStdioToStream(stream: fs.WriteStream): RestoreStdioFn;
41
+
42
+ export { TeeLogger, pipeStdioToStream, provideTeeLogger };
43
+ export type { RestoreStdioFn };
29
44
  //# sourceMappingURL=nx-ddd-logging-tee.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nx-ddd-logging-tee.d.ts","sources":["../../../../../packages/@nx-ddd/logging/src/lib/tee/tee.logger.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAIA;;;;;;;;;AASG;AACH,cAAA,SAAA,SAAA,UAAA;;;;;AAKqF;;AAsBnF;;;AAMD;AAED,iBAAA,gBAAA,IAAA,QAAA;;;;"}
1
+ {"version":3,"file":"nx-ddd-logging-tee.d.ts","sources":["../../../../../packages/@nx-ddd/logging/src/lib/tee/tee.logger.ts","../../../../../packages/@nx-ddd/logging/src/lib/tee/pipe-stdio.ts"],"sourcesContent":[null,null],"names":[],"mappings":";;;;;AAKA;;;;;;;;;AASG;AACH;;;;;;;;AAUsD;;AA6BpD;;;AAUD;AAED;;AChEM;AAIN;;;;;;AAMG;AACH;;;"}