Winston: Vorgeschlagener Umgang mit info[SPLAT]

Erstellt am 12. Juli 2018  ·  4Kommentare  ·  Quelle: winstonjs/winston

Was ist die Funktion?

Dies ist ein Vorschlag für eine andere Behandlung von Objekten (JSON/Array/andere) für vielseitigere Anwendungsfälle.

Kurz gesagt, dieser Vorschlag deckt zwei Dinge ab.

  1. Teilen Sie das info.meta-Parsing von logform.splat auf
  2. Erstellen Sie eine neue Transformation, die Objekte in options.meta verschiebt

Welches Problem soll die Funktion lösen?

Verschiedene Benutzer (zB #1377, #1381, ich selbst) haben festgestellt, dass die Behandlung von Objekten/Arrays in V3 anders ist als in V2. In V2 würden diese Objekttypen im options.meta -Feld gespeichert und könnten getrennt von der Nachricht, Ebene und Objekten verarbeitet werden.

In V3 gibt es nur ein Szenario/eine Transformation, in der options.meta genauso verarbeitet wird wie in V2. Dies ist der Fall, wenn die logform.splat-Transformation verwendet wird. Splat analysiert Meta nur dann korrekt, wenn ein Token im Protokoll vorhanden ist. Z.B:
logger.log('info', 'this is a string I want to splat %s', 'together', {an: 'object'})
wird darin enden, dass:
info: this is a string I want to splat together {"meta":{"an":"object"}} // with .simple() transform

Wenn Benutzer logform.splat nicht verwenden möchten, wird info.meta nicht verarbeitet. Stattdessen werden die Metaobjekte in info[SPLAT] unberührt gelassen.

Das Hinzufügen eines Protokollformulars, das alle info[SPLAT] nach info[meta] kopiert, wird sowohl die Erwartungen von V2-Benutzern erfüllen als auch flexibler sein. (Alternativ könnte das direkte Hinzufügen von info[SPLAT] zur Loggerausgabe und das Bereitstellen von Dokumentation zu info[meta] => info[SPLAT] akzeptabel sein.)

Eine neue Transformation (z. B. logform.captureAllMeta, nur um der Namensgebung willen) könnte so einfach sein wie:

// file captureAllMeta.js psuedo-code

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

Das Äquivalent von

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

würde werden

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

Der extraSplat -Code könnte aus splat() entfernt werden, da er in der nachfolgenden (neuen) Transformation behandelt wird.

Ein zusätzlicher Vorteil besteht darin, dass Benutzer, die format.splat() nicht verwenden möchten, immer noch format.captureAllMeta() als eigenständige Transformation einschließen können.

Blockiert das Fehlen dieser Funktion Sie oder Ihr Team? Wenn das so ist, wie?

Jetzt wissend, dass info[SPLAT] speichert, was in info[meta] fehlt, könnte dies als Wissens-/Dokumentationslücke angesehen werden.

Ist diese Funktion einer vorhandenen Funktion in einem anderen Tool ähnlich?

Erweitert die Kompatibilität von V2 auf V3.

Ist dies eine Funktion, die Sie mit Unterstützung von uns implementieren möchten?

Ja, ich kann mein Bestes tun, um dies zu unterstützen.

Um das Problem zu reproduzieren

  • _ winston -Version?_

    • [ ] winston@2

    • [X] winston@3

  • _ node -v Ausgaben:_ 6.10.0
  • _Betriebssystem?_ (Windows, macOS oder Linux) Beliebig
  • _Sprache?_ (alle | TypeScript XX | ES6/7 | ES5 | Dart) alle

Was ist das Problem?

Hier ist ein Beispiel für einen V2-Transportcode mit Ausgabe:

        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."]

In V3 habe ich versucht, dies mit dem folgenden Code zu replizieren, aber das Ergebnis zeigte das Array nicht an.

    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

Hilfreichster Kommentar

Also habe ich gerade festgestellt, dass die Verwendung von format.splat() den Informationen ein Metaobjekt hinzufügt, ABER nur, wenn Sie auch Interpolation verwendet haben. Wenn Sie keine Interpolation verwenden, wird das Meta nur in das Info-Objekt gemischt.

Auch bei Verwendung von Interpolation und Meta gibt format.simple() das Meta als {meta:{METAOBJ}} statt nur als {METAOBJ} wie v2 aus.

Alle 4 Kommentare

Ich habe letzte Nacht daran gearbeitet und einen Zweig mit Code erstellt, der das Obige implementiert. Lassen Sie mich wissen, wenn Sie möchten, dass ich dafür eine PR in Logform erstelle.

Hier ist eine Testdatei, die ich verwendet habe ...

'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('---')

mit folgenden Ausgaben...

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
---

Unterstützung für meinen Code für info.splat zusätzlich zu info[SPLAT] hinzugefügt.

So etwas wird benötigt. Grundsätzlich, wenn Sie nicht auf v3 upgraden können, ohne Ihre vorhandenen Protokollanweisungen zu berühren, UND in der Lage sind, Meta als SEPARATES Objekt NACH der Interpolation zu erhalten, dann ist v3 für die meisten aufstrebenden Benutzer ein Nichtstarter. Ich habe keine Ahnung, warum irgendjemand dachte, es sei eine gute Idee, Level, Botschaft und Meta in einem großen Objekt zu mischen. Es ist reif für Konflikte. info[Symbol.for('splat)] ist auch nicht zuverlässig, da es Interpolationswerte und Meta miteinander mischt. Wir wollen meta GETRENNT.

Also habe ich gerade festgestellt, dass die Verwendung von format.splat() den Informationen ein Metaobjekt hinzufügt, ABER nur, wenn Sie auch Interpolation verwendet haben. Wenn Sie keine Interpolation verwenden, wird das Meta nur in das Info-Objekt gemischt.

Auch bei Verwendung von Interpolation und Meta gibt format.simple() das Meta als {meta:{METAOBJ}} statt nur als {METAOBJ} wie v2 aus.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

sinai-doron picture sinai-doron  ·  3Kommentare

JaehyunLee-B2LiNK picture JaehyunLee-B2LiNK  ·  3Kommentare

ghost picture ghost  ·  4Kommentare

bertolo1988 picture bertolo1988  ·  3Kommentare

pocesar picture pocesar  ·  3Kommentare