Comments (19)
My initial idea was to leverage Error.stack but I'm concerned with performance, throwing error at each logged message can't be a good idea.
Hm.. It's possible we could provide __LINE__
as a preprocessed symbol in deno. For the filename we could use import.meta once denoland/deno#975 lands.
from deno_std.
Probably yes, I'm still trying to figure it out. But if you look for example at deno.open
it's asynchronous, so making most of the handlers would be asynchronous operation. AFAIK you can't do asynchronous stuff in class constructor, so it might be rewritten to: await new FileHandler().setup({ filename })
from deno_std.
@djKooks you can track progress in #51
from deno_std.
I reckon log
implementation is good enough now we can close this.
from deno_std.
-
I suggest we rename it to "log" - it's shorter.
-
I think the golang logger has reflected on python's and provides a good design to copy
https://golang.org/pkg/log/ -
Currently Deno only has two built-in log-levels: debug and info. These can be in JS or Rust and are triggered by "-D"... Should the log module also be conditioned on "-D" ?
from deno_std.
- Agreed
- IMHO Go's logging module is low level compared to Python's. Do we want to provide simpler solution in standard library and leave it to user libraries to provide more battery-included solution?
- I think so, default logging level should display only error and critical messages, while
-D
set default log level to debug.
from deno_std.
- I kinda agree - although we need to provide some support for capturing logs and sending them elsewhere. Out of the box I'd like to be able to do
import * as log from "https://deno.land/std/log.ts";
log.debug("blah");
log.info("foo");
from deno_std.
@ry I totally agree. We can expose logging methods in exports, and those methods would call default logger.
Those two snippets would then be equivalent.
import * as log from "https://deno.land/std/log.ts";
log.debug("blah");
log.info("foo");
import * as log from "https://deno.land/std/log.ts";
const myLogger = log.getLogger();
myLogger.debug("blah");
myLogger.info("foo");
Regarding capturing and sending logs somewhere else, that's where Python's implementation shines.
We could do something like this:
import * as log from "https://deno.land/std/log.ts";
await log.config({
handlers: {
console: {
level: 'debug',
handler: new log.ConsoleHandler(),
},
file: {
level: 'info',
handler: new log.FileHandler(),
},
},
loggers: {
deno: {
level: 'debug',
handlers: ['console', 'file']
}
}
});
const logger = log.getLogger('deno');
logger.debug("blah"); // logged to console only
logger.info("foo"); // logged to both console and file
from deno_std.
@bartlomieju seems good!
Have one question...is log.config
need await
?
from deno_std.
@bartlomieju please share to me how logger will be implemented when decided. I'll fix my PR by the guide if needed. Thanks for your work.
from deno_std.
During chat conversation with @ry we concluded that logging methods should take only one argument msg
and leave it to user to format message properly, eg.
import * as deno from 'deno';
import * as log from 'https://deno.land/x/std/logging/index.ts';
const someNum = 100;
const someObj = { a: 1, b: 2 };
// instead of interpolation ...
log.info("Number: %n, object: %o", someNum, someObj);
// just use template strings
log.info(`Number: ${someNum}, object: ${deno.inspect(someObj)}`)
This minimizes the API that has to be implemented.
As for output format of each message, Glog's style was proposed (also here). Note: we're not sure why leading bracket [
is missing in glog's format.
Proposed format:
[Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg
where:
L
- level of messagemmdd
- month and dayhh:mm:ss.uuuuuu
- timestampthreadid
- PID of thread/processfile:line
- filename and line from where message originated. Not sure we can get that info currently.
Example line would look like this:
[D0301 10:04:23:43111 3451 main.ts:30] Some logged message
To be honest I'm not a big fan of this format, I'd prefer to output ISO date like this:
[D 2018-01-03 10:04:23:43111 pid:3451 main.ts:30] Some logged message
from deno_std.
Would this be configurable?
from deno_std.
[D0301 10:04:23:43111 3451 main.ts:30] Some logged message
Have you thought about how to extract "main.ts:30" ?
Note: we're not sure why leading bracket [ is missing in glog's format.
If we're going to use glogs format, let's copy it exactly, including the unmatched bracket. It's not a mistake. I just don't know the reason for it.
To be honest I'm not a big fan of this format
Your proposed format is longer...
Would this be configurable?
I'd rather we agree on one format...
from deno_std.
Have you thought about how to extract "main.ts:30" ?
My initial idea was to leverage Error.stack
but I'm concerned with performance, throwing error at each logged message can't be a good idea.
To be honest I'm not a big fan of this format
Your proposed format is longer...
It is, but glog's format is hard to grep when you see it for first time, especially conjunction of log level and date. But I'm not sticking to it no matter what.
Would this be configurable?
I'd rather we agree on one format...
That's fine for me, but it will bring a need for another logging libraries that allow to configure that.
from deno_std.
@ry one more comment on configurable format - tests would be much simpler if format could be manipulated, eg. date could be skipped. Otherwise we'd need some kind of wildcard matching?
from deno_std.
@bartlomieju true good point.
from deno_std.
After some consideration I think we might want to change LogRecord
and signature of logging methods from:
export interface LogRecord {
msg: string;
args: any[];
datetime: Date;
level: number;
levelName: string;
}
debug(msg: string, ...args: any[]) {
return this._log(LogLevel.DEBUG, msg, ...args);
}
to:
type LogMetadata = {[key: string]: any};
export interface LogRecord {
msg: string;
metadata?: LogMetadata;
datetime: Date;
level: number;
levelName: string;
}
debug(msg: string, metadata?: LogMetadata) {
return this._log(LogLevel.DEBUG, msg, metadata);
}
this object would be placed in LogRecord
and be later utilized in custom formatter. Simple but powerful IMHO.
from deno_std.
@bartlomieju That seems like more to type? Or maybe I misunderstand. Can you give some examples of invocation?
from deno_std.
Yeah after all it seems so. My initial idea was that args
would be interpolated in msg
(msg % args
), but we already established that we don't want that.
We could keep LogRecord.args
and allow to use that instead of metadata
from deno_std.
Related Issues (20)
- jsr Support for std/http
- bug: `parseRange()` returns unexpected result HOT 1
- todo: fix tests after workspaces migration script is run HOT 1
- snapshot testing fails with Deno v1.40.5 when stdout is terminal HOT 2
- Fix test failures after running `_tools/convert_to_workspace.ts` HOT 2
- [Streams] Add CSV separator setting on CsvParseStreamOptions documentation HOT 5
- bug(log): `RotatingFileHandler.log()` should handle message longer than 4096 HOT 1
- link replacement of fs.ensureSymlink() HOT 3
- semver: deprecate `rangeMax` and `rangeMin` HOT 4
- proposal: config module HOT 1
- Log: debug level logs not showing HOT 3
- suggestion: more readable function chaining for `collections` (pipe, chain, data-last)
- The OS Signals Async iterator example is broken because `std/signal` was removed HOT 1
- deprecation(log): deprecate `LogRecord` class and use plain object instead HOT 3
- question(log): remove `setup()` and `destroy()` from `BaseHandler`? HOT 8
- question(log): public methods in classes HOT 1
- proposal(front_matter): fix file names and exports HOT 5
- is it possible to cache all std lib? HOT 2
- suggestion: optional `reason` param for assert::unreachable
- proposal(std): standardise JSDoc tag usage HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from deno_std.