1 | 'use strict'
|
2 |
|
3 | let cli = require('heroku-cli-util')
|
4 | let EventSource = require('eventsource')
|
5 | let url = require('url')
|
6 | let liner = require('../lib/line_transform')
|
7 | const colorize = require('./colorize')
|
8 | const HTTP = require('http-call')
|
9 |
|
10 | function 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 |
|
19 | async 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 |
|
31 | function 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 |
|
64 | async 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 |
|
86 | module.exports = logDisplayer
|