333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
'use strict';
 
const ChildProcess = require('child_process').ChildProcess;
const Console = require('console').Console;
const through = require('through2');
const split = require('split2');
const pumpify = require('pumpify');
 
 
const defaults = {
  stdout: process.stdout,
  stderr: process.stderr,
  prefix: '',
  time: true,
};
 
/**
 * log/debug/info -> this.stdout(pad) -> opt.stdout
 * warn/error -> this.stderr(pad) -> opt.stderr
 */
class Logger extends Console {
 
  constructor(options) {
    options = Object.assign({}, defaults, options);
    const stdout = padStream(() => this._getPrefix());
    const stderr = padStream(() => this._getPrefix());
    super(stdout, stderr);
 
    this.stdout = stdout;
    this.stderr = stderr;
    this.options = options;
 
    stdout.setMaxListeners(100);
    stderr.setMaxListeners(100);
    stdout.pipe(options.stdout);
    stderr.pipe(options.stderr);
  }
 
  child(obj, prefix) {
    // child('> ')
    if (typeof obj === 'string') {
      prefix = obj;
      obj = null;
    }
 
    // obj -> child.stdout/stderr(pad) -> this.stdout/stderr(pad) -> opt.stdout
    const child = new Logger({
      stdout: this.stdout,
      stderr: this.stderr,
      time: false,
      prefix: prefix || '',
    });
 
    if (obj) {
      if (obj instanceof ChildProcess) {
        obj.stdout.pipe(child.stdout, { end: false });
        obj.stderr.pipe(child.stderr, { end: false });
      } else if (obj.pipe) {
        obj.pipe(child.stdout, { end: false });
      }
    }
 
    return child;
  }
 
  end() {
    this.stdout.end();
    this.stderr.end();
  }
 
  _getPrefix() {
    let prefix = this.options.prefix;
    if (typeof prefix === 'function') {
      prefix = prefix();
    }
    if (!this.options.time) return prefix;
    const d = new Date();
    let hours = d.getHours();
    if (hours < 10) {
      hours = '0' + hours;
    }
    let mintues = d.getMinutes();
    if (mintues < 10) {
      mintues = '0' + mintues;
    }
    let seconds = d.getSeconds();
    if (seconds < 10) {
      seconds = '0' + seconds;
    }
    return `[${hours}:${mintues}:${seconds}] ${prefix}`;
  }
 
}
 
module.exports = Logger;
 
function padStream(prefix) {
  return pumpify(split(), through(function(data, enc, cb) {
    this.push(prefix());
    this.push(data);
    this.push('\n');
    cb();
  }));
}