Spec-Zone.ru › Node.js 20 LTS

Отчёт о диагностике

Устойчивость: 2 - Стабильно
История
Версия Изменения
v20.13.0

Добавлен параметр --report-exclude-network для исключения сетевых операций, которые в некоторых случаях могут замедлить генерацию отчёта.

Возвращает JSON-отчёт о диагностике, записывая его в файл.

Отчёт предназначен для использования в разработке, тестировании и производстве, для сбора и сохранения информации для определения проблем. Он включает JavaScript и системные трассировки стека, статистику кучи, информацию о платформе, использование ресурсов и т.д. При включённом параметре отчёта, отчёты о диагностике могут быть сгенерированы при необработанных исключениях, критических ошибках и пользовательских сигналах, а также вызваны программно через вызовы API.

Ниже приведён пример полного отчёта, сгенерированного при необработанном исключении, для справки.

{
  "header": {
    "reportVersion": 3,
    "event": "exception",
    "trigger": "Exception",
    "filename": "report.20181221.005011.8974.0.001.json",
    "dumpEventTime": "2018-12-21T00:50:11Z",
    "dumpEventTimeStamp": "1545371411331",
    "processId": 8974,
    "cwd": "/home/nodeuser/project/node",
    "commandLine": [
      "/home/nodeuser/project/node/out/Release/node",
      "--report-uncaught-exception",
      "/home/nodeuser/project/node/test/report/test-exception.js",
      "child"
    ],
    "nodejsVersion": "v12.0.0-pre",
    "glibcVersionRuntime": "2.17",
    "glibcVersionCompiler": "2.17",
    "wordSize": "64 bit",
    "arch": "x64",
    "platform": "linux",
    "componentVersions": {
      "node": "12.0.0-pre",
      "v8": "7.1.302.28-node.5",
      "uv": "1.24.1",
      "zlib": "1.2.11",
      "ares": "1.15.0",
      "modules": "68",
      "nghttp2": "1.34.0",
      "napi": "3",
      "llhttp": "1.0.1",
      "openssl": "1.1.0j"
    },
    "release": {
      "name": "node"
    },
    "osName": "Linux",
    "osRelease": "3.10.0-862.el7.x86_64",
    "osVersion": "#1 SMP Wed Mar 21 18:14:51 EDT 2018",
    "osMachine": "x86_64",
    "cpus": [
      {
        "model": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
        "speed": 2700,
        "user": 88902660,
        "nice": 0,
        "sys": 50902570,
        "idle": 241732220,
        "irq": 0
      },
      {
        "model": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
        "speed": 2700,
        "user": 88902660,
        "nice": 0,
        "sys": 50902570,
        "idle": 241732220,
        "irq": 0
      }
    ],
    "networkInterfaces": [
      {
        "name": "en0",
        "internal": false,
        "mac": "13:10:de:ad:be:ef",
        "address": "10.0.0.37",
        "netmask": "255.255.255.0",
        "family": "IPv4"
      }
    ],
    "host": "test_machine"
  },
  "javascriptStack": {
    "message": "Error: *** test-exception.js: throwing uncaught Error",
    "stack": [
      "at myException (/home/nodeuser/project/node/test/report/test-exception.js:9:11)",
      "at Object.<anonymous> (/home/nodeuser/project/node/test/report/test-exception.js:12:3)",
      "at Module._compile (internal/modules/cjs/loader.js:718:30)",
      "at Object.Module._extensions..js (internal/modules/cjs/loader.js:729:10)",
      "at Module.load (internal/modules/cjs/loader.js:617:32)",
      "at tryModuleLoad (internal/modules/cjs/loader.js:560:12)",
      "at Function.Module._load (internal/modules/cjs/loader.js:552:3)",
      "at Function.Module.runMain (internal/modules/cjs/loader.js:771:12)",
      "at executeUserCode (internal/bootstrap/node.js:332:15)"
    ]
  },
  "nativeStack": [
    {
      "pc": "0x000055b57f07a9ef",
      "symbol": "report::GetNodeReport(v8::Isolate*, node::Environment*, char const*, char const*, v8::Local<v8::String>, std::ostream&) [./node]"
    },
    {
      "pc": "0x000055b57f07cf03",
      "symbol": "report::GetReport(v8::FunctionCallbackInfo<v8::Value> const&) [./node]"
    },
    {
      "pc": "0x000055b57f1bccfd",
      "symbol": " [./node]"
    },
    {
      "pc": "0x000055b57f1be048",
      "symbol": "v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [./node]"
    },
    {
      "pc": "0x000055b57feeda0e",
      "symbol": " [./node]"
    }
  ],
  "javascriptHeap": {
    "totalMemory": 5660672,
    "executableMemory": 524288,
    "totalCommittedMemory": 5488640,
    "availableMemory": 4341379928,
    "totalGlobalHandlesMemory": 8192,
    "usedGlobalHandlesMemory": 3136,
    "usedMemory": 4816432,
    "memoryLimit": 4345298944,
    "mallocedMemory": 254128,
    "externalMemory": 315644,
    "peakMallocedMemory": 98752,
    "nativeContextCount": 1,
    "detachedContextCount": 0,
    "doesZapGarbage": 0,
    "heapSpaces": {
      "read_only_space": {
        "memorySize": 524288,
        "committedMemory": 39208,
        "capacity": 515584,
        "used": 30504,
        "available": 485080
      },
      "new_space": {
        "memorySize": 2097152,
        "committedMemory": 2019312,
        "capacity": 1031168,
        "used": 985496,
        "available": 45672
      },
      "old_space": {
        "memorySize": 2273280,
        "committedMemory": 1769008,
        "capacity": 1974640,
        "used": 1725488,
        "available": 249152
      },
      "code_space": {
        "memorySize": 696320,
        "committedMemory": 184896,
        "capacity": 152128,
        "used": 152128,
        "available": 0
      },
      "map_space": {
        "memorySize": 536576,
        "committedMemory": 344928,
        "capacity": 327520,
        "used": 327520,
        "available": 0
      },
      "large_object_space": {
        "memorySize": 0,
        "committedMemory": 0,
        "capacity": 1520590336,
        "used": 0,
        "available": 1520590336
      },
      "new_large_object_space": {
        "memorySize": 0,
        "committedMemory": 0,
        "capacity": 0,
        "used": 0,
        "available": 0
      }
    }
  },
  "resourceUsage": {
    "rss": "35766272",
    "free_memory": "1598337024",
    "total_memory": "17179869184",
    "available_memory": "1598337024",
    "maxRss": "36624662528",
    "constrained_memory": "36624662528",
    "userCpuSeconds": 0.040072,
    "kernelCpuSeconds": 0.016029,
    "cpuConsumptionPercent": 5.6101,
    "userCpuConsumptionPercent": 4.0072,
    "kernelCpuConsumptionPercent": 1.6029,
    "pageFaults": {
      "IORequired": 0,
      "IONotRequired": 4610
    },
    "fsActivity": {
      "reads": 0,
      "writes": 0
    }
  },
  "uvthreadResourceUsage": {
    "userCpuSeconds": 0.039843,
    "kernelCpuSeconds": 0.015937,
    "cpuConsumptionPercent": 5.578,
    "userCpuConsumptionPercent": 3.9843,
    "kernelCpuConsumptionPercent": 1.5937,
    "fsActivity": {
      "reads": 0,
      "writes": 0
    }
  },
  "libuv": [
    {
      "type": "async",
      "is_active": true,
      "is_referenced": false,
      "address": "0x0000000102910900",
      "details": ""
    },
    {
      "type": "timer",
      "is_active": false,
      "is_referenced": false,
      "address": "0x00007fff5fbfeab0",
      "repeat": 0,
      "firesInMsFromNow": 94403548320796,
      "expired": true
    },
    {
      "type": "check",
      "is_active": true,
      "is_referenced": false,
      "address": "0x00007fff5fbfeb48"
    },
    {
      "type": "idle",
      "is_active": false,
      "is_referenced": true,
      "address": "0x00007fff5fbfebc0"
    },
    {
      "type": "prepare",
      "is_active": false,
      "is_referenced": false,
      "address": "0x00007fff5fbfec38"
    },
    {
      "type": "check",
      "is_active": false,
      "is_referenced": false,
      "address": "0x00007fff5fbfecb0"
    },
    {
      "type": "async",
      "is_active": true,
      "is_referenced": false,
      "address": "0x000000010188f2e0"
    },
    {
      "type": "tty",
      "is_active": false,
      "is_referenced": true,
      "address": "0x000055b581db0e18",
      "width": 204,
      "height": 55,
      "fd": 17,
      "writeQueueSize": 0,
      "readable": true,
      "writable": true
    },
    {
      "type": "signal",
      "is_active": true,
      "is_referenced": false,
      "address": "0x000055b581d80010",
      "signum": 28,
      "signal": "SIGWINCH"
    },
    {
      "type": "tty",
      "is_active": true,
      "is_referenced": true,
      "address": "0x000055b581df59f8",
      "width": 204,
      "height": 55,
      "fd": 19,
      "writeQueueSize": 0,
      "readable": true,
      "writable": true
    },
    {
      "type": "loop",
      "is_active": true,
      "address": "0x000055fc7b2cb180",
      "loopIdleTimeSeconds": 22644.8
    }
  ],
  "workers": [],
  "environmentVariables": {
    "REMOTEHOST": "REMOVED",
    "MANPATH": "/opt/rh/devtoolset-3/root/usr/share/man:",
    "XDG_SESSION_ID": "66126",
    "HOSTNAME": "test_machine",
    "HOST": "test_machine",
    "TERM": "xterm-256color",
    "SHELL": "/bin/csh",
    "SSH_CLIENT": "REMOVED",
    "PERL5LIB": "/opt/rh/devtoolset-3/root//usr/lib64/perl5/vendor_perl:/opt/rh/devtoolset-3/root/usr/lib/perl5:/opt/rh/devtoolset-3/root//usr/share/perl5/vendor_perl",
    "OLDPWD": "/home/nodeuser/project/node/src",
    "JAVACONFDIRS": "/opt/rh/devtoolset-3/root/etc/java:/etc/java",
    "SSH_TTY": "/dev/pts/0",
    "PCP_DIR": "/opt/rh/devtoolset-3/root",
    "GROUP": "normaluser",
    "USER": "nodeuser",
    "LD_LIBRARY_PATH": "/opt/rh/devtoolset-3/root/usr/lib64:/opt/rh/devtoolset-3/root/usr/lib",
    "HOSTTYPE": "x86_64-linux",
    "XDG_CONFIG_DIRS": "/opt/rh/devtoolset-3/root/etc/xdg:/etc/xdg",
    "MAIL": "/var/spool/mail/nodeuser",
    "PATH": "/home/nodeuser/project/node:/opt/rh/devtoolset-3/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin",
    "PWD": "/home/nodeuser/project/node",
    "LANG": "en_US.UTF-8",
    "PS1": "\\u@\\h : \\[\\e[31m\\]\\w\\[\\e[m\\] >  ",
    "SHLVL": "2",
    "HOME": "/home/nodeuser",
    "OSTYPE": "linux",
    "VENDOR": "unknown",
    "PYTHONPATH": "/opt/rh/devtoolset-3/root/usr/lib64/python2.7/site-packages:/opt/rh/devtoolset-3/root/usr/lib/python2.7/site-packages",
    "MACHTYPE": "x86_64",
    "LOGNAME": "nodeuser",
    "XDG_DATA_DIRS": "/opt/rh/devtoolset-3/root/usr/share:/usr/local/share:/usr/share",
    "LESSOPEN": "||/usr/bin/lesspipe.sh %s",
    "INFOPATH": "/opt/rh/devtoolset-3/root/usr/share/info",
    "XDG_RUNTIME_DIR": "/run/user/50141",
    "_": "./node"
  },
  "userLimits": {
    "core_file_size_blocks": {
      "soft": "",
      "hard": "unlimited"
    },
    "data_seg_size_kbytes": {
      "soft": "unlimited",
      "hard": "unlimited"
    },
    "file_size_blocks": {
      "soft": "unlimited",
      "hard": "unlimited"
    },
    "max_locked_memory_bytes": {
      "soft": "unlimited",
      "hard": 65536
    },
    "max_memory_size_kbytes": {
      "soft": "unlimited",
      "hard": "unlimited"
    },
    "open_files": {
      "soft": "unlimited",
      "hard": 4096
    },
    "stack_size_bytes": {
      "soft": "unlimited",
      "hard": "unlimited"
    },
    "cpu_time_seconds": {
      "soft": "unlimited",
      "hard": "unlimited"
    },
    "max_user_processes": {
      "soft": "unlimited",
      "hard": 4127290
    },
    "virtual_memory_kbytes": {
      "soft": "unlimited",
      "hard": "unlimited"
    }
  },
  "sharedObjects": [
    "/lib64/libdl.so.2",
    "/lib64/librt.so.1",
    "/lib64/libstdc++.so.6",
    "/lib64/libm.so.6",
    "/lib64/libgcc_s.so.1",
    "/lib64/libpthread.so.0",
    "/lib64/libc.so.6",
    "/lib64/ld-linux-x86-64.so.2"
  ]
} copy

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

node --report-uncaught-exception --report-on-signal \
--report-on-fatalerror app.js copy
  • --report-uncaught-exception Включает генерацию отчёта при необработанных исключениях. Полезно для просмотра JavaScript стека в сочетании с системным стеком и другими данными среды выполнения.

  • --report-on-signal Включает генерацию отчёта при получении указанного (или предопределённого) сигнала в работающий процесс Node.js. (См. ниже, как изменить сигнал, вызывающий отчёт). Значение по умолчанию - SIGUSR2. Полезно, когда отчёт нужно инициировать из другой программы. Мониторы приложений могут использовать эту функцию для сбора отчётов через регулярные интервалы и отображения наглядно данных о среде выполнения.

Генерация отчёта на основе сигналов не поддерживается в Windows.

В обычных ситуациях нет необходимости изменять сигнал, вызывающий генерацию отчёта. Однако, если SIGUSR2 уже используется для других целей, этот флаг помогает изменить сигнал для генерации отчёта и сохранить исходное значение SIGUSR2 для этих целей.

  • --report-on-fatalerror Включает генерацию отчёта при возникновении критических ошибок (внутренних ошибок среды выполнения Node.js, таких как недостаток памяти), приводящих к завершению приложения. Полезно для проверки различных элементов диагностических данных, таких как куча, стек, состояние цикла событий, использование ресурсов и т.д. для анализа критической ошибки.

  • --report-compact Записывает отчёты в компактном формате JSON в одной строке, что более удобно для систем обработки логов, чем стандартный многострочный формат, предназначенный для чтения человеком.

  • --report-directory Место, где будет сгенерирован отчёт.

  • --report-filename Имя файла, в который будет записан отчёт.

  • --report-signal Устанавливает или сбрасывает сигнал для генерации отчёта (не поддерживается в Windows). Значение по умолчанию - SIGUSR2.

  • --report-exclude-network Исключить header.networkInterfaces из отчёта о диагностике. По умолчанию это не установлено, и сетевые интерфейсы включены.

Отчёт также может быть вызван через API-вызов из приложения JavaScript:

process.report.writeReport(); copy

Эта функция принимает необязательный дополнительный аргумент filename, который представляет собой имя файла, в который записывается отчёт.

process.report.writeReport('./foo.json'); copy

Эта функция принимает необязательный дополнительный аргумент err, который является объектом Error, который будет использоваться в качестве контекста для вывода JavaScript стека в отчёте. При использовании отчёта для обработки ошибок в обработчике обратного вызова или исключения, это позволяет отчёту включать местоположение исходной ошибки, а также место, где она была обработана.

try {
  process.chdir('/non-existent-path');
} catch (err) {
  process.report.writeReport(err);
}
// Any other code copy

Если в writeReport() переданы и имя файла, и объект ошибки, то объект ошибки должен быть вторым параметром.

try {
  process.chdir('/non-existent-path');
} catch (err) {
  process.report.writeReport(filename, err);
}
// Any other code copy

Содержание отчёта о диагностике может быть возвращено в виде объекта JavaScript через вызов API из приложения JavaScript:

const report = process.report.getReport();
console.log(typeof report === 'object'); // true

// Similar to process.report.writeReport() output
console.log(JSON.stringify(report, null, 2)); copy

Эта функция принимает необязательный дополнительный аргумент err, который является объектом Error, который будет использоваться в качестве контекста для вывода JavaScript стека в отчёте.

const report = process.report.getReport(new Error('custom error'));
console.log(typeof report === 'object'); // true copy

Версии API полезны при проверке состояния среды выполнения из приложения, в ожидании самонастройки потребления ресурсов, балансировки нагрузки, мониторинга и т.д.

Содержание отчёта состоит из раздела заголовка, содержащего тип события, дату, время, PID и версию Node.js, разделов с JavaScript и системными трассировками стека, раздела с информацией о куче V8, раздела с libuv информацией о обработчиках и раздела с информацией о платформе ОС, показывающей использование ЦП и памяти, а также системные ограничения. Пример отчёта можно сгенерировать, используя Node.js REPL:

$ node
> process.report.writeReport();
Writing Node.js report to file: report.20181126.091102.8480.0.001.json
Node.js report completed
> copy

При записи отчёта в stderr выводятся сообщения о начале и конце, а имя файла отчёта возвращается вызывающей стороне. Имя файла по умолчанию включает дату, время, PID и порядковый номер. Порядковый номер помогает сопоставить дамп отчёта со состоянием среды выполнения, если он генерируется несколько раз для одного и того же процесса Node.js.

Отчёт о диагностике имеет связанный с ним однозначный цифровой номер версии (report.header.reportVersion), уникально представляющий формат отчёта. Номер версии увеличивается при добавлении или удалении нового ключа или изменении типа данных значения. Определения версий отчётов согласованы между LTS выпусками.

Настройка

Дополнительная настройка среды выполнения для генерации отчётов доступна через следующие свойства process.report:

reportOnFatalError активирует отчёт о диагностике при критических ошибках, если true. По умолчанию false.

reportOnSignal активирует отчёт о диагностике при сигнале, если true. Это не поддерживается в Windows. По умолчанию false.

reportOnUncaughtException активирует отчёт о диагностике при необработанном исключении, если true. По умолчанию false.

signal указывает идентификатор POSIX сигнала, который будет использоваться для перехвата внешних триггеров для генерации отчёта. По умолчанию 'SIGUSR2'.

filename указывает имя выходного файла в файловой системе. Специальное значение присваивается stdout и stderr. Использование этих значений приведёт к записи отчёта в соответствующие стандартные потоки. В случаях использования стандартных потоков значение directory игнорируется. URL не поддерживаются. По умолчанию используется составное имя файла, содержащее отметку времени, PID и порядковый номер.

directory указывает каталог файловой системы, в который будет записан отчёт. URL не поддерживаются. По умолчанию используется текущий рабочий каталог процесса Node.js.

excludeNetwork исключает header.networkInterfaces из отчёта о диагностике.

// Trigger report only on uncaught exceptions.
process.report.reportOnFatalError = false;
process.report.reportOnSignal = false;
process.report.reportOnUncaughtException = true;

// Trigger report for both internal errors as well as external signal.
process.report.reportOnFatalError = true;
process.report.reportOnSignal = true;
process.report.reportOnUncaughtException = false;

// Change the default signal to 'SIGQUIT' and enable it.
process.report.reportOnFatalError = false;
process.report.reportOnUncaughtException = false;
process.report.reportOnSignal = true;
process.report.signal = 'SIGQUIT';

// Disable network interfaces reporting
process.report.excludeNetwork = true; copy

Настройка при инициализации модуля также доступна через переменные окружения:

NODE_OPTIONS="--report-uncaught-exception \
  --report-on-fatalerror --report-on-signal \
  --report-signal=SIGUSR2  --report-filename=./report.json \
  --report-directory=/home/nodeuser" copy

Подробная документация по API доступна в разделе process API documentation.

Взаимодействие с рабочими процессами

История
Версия Изменения
v13.9.0, v12.16.2

Рабочие процессы теперь включены в отчёт.

Worker потоки могут создавать отчёты так же, как и основной поток.

Отчёты будут включать информацию обо всех рабочих процессах, являющихся дочерними для текущего потока, как часть раздела workers, причём каждый рабочий процесс создаёт отчёт в стандартном формате отчёта.

Поток, генерирующий отчёт, будет ожидать завершения отчётов от рабочих потоков. Однако задержка обычно будет низкой, поскольку для генерации отчёта прерываются как выполнение JavaScript, так и цикл событий.

© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v20.x/docs/api/report.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API