UNPKG

2.18 kBJavaScriptView Raw
1'use strict'
2
3let cli = require('heroku-cli-util')
4let EventSource = require('eventsource')
5let url = require('url')
6let liner = require('../lib/line_transform')
7const colorize = require('./colorize')
8const HTTP = require('http-call')
9
10function readLogs (logplexURL) {
11 let u = url.parse(logplexURL)
12 if (u.query && u.query.includes('srv')) {
13 return readLogsV1(logplexURL)
14 } else {
15 return readLogsV2(logplexURL)
16 }
17}
18
19async function readLogsV1 (logplexURL) {
20 let {response} = await HTTP.stream(logplexURL)
21 return new Promise(function (resolve, reject) {
22 response.setEncoding('utf8')
23 liner.setEncoding('utf8')
24 response.pipe(liner)
25 liner.on('data', line => cli.log(colorize(line)))
26 response.on('end', resolve)
27 response.on('error', reject)
28 })
29}
30
31function readLogsV2 (logplexURL) {
32 return new Promise(function (resolve, reject) {
33 const u = url.parse(logplexURL, true)
34 const isTail = u.query.tail && u.query.tail === 'true'
35 const userAgent = process.env.HEROKU_DEBUG_USER_AGENT || 'heroku-run'
36 const proxy = process.env.https_proxy || process.env.HTTPS_PROXY
37 const es = new EventSource(logplexURL, {
38 proxy,
39 headers: {
40 'User-Agent': userAgent
41 }
42 })
43
44 es.onerror = function (err) {
45 if (!isTail) {
46 resolve()
47 es.close()
48 }
49
50 if (err && (err.status === 404 || err.status === 403)) {
51 reject(new Error('Log stream timed out. Please try again.'))
52 es.close()
53 }
54 }
55
56 es.onmessage = function (e) {
57 e.data.trim().split(/\n+/).forEach((line) => {
58 cli.log(colorize(line))
59 })
60 }
61 })
62}
63
64async function logDisplayer (heroku, options) {
65 process.stdout.on('error', err => {
66 if (err.code === 'EPIPE') {
67 process.exit(0)
68 } else {
69 console.error(err.stack)
70 process.exit(1)
71 }
72 })
73 const response = await heroku.request({
74 path: `/apps/${options.app}/log-sessions`,
75 method: 'POST',
76 body: {
77 tail: options.tail,
78 dyno: options.dyno,
79 source: options.source,
80 lines: options.lines
81 }
82 })
83 return readLogs(response.logplex_url)
84}
85
86module.exports = logDisplayer