'use strict' let cli = require('heroku-cli-util') let EventSource = require('@heroku/eventsource') let url = require('url') let liner = require('../lib/line_transform') const colorize = require('./colorize') const HTTP = require('http-call') function readLogs (logplexURL) { let u = url.parse(logplexURL) if (u.query && u.query.includes('srv')) { return readLogsV1(logplexURL) } else { return readLogsV2(logplexURL) } } async function readLogsV1 (logplexURL) { let {response} = await HTTP.stream(logplexURL) return new Promise(function (resolve, reject) { response.setEncoding('utf8') liner.setEncoding('utf8') response.pipe(liner) liner.on('data', line => cli.log(colorize(line))) response.on('end', resolve) response.on('error', reject) }) } function readLogsV2 (logplexURL) { return new Promise(function (resolve, reject) { const u = url.parse(logplexURL, true) const isTail = u.query.tail && u.query.tail === 'true' const userAgent = process.env.HEROKU_DEBUG_USER_AGENT || 'heroku-run' const proxy = process.env.https_proxy || process.env.HTTPS_PROXY const es = new EventSource(logplexURL, { proxy, headers: { 'User-Agent': userAgent } }) es.onerror = function (err) { if (err && (err.status || err.message)) { const msg = (isTail && (err.status === 404 || err.status === 403)) ? 'Log stream timed out. Please try again.' : `Logs eventsource failed with: ${err.status} ${err.message}` reject(msg) es.close() } if (!isTail) { resolve() es.close() } // should only land here if --tail and no error status or message } es.onmessage = function (e) { e.data.trim().split(/\n+/).forEach((line) => { cli.log(colorize(line)) }) } }) } async function logDisplayer (heroku, options) { process.stdout.on('error', err => { if (err.code === 'EPIPE') { process.exit(0) } else { console.error(err.stack) process.exit(1) } }) const response = await heroku.request({ path: `/apps/${options.app}/log-sessions`, method: 'POST', body: { tail: options.tail, dyno: options.dyno, source: options.source, lines: options.lines } }) return readLogs(response.logplex_url) } module.exports = logDisplayer