
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
0) Install globally for easier viewer access:
npm install -g log0
1) Write to your logs from any node.js app:
const log = require('log0'); // obviously
let abc=123, xyz="string", obj={abc,xyz}; // testing
// then...
log('hello there!', abc, xyz, obj);
// fancy...
log.myStream1(abc, 'some other information', xyz);
log.someOtherLog('more info still', xyz, abc);
log.runtime(obj, 'fancy stuff here', xyz, abc);
log.myStream1.subStream(xyz, obj, 'yet more information here', abc);
log.runtime.error(`whoops, you've done it again!`, xyz);
log.runtime.warning(`i forgive you this time!`, xyz);
log.parsing('parse phase #42 info', obj);
log.parsing.error('sorry, no can do', xyz);
log.parsing.warning(`it's ok, i'll just keep going`, xyz);
log.topical.screamingLilies('what is that???');
// neato...
const perr = log.parsing.error;
perr('sorry, no can do', xyz);
2) View live logs simultaneously in different terminal windows:
log(...) entries always go to stdout (same as console.log)log0 my-stream1
log.myStream1(...) entries show up herelog0 myStream1.subStream
log.myStream1.subStream(...) entries show up herelog0 my-stream1.sub-stream
log0 some-other-log
log.someOtherLog(...) entries show up herelog0 ...error
error show up herelog.runtime.error and log.parsing.error from abovelog0 parsing...
parsing show up herelog.parsing and log.parsing.error from abovelog0 ...s...ream...
s and ream show up herelog.myStream1, log.myStream1.subStream, and log.topical.screamingLilies from abovelog0 ...warning... ...error...
warning or error show up herelog.runtime.error, log.runtime.warning, log.parsing.error, and log.parsing.warning from abovelog0 addresses the primary limitation of debugging with console.log, namely that everything goes to a single stream, stdout.
Instead, use log.yourLogNameHere('hello there!') in your node.js app, so that you can then, from any other [multiple] terminal window(s), view that log live, on-the-fly stream by simply typing log0 yourLogNameHere at the command line (or log0 your-log-name-here).
Your node.js app can always write to the main (primary) terminal console (stdout) by using the unadorned log() function.
You can create any number of "virtual logs" (a.k.a. streams) just by accessing them as dynamic properties
of the "root" log, such as log.aVirtualLogNameHere().
You can create "sub-logs" by simply nesting further, such as log.virtual1.subVirtual2.subSubVirtual3.sub4().
You can use a shorthand notation within any node.js app file for legibility. For example:
// long way...
log.virtual1.subVirtual2.subSubVirtual3.sub4('some information here');
// a better way...
const logx = log.virtual1.subVirtual2.subSubVirtual3.sub4;
// then...
logx('some information here');
It's not a long term archival logger such as Winston or Banyan, or for Cloud Logging.
It's not a way to log into something.
It's not a browser-based utility.
It's not a Captain's Log, Stardate 2020.
It's not a log cabin
It's not syrup
log0's purpose is for LIVE, IMMEDIATE, while-you-are-developing, LOCAL, console.log-like logging for server-side node.js development.
And that's where it derives its name from:
Logging means different things to different parties: for production apps & managers, logging is long-term and meant to record events as they happen for later analysis (especially large apps with cloud-based logging) for bug extraction and performance improvement or feature enhancement.
For developers, the stage of development (beta, production, alpha, or early-pre-alpha) affects the type and purpose of logging. Often, very early on, logging is really just quick-n-dirty debugging (not involving an actual debugger). It doesn't replace a debugger, but rather it's just another tool in our developer's toolbelt.
In these cases, logging is not about "logging an event" but rather it's to "dump a value" as an app is running to see what's going on (especially when an actual debugger is not available or practical or worth that particular effort).
Basically, just plain 'console.log' something and see if it 'looks right.'
For these times, different parts of the app may be generating different volumes of information and you may want separate windows (i.e. terminals) to see each in realtime.
In particular, when you do fancy window-like handling of main stdout, you may want to use other windows to view a "running commentary" (reality checks) of debugging events (i.e. log.x() statements) within your app.
Once log0 is installed, it's used in 2 parts:
npm install -g log0
By installing globally, you can always, from any terminal window, access the viewer by simply
using the log0 command. For example: log0 builder ...error
If not installed globally, can always use it, in a given project, as: npx log0 ...error
ps: you SHOULD INSTALL this package as GLOBAL (-g).
use by any means, as follows:
const log = require('log0');const {log,lo0} = require('log0'); [both are the same, for convenience]Can create on-the-fly logs as follows:
const {normalStuff, error, warning, neverMind, fancyBee} = log;
normalStuff('log message here');
error('log message here');
warning('log message here');
neverMind('log message here');
fancyBee('log message here');
A stream is dynamically created by simply accessing it as a property on the root log() function.
So, to create a stream named abcxyz, just write to it using log.abcxyz(...your stuff here...).
// log(...) to log to .log0/logs/log0/stdout // log.xyz(...) to log to .log0/logs/log0/xyz // log.setApp('abc').log(...) to log to .log0/logs/abc/xyz // log.setApp('abc').xyz(...) to log to .log0/logs/abc/xyz
// reserved log props: cannot be used as stream names // log | if | set // - but ok to use variants (e.g. IF or Log): stream/filenames will still be lowercase
Also should be valid file names since used mostly as is for that
It's minimal and used to treat camelNotation as camel-notation for the files then dash-notation back to camelNotation for stream names within the app.
For any given log stream, you can retrieve information for it (not sure that purpose other than to view the actual filename of that log)
// can extract log's details (e.g. filename) by calling .set() [without any parms] // - e.g. const { name, filename } = log.set();
// 2 ways to control log entries: [move this to readme.md] // - setEnabled (or .if()): entries displayed or not
// - setFormatter: takes args or computed string and returns string or nothing // - also acts as a filter (i.e. return undefined to NOT log an entry)
// DEFAULT LOG is done to main console // ALL OTHER LOGGING (i.e. new streams) done to files: is that correct???
log() or log0() goto console always ALL OTHER go to streams: log.xyz()
in other words: log(...) ALWAYS goes to main/primary console log.abc(...) NEVER goes to main/primary console: need log0 viewer (on another terminal window) to view it
If no appID, use log0
If setApp, do early on can only do this ONCE per runtime per app
// ALL log files recycled (deleted/restarted) after certain size (else would grow to LARGE SIZES quickly)
// todo: DOCUMENT how/when to specify if log/stream is SYNC or not: matters for fast logging // - when order of entries matters (else some later entries may end up ahead of earlier ones) // - sync also ensures that all logging is complete before app end (e.g. if process.exit // called somewhere else; without sync, could leave some log entries unwritten) // CURRENT DEFAULT IS SYNC
The log0 viewer is like linux tail command but for multiple files at once including non-existing ones yet (e.g. where there may
not have been an entry into the error stream, say);)
usage: log0 [[app=]app-name] [stream directive]* where: live logs from 'app-name' are displayed - 'app=' prefix optional if 'app-name' dir exists already - if no app-name specified, 'log0' is used by default can have 0 or more [stream directive] - if no directives, all streams for app are displayed live - each stream directive has format: [+|-]stream-name[...] '+' to display a stream (default so '+' optional) '-' to NOT display that stream (use when displaying any other streams) - if any '+' directive(s), only those stream(s) are displayed - if only '-' directive(s), all other streams displayed - use ellipsis ('...') as wildcards to display streams whose names contain specific words (see below)
// basically, from separate terminal windows:
// - log0 [to view ALL logs (streams) for unnamed app(s)]
// - log0 my-app [to view ALL logs (streams) for app named 'my-app']
// - log0 my-app error warning [to view only the error and warning stream for app named 'my-app']
// - log0 my-app ...error ...warning [to view my-app streams with names ending in 'error' or 'warning']
// - log0 my-app error... ...warning [to view my-app streams with names starting with 'error' or ending with 'warning']
// - log0 my-app ...abcxyz... warning.severe [to view my-app streams with names containing 'abcxyz'; also the warning.severe stream]
WILDCARDS in stream names:
- use '...' as a wildcard [instead of the more intuitive '*' because linux shells
(e.g. bash, zsh) treat '*' as a shell construct and gobble it up]
- '...' can be used as prefix, suffix, or anywhere in between:
SO, for example, can do this:
log0 app-name ...abcx [view streams that end with 'abcx']
log0 app-name abcx... [view streams that start with 'abcx']
log0 app-name ...xyz... [view streams that contain 'xyz' in their name]
log0 app-name +...xyz... [same as above]
log0 app-name -...xyz... [do NOT view any stream that contains xyz in its name]
cmd> log0 ...
log0's "magic" is in using plain text files in the background which can then be viewed by other concurrent processes. These files are usually deleted before or after after each use to prevent unbound storage issues (though you have control over this, including size of the files before, or if, deleted)
~/.log0 (for example /Users/Frederic/.log0)log0 and so is kept as ~/.log0/log0;log.set({app: 'apple-pie'});, its logs will be kept under ~/.log0/apple-pieStream files (i.e. the actual log files) are then kept as single files under each app's applicable log0 directory, as per above.
The following very low priority items may be considered for future implementation.
Since the idea is to keep log0 slim & very lightweight, the implementation of items below will be based on user demand (if any and only if significant: so, let me know!).
Like it says... 😀
A feature to allow a stream (e.g. log.streamX()) to be written out to simulataneous files, or to be sent
to multiple destinations. A little like the tee feature in Linux.
This could include other files, or event being emitted, or a more permanent syslog, or even back to main console again.
possible implementation: log.streamx.set({duplicate: {...parms here...}});
A feature to allow a specific log/stream (e.g. log.streamX()) to be kept open
using (for example) fs.createWriteStream(filename, { flags: 'a', encoding: 'utf8' })
instead of being one-off appended on every call, as done currently (fs.appendFile(filename, logEntry)).
This could improve performance in high-volume, low-latency cases, where a lot of log entries are being generated in a very short amount of time (e.g. sub-milliseconds);
possible implementation: log.streamx.set({streamingMode: 'keep open'});
note: would then want to have: process.on('exit', () => strm.close());
A feature to allow a file to be written in a circular fashion: when end of max-size of file is reached, write new entries back at the front.
This would simplifiy maximum file size (no need to delete, re-create) and allow for a record left of prior entries (i.e. a tail) which is currently lost when a log file is recycled (i.e. deleted before new entries are written)
While it would be a nice clean solution, a challenge would be how to efficiently keep track of current start and end of the file, and how this gets communicated to the viewers.
FAQs
a minimal local logger that improves on console.log for node.js development
The npm package log0 receives a total of 1 weekly downloads. As such, log0 popularity was classified as not popular.
We found that log0 demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.