Winston: Usulan penanganan info[SPLAT]

Dibuat pada 12 Jul 2018  ·  4Komentar  ·  Sumber: winstonjs/winston

Apa fiturnya?

Ini adalah proposal untuk penanganan objek yang berbeda (JSON/array/lainnya) untuk kasus penggunaan yang lebih fleksibel.

Singkatnya, proposal ini mencakup dua hal.

  1. Pisahkan parsing info.meta dari logform.splat
  2. Buat transformasi baru yang memindahkan objek ke options.meta

Masalah apa yang ingin dipecahkan oleh fitur tersebut?

Berbagai pengguna (misalnya #1377, #1381, saya sendiri) telah mencatat bahwa perlakuan objek/array berbeda di V3 dari V2. Di V2 jenis objek ini akan disimpan di bidang options.meta dan dapat diproses secara terpisah dari pesan dan level dan objek.

Di V3, hanya ada satu skenario/transformasi di mana options.meta diproses sama seperti di V2. Ini adalah saat menggunakan transformasi logform.splat. Splat akan mengurai meta dengan benar hanya ketika token ada di log. MISALNYA:
logger.log('info', 'this is a string I want to splat %s', 'together', {an: 'object'})
akan menghasilkan:
info: this is a string I want to splat together {"meta":{"an":"object"}} // with .simple() transform

Jika pengguna tidak ingin menggunakan logform.splat, info.meta tidak akan diproses. Sebagai gantinya, objek meta tidak akan tersentuh di info[SPLAT].

Menambahkan formulir log yang menyalin semua info[SPLAT] ke info[meta] akan memenuhi harapan pengguna V2 dan menjadi lebih fleksibel. (Atau, langsung menambahkan info[SPLAT] ke output logger dan memberikan dokumentasi pada info[meta] => info[SPLAT] dapat diterima.)

Transformasi baru (misalnya logform.captureAllMeta hanya untuk penamaan) bisa sesederhana:

// file captureAllMeta.js psuedo-code

module.exports = transform((info, opts) => {
  if (info[SPLAT]) {
    info.meta = info[SPLAT]
  return info;
});

Setara dengan

format.combine(
        format.splat(),
        ...
    )

akan menjadi

format.combine(
        format.splat(),
        format.captureAllMeta(),
        ...
        // still need to have a formatter for options.meta.  maybe a separate feature request.
    )

Kode extraSplat dapat dihapus dari splat() karena ditangani dalam transformasi (baru) berikutnya.

Manfaat tambahan adalah jika pengguna tidak ingin menggunakan format.splat(), mereka masih dapat menyertakan format.captureAllMeta() sebagai transformasi mandiri.

Apakah ketiadaan fitur ini menghalangi Anda atau tim Anda? Jika demikian, bagaimana?

Sekarang mengetahui bahwa info[SPLAT] menyimpan apa yang hilang dalam info[meta], ini dapat dianggap sebagai kesenjangan pengetahuan/dokumentasi.

Apakah fitur ini mirip dengan fitur yang ada di alat lain?

Memperluas kompatibilitas V2 ke V3.

Apakah ini fitur yang siap Anda terapkan, dengan dukungan dari kami?

Ya, saya bisa melakukan yang terbaik untuk mendukung ini.

Untuk mereproduksi masalah

  • _ winston versi?_

    • [ ] winston@2

    • [X] winston@3

  • _ node -v keluaran:_ 6.10.0
  • _Sistem Operasi?_ (Windows, macOS, atau Linux) Ada
  • _Bahasa?_ (semua | TypeScript XX | ES6/7 | ES5 | Dart) semua

Apa masalahnya?

Berikut adalah contoh kode transport V2 dengan output:

        logger = winston.createLogger({
            transports: [
                new (winston.transports.Console)({
                    timestamp: function () {
                        return dateFormat(Date.now(), "HH:MM:ss.l");
                    },
                    formatter: function (options) {
                        // Return string will be passed to logger.
                        return options.timestamp() + ' ' + winston.config.colorize(options.level, options.level.toUpperCase()) + ' ' + (undefined !== options.message ? options.message : '') +
                            (options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : '');
                    },
                    colorize: true,
                    level: container.settings.get('logLevel') || 'info',
                    stderrLevels: [],
                    handleExceptions: true,
                    humanReadableUnhandledException: true
                })
            ]
        });


// results of Winston<strong i="33">@2</strong>
08:31:30.363 DEBUG Server starting complete.
        ["Server https started.","Server http started.","Server SSDP started.","Server MDNS started."]

Di V3, saya mencoba mereplikasi ini dengan kode berikut, tetapi hasilnya tidak menampilkan array.

    const processObj = logform.format(info => {
             console.log('raw: ', raw)
            return info
        }
    )

    const myFormat = printf(info => {
        info.timestamp = dateFormat(Date.now(), "m/d/yy HH:MM:ss.l")
        return `${info.timestamp} ${info.level}: ${info.message}`;
    });

        logger = createLogger({
            level: container.settings.get('logLevel') || 'info',
            format: combine(
                processObj(),
                format.json(),
                timestamp({format: () => new Date().toLocaleString()}),
                format.colorize(),
                format.align(),
                format.splat(),
                myFormat
            ),
            transports: [new transports.Console()]
        });
        logger.exceptions.handle()
        logger.exitOnError = false;

results = [ 'Not starting https server.', 'Server http started.', 'Server SSDP started.', 'Server MDNS started.']
logger.debug('Server status', results)

// results of winston<strong i="6">@3</strong> -- missing the results array
6/25/18 08:16:30.501 debug:     Server starting complete.
investigate

Komentar yang paling membantu

Jadi saya baru menyadari bahwa menggunakan format.splat() memang menambahkan objek meta ke info, TETAPI hanya jika Anda juga menggunakan interpolasi. Jika Anda tidak menggunakan interpolasi, meta hanya dicampur ke dalam objek info.

Juga saat menggunakan interpolasi dan meta, format.simple() mengeluarkan meta sebagai {meta:{METAOBJ}} bukan hanya {METAOBJ} seperti v2.

Semua 4 komentar

Saya mengerjakan ini tadi malam dan membuat cabang dengan kode yang mengimplementasikan hal di atas. Beri tahu saya jika Anda ingin saya membuat PR di Logform untuk ini.

Berikut adalah file tes yang saya gunakan ...

'use strict';

const winston = require('winston');
const logform = require('logform')
const {SPLAT} = require('triple-beam');


const {createLogger, format, transports} = require('winston');
var logger = createLogger({
    format: format.combine(

        format.splat()
        , format.captureAllMeta()
        ,
        logform.format.printf(info => {

            // return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;
            if ((!info.meta.length)) {
                return (`${info.level}: ${info.message}`);

            }
            else {
                return (`${info.level}: ${info.message}\n\t${JSON.stringify(info.meta)}`);

            }
        })
    ),
    transports: [new transports.Console()]
});


let count = 1

logger.log('info', count + '. this is a string I want to splat %s', 'together', {an: 'object'})
count += 1
console.log('---')

logger.log('info', count + '.this is a string followed by an object and an array', {an: 'object'}, ['an', 'array'])
count += 1
console.log('---')

logger.log('info', count + '.this is a string followed by an object and an array', ['an', 'array'], {an: 'object'})
count += 1
console.log('---')


logger.log('info', count + '. string followed by', 'a string')
console.log('---')
count += 1

logger.log('info', count + '. string followed by 2', 'separate', 'strings')
console.log('---')
count += 1

logger.log('info', count + '. string followed by', {an: 'object'})
console.log('---')
count += 1

logger.log('info', count + '. string followed by 2', {an: 'object'}, ['an', 'array'])
console.log('---')
count += 1

logger.log('info', count + '. string with token followed by string %s', 'string')
console.log('---')
count += 1

logger.log('info', count + '. string with token followed by obj %j', {idunno: 'notsure'})
console.log('---')
count += 1

logger.log('info', count + '. string with token followed by string %s and then objects', 'or here', {an: 'object'}, ['i', 'am', 'missed'])
console.log('---')
count += 1

logger.log('info', count + '. string with two tokens %s %s followed by one ', 'string')
console.log('---')
count += 1

logger.log('info', count + '. string with two tokens %s %j followed by one string and one object', 'string', {an: 'object'}, [1,2,3])
count += 1
console.log('---')


logger.info({message: 'just an object', [SPLAT]: {more:'stuff'}})
count += 1
console.log('---')

logger.info(['an','array'])
count += 1
console.log('---')

logger.info(['an','array',{with:'object'}])
count += 1
console.log('---')


logger.log({
    level: 'info',
    message: '%d: The answer to life, the universe and everything',
    splat: [42]
})
count += 1
console.log('---')

logger.log({
    level: 'info',
    message: '%d: The answer to life, the universe and everything',
    splat: [43],
    [Symbol.for('splat')]: [44]
})
count += 1
console.log('---')

logger.log({
    level: 'info',
    message: '%d: The answer to life, the universe and everything'
})
count += 1
console.log('---')

dengan output berikut...

info: 1. this is a string I want to splat together
    [{"an":"object"}]
---
info: 2.this is a string followed by an object and an array
    [{"an":"object"},["an","array"]]
---
info: 3.this is a string followed by an object and an array
    [["an","array"],{"an":"object"}]
---
info: 4. string followed by
    ["a string"]
---
info: 5. string followed by 2
    ["separate","strings"]
---
info: 6. string followed by
    [{"an":"object"}]
---
info: 7. string followed by 2
    [{"an":"object"},["an","array"]]
---
info: 8. string with token followed by string string
---
info: 9. string with token followed by obj {"idunno":"notsure"}
---
info: 10. string with token followed by string or here and then objects
    [{"an":"object"},["i","am","missed"]]
---
info: 11. string with two tokens string %s followed by one
---
info: 12. string with two tokens string {"an":"object"} followed by one string and one object
    [[1,2,3]]
---
info: just an object
    [{"more":"stuff"}]
---
info: an,array
---
info: an,array,[object Object]  // expected... no %j token
---
info: 42: The answer to life, the universe and everything
---
info: 44: The answer to life, the universe and everything
---
info: %d: The answer to life, the universe and everything
---

Menambahkan dukungan ke kode saya untuk info.splat selain info[SPLAT].

Sesuatu seperti ini diperlukan. Pada dasarnya, jika Anda tidak dapat meningkatkan ke v3 tanpa menyentuh pernyataan log yang ada, DAN bisa mendapatkan meta sebagai objek TERPISAH SETELAH interpolasi, maka v3 adalah non-starter untuk sebagian besar pengguna yang keluar. Saya tidak tahu mengapa ada orang yang berpikir bahwa menggabungkan level, pesan, dan meta menjadi satu objek besar adalah ide yang bagus. Sudah matang untuk konflik. info[Symbol.for('splat)] juga tidak dapat diandalkan karena akan menggabungkan nilai interpolasi dan meta bersama-sama. Kami ingin meta TERPISAH.

Jadi saya baru menyadari bahwa menggunakan format.splat() memang menambahkan objek meta ke info, TETAPI hanya jika Anda juga menggunakan interpolasi. Jika Anda tidak menggunakan interpolasi, meta hanya dicampur ke dalam objek info.

Juga saat menggunakan interpolasi dan meta, format.simple() mengeluarkan meta sebagai {meta:{METAOBJ}} bukan hanya {METAOBJ} seperti v2.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat