winstonjs / logform Goto Github PK
View Code? Open in Web Editor NEWAn mutable object format designed for chaining & objectMode streams
License: MIT License
An mutable object format designed for chaining & objectMode streams
License: MIT License
const { format } = require('logform');
const alignedWithColorsAndTime = format.combine(
format.colorize(),
format.timestamp(),
format.align(),
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
);
const info = alignedWithColorsAndTime.transform({
level: 'info',
message: 'What time is the testing at?'
});
console.log(info);
error
if (!Array.isArray(Colorizer.allColors[lookup])) {
^
TypeError: Cannot read property 'undefined' of undefined
I am working on a React.js project and trying to use [email protected] within this project. I followed the comments outlined here:
When I go to run our build using webpack, I see the following error:
Starting type checking and linting service...
Using 1 worker with 2048MB memory limit
ts-loader: Using [email protected] and D:\dev\my-project\our-ui\tsconfig.json
Failed to compile.
Failed to minify the code from this file:
./node_modules/logform/format.js:7
Read more here: http://bit.ly/2tRViJ9
npm ERR! code ELIFECYCLE
npm ERR! errno 1
At first I tried changing the custom error object from ES6 classes to the old fashioned way:
function InvalidFormatError(formatFn) {
var instance = new Error(`Format functions must be synchronous taking a two arguments: (info, opts)
Found: ${formatFn.toString().split('\n')[0]}\n`);
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
if (Error.captureStackTrace) {
Error.captureStackTrace(instance, InvalidFormatError);
}
return instance;
}
InvalidFormatError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
if (Object.setPrototypeOf){
Object.setPrototypeOf(InvalidFormatError, Error);
} else {
InvalidFormatError.__proto__ = Error;
}
But that still produced the same errror:
Starting type checking and linting service...
Using 1 worker with 2048MB memory limit
ts-loader: Using [email protected] and D:\dev\my-project\our-ui\tsconfig.json
Failed to compile.
Failed to minify the code from this file:
./node_modules/logform/format.js:7
Read more here: http://bit.ly/2tRViJ9
npm ERR! code ELIFECYCLE
npm ERR! errno 1
Any help is appreciated, not sure if this is a logform issue our a webpack config issue.
The last release was 2.1.2 on 2019-02-01. Two small(?) features and a fix were added to master since then which can be seen here: 2.1.2...master
Could a new release be cut? Are there any blockers?
I recognize that using function callback in colors could be useful.
I tried to implement this feature here.
This is an sample code
const chalk = require('chalk');
const warningColorize = (message) => {
return chalk.yellow.italic(message.toUpperCase());
};
const syslogConfig = {
levels: {
emerg: 0,
alert: 1,
crit: 2,
error: 3,
warning: 4,
notice: 5,
info: 6,
debug: 7,
},
colors: {
emerg: 'magentaBright bold',
alert: 'magenta',
crit: 'redBright bold',
error: 'red',
warning: warningColorize, // Any format function
notice: 'greenBright',
info: 'green',
debug: 'blue',
}
};
// Create Winston logger
const logger = winston.createLogger({
levels: syslogConfig.levels,
level: process.env.LOG_LEVEL || 'debug',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
),
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
// - Write all logs error (and below) to `error.log`.
//
new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
new winston.transports.File({ filename: 'logs/combined.log' })
],
}
//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(syslogConfig),
winston.format.simple(),
)
}));
}
The errors format is not exposed in the browser:
https://github.com/winstonjs/logform/blob/master/browser.js
Is there a reason for this? If not, I can open a PR to expose it.
Thanks
The comment for printf.js
seems incorrect — perhaps it was partially copied and pasted from colorize.js
, because it says stuff about color, and as far as I know, printf
has nothing to do with colors:
/*
* function printf (templateFn)
* Returns a new instance of the printf Format that creates an
* intermediate prototype to store the
* level colors to `info` objects. This was previously exposed
* as { colorize: true } to transports in `winston < 3.0.0`.
*/
New logform version results in timestamp at the end of the line for winston with the following example code
const winston = require('winston');
class TimestampFirst {
constructor(enabled = true) {
this.enabled = enabled;
}
transform(obj) {
if (this.enabled) {
return Object.assign({
timestamp: obj.timestamp
}, obj);
}
return obj;
}
}
var myFormat = winston.format.combine(
winston.format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss.SSS'
}),
new TimestampFirst(true),
winston.format.json()
);
winstonLogger = winston.createLogger();
winstonLogger.configure({
level: 'info',
format: myFormat,
transports: [
new winston.transports.Console(),
]
});
winstonLogger.info('hello', {
message: 'test'
});
There were some important bug fixes made a while back (+14 months) for example #101 that are not part of the latest tag.
Can someone publish another release to npm?
The error formatter example describes that it will log:
// Error: Oh no!
// at repl:1:13
// at ContextifyScript.Script.runInThisContext (vm.js:50:33)
// at REPLServer.defaultEval (repl.js:240:29)
// at bound (domain.js:301:14)
// at REPLServer.runBound [as eval] (domain.js:314:12)
// at REPLServer.onLine (repl.js:468:10)
// at emitOne (events.js:121:20)
// at REPLServer.emit (events.js:211:7)
// at REPLServer.Interface._onLine (readline.js:282:10)
// at REPLServer.Interface._line (readline.js:631:8)
Whereas it really logs:
{ level: undefined, message: 'Oh no!', stack: 'Error: Oh no!\n at Object.<anonymous> (C:\\Users\\Fennec\\Documents\\errlog.js:6:37)\n at Module._compile (internal/modules/cjs/loader.js:688:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)\n at Module.load (internal/modules/cjs/loader.js:598:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:537:12)\n at Function.Module._load (internal/modules/cjs/loader.js:529:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:741:12)\n at startup (internal/bootstrap/node.js:285:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)', [Symbol(level)]: undefined, [Symbol(message)]: 'Oh no!' }
Current behavior>
Splat does not correcly add meta
key with the rest of arguments when no interpolation is needed.
Expected behavior:
All other arguments are added under the meta
key.
Reproduction:
const { createLogger, format, transports } = require('winston');
const { SPLAT, LEVEL } = require('triple-beam');
const logger = createLogger({
level: 'info',
format: format.combine(format.splat(), format.json()),
transports: [new transports.Console()],
});
logger.error('one %s', 'two', 'three');
// {"level":"error","message":"one two","meta":"three"}
logger.error('one %s', 'two', 'three', 'forth');
// {"level":"error","message":"one two","meta":["three","forth"]}
logger.error('one', 'two', 'three');
// {"level":"error","message":"one"}
logger.error('one', 'two', 'three', 'forth');
// {"level":"error","message":"one"}
Hello,
I'm suggesting to add an option to the splat transformer that would allow to keep the source/original message (before formatting) in the metadata.
Current behavior:
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.splat(),
winston.format.logstash()
),
transports: [
new winston.transports.Console()
]
});
logger.info('hello %s', 'world', { foo: 'bar'} );
//> {"@message":"hello world","@fields":{"level":"info","foo":"bar"}}
Desired behavior
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.splat({ source: 'raw', arguments: 'params'}),
winston.format.logstash()
),
transports: [
new winston.transports.Console()
]
});
logger.info('hello %s', 'world', { foo: 'bar'} );
//> {"@message":"hello world","@fields":{"level":"info","raw":"hello %s","params":["world"],"foo":"bar"}}
I hope this suggestion will be accepted, it would be very useful when working with logging systems like the Elastic stack.
Best regards
I am not sure, but I thought each formatter return a new info object (if I want to keep the original object immutable), and that object will be passed on to the next formatter (as it currently is), and returned as the final value of the cascade function (which it currently isn't).
Am I missing something?
When following example outlined in the readme. I get the following error:
TypeError: Cannot destructure property `stack` of 'undefined' or 'null'.
at Format.module.exports.format [as transform] (.../node_modules/logform/errors.js:14:25)
It is traceable back to this line. More specifically to the second argument of format
's callback: { stack }
. When I call errorsFormat.transform(new Error('Oh no!'));
the second argument in the callback will attempt to destructure whatever is passed and fine the stack
property but since there is only one argument passed, it cannot destructure the second argument of undefined
.
That is my analysis anyway, so I might be wrong but doing something like errorsFormat.transform(new Error('Oh no!'), new Error('Oh no!'));
while pointless, it works.
I'm using the 'Errors' format and pipelining it through a custom printf format.
Basically I'm having enormous inconsistencies when I try to log my error with some metadata.
So logger.info(err)
works fine, but logger.info(err, someMetaData)
fails to give me the message or the stack, they both come as undefined when I log the "info" object that's coming in my custom format function.
What's more, this only happens if I DID NOT set a message for the Error in ins constructor, even if it's just an empty string.
So in summary, this gives me a headache:
let err = new Error();
err.message = 'Message set later';
logger.info(err, someMetaData);
But these work::
let err = new Error();
err.message = 'message set later';
logger.info(err);
let err = new Error('message in constructor'); // or let err = new Error('');
err.message = 'another message';
logger.info(err, someMetaData);
let err = new Error('Message in constructor');
err.message = 'another message';
logger.info(err);
Currently, I'm using this configuration for my logger:
const devPrint = info => {
// This is the final format before info is printed on console
// Gonna print info to normal console to compare
console.log(info);
let {level, message, timestamp, stack, ...metadata} = info;
let print = `${timestamp}: ${level} ${message}\n`;
if (metadata && Object.keys(metadata).length > 0) print += `METADATA ==> ${JSON.stringify(metadata, null, 2)}\n`;
if (info.stack) print += `STACK ==> ${stack}\n`;
return print;
};
const options = {
level: 'debug',
format: winston.format.combine(
winston.format.errors({stack: true}),
winston.format.printf(devPrint)
)
};
const logger = winston.createLogger({
transports: [
new winston.transports.Console(options)
]
});
Is there something wrong with my configuration?
This probably just needs a documentation enhancement but want to call this out. After several hours of fighting with the formatter I realized that ordering matters when defining a format.
// The following code prints a json formatted error message with a timestamp
export const logger = createLogger({
format: format.combine(
format.timestamp(),
format.json()
),
transports: [
new transports.Console()
]
});
logger.info("timestamp is")
// {"message":"timestamp is","level":"info","timestamp":"2020-03-17T15:38:01.527Z"}
The following code prints a json formatted message but excludes the timestamp.
export const logger = createLogger({
format: format.combine(
format.json(),
format.timestamp()
),
transports: [
new transports.Console()
]
});
logger.info("timestamp is")
//{"message":"timestamp is","level":"info"}
If this is already covered in the documentation and I am missing it then we can close this otherwise id like to propose an addendum to the docs to make this more clear. The examples are correct and it took me finally copy/pasting an example into my project to see the timestamp working to realize what was happening.
Hey,
running into this, used to work :( I have to say i'm getting a bit confused an it's become impossible to debug across so many packages
TypeError: Cannot read property 'error' of undefined
at Colorizer.colorize (/home/valentin/repro/node_modules/logform/colorize.js:88:41)
at Colorizer.transform (/home/valentin/repro/node_modules/logform/colorize.js:112:23)
at Format.cascaded [as transform] (/home/valentin/repro/node_modules/logform/combine.js:34:24)
at Console._write (/home/valentin/repro/node_modules/winston-transport/index.js:90:33)
at doWrite (/home/valentin/repro/node_modules/winston-transport/node_modules/readable-stream/lib/_stream_writable.js:428:64)
at writeOrBuffer (/home/valentin/repro/node_modules/winston-transport/node_modules/readable-stream/lib/_stream_writable.js:417:5)
at Console.Writable.write (/home/valentin/repro/node_modules/winston-transport/node_modules/readable-stream/lib/_stream_writable.js:334:11)
at DerivedLogger.ondata (/home/valentin/repro/node_modules/winston/node_modules/readable-stream/lib/_stream_readable.js:619:20)
at emitOne (events.js:116:13)
at DerivedLogger.emit (events.js:211:7)
at addChunk (/home/valentin/repro/node_modules/winston/node_modules/readable-stream/lib/_stream_readable.js:291:12)
at readableAddChunk (/home/valentin/repro/node_modules/winston/node_modules/readable-stream/lib/_stream_readable.js:278:11)
at DerivedLogger.Readable.push (/home/valentin/repro/node_modules/winston/node_modules/readable-stream/lib/_stream_readable.js:245:10)
at DerivedLogger.Transform.push (/home/valentin/repro/node_modules/winston/node_modules/readable-stream/lib/_stream_transform.js:148:32)
at DerivedLogger._transform (/home/valentin/repro/node_modules/winston/lib/winston/logger.js:210:12)
at DerivedLogger.Transform._read (/home/valentin/repro/node_modules/winston/node_modules/readable-stream/lib/_stream_transform.js:184:10
const alignedWithColorsAndTime = format.combine(
format.colorize(),
format.timestamp(),
format.printf((info: any) => {
let errStr = ''
if (info.err) {
errStr = `${getFullErrorStack(info.err)}`
}
const toPrint = Object.assign({}, info, {
level: undefined,
message: undefined
})
if (toPrint['err']) {
toPrint['err'] = `${info.err.name}: ${info.err.message}`
}
const json = stringify(toPrint, null, 2)
return `${info.timestamp} ${info.level}: ${info.message} ${json} ${errStr}`
})
);
var logger: = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
});
logger.add(
new winston.transports.Console({
format: alignedWithColorsAndTime,
level: process.env.LOG_LEVEL || 'silly',
colorize: true
})
);
Splat does not work if used in a combine format along with cli format, and splat is the second parameter of combine().
In order to work, splat needs to be the first parameter.
Splat format should work with combine format regardless of which order it appears as a parameter to combine().
const logger = winston.createLogger({
level: "info",
format: winston.format.combine(
winston.format.cli(),
winston.format.splat()
),
transports: [new winston.transports.Console()]
})
logger.log('info', 'test message %d', 123);
Expected output: info: test message 123
Actual output: info: test message %d
The simple
format is exactly what I need, except I would like it to be prefixed with a timestamp. Is this possible without copying/pasting the entire definition of simple
?
When I use Rollup (https://rollupjs.org/) to bundle Winston, the following error is thrown when running the app:
node example/index.js
/Users/mike/logging/lib/bundle.js:21
throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
^
Error: Dynamic requires are not currently supported by rollup-plugin-commonjs
at commonjsRequire (/Users/mike/logging/lib/bundle.js:21:8)
at Function.get (/Users/mike/logging/lib/bundle.js:8108:31)
at _getConsoleLogFormat (/Users/mike/logging/lib/bundle.js:10777:10)
at _winstonConsole (/Users/mike/logging/lib/bundle.js:10792:13)
at getTransports (/Users/mike/logging/lib/bundle.js:10814:13)
at Object._init (/Users/mike/logging/lib/bundle.js:10820:17)
at Object.<anonymous> (/Users/mike/logging/example/index.js:4:23)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
The issue is caused by https://github.com/winstonjs/logform/blob/master/index.js#L27. Ideally, it'd be great to revert back to 972dbec#diff-168726dbe96b3ce427e7fedce31bb0bcL21. Although more verbose, it would open up Winston to being bundled by Rollup once winstonjs/winston#1100 is merged.
Message:
at Colorizer.colorize (/Users/krzysztofszostak/Documents/GitHub/sb-logger/node_modules/logform/colorize.js:72:43)
at Colorizer.transform (/Users/krzysztofszostak/Documents/GitHub/sb-logger/node_modules/logform/colorize.js:98:25)
Winston: 3.1.0
Logform: 2.1.2
Anyone have any idea how to solve this issue?
The Winston 2.x behavior was to output
${level}\t: ${message}
Currently combine(align(), simple())
produces
${level}:\t ${message}
This does not align correctly, because the level names exceed the tab width.
For example:
info: Hello
verbose: World
Changing the align formatter to
module.exports = format(info => {
info.level = `${info.level}\t`;
return info;
});
Restores the old behavior for me.
I'm currently using a format like so:
const formatter = require("winston").format;
new winston.transports.Console({
format: formatter.combine(
formatter.timestamp(),
formatter.colorize(),
formatter.align(),
formatter.printf(
(info) => `[${info.timestamp}] ${info.level}: ${info.message}`
)
),
})
I wanted to set a colour to my timestamp, I don't see a way of doing that at this point. Adding this to the colors
object would be ideal. Something like:
formatter.colorize({
colors: {
timestamp: "red",
},
})
I have a small recommendation for the default color for timestamp too: #666666
, in case anyone's listening :)
shouldn't format.errors({})
have type { stack: boolean } | undefined
instead of object | undefined
.
I got a strange error using cli
formatter, that boils down to this:
Lines 13 to 16 in 28c9bcf
I think this should be combine
instead of format
on line 13.
I am trying to write a filter for the logstash formatted log in logstash. The current message string is:
{"@message":"1 users connected","@timestamp":"2020-04-02T00:10:17.871Z","@fields":{"level":"info"}}
I tried using
else if [fields][log_type] == "city_dashboard_logs" { json { source => “message” target => “message” } }
but this did not work.
Any suggestions?
Currently if you add a colorizer to a transport there is no way to remove it without recreating the entire formatter on the transport in question. I would have expected that the implementation of uncolorize would behave in such a way that if colorize as a function were present in the combined format that it would also remove it (or there be another means of removing the colorize formatter from the combined formatter, although I couldn't find anything like this in the source or docs.)
Consider the following example:
Creating a basic winston logger, with a simple message format, the default colorizer, and a timestamp:
import * as winston from 'winston';
const basicFormat = winston.format.printf(
msg => {
return `${msg.timestamp} - ${msg.level}: ${msg.message}`;
}
);
const logger = winston.createLogger({
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
basicFormat,
)
}),
],
});
logger.info(`thanos`);
logger.warn(`was`);
logger.error(`right`);
This prints the expected output with the default colours:
Currently the only way to remove the colours without recreating the transport (which can be cumbersome if you have various transports) is to use uncolorizer at the end of your combined format:
logger.transports[0].format = winston.format.combine(
logger.transports[0].format,
winston.format.uncolorize(),
)
Which yields the expected output with said colours removed:
The problem with doing this is that each logged message is then going through the combined formatter as:
Which of course is adding extra operations to each log.
Although this may be intended behaviour, in that your desired approach to this is to either recreate the transports effected or at the least recreate their formatters?
In all honesty, feel free to leave a comment and close this if it's by design.
I have a cluster of Node.js instances where only one of the nodes in the cluster (the master-node) is responsible for writing logs. I label each log object with the node-id, so I can tell where the log object originated. I would also label logs that originated from master.
The problem is that when I run the log object that originated from a worker instance (with the worker id), the master logger overwrites the worker's log's label.
There are two ways to solve this problem:
solution 1:
const masterTemplate = ({ timestamp, level, message, label }) =>
`${timestamp} - [${label || 'master'}] ${level}: ${message}`;
const masterFormat = printf(masterTemplate);
solution 2:
const label = format((info, opts) => {
info.label = info.label || opts.label;
return info;
});
While both of the above solutions sufficiently solve my problem, adding one line to the current label formatter would be much cleaner:
module.exports = format((info, opts) => {
info.label = info.label || opts.label;
if (opts.message) {
info.message = `[${info.label}] ${info.message}`;
return info;
}
return info;
});
I presume that there are more use cases for preserving the original label
property than there are for overwriting it, but if I'm wrong, please close the this issue.
Issue in Linux with Winston 3.2.1 and Node 10.15.1.
Though this isn't a critical error, I find it annoying that the JSON formatter doesn't stringify the resulting object with the attributes always in the same order.
For example, I have a File transport with the errors, splat, timestamp and JSON formatters and the following lines result in different log lines:
logger.info('TEST TEST');
logger.info('TEST %s', 'TEST');
{"message":"TEST TEST","level":"info","timestamp":"2019-04-05T15:09:52.076Z"}
{"level":"info","message":"TEST TEST","timestamp":"2019-04-05T15:09:52.077Z"}
Not sure if that change in behaviour could be considered a bug in Winston itself, but I think these problems could easily be avoided by having the JSON formatter stringify in a consistent order, most likely by using fastSafeStringify.stableStringify instead of the library's default method. Maybe it could be configurable with a new option?
Right now I'm avoiding this annoyance by setting a custom formatter before the JSON one that resets the options' keys in alphabetical order, in case someone has this problem as well:
winston.format(options => {
var keys = Object.keys(options).sort();
for (var i = 0, len = keys.length; i<len; i++) {
var value = options[keys[i]];
delete options[keys[i]];
options[keys[i]] = value;
}
return options;
})()
Hi, I'm trying to format timestamp with moment but doesnt work
format.timestamp(() => moment().format('LT'))
The log still with ISO format
We are facing an issue using this module with a nexe bundled project. Essentially nexe does not support any type of dynamic module imports.
Is there any specific reason why the transports are setup lazily?
Hey,
I am unable to run logform in IE11 since format.js
is using classes that are not ES5 compatible. Would it be possible to transpile whole repo before publishing or writing it es5 compatible?
class InvalidFormatError extends Error {
constructor(formatFn) {
super(`Format functions must be synchronous taking a two arguments: (info, opts)
Found: ${formatFn.toString().split('\n')[0]}\n`);
Error.captureStackTrace(this, InvalidFormatError);
}
}
Thanks!
This issue was previously reported on the main Winston issues list as #1308. Moving it here since the prettyPrint
function is actually a part of this repository.
I'm running the sample code under the Combining Formats section. I've created a brand new Node project, and Winston is the only package installed. I created a new index.js
file, and it only contains the code in the Combining Formats section. When I execute the code, I see the following log output:
{ level: 'info',
message: 'What time is the testing at?',
label: 'right meow!',
timestamp: '2018-05-10T00:52:02.906Z',
[Symbol(level)]: 'info' }
According to the text in the section, I should see:
{ level: 'info',
message: 'What time is the testing at?',
label: 'right meow!',
timestamp: '2018-05-10T00:52:02.906Z' }
According to my testing (using the latest version of Winston), the [Symbol(level)]: 'info'
part is coming from the prettyPrint
function invocation. I looked at the function itself, and I couldn't immediately see why it logged the Symbol
portion. Is there a defect with the function or is it part of the configuration?
Browsing your source code I came across this comment. Not sure what was meant, but better update it since April 2019 is gone by. @indexzero
Lines 21 to 28 in ec7d624
[…] adds the specified
opts.label
before the message.
const logger = createLogger({
format: combine(
splat(),
label({ label: 'right meow!' }),
),
// …
});
logger.info('something');
Expected result: "right meow! something"
Actual result: "something"
Cause: label never succeeds its message
condition check, and thus only ever adds a label
property to the info
object. This is caused by checking if (
opts
.message)
instead of if (info.message)
.
There are a number of fancy formatters out there for tty-based terminals. The most recent one I came across is signale. Their data structure is similar to what we do already with levels & colors. Could be an interesting place to collaborate and/or develop interoperability with a logform
based format.
const options = {
scope: 'custom',
types: {
remind: {
badge: '**',
color: 'yellow',
label: 'reminder'
},
santa: {
badge: '🎅',
color: 'red',
label: 'santa'
}
}
};
If you are looking to implement this format check out the code for colorize.js
and pad-levels.js
. This format would follow those established patterns to manage initial state vs. using the simpler format
function.
I am having some trouble with the colorizing of logs. Specifically, when logging to non-tty outputs.
There is an override in colorize.js:9 that prevents the colors
package to enable or disable when supported.
First of all, I would like to know why this decision was made, and if it can be removed.
I have made a hack as a workaround. Here it is, in case anyone wants to know how to do it:
format: format.combine(
LOGGER_COLORS === 'true' ? format.colorize({ all: true }) : format(i => i)(),
format.printf(({
label = 'default',
namespace = 'default',
level = 'debug',
message,
timestamp,
}) => {
let string = `${label}:${namespace} ${level}: ${message}`;
if (LOGGER_CONSOLE_TIMESTAMP === 'true') {
string = `${timestamp} ${string}`;
}
return string;
}),
),
format
option of timestamp()
accepts either a format string or a function that returns a formatted date,
but current index.d.ts has only string
type for TimestampOptions.format
.
import moment from "moment-timezone";
import { createLogger, format, transports } from "winston";
export default createLogger({
level: "info",
format: format.combine(
format.timestamp({
format: () =>
moment()
.tz("Asia/Tokyo")
.format()
}),
format.errors({ stack: true }),
format.splat(),
format.json()
),
transports: [new transports.Console()]
});
Argument of type '{ format: () => string; }' is not assignable to parameter of type 'TimestampOptions'.
Types of property 'format' are incompatible.
Type '() => string' is not assignable to type 'string'.
It would be very helpful for newcomers if the README contained a list of the built-in formats, with a brief example of the output of each. Currently, it seems you have to dig through the source to figure out what built-in formats are available, and try them in code in order to see what they will look like.
I'm seeing this warning while importing winston
. (With typescript 2.6.2).
WARNING in ./node_modules/logform/index.d.ts
Module build failed: Error: Typescript emitted no output for /Users/aneil/code/myapp/web/app-backend/node_modules/logform/index.d.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
at successLoader (/Users/aneil/code/myapp/web/app-backend/node_modules/ts-loader/dist/index.js:47:15)
at Object.loader (/Users/aneil/code/myapp/web/app-backend/node_modules/ts-loader/dist/index.js:29:12)
@ ./node_modules/logform ^\.\/.*$
@ ./node_modules/logform/index.js
@ ./node_modules/winston/lib/winston.js
@ ./src/logger.ts
// src/logger.ts
const winston = require('winston');
export const log = winston.createLogger({
transports: [
new winston.transports.Console(),
]
});
For example :
const logger = createLogger({
format: format.combin(
format.json(),
format.errors(),
)
});
// i can add format by addFormat API or some other API, someone can help me
logger.addFormat(format.timestamp())
Thanks for this repo. Give a suggestion:
label option like:
format.label({ label: 'right meow!' }),
but timestamp option like:
format.timestamp({format: () => moment().format('LT')}),
I do suppose the timestamp option should like:
format.timestamp({timestamp: () => moment().format('LT')}),
{format:
-> {timestamp:
Hi!,
i discover that:
./logform/timestamp.js:
14 module.exports = format(function (info, opts) {
15 if (opts.format) {
16 info.timestamp = typeof opts.format === 'function'
17 ? opts.format()
18 : formatDate(new Date(), opts.format); // <<<<<<<<<<<<<<<<<<<<< the solution!
19 }
20
21 if (!info.timestamp) {
22 info.timestamp = new Date().toISOString();
23 }
24
25 if (opts.alias) {
26 info[opts.alias] = info.timestamp;
27 }
28
29 return info;
30 });
Sorry if i dont respect de standards to report an issue.
Hi there,
Trying to understand how I should be leveraging the Errors formatter in my own project. I tried following along with the example, but I get a TypeError
. Is the example possibly out of date?
> const {format} = require('logform')
undefined
> const { errors } = format
undefined
> const fmt = errors({stack: true})
undefined
> const info = fmt.transform(new Error('oh no!'))
TypeError: Cannot destructure property `stack` of 'undefined' or 'null'.
at Format.module.exports.format [as transform] (/Users/jjdonov/<omitted>/node_modules/logform/errors.js:14:25)
at repl:1:18
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at REPLServer.defaultEval (repl.js:240:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:441:10)
at emitOne (events.js:121:20)
at REPLServer.emit (events.js:211:7)
at REPLServer.Interface._onLine (readline.js:282:10)
I am using logform 2.1.2, included with winston 3.2.1
npm ls logform
<omitted>@0.0.0 <omitted>
└─┬ [email protected]
└── [email protected]
If there is an additional string parameter that is not insert via %s
into the message template, its characters are inserted individually as properties into the result:
const {createLogger, format, transports} = require('winston');
const logger = createLogger({
level: 'info',
format: format.combine(format.splat(), format.json()),
transports: [new transports.Console()],
});
logger.error('one %s', 'two', 'three');
// {"0":"t","1":"h","2":"r","3":"e","4":"e","level":"error","message":"one two"}
While this is in compliance with the documentation at https://github.com/winstonjs/logform#splat it is still not expected. The behavior should be aligned to what console.log()
does where additional parameters are just printed as they are.
Issue #51 suggests that they should be collected into a meta
-property which would also be fine as they could then be used in a custom printf transformation.
Versions:
[email protected]
[email protected]
I'm getting "TypeError: Cannot read property 'length' of undefined" due to the following line of code:
https://github.com/winstonjs/logform/blob/master/splat.js#L55
I've isolated the issue and it's when I'm logging text with special characters such as "%o", "%s", etc.
The TransformableInfo
key is no longer restricted to only a string. triple-beam
changed their typings such that the constants are no longer strings.
see triple-beam change: DefinitelyTyped/DefinitelyTyped#46490
usage in winston: https://github.com/winstonjs/winston/blob/68ea786e053e50b51396e0cc8993c67ff789609c/lib/winston/logger.js#L251
Location of required change: https://github.com/winstonjs/logform/blob/master/index.d.ts#L10
TL;DR the type needs to support strings and unique symbol
.
Current ugly workaround for projects using these typings:
import { SPLAT as SPLAT_Symbol } from 'triple-beam'
const SPLAT = SPLAT_Symbol as unknown as string // this is not a string
...
format.printf(info => {
if(info[SPLAT]) { ... }
})
When bundling winston
with esbuild
, the format
exports are missing because they are required dynamically. Esbuild currently can't handle dynamic import resolution.
evanw/esbuild#56 explains why esbuild
can't handle the dynamic imports, there seems to be a plugin on the way tho (evanw/esbuild#700).
I guess those lines are the main issue: https://github.com/winstonjs/logform/blob/b91bfa5c32a6077adcf2526ee8d3414c7171e557/index.js#L24#L32
Maybe related to #5
Here's how I'm defining my format
return format.combine(
format.colorize(),
format.timestamp({
format: TIMESTAMP_PATTERN
}),
winston.format.simple(),
format.printf(info => `[${info.timestamp}] ${info.level}: ${info.message}`)
)
and it throws the following stack trace
TypeError: Cannot read property 'error' of undefined
at Colorizer.colorize (/Users/ryan/git/p-nodejs/p-common/psp-logger/node_modules/logform/colorize.js:72:43)
at Colorizer.transform (/Users/ryan/git/p-nodejs/p-common/psp-logger/node_modules/logform/colorize.js:94:28)
at Format.info [as transform] (/Users/ryan/git/p-nodejs/p-common/psp-logger/node_modules/logform/combine.js:20:24)
When I remove the format.colorize()
it logs fine. I am running MacOS Mojave. Going to try downgrading and see if there is any improvement.
edit: It looks like version 1.10.0 doesn't have the issue
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.