Как получить результат console.trace () в виде строки в javascript с помощью Chrome или Firefox?

99

console.trace()выводит результат на консоль.
Я хочу получить результаты в виде строки и сохранить их в файл.

Я не определяю имена для функций, и я также не могу получить их имена callee.caller.name.

js_
источник
1
это не работает в PhantomJS :(
ekkis

Ответы:

103

Я не уверен насчет firefox, но в v8 / chrome вы можете использовать метод вызываемого конструктора Error captureStackTrace. ( Подробнее здесь )

Итак, хакерский способ получить это:

var getStackTrace = function() {
  var obj = {};
  Error.captureStackTrace(obj, getStackTrace);
  return obj.stack;
};

console.log(getStackTrace());

Обычно getStackTraceпри захвате будет в стеке. Второй аргумент исключает getStackTraceвключение в трассировку стека.

chjj
источник
18
Спасибо за информацию. Это работало в хроме, но не в Firefox. Я снова поискал и нашел Error().stack. Хотя имена объектов и функций теряются в firefox, а имя объекта теряется в chrome (так же, как Error.captureStackTrace), Error().stackработает в обоих браузерах и дает мне достаточно информации для отладки.
js_
Точно такой же результат, как ответ @Konstantin Smolyanin. В результате остались те же ограниченные детали.
Codebeat 04
Это не должен быть общепринятым ответом. Стек, который вы здесь видите, является «сокращенным» и содержит только «верхнюю часть», а console.trace () покажет полный стек. См. Пример с глубиной стека 30 здесь: stackoverflow.com/questions/62768598/…
mathheadinclouds
34

Error.stack - это то, что вам нужно. Работает в Chrome и Firefox. Например

try { var a = {}; a.debug(); } catch(ex) {console.log(ex.stack)}

выдаст в Chrome:

TypeError: Object #<Object> has no method 'debug'
    at eval at <anonymous> (unknown source)
    at eval (native)
    at Object._evaluateOn (unknown source)
    at Object._evaluateAndWrap (unknown source)
    at Object.evaluate (unknown source)

и в Firefox:

@http://www.google.com.ua/:87 _firebugInjectedEvaluate("with(_FirebugCommandLine){try { var a = {}; a.debug() } catch(ex) {console.log(ex.stack)}\n};")
@http://www.google.com.ua/:87 _firebugEvalEvent([object Event])
@http://www.google.com.ua/:67
Молекулярный человек
источник
2
Спасибо за Ваш ответ. Но это работает только при возникновении исключения. Мне нужно получить трассировку стека без исключения.
js_
8
Что насчет(new Error).stack
Джейсон Смит
Это должно вызвать исключение в a.debug () - это дорогой способ получить стек, но он должен работать.
fijiaaron
Этот подход также удобен при попытке получить трассировку от некоторого кода, который может работать только, например, PhantomJS и т.п. по какой-либо причине.
Waxspin
18

Это даст трассировку стека (как массив строк) для современных Chrome, Firefox, Opera и IE10 +

function getStackTrace () {

  var stack;

  try {
    throw new Error('');
  }
  catch (error) {
    stack = error.stack || '';
  }

  stack = stack.split('\n').map(function (line) { return line.trim(); });
  return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

Использование:

console.log(getStackTrace().join('\n'));

Он исключает из стека свой собственный вызов, а также заголовок «Ошибка», который используется Chrome и Firefox (но не IE).

Он не должен падать в старых браузерах, а просто возвращать пустой массив. Если вам нужно более универсальное решение, посмотрите stacktrace.js . Список поддерживаемых браузеров действительно впечатляет, но, на мой взгляд, он очень велик для той небольшой задачи, для которой он предназначен: 37 КБ уменьшенного текста, включая все зависимости.

Константин Смолянин
источник
12

Существует библиотека под названием stacktrace.js, которая дает вам кроссбраузерную трассировку стека. Вы можете использовать его, просто включив скрипт и вызвав в любой момент:

var trace = printStackTrace();
Fijiaaron
источник
Я бы посмотрел на github.com/stacktracejs/stacktrace.js, поскольку реализация была изменена для поддержки обещаний ES6.
Эрез Коэн,
Обратите внимание, что на данный момент следует использовать это: github.com/stacktracejs/stacktrace.js/tree/stable?files=1 (новая версия еще не выпущена)
Эрез Коэн
10

Это лишь незначительное улучшение отличного кода Константина. Это немного сокращает расходы на перехват и просто создает экземпляр стека ошибок:

function getStackTrace () {
    let stack = new Error().stack || '';
    stack = stack.split('\n').map(function (line) { return line.trim(); });
    return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

Обычно мне нужен определенный уровень трассировки стека (для моего пользовательского регистратора), поэтому это также возможно при вызове:

getStackTrace()[2]; // get stack trace info 2 levels-deep
сгурос
источник
6

вам только нужно var stack = new Error().stack. это упрощенная версия ответа @sgouros.

function foo() {
  bar();
}
function bar() {
  baz();
}
function baz() {
  console.log(new Error().stack);
}

foo();

Наверное, не будет работать в каждом браузере (работает в Chrome).

jcubic
источник