Spec-Zone.ru › Node.js 18 LTS

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

Устойчивость: 2 - Стабильно

Создаёт 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.

Отчёт также может быть инициирован посредством вызова 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.

// 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'; 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-v18.x/docs/api/report.html

Spec-Zone.ru

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