UNPKG

2.4 kBJavaScriptView Raw
1'use strict'
2
3let cli = require('heroku-cli-util')
4let EventSource = require('@heroku/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 (err && (err.status || err.message)) {
46 const msg = (isTail && (err.status === 404 || err.status === 403)) ?
47 'Log stream timed out. Please try again.' :
48 `Logs eventsource failed with: ${err.status} ${err.message}`
49 reject(msg)
50 es.close()
51 }
52
53 if (!isTail) {
54 resolve()
55 es.close()
56 }
57
58 // should only land here if --tail and no error status or message
59 }
60
61 es.onmessage = function (e) {
62 e.data.trim().split(/\n+/).forEach((line) => {
63 cli.log(colorize(line))
64 })
65 }
66 })
67}
68
69async function logDisplayer (heroku, options) {
70 process.stdout.on('error', err => {
71 if (err.code === 'EPIPE') {
72 process.exit(0)
73 } else {
74 console.error(err.stack)
75 process.exit(1)
76 }
77 })
78 const response = await heroku.request({
79 path: `/apps/${options.app}/log-sessions`,
80 method: 'POST',
81 body: {
82 tail: options.tail,
83 dyno: options.dyno,
84 source: options.source,
85 lines: options.lines
86 }
87 })
88 return readLogs(response.logplex_url)
89}
90
91module.exports = logDisplayer