Winston: νƒ€μž„μŠ€νƒ¬ν”„ ν˜•μ‹μ„ μ‚¬μš©μž μ§€μ •ν•˜λŠ” 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

에 λ§Œλ“  2017λ…„ 11μ›” 10일  Β·  18μ½”λ©˜νŠΈ  Β·  좜처: winstonjs/winston

3.0.0-rc1을 μ‚¬μš©ν•˜κ³  있으며 λ¬Έμ„œμ—μ„œ νƒ€μž„μŠ€νƒ¬ν”„ ν˜•μ‹μ„ μ‚¬μš©μž μ§€μ •ν•˜λŠ” 방법에 λŒ€ν•΄ λͺ…ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ„μ™€μ£Όμ„Έμš”.

감사 ν•΄μš”,
μ•Œλ°”λ‘œ

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

이것은 νƒ€μž„μŠ€νƒ¬ν”„(μ–΄μ¨Œλ“  기본값이어야 함)λ₯Ό μΈμ‡„ν•˜λŠ” κ°€μž₯ κ°„λ‹¨ν•œ μš”κ΅¬ 사항에 λŒ€ν•΄ 맀우 λ³΅μž‘ν•©λ‹ˆλ‹€.

λͺ¨λ“  18 λŒ“κΈ€

μ†ŒμŠ€ μ½”λ“œλ₯Ό 읽고 ν˜•μ‹μ„ μ‚¬μš©μž μ •μ˜ν•˜λŠ” 데 도움이 될 수 μžˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” λ‹Ήμ‹ μ—κ²Œ λ‚˜μ˜ 예λ₯Ό 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.

const winston = require('winston');
const moment = require('moment');
const util = require('util');
const MESSAGE = Symbol.for('message');

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
        winston.format(function(info, opts) {
            prefix = util.format('[%s] [%s]', moment().format('YYYY-MM-DD hh:mm:ss').trim(), info.level.toUpperCase());
            if (info.splat) {
                info.message = util.format('%s %s', prefix, util.format(info.message, ...info.splat));
            } else {
                info.message = util.format('%s %s', prefix, info.message);
            }
            return info;
        })(),
        winston.format(function(info) {
            info[MESSAGE] = info.message + ' ' + JSON.stringify(
                Object.assign({}, info, {
                    level: undefined,
                    message: undefined,
                    splat: undefined
                })
            );
            return info;
        })()
    ),
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({ filename: './logs/bitcoin.log' })
    ]
});

이것은 νƒ€μž„μŠ€νƒ¬ν”„(μ–΄μ¨Œλ“  기본값이어야 함)λ₯Ό μΈμ‡„ν•˜λŠ” κ°€μž₯ κ°„λ‹¨ν•œ μš”κ΅¬ 사항에 λŒ€ν•΄ 맀우 λ³΅μž‘ν•©λ‹ˆλ‹€.

μ—¬κΈ° λ‚΄κ°€ ν•˜λŠ” 일이...

//둜거.js

const winston = require('winston');
const moment = require('moment');

// create formatter for dates used as timestamps
//const tsFormat = () => (new Date()).toLocaleTimeString();
const tsFormat = () => moment().format('YYYY-MM-DD hh:mm:ss').trim();

// define a logger with 2 transports - console and a file
const logger = new (winston.Logger)({
  transports: [
    // colorize the output to the console
    new (winston.transports.Console)({
        timestamp: tsFormat,
        colorize: true
    }),
    new winston.transports.File({
        filename: './logs/ttracker.log',
        timestamp: tsFormat,            // makes timestamp 'pretty'
        json: false                 // makes log format just like console output
    })
  ]
});

// set logging level one of { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
logger.level = 'debug';

module.exports = logger;

μΆ”μ‹  : λ‚˜λŠ” timestamp: true, 즉 2017-12-05T08:22:09.179Zλ₯Ό μ„€μ •ν•˜μ—¬ μ–»λŠ” κΈ°λ³Έ ν˜•μ‹μ΄ λ§ˆμŒμ— 듀지 μ•ŠκΈ° λ•Œλ¬Έμ— timestamp: 만 ν•¨μˆ˜λ‘œ μ„€μ •ν–ˆμŠ΅λ‹ˆλ‹€.

@jimwhurr - λ‚˜λ₯Ό μœ„ν•΄ μ½”λ“œ(λ…Έλ“œ v6.11.0)λŠ” λ‹€μŒμ„ μƒμ„±ν•©λ‹ˆλ‹€.

Error: winston.Logger was moved in [email protected].
Use a winston.createLogger instead.
    at new <anonymous> (/Users/adrian/Documents/winston_test/node_modules/winston/lib/winston/common.js:162:15)
    at Object.<anonymous> (/Users/adrian/Documents/winston_test/index.js:7:16)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)

여기에 예제λ₯Ό μ‚¬μš©ν•˜μ—¬ 더 κ°„λ‹¨ν•œ 독립 μ‹€ν–‰ν˜• 예제λ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

https://gist.github.com/ah/d02bd4ff238e5923fcf5369233e51401

const winston = require('winston');
const MESSAGE = Symbol.for('message');

const jsonFormatter = (logEntry) => {
  const base = { timestamp: new Date() };
  const json = Object.assign(base, logEntry)
  logEntry[MESSAGE] = JSON.stringify(json);
  return logEntry;
}

const logger = winston.createLogger({
  level: 'info',
  format: winston.format(jsonFormatter)(),
  transports: new winston.transports.Console(),
});

logger.info('message content', { "context": "index.js", "metric": 1 })
logger.info('message content 2')

μ‚°μΆœ:

{"timestamp":"2017-12-07T16:07:10.518Z","context":"index.js","metric":1,"level":"info","message":"message content"}
{"timestamp":"2017-12-07T16:07:10.520Z","message":"message content 2","level":"info"}

μ•ˆλ…•ν•˜μ„Έμš”, νƒ€μž„μŠ€νƒ¬ν”„λ‘œ λ‘œκΉ…ν•˜λŠ” 또 λ‹€λ₯Έ μ˜΅μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€(3.0.0-rc0μ—μ„œ ν…ŒμŠ€νŠΈ):

const μœˆμŠ€ν„΄ = μš”κ΅¬('μœˆμŠ€ν„΄');
var μ‚¬μš©μž μ •μ˜ ν˜•μ‹ = winston.format.combine(
winston.format(
κΈ°λŠ₯ dynamicContent(정보, μ˜΅μ…˜) {
info.level = '정보';
if(info.time) {
var dt = μƒˆλ‘œμš΄ λ‚ μ§œ(),
date_now = dt.getDate() < 10 ? '0'+ dt.getDate() : dt.getDate(),
month_now = (dt.getMonth() + 1) < 10 ? '0'+ (dt.getMonth() + 1) : (dt.getMonth() + 1),
year_now = dt.getFullYear(),
hrs_now = dt.getHours(),
mins_now = dt.getMinutes(),
secs_now = dt.getSeconds(),
millisec_now = dt.getMilliseconds();
info.time = ' '+date_now+'-'+month_now+'-'+year_now+' '+hrs_now+':'+mins_now+':'+secs_now+':'+millisec_now+' ';
}
정보 λ°˜ν™˜;
}
)(),
winston.format.simple() //좜λ ₯ ν˜•μ‹, μ‚¬μš© κ°€λŠ₯: .json()(.simple λŒ€μ‹ )
);

const 둜거 = winston.createLogger({
레벨: '정보',
ν˜•μ‹: μ‚¬μš©μž 지정 ν˜•μ‹,
μˆ˜μ†‘: [
μƒˆλ‘œμš΄ winston.transports.File({ 파일 이름: 'logs.log' })
]
});
module.exports = 둜거;`

그리고 둜그의 경우:

logger.log({ time: true, level: 'info', message: 'message for logging' });

도움이 될 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

ν˜•μ‹ λ¬Έμžμ—΄λ‘œ νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό μ‚¬μš©μž 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

winston.createLogger({
    level: ...
    format: winston.format.combine(
        winston.format.label({ label: '[my-label]' }),
        winston.format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        winston.format.simple()
    ),
    transports: ...
});
winston.createLogger({
    level: ...
    format: winston.format.combine(
        winston.format.label({ label: '[my-label]' }),
        winston.format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        winston.format.simple()
    ),
    transports: ...
});

이것은 λ¬Έμ„œμ— μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. @felipemullen κ°μ‚¬ν•©λ‹ˆλ‹€!

@felipemullen μƒ˜ν”Œμ„ μ œκ³΅ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. @ricardoaat 에 λ™μ˜ν•©λ‹ˆλ‹€. 이것은 λ¬Έμ„œμ— μžˆμ–΄μ•Ό ν•˜λ―€λ‘œ ... 이제 examples/custom-timestamp.js μž…λ‹ˆλ‹€.

@youngkylejan oh oh..... 도움이 λ˜λ„€...
ν•˜μ§€λ§Œ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€...둜그 끝에 μžˆλŠ” {} λŠ” λ¬΄μ—‡μΈκ°€μš”?

[2018-05-14 04:39:52] [정보] localhost:3000 {}μ—μ„œ μ‹€ν–‰λ˜λŠ” API

μ €λŠ” Winston이 처음이고 λ¬Έμ„œλ₯Ό λ”°λΌν•˜κΈ°κ°€ λ†€λΌμšΈ μ •λ„λ‘œ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

μ–΄λ–»κ²Œ λ“  λ‹€μŒκ³Ό 같이 더 κ°„λ‹¨ν•œ μ†”λ£¨μ…˜μœΌλ‘œ λλ‚¬μŠ΅λ‹ˆλ‹€.

winston.createLogger({
    level: ...
    format: winston.format.printf(info => `${new Date().toISOString()} ${info.message}`),
    transports: ...
});

@hosseinGanjyar
λ³€ν™”
info[MESSAGE] = info.message + ' ' + JSON.stringify(...);
κ·Έλƒ₯
info[MESSAGE] = info.message;

이것은 λ‚˜λ₯Ό μœ„ν•΄ μΌν–ˆμŠ΅λ‹ˆλ‹€.

μ„€μ •:

  • JSON 둜그
  • νƒ€μž„μŠ€νƒ¬ν”„
  • 둜그 νšŒμ „
  • 파일 및 μ½˜μ†” λ‘œκΉ…
import winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';
import fs from 'fs';
import path from 'path';

const LOG_DIR = path.normalize(`${process.cwd()}/logs`);

if (!fs.existsSync(LOG_DIR)) {
  fs.mkdirSync(LOG_DIR);
}

const logger = winston.createLogger({
  exitOnError: false,
  silent: process.env.SUPPRESS_LOGS,
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss',
    }),
    winston.format.json(),
  ),
  transports: [
    new winston.transports.Console(),
    new DailyRotateFile({
      dirname: LOG_DIR,
      filename: '%DATE%.log',
      datePattern: 'YYYY-MM-DD-HH',
      zippedArchive: false,
      maxSize: '1m',
      maxFiles: '14d',
    }),
  ],
});

export default logger;

이것은 λͺ¨λ‘ winston 3.0.0 및 @types/winston 2.3.9μš©μž…λ‹ˆλ‹€.

const consoleFormat = winston.format.printf(info => {
    const d = new Date();
    const timestamp = d.toLocaleTimeString();
    return `${timestamp} ${info.level}: ${info.message}`;

이것은 ν˜„μž¬ μ‹œκ°„λŒ€μ˜ μ‹œκ°„μΈ νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
λ‚΄κ°€ μ‚¬μš©ν•˜λŠ” fileFormat의 경우

const timestamp = `${d.toISOString()} (${d.toLocalTimeString()})`;

κ·Έ λ‹€μŒμ—

const logger = winston.createLogger({
    level: "debug",
    format: fileFormat,
    transports: [ new winston.transports.File({ filename: "yourname.log", level: "debug"}) ]
});

μ•„λ§ˆ 레벨이 두 번 ν•„μš”ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 그것이 λ‚΄κ°€ ν˜„μž¬ μ‚¬μš©ν•˜κ³  μžˆλŠ” κ²ƒμž…λ‹ˆλ‹€.

ν˜•μ‹ λ¬Έμžμ—΄λ‘œ νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό μ‚¬μš©μž 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

winston.createLogger({
    level: ...
    format: winston.format.combine(
        winston.format.label({ label: '[my-label]' }),
        winston.format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        winston.format.simple()
    ),
    transports: ...
});

생λͺ…μ˜ 은인. λ§Žμ€ κ°μ‚¬ν•©λ‹ˆλ‹€!!!

YYYY-MM-DD HH:mm:ss μ΄μ™Έμ˜ ν˜•μ‹ λ¬Έμžμ—΄μ„ μ‚¬μš©μž μ •μ˜ν•˜λŠ” 방법을 μ°ΎκΈ° μœ„ν•΄ 여기에 μžˆλŠ” μ‚¬λžŒλ“€μ„ μœ„ν•΄: winston 은 ν›„λ“œ μ•„λž˜μ—μ„œ fechaλ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ fecha λ¬Έμ„œ λ₯Ό μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ λͺ¨λ“  μ˜ˆλŠ” λ‘œκ·Έμ—μ„œ λ‚˜λ¨Έμ§€ λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€. format.simple()을 μ‚¬μš©ν•˜κ³  μ‹œμž‘ λΆ€λΆ„μ—λ§Œ νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό μΆ”κ°€ν•˜κ³  λ‚˜λ¨Έμ§€μ—μ„œ μ œκ±°ν•˜λ €λŠ” 경우 λ‹€μŒκ³Ό 같이 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const simpleFormat = format.simple()
const MESSAGE = Symbol.for('message')
const simpleTimestamp = format(info => {
  const { timestamp, ...rest } = info
  const simpled = simpleFormat.transform(rest)
  if (typeof simpled !== 'boolean') {
    // @ts-ignore
    simpled[MESSAGE] = `${timestamp} ${simpled[MESSAGE]}`
  }
  return simpled
})

logger.add(new transports.Console({
  format: format.combine(
      format.timestamp(),
      format.colorize(),
      simpleTimestamp(),
  ),
}))
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰