UNPKG

19.5 kBMarkdownView Raw
1<!-- TITLE/ -->
2
3<h1>Caterpillar</h1>
4
5<!-- /TITLE -->
6
7
8<!-- BADGES/ -->
9
10<span class="badge-githubworkflow"><a href="https://github.com/bevry/caterpillar/actions?query=workflow%3Abevry" title="View the status of this project's GitHub Workflow: bevry"><img src="https://github.com/bevry/caterpillar/workflows/bevry/badge.svg" alt="Status of the GitHub Workflow: bevry" /></a></span>
11<span class="badge-npmversion"><a href="https://npmjs.org/package/caterpillar" title="View this project on NPM"><img src="https://img.shields.io/npm/v/caterpillar.svg" alt="NPM version" /></a></span>
12<span class="badge-npmdownloads"><a href="https://npmjs.org/package/caterpillar" title="View this project on NPM"><img src="https://img.shields.io/npm/dm/caterpillar.svg" alt="NPM downloads" /></a></span>
13<span class="badge-daviddm"><a href="https://david-dm.org/bevry/caterpillar" title="View the status of this project's dependencies on DavidDM"><img src="https://img.shields.io/david/bevry/caterpillar.svg" alt="Dependency Status" /></a></span>
14<span class="badge-daviddmdev"><a href="https://david-dm.org/bevry/caterpillar#info=devDependencies" title="View the status of this project's development dependencies on DavidDM"><img src="https://img.shields.io/david/dev/bevry/caterpillar.svg" alt="Dev Dependency Status" /></a></span>
15<br class="badge-separator" />
16<span class="badge-githubsponsors"><a href="https://github.com/sponsors/balupton" title="Donate to this project using GitHub Sponsors"><img src="https://img.shields.io/badge/github-donate-yellow.svg" alt="GitHub Sponsors donate button" /></a></span>
17<span class="badge-patreon"><a href="https://patreon.com/bevry" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
18<span class="badge-flattr"><a href="https://flattr.com/profile/balupton" title="Donate to this project using Flattr"><img src="https://img.shields.io/badge/flattr-donate-yellow.svg" alt="Flattr donate button" /></a></span>
19<span class="badge-liberapay"><a href="https://liberapay.com/bevry" title="Donate to this project using Liberapay"><img src="https://img.shields.io/badge/liberapay-donate-yellow.svg" alt="Liberapay donate button" /></a></span>
20<span class="badge-buymeacoffee"><a href="https://buymeacoffee.com/balupton" title="Donate to this project using Buy Me A Coffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg" alt="Buy Me A Coffee donate button" /></a></span>
21<span class="badge-opencollective"><a href="https://opencollective.com/bevry" title="Donate to this project using Open Collective"><img src="https://img.shields.io/badge/open%20collective-donate-yellow.svg" alt="Open Collective donate button" /></a></span>
22<span class="badge-crypto"><a href="https://bevry.me/crypto" title="Donate to this project using Cryptocurrency"><img src="https://img.shields.io/badge/crypto-donate-yellow.svg" alt="crypto donate button" /></a></span>
23<span class="badge-paypal"><a href="https://bevry.me/paypal" title="Donate to this project using Paypal"><img src="https://img.shields.io/badge/paypal-donate-yellow.svg" alt="PayPal donate button" /></a></span>
24<span class="badge-wishlist"><a href="https://bevry.me/wishlist" title="Buy an item on our wishlist for us"><img src="https://img.shields.io/badge/wishlist-donate-yellow.svg" alt="Wishlist browse button" /></a></span>
25
26<!-- /BADGES -->
27
28
29<!-- DESCRIPTION/ -->
30
31Caterpillar is the ultimate logging system for Deno, Node.js, and Web Browsers. Log levels are implemented to the RFC standard. Log entries can be filtered and piped to various streams, including coloured output to the terminal, the browser's console, and debug files. You can even write your own transforms.
32
33<!-- /DESCRIPTION -->
34
35
36## Usage
37
38[Complete API Documentation.](http://master.caterpillar.bevry.surge.sh/docs/)
39
40### Examples
41
42- [Deno Example](https://repl.it/@balupton/caterpillar-deno)
43- [Node.js Example](https://repl.it/@balupton/caterpillar-node)
44- [Web Browser Example](https://repl.it/@balupton/caterpillar-browser)
45- [Writing a Custom Transform](https://repl.it/@balupton/caterpillar-custom-transform)
46
47### Overview
48
49The RFC Log Levels are provided by the [`rfc-log-levels` package](https://github.com/bevry/rfc-log-levels) which follows [RFC 3164 - The BSD Syslog Protocol](http://www.faqs.org/rfcs/rfc3164.html).
50
51[Log Entries](http://master.caterpillar.bevry.surge.sh/docs/interfaces/logentry.html) that are within the [lineLevel](http://master.caterpillar.bevry.surge.sh/docs/classes/logger.html#linelevel) range, will have their line information fetched using the [`get-current-line` package](https://github.com/bevry/get-current-line).
52
53The [`Logger`](http://master.caterpillar.bevry.surge.sh/docs/classes/logger.html) is what you write your log messages to, which you then pipe to destinations and transforms.
54
55The [`Filter` transport](http://master.caterpillar.bevry.surge.sh/docs/classes/filter.html) is used to filter out log levels that we do not want to pass onto the next destination.
56
57The [`Human` transport](http://master.caterpillar.bevry.surge.sh/docs/classes/human.html) is used to convert the Log Entries into a human readable and colourful output.
58
59The [`Browser` transport](https://github.com/bevry/caterpillar/blob/master/source/transforms/browser.ts) is used to send the human output, including colours, to the Web Browser console.
60
61The [`Transform`](http://master.caterpillar.bevry.surge.sh/docs/classes/transform.html) is used to write your own transforms, and is what all the others are based from.
62
63### Node.js Guide
64
65To get started for Node.js, setup a new Node.js project for this guide and install Caterpillar.
66
67```bash
68mkdir caterpillar-guide
69cd caterpillar-guide
70npm init
71npm install --save caterpillar
72touch index.js
73```
74
75Then edit our `index.js` file with the following, that will output all the log messages in JSON format to stdout, and can be run via `node index.js`:
76
77```javascript
78const { Logger } = require('caterpillar')
79const logger = new Logger()
80
81logger.pipe(process.stdout)
82
83logger.log('warn', 'this is a warning, which is level', 4)
84logger.warn('this is a warning, which is level', 4)
85logger.log('debug', 'this is a debug message, which is level', 7)
86logger.warn('this is a debug message, which is level', 7)
87```
88
89Outputting in JSON format is not a nice experience, instead we can do better by using the [`Human` transport](http://master.caterpillar.bevry.surge.sh/docs/classes/human.html) such that it is human readable.
90
91```javascript
92const { Logger, Human } = require('caterpillar')
93const logger = new Logger()
94
95logger.pipe(new Human()).pipe(process.stdout)
96
97logger.log('warn', 'this is a warning, which is level', 4)
98logger.warn('this is a warning, which is level', 4)
99logger.log('debug', 'this is a debug message, which is level', 7)
100logger.warn('this is a debug message, which is level', 7)
101```
102
103However, perhaps we want to still store the JSON format for querying later. We can pipe the human format to stdout as before, but we can pipe the raw output to a debug file.
104
105```javascript
106const { Logger, Human } = require('caterpillar')
107const logger = new Logger()
108
109const { createWriteStream } = require('fs')
110logger.pipe(createWriteStream('./debug.log'))
111
112logger.pipe(new Human()).pipe(process.stdout)
113
114logger.log('warn', 'this is a warning, which is level', 4)
115logger.warn('this is a warning, which is level', 4)
116logger.log('debug', 'this is a debug message, which is level', 7)
117logger.warn('this is a debug message, which is level', 7)
118```
119
120Now let's stay for some reason, we want to capitalise all the log messages that are warning levels and higher, we can do this by making our own transport by extending the [`Transform`](http://master.caterpillar.bevry.surge.sh/docs/classes/transform.html).
121
122```javascript
123const { Logger, Transform, Human } = require('caterpillar')
124const logger = new Logger()
125
126const { createWriteStream } = require('fs')
127logger.pipe(createWriteStream('./debug.log'))
128
129class Uppercase extends Transform {
130 format(entry) {
131 if (entry.levelNumber <= 4) {
132 entry.args.forEach(function (value, index) {
133 if (typeof value === 'string') {
134 entry.args[index] = value.toUpperCase()
135 }
136 })
137 }
138 return entry
139 }
140}
141
142logger.pipe(new Uppercase()).pipe(new Human()).pipe(process.stdout)
143
144logger.log('warn', 'this is a warning, which is level', 4)
145logger.warn('this is a warning, which is level', 4)
146logger.log('debug', 'this is a debug message, which is level', 7)
147logger.warn('this is a debug message, which is level', 7)
148```
149
150Futhermore, the user probably doesn't need to see debug messages, even though they are useful for debugging. We can filter out the debug messages for the user, but maintain them for the `debug.log` file by applying the [`Filter` transport](http://master.caterpillar.bevry.surge.sh/docs/classes/filter.html) to the pipe that goes to stdout.
151
152```javascript
153const { Logger, Transform, Filter, Human } = require('caterpillar')
154const logger = new Logger()
155
156const { createWriteStream } = require('fs')
157logger.pipe(createWriteStream('./debug.log'))
158
159class Uppercase extends Transform {
160 format(entry) {
161 if (entry.levelNumber <= 4) {
162 entry.args.forEach(function (value, index) {
163 if (typeof value === 'string') {
164 entry.args[index] = value.toUpperCase()
165 }
166 })
167 }
168 return entry
169 }
170}
171
172logger
173 .pipe(new Filter({ filterLevel: 5 }))
174 .pipe(new Uppercase())
175 .pipe(new Human())
176 .pipe(process.stdout)
177
178logger.log('warn', 'this is a warning, which is level', 4)
179logger.warn('this is a warning, which is level', 4)
180logger.log('debug', 'this is a debug message, which is level', 7)
181logger.warn('this is a debug message, which is level', 7)
182```
183
184As fetching line information is computationally expensive process, for large applications for performance we probably only want to fetch the line information for messages that we actually show to the user. As such, we should make the [`filterLevel`](http://master.caterpillar.bevry.surge.sh/docs/classes/filter.html#filterlevel) and the [`lineLevel`](http://master.caterpillar.bevry.surge.sh/docs/classes/logger.html#linelevel) the same.
185
186```javascript
187const { Logger, Transform, Filter, Human } = require('caterpillar')
188const level = 5
189const logger = new Logger({ lineLevel: level })
190
191const { createWriteStream } = require('fs')
192logger.pipe(createWriteStream('./debug.log'))
193
194class Uppercase extends Transform {
195 format(entry) {
196 if (entry.levelNumber <= 4) {
197 entry.args.forEach(function (value, index) {
198 if (typeof value === 'string') {
199 entry.args[index] = value.toUpperCase()
200 }
201 })
202 }
203 return entry
204 }
205}
206
207logger
208 .pipe(new Filter({ filterLevel: 5 }))
209 .pipe(new Uppercase())
210 .pipe(new Human())
211 .pipe(process.stdout)
212
213logger.log('warn', 'this is a warning, which is level', 4)
214logger.warn('this is a warning, which is level', 4)
215logger.log('debug', 'this is a debug message, which is level', 7)
216logger.warn('this is a debug message, which is level', 7)
217```
218
219Finally, if we are using Caterpillar in web browser environments, instead of Node.js, instead of doing:
220
221```javascript
222const { Logger, Transform, Filter, Human } = require('caterpillar')
223// ...
224logger.pipe(new Human()).pipe(process.stdout)
225// ...
226```
227
228We would pipe to the Browser transform instead of to stdout.
229
230```javascript
231const { Logger, Transform, Filter, Human, Browser } = require('caterpillar')
232// ...
233logger.pipe(new Human()).pipe(new Browser())
234// ...
235```
236
237With this, you now have enough information to leverage the cross-platform power of Caterpillar for most purposes, and the power to write your own custom transforms which can be published as their own packages and shared.
238
239<!-- INSTALL/ -->
240
241<h2>Install</h2>
242
243<a href="https://npmjs.com" title="npm is a package manager for javascript"><h3>npm</h3></a>
244<ul>
245<li>Install: <code>npm install --save caterpillar</code></li>
246<li>Import: <code>import * as pkg from ('caterpillar')</code></li>
247<li>Require: <code>const pkg = require('caterpillar')</code></li>
248</ul>
249
250<a href="https://www.skypack.dev" title="Skypack is a JavaScript Delivery Network for modern web apps"><h3>Skypack</h3></a>
251
252``` html
253<script type="module">
254 import * as pkg from '//cdn.skypack.dev/caterpillar@^6.8.0'
255</script>
256```
257
258<a href="https://unpkg.com" title="unpkg is a fast, global content delivery network for everything on npm"><h3>unpkg</h3></a>
259
260``` html
261<script type="module">
262 import * as pkg from '//unpkg.com/caterpillar@^6.8.0'
263</script>
264```
265
266<a href="https://jspm.io" title="Native ES Modules CDN"><h3>jspm</h3></a>
267
268``` html
269<script type="module">
270 import * as pkg from '//dev.jspm.io/caterpillar@6.8.0'
271</script>
272```
273
274<h3><a href="https://editions.bevry.me" title="Editions are the best way to produce and consume packages you care about.">Editions</a></h3>
275
276<p>This package is published with the following editions:</p>
277
278<ul><li><code>caterpillar/source/index.ts</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> source code with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li>
279<li><code>caterpillar/edition-browsers/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#11th_Edition_–_ECMAScript_2020" title="ECMAScript ES2020">ES2020</a> for web browsers with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li>
280<li><code>caterpillar</code> aliases <code>caterpillar/edition-es2019/index.js</code></li>
281<li><code>caterpillar/edition-es2019/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_-_ECMAScript_2019" title="ECMAScript ES2019">ES2019</a> for <a href="https://nodejs.org" title="Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine">Node.js</a> 10 || 12 || 14 || 16 with <a href="https://nodejs.org/dist/latest-v5.x/docs/api/modules.html" title="Node/CJS Modules">Require</a> for modules</li>
282<li><code>caterpillar/edition-es2019-esm/index.js</code> is <a href="https://www.typescriptlang.org/" title="TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. ">TypeScript</a> compiled against <a href="https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_-_ECMAScript_2019" title="ECMAScript ES2019">ES2019</a> for <a href="https://nodejs.org" title="Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine">Node.js</a> 12 || 14 || 16 with <a href="https://babeljs.io/docs/learn-es2015/#modules" title="ECMAScript Modules">Import</a> for modules</li></ul>
283
284<!-- /INSTALL -->
285
286
287<!-- HISTORY/ -->
288
289<h2>History</h2>
290
291<a href="https://github.com/bevry/caterpillar/blob/master/HISTORY.md#files">Discover the release history by heading on over to the <code>HISTORY.md</code> file.</a>
292
293<!-- /HISTORY -->
294
295
296<!-- BACKERS/ -->
297
298<h2>Backers</h2>
299
300<h3>Maintainers</h3>
301
302These amazing people are maintaining this project:
303
304<ul><li><a href="https://balupton.com">Benjamin Lupton</a><a href="https://github.com/bevry/caterpillar/commits?author=balupton" title="View the GitHub contributions of Benjamin Lupton on repository bevry/caterpillar">view contributions</a></li></ul>
305
306<h3>Sponsors</h3>
307
308No sponsors yet! Will you be the first?
309
310<span class="badge-githubsponsors"><a href="https://github.com/sponsors/balupton" title="Donate to this project using GitHub Sponsors"><img src="https://img.shields.io/badge/github-donate-yellow.svg" alt="GitHub Sponsors donate button" /></a></span>
311<span class="badge-patreon"><a href="https://patreon.com/bevry" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
312<span class="badge-flattr"><a href="https://flattr.com/profile/balupton" title="Donate to this project using Flattr"><img src="https://img.shields.io/badge/flattr-donate-yellow.svg" alt="Flattr donate button" /></a></span>
313<span class="badge-liberapay"><a href="https://liberapay.com/bevry" title="Donate to this project using Liberapay"><img src="https://img.shields.io/badge/liberapay-donate-yellow.svg" alt="Liberapay donate button" /></a></span>
314<span class="badge-buymeacoffee"><a href="https://buymeacoffee.com/balupton" title="Donate to this project using Buy Me A Coffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg" alt="Buy Me A Coffee donate button" /></a></span>
315<span class="badge-opencollective"><a href="https://opencollective.com/bevry" title="Donate to this project using Open Collective"><img src="https://img.shields.io/badge/open%20collective-donate-yellow.svg" alt="Open Collective donate button" /></a></span>
316<span class="badge-crypto"><a href="https://bevry.me/crypto" title="Donate to this project using Cryptocurrency"><img src="https://img.shields.io/badge/crypto-donate-yellow.svg" alt="crypto donate button" /></a></span>
317<span class="badge-paypal"><a href="https://bevry.me/paypal" title="Donate to this project using Paypal"><img src="https://img.shields.io/badge/paypal-donate-yellow.svg" alt="PayPal donate button" /></a></span>
318<span class="badge-wishlist"><a href="https://bevry.me/wishlist" title="Buy an item on our wishlist for us"><img src="https://img.shields.io/badge/wishlist-donate-yellow.svg" alt="Wishlist browse button" /></a></span>
319
320<h3>Contributors</h3>
321
322These amazing people have contributed code to this project:
323
324<ul><li><a href="https://balupton.com">Benjamin Lupton</a><a href="https://github.com/bevry/caterpillar/commits?author=balupton" title="View the GitHub contributions of Benjamin Lupton on repository bevry/caterpillar">view contributions</a></li>
325<li><a href="https://github.com/thelfensdrfer">Tim Helfensdörfer</a><a href="https://github.com/bevry/caterpillar/commits?author=thelfensdrfer" title="View the GitHub contributions of Tim Helfensdörfer on repository bevry/caterpillar">view contributions</a></li>
326<li><a href="https://github.com/t-visualappeal">t-visualappeal</a><a href="https://github.com/bevry/caterpillar/commits?author=t-visualappeal" title="View the GitHub contributions of t-visualappeal on repository bevry/caterpillar">view contributions</a></li></ul>
327
328<a href="https://github.com/bevry/caterpillar/blob/master/CONTRIBUTING.md#files">Discover how you can contribute by heading on over to the <code>CONTRIBUTING.md</code> file.</a>
329
330<!-- /BACKERS -->
331
332
333<!-- LICENSE/ -->
334
335<h2>License</h2>
336
337Unless stated otherwise all works are:
338
339<ul><li>Copyright &copy; 2012+ <a href="http://bevry.me">Bevry Pty Ltd</a></li>
340<li>Copyright &copy; 2011 <a href="https://balupton.com">Benjamin Lupton</a></li></ul>
341
342and licensed under:
343
344<ul><li><a href="http://spdx.org/licenses/MIT.html">MIT License</a></li></ul>
345
346<!-- /LICENSE -->