├── .gitignore
├── README.md
├── index.html
├── index.js
├── package.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Inline log
2 |
3 | I wrote a tiny (potentially naff) logger thing that captures all `stdout` and `stderr` and logs in realtime to the browser (using server sent events).
4 |
5 | Kinda inspired by the way [Zeit's now](https://zeit.co/now) shows you a loading screen during deployment, but I wanted to get at the stdout logging on my now instances (since you don't have this functionality at the moment).
6 |
7 | ## Install
8 |
9 | Firslty get the module: `npm i -S inline-log`, then in your http server (I'm using Express below):
10 |
11 | ```js
12 | app.use('/_logger', require('inline-log')({ limit: 50 }))
13 | ```
14 |
15 | That'll capture all the stdout/err and when you visit http://my-site.com/_logger it'll put your logs on the screen (with the last 50 lines). Obviously you can add auth or stuff before the middleware too.
16 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | _log
5 |
6 |
70 |
71 |
72 |
73 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const intercept = require('intercept-stdout');
2 | const localLogger = require('fs').readFileSync(__dirname + '/index.html', 'utf8');
3 | let connections = [];
4 | let id = 0;
5 | const log = [];
6 |
7 | module.exports = ({ limit = 50 } = {}) => {
8 | unhook = intercept(
9 | captureLog.bind(null, 'stdout', limit),
10 | captureLog.bind(null, 'stderr', limit)
11 | );
12 | return logger;
13 | };
14 |
15 | function captureLog(type, limit, txt) {
16 | id++;
17 | const data = { txt, id, timestamp: new Date().toJSON(), type };
18 | log.push(data);
19 | connections = connections.filter(res => {
20 | if (res.connection.writable) {
21 | res.write(`data: ${JSON.stringify(data)}\neventId:${id}\n\n`);
22 | return true;
23 | }
24 |
25 | try {
26 | res.close();
27 | } catch (e) {};
28 |
29 | return false;
30 | });
31 |
32 | log.splice(0, log.length - limit);
33 | }
34 |
35 | function logger(req, res, next) {
36 | if (req.headers.accept !== 'text/event-stream') {
37 | // send the HTML page instead
38 | res.writeHead(200, { 'content-type': 'text/html' });
39 | res.end(localLogger);
40 | return;
41 | }
42 | // req.socket.setTimeout(Infinity);
43 | res.writeHead(200, {
44 | 'content-type': 'text/event-stream',
45 | 'cache-control': 'no-cache',
46 | 'connection': 'keep-alive',
47 | 'x-accel-buffering': 'no',
48 | 'transfer-encoding': '',
49 | });
50 |
51 | let offset = parseInt(req.headers['Last-Event-ID'], 10) || 0;
52 |
53 | // flush
54 | res.write('\n'.repeat(2048));
55 |
56 | log.forEach(log => {
57 | if (log.id > offset) {
58 | res.write(`data: ${JSON.stringify(log)}\neventId:${log.id}\n\n`);
59 | }
60 | });
61 |
62 | connections.push(res);
63 | }
64 |
65 | setInterval(() => {
66 | connections = connections.filter(res => {
67 | if (res.connection.writable) {
68 | res.write(`eventId:${id}\n\n`);
69 | return true;
70 | }
71 |
72 | try {
73 | res.close();
74 | } catch (e) {};
75 |
76 | return false;
77 | });
78 | }, 1000);
79 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "inline-log",
3 | "version": "1.0.5",
4 | "description": "Middleware logger that captures STDOUT + STDERR",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "Remy Sharp",
11 | "license": "MIT",
12 | "dependencies": {
13 | "intercept-stdout": "^0.1.2"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 | intercept-stdout:
4 | version "0.1.2"
5 | resolved "https://registry.yarnpkg.com/intercept-stdout/-/intercept-stdout-0.1.2.tgz#126abf1fae6c509a428a98c61a631559042ae9fd"
6 | dependencies:
7 | lodash.toarray "^3.0.0"
8 |
9 | lodash._arraycopy@^3.0.0:
10 | version "3.0.0"
11 | resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1"
12 |
13 | lodash._basevalues@^3.0.0:
14 | version "3.0.0"
15 | resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7"
16 |
17 | lodash._getnative@^3.0.0:
18 | version "3.9.1"
19 | resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
20 |
21 | lodash.isarguments@^3.0.0:
22 | version "3.1.0"
23 | resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
24 |
25 | lodash.isarray@^3.0.0:
26 | version "3.0.4"
27 | resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
28 |
29 | lodash.keys@^3.0.0:
30 | version "3.1.2"
31 | resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
32 | dependencies:
33 | lodash._getnative "^3.0.0"
34 | lodash.isarguments "^3.0.0"
35 | lodash.isarray "^3.0.0"
36 |
37 | lodash.toarray@^3.0.0:
38 | version "3.0.2"
39 | resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-3.0.2.tgz#2b204f0fa4f51c285c6f00c81d1cea5a23041179"
40 | dependencies:
41 | lodash._arraycopy "^3.0.0"
42 | lodash._basevalues "^3.0.0"
43 | lodash.keys "^3.0.0"
44 |
45 |
--------------------------------------------------------------------------------