Gathering detailed insights and metrics for le_node
Gathering detailed insights and metrics for le_node
npm install le_node
Typescript
Module System
Min. Node Version
Node Version
NPM Version
new feature: prepend hostnames to log lines (optional)
Published on 21 Jun 2017
node v7 support for CI
Published on 28 Nov 2016
fix for new winston release and logging error objects with winston
Published on 16 Nov 2016
socket hang up bug fix and bunyan version updated
Published on 09 Nov 2016
hot fix for multiple bunyan streams
Published on 30 Sept 2016
added option to disable socket inactivity timeout
Published on 27 Sept 2016
JavaScript (100%)
Love this project? Help keep it running — sponsor us today! 🚀
Total Downloads
5,948,246
Last Day
741
Last Week
4,363
Last Month
14,237
Last Year
219,869
108 Stars
287 Commits
60 Forks
66 Watching
7 Branches
238 Contributors
Minified
Minified + Gzipped
Latest Version
1.8.0
Package Id
le_node@1.8.0
Size
38.66 kB
NPM Version
6.4.1
Node Version
8.12.0
Publised On
25 Oct 2018
Cumulative downloads
Total Downloads
Last day
84.3%
741
Compared to previous day
Last week
63.3%
4,363
Compared to previous week
Last month
14.8%
14,237
Compared to previous month
Last year
-11.6%
219,869
Compared to previous year
26
Please use our updated library which supports specifying region to send your log data to.
Allows you to send logs to your logentries account from Node or io.js.
It might work with Browserify, too, but you would need to use shims for net and tls. Such shims do exist, based on forge, but I haven’t tested it. There’s a seperate client intended for use in the browser though, called le_js, which uses http and is optimized for browser-specific logging needs.
Tested in Node v0.10 + and io.js. It probably works in Node 0.8 too, but one of the test libraries (mitm) doesn’t, so it remains unconfirmed.
What is now "le_node" was previously "logentries-client"; users of le_node versions before 1.0.2 should read the sections below that detail differences if they wish to update.
1var Logger = require('le_node'); 2 3var logger = new Logger({ token: 'myAccessToken' }); 4 5logger.warning('The kittens have become alarmingly adorable.')
The options object you provide to the constructor only requires your access token, but you can configure its behavior further.
All of the following except token
, levels
and secure
can also be
configured after instantiation as settable properties on the client. They are
accessors, though, and invalid values will be ignored.
console.log
,
console.warn
and console.error
as appropriate. Default: false
.16192
.false
.1000
15 * 1000
fibonacci
or exponential
. Default: fibonnacci
15
.15 * 60 * 1000
.false
. More details on this below.flatten
is true, you can also indicate whether arrays
should be subject to the same process. Defaults to true
if flatten
is
true
; otherwise meaningless.false
.true
.Error
object, setting this to
true
will cause the stack trace to be included. Default: false.
secure
is false, or 443 if
it’s true.true
will enable debug logging with a default stdout
logger.log
method.The default log levels are:
You can provision the constructor with custom names for these levels with either an array or an object hash:
1[ 'boring', 'yawn', 'eh', 'hey' ] 2 3{ boring: 0, yawn: 1, eh: 2, hey: 3 }
In the former case, the index corresponds to the numeric level, so sparse arrays are valid. In either case, missing levels will be filled in with the defaults.
The minLevel
option respects either level number (e.g. 2
) or the name (e.g.
'eh'
).
The level names each become methods on the client, which are just sugar for
calling client.log(lvl, logentry)
with the first argument curried.
Since these names will appear on the client, they can’t collide with existing properties. Not that you’re particularly likely to try naming a log level ‘hasOwnProperty’ or ‘_write’ but I figured I should mention it.
So the following three are equivalent:
1logger.notice('my msg'); 2logger.log('notice', 'my msg'); 3logger.log(2, 'my msg');
It’s also possible to forgo log levels altogether. Just call log
with a single
argument and it will be interpretted as the log entry. When used this way, the
minLevel
setting is ignored.
'error'
The client is an EventEmitter, so you should (as always) make sure you have a
listener on 'error'
. Error events can occur when there’s been a problem with
the connection or if a method was called with invalid parameters. Note that
errors that occur during instantiation, as opposed to operation, will throw.
'log'
Triggered when a log is about to be written to the underlying connection. The prepared log object or string is supplied as an argument.
'connected'
and 'disconnected'
and 'timed out'
These indicate when a new connection to the host is established, destroyed or timed out due to client side inactivity. Inactivity timeout is normal if the connection is inactive for a configurable period of time (see inactivityTimeout); it will be reopened when needed again. Disconnection can be either a result of socket inactivity or a network failure.
'drain'
, 'finish'
, 'pipe'
, and 'unpipe'
These are events inherited from Writable
.
'connection drain'
DEPRECATED. Use buffer drain
event instead.
'buffer drain'
This event is emitted when the underlying ring buffer is fully consumed and Socket.write callback called. This can be useful when it’s time for the application to terminate but you want to be sure any pending logs have finished writing.
1 logger.notice({ type: 'server', event: 'shutdown' }); 2 logger.once('buffer drain', () => { 3 logger.closeConnection(); 4 logger.on('disconnected', () => { 5 process.exit(); 6 }); 7 });
'buffer shift'
Buffer shift event is emitted when the internal buffer is shifted due to reaching bufferSize
of events in the buffer. This event may be listened for security/operations related reasons as
each time this event is emitted, a log event will be discarded and discarded log event will
never make it to Logentries.
1logger.ringBuffer.on('buffer shift', () => { 2 // page devops or send an email 3});
Log entries can be strings or objects. If the log argument is an array, it will be interpretted as multiple log events.
In the case of objects, the native JSON.stringify serialization is augmented in several ways. In addition to handling circular references, it will automatically take care of a variety of objects and primitives which otherwise wouldn’t serialize correctly, like Error, RegExp, Set, Map, Infinity, NaN, etc.
If you choose to set withStack
to true, errors will include their stacktraces
as an array (so that they are not painful to look at). Be sure to turn on
"expand JSON" (meaning pretty print) in the options on logentries:
You can adjust this further by supplying your own custom replacer
. This is a
standard argument to JSON.stringify -- See MDN: JSON > Stringify > The Replacer Parameter
for details. In the event that you supply a custom replacer, it is applied
prior to the built-in replacer described above so you can override its behavior.
Two options are available, timestamp
and withLevel
, which will add data to
your log events. For objects, these are added as properties (non-mutatively).
For strings, these values are prepended. If the name of a property would cause
a collision with an existing property, it will be prepended with an underscore.
In some cases it will end up being easier to query your data if objects aren’t
deeply nested. With the flatten
and flattenArrays
options, you can tell the
client to transform objects like so:
{ "a": 1, "b": { "c": 2 } }
=> { "a": 1, "b.c": 2 }
If flattenArrays
has not been set to false, this transformation will apply to
arrays as well:
{ "a": [ "b", { "c": 3 } ] }
=> { "a.0": "b", "a.1.c": 3 }
In addition to log
and its arbitrary sugary cousins, you can call
closeConnection
to explicitly close an open connection if one exists; you
might wish to do this as part of a graceful exit. The connection will reopen if
you log further.
Also, because the client is actually a writable stream, you can call write
directly. This gives you lower-level access to writing entries. It is in object
mode, but this means it expects discreet units (one call = one entry), not
actual objects; you should pass in strings. This is useful if you want to pipe
stdout, for example.
If there’s a problem with the connection (network loss or congestion),
entries will be buffered in an internal ring buffer to a max of 16192(bufferSize
)
entries by default. After that, internal ring buffer will shift
records
to keep only last bufferSize
number of records in memory. A log that indicates the
buffer was full will be sent to internal logger "once" this happens.
If console
is true, these log entries will still display there, but they will
not make it to LogEntries.
You can adjust the maximum size of the buffer with the bufferSize
option.
You’ll want to raise it if you’re dealing with very high volume (either a high
number of logs per second, or when log entries are unusually long on average).
Outside of these situations, exceeding the max buffer size is more likely an
indication of creating logs in a synchronous loop (which seems like a bad idea).
If the connection fails, it will keep retrying with a fibonacci
backoff by default.
Connection retry will start with a delay of reconnectInitialDelay
and the delay between each retry
will go up to a maximum of reconnectMaxDelay
with each retry in fibonacci sequence.
Backoff strategy can be changed to exponential
through constructor if necessary.
A connection to the host does not guarantee that your logs are transmitting successfully. If you have a bad token, there is no feedback from the server to indicate this. The only way to confirm that your token is working is to check the live tail on Logentries. I will investigate this further to see if there’s some other means with which a token can be tested for validity.
If Winston is included in your package.json dependencies, simply requiring the
Logentries client will place the transport constructor at winston.transports
,
even if Winston itself hasn’t yet been required.
1var Logger = require('le_node'); 2var winston = require('winston'); 3 4assert(winston.transports.Logentries);
When adding a new Logentries transport, the options argument passed to Winston’s
add
method supports the usual options in addition to those which are Winston-
specific. If custom levels are not provided, Winston’s defaults will be used.
1winston.add(winston.transports.Logentries, { token: myToken });
In the hard-to-imagine case where you’re using Winston without including it in
package.json, you can explicitly provision the transport by first requiring
Winston and then calling Logger.provisionWinston()
.
For Bunyan it’s like so:
1var bunyan = require('bunyan'); 2 3var Logger = require('le_node'); 4 5var loggerDefinition = Logger.bunyanStream({ token: myToken }); 6 7// One stream 8var logger1 = bunyan.createLogger(loggerDefinition); 9 10// Multiple streams 11var logger2 = bunyan.createLogger({ 12 name: 'whatevs', 13 streams: [ loggerDefinition, otherLoggerDefinition ] 14});
As with Winston, the options argument takes the normal constructor options (with
the exception of timestamp
, which is an option you should set on Bunyan itself
instead). Bunyan uses six log levels, so the seventh and eighth, if provided,
will be ignored; by default Bunyan’s level names will be used.
The object returned by bunyanStream
is the Bunyan logging ‘channel’ definition
in total. If you want to futz with this you can -- you can change its name
or
get the stream
object itself from here.
When you create an account at Logentries (just a standard signup form; there’s a free tier), you can find the token you need. It’s shown during the initial walk- through but you can find it later under Logs/Hosts/{ the name of your host } -- on the far right, a gray TOKEN button that you can click to reveal the string.
That’s it -- once you have the token you’re set.
Previously, "le_node" and "logentries-client" were two different modules. The former has been replaced with the latter codebase, but the le_node name is the canonical repo (it’s referenced in many places). It’s still possible to get logentries-client under that name on NPM, but it’s soon just going to be an alias for this repository, le_node.
For users of le_node from before this switch, there are some important differences to note before upgrading.
The new codebase does follow the same essential pattern. If you only used the client constructor and the log methods previously, there may be no breaking changes for you. But for anybody else...
client.end()
Unlike old le_node, the client is itself a writable stream (and therefore you
can pipe to it, for example from stdout, though note that 1 write invocation =
1 log entry). This also means that it has standard writable stream events and
methods, including .end()
. In the old le_node, .end()
was a non-stream
method that closed the underlying connection to the host.
For the functionality previously provided by .end()
, use .closeConnection()
.
client.level()
and client.winston()
The old le_node had a method called level()
for setting the minimum log level.
This is now a property (not a method) called minLevel
. It can be set to either
the name of the level or its index. The level()
method has been added to the
new codebase to facilitate migration, but will be removed at a later date.
Simply requiring le_node now automatically provisions Winston, if present, with
a Logentries transport constructor. You don’t have to do anything else. The
winston()
method has also been added to the new codebase to prevent errors,
but it’s a noop and will be removed at a later date.
The old documentation seemed to suggest that placing a listener on the client for error events was an optional thing. This isn’t the case (and wasn’t the case in the old client, either). An unhandled error event from an EventEmitter is an unhandled error period. If you don’t place a listener for error events, your application will crash if the client emits an error.
The new codebase has a lot of new features, including some that are similar to, but not necessarilly the same as, old features that had been removed at some point or were just not documented.
The outstanding issues that exist for le_node at the time of writing are mostly things which either never affected this codebase or no longer make sense in regard to it.
time
and level
properties will never collide with existing props and are
both optionalYou should assume that there are other breaking changes which I am unaware of. When I wrote Logentries Client I hadn’t considered that it might replace le_node, so unfortunately interoperability was not on my mind. You’ll wish to test thoroughly before updating an existing codebase to use the new client.
.end()
method will not synchronously terminate the underlying
connection anymore. Instead, it waits for drain before doing so.level
property.level()
and winston()
methods with deprecation warnings so that
existing le_node applications do not throw TypeErrors.withLevel
and timeout
optionshost
and port
options for testingclient.log
client.log
method no longer accepts an arbitrary number of
log entry arguments (to support above case, which seems much likely to be
useful)minLevel
value to zero (1 was an accident)flatten
and flattenArray
optionswithStack
set to truewithStack
optionrunInContext()
to prevent template string problems(Pieced together to the best of my ability by reviewing commit history.)
Please email our support team at support@logentries.com if you need any help.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
Found 10/22 approved changesets -- score normalized to 4
Reason
project is archived
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-02-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More