123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- import { _optionalChain } from '@sentry/utils';
- import { execFile } from 'child_process';
- import { readFile, readdir } from 'fs';
- import * as os from 'os';
- import { join } from 'path';
- import { promisify } from 'util';
- import { defineIntegration, convertIntegrationFnToClass } from '@sentry/core';
- const readFileAsync = promisify(readFile);
- const readDirAsync = promisify(readdir);
- const INTEGRATION_NAME = 'Context';
- const _nodeContextIntegration = ((options = {}) => {
- let cachedContext;
- const _options = {
- app: true,
- os: true,
- device: true,
- culture: true,
- cloudResource: true,
- ...options,
- };
-
- async function addContext(event) {
- if (cachedContext === undefined) {
- cachedContext = _getContexts();
- }
- const updatedContext = _updateContext(await cachedContext);
- event.contexts = {
- ...event.contexts,
- app: { ...updatedContext.app, ..._optionalChain([event, 'access', _ => _.contexts, 'optionalAccess', _2 => _2.app]) },
- os: { ...updatedContext.os, ..._optionalChain([event, 'access', _3 => _3.contexts, 'optionalAccess', _4 => _4.os]) },
- device: { ...updatedContext.device, ..._optionalChain([event, 'access', _5 => _5.contexts, 'optionalAccess', _6 => _6.device]) },
- culture: { ...updatedContext.culture, ..._optionalChain([event, 'access', _7 => _7.contexts, 'optionalAccess', _8 => _8.culture]) },
- cloud_resource: { ...updatedContext.cloud_resource, ..._optionalChain([event, 'access', _9 => _9.contexts, 'optionalAccess', _10 => _10.cloud_resource]) },
- };
- return event;
- }
-
- async function _getContexts() {
- const contexts = {};
- if (_options.os) {
- contexts.os = await getOsContext();
- }
- if (_options.app) {
- contexts.app = getAppContext();
- }
- if (_options.device) {
- contexts.device = getDeviceContext(_options.device);
- }
- if (_options.culture) {
- const culture = getCultureContext();
- if (culture) {
- contexts.culture = culture;
- }
- }
- if (_options.cloudResource) {
- contexts.cloud_resource = getCloudResourceContext();
- }
- return contexts;
- }
- return {
- name: INTEGRATION_NAME,
-
- setupOnce() {},
- processEvent(event) {
- return addContext(event);
- },
- };
- }) ;
- const nodeContextIntegration = defineIntegration(_nodeContextIntegration);
- const Context = convertIntegrationFnToClass(INTEGRATION_NAME, nodeContextIntegration)
- ;
- function _updateContext(contexts) {
-
- if (_optionalChain([contexts, 'optionalAccess', _11 => _11.app, 'optionalAccess', _12 => _12.app_memory])) {
- contexts.app.app_memory = process.memoryUsage().rss;
- }
- if (_optionalChain([contexts, 'optionalAccess', _13 => _13.device, 'optionalAccess', _14 => _14.free_memory])) {
- contexts.device.free_memory = os.freemem();
- }
- return contexts;
- }
- async function getOsContext() {
- const platformId = os.platform();
- switch (platformId) {
- case 'darwin':
- return getDarwinInfo();
- case 'linux':
- return getLinuxInfo();
- default:
- return {
- name: PLATFORM_NAMES[platformId] || platformId,
- version: os.release(),
- };
- }
- }
- function getCultureContext() {
- try {
-
- if (typeof (process.versions ).icu !== 'string') {
-
- return;
- }
-
-
-
-
- const january = new Date(9e8);
- const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
- if (spanish.format(january) === 'enero') {
- const options = Intl.DateTimeFormat().resolvedOptions();
- return {
- locale: options.locale,
- timezone: options.timeZone,
- };
- }
- } catch (err) {
-
- }
- return;
- }
- function getAppContext() {
- const app_memory = process.memoryUsage().rss;
- const app_start_time = new Date(Date.now() - process.uptime() * 1000).toISOString();
- return { app_start_time, app_memory };
- }
- function getDeviceContext(deviceOpt) {
- const device = {};
-
- let uptime;
- try {
- uptime = os.uptime && os.uptime();
- } catch (e) {
-
- }
-
-
-
- if (typeof uptime === 'number') {
- device.boot_time = new Date(Date.now() - uptime * 1000).toISOString();
- }
- device.arch = os.arch();
- if (deviceOpt === true || deviceOpt.memory) {
- device.memory_size = os.totalmem();
- device.free_memory = os.freemem();
- }
- if (deviceOpt === true || deviceOpt.cpu) {
- const cpuInfo = os.cpus();
- if (cpuInfo && cpuInfo.length) {
- const firstCpu = cpuInfo[0];
- device.processor_count = cpuInfo.length;
- device.cpu_description = firstCpu.model;
- device.processor_frequency = firstCpu.speed;
- }
- }
- return device;
- }
- const PLATFORM_NAMES = {
- aix: 'IBM AIX',
- freebsd: 'FreeBSD',
- openbsd: 'OpenBSD',
- sunos: 'SunOS',
- win32: 'Windows',
- };
- const LINUX_DISTROS = [
- { name: 'fedora-release', distros: ['Fedora'] },
- { name: 'redhat-release', distros: ['Red Hat Linux', 'Centos'] },
- { name: 'redhat_version', distros: ['Red Hat Linux'] },
- { name: 'SuSE-release', distros: ['SUSE Linux'] },
- { name: 'lsb-release', distros: ['Ubuntu Linux', 'Arch Linux'] },
- { name: 'debian_version', distros: ['Debian'] },
- { name: 'debian_release', distros: ['Debian'] },
- { name: 'arch-release', distros: ['Arch Linux'] },
- { name: 'gentoo-release', distros: ['Gentoo Linux'] },
- { name: 'novell-release', distros: ['SUSE Linux'] },
- { name: 'alpine-release', distros: ['Alpine Linux'] },
- ];
- const LINUX_VERSIONS
- = {
- alpine: content => content,
- arch: content => matchFirst(/distrib_release=(.*)/, content),
- centos: content => matchFirst(/release ([^ ]+)/, content),
- debian: content => content,
- fedora: content => matchFirst(/release (..)/, content),
- mint: content => matchFirst(/distrib_release=(.*)/, content),
- red: content => matchFirst(/release ([^ ]+)/, content),
- suse: content => matchFirst(/VERSION = (.*)\n/, content),
- ubuntu: content => matchFirst(/distrib_release=(.*)/, content),
- };
- function matchFirst(regex, text) {
- const match = regex.exec(text);
- return match ? match[1] : undefined;
- }
- async function getDarwinInfo() {
-
-
-
- const darwinInfo = {
- kernel_version: os.release(),
- name: 'Mac OS X',
- version: `10.${Number(os.release().split('.')[0]) - 4}`,
- };
- try {
-
-
-
- const output = await new Promise((resolve, reject) => {
- execFile('/usr/bin/sw_vers', (error, stdout) => {
- if (error) {
- reject(error);
- return;
- }
- resolve(stdout);
- });
- });
- darwinInfo.name = matchFirst(/^ProductName:\s+(.*)$/m, output);
- darwinInfo.version = matchFirst(/^ProductVersion:\s+(.*)$/m, output);
- darwinInfo.build = matchFirst(/^BuildVersion:\s+(.*)$/m, output);
- } catch (e) {
-
- }
- return darwinInfo;
- }
- function getLinuxDistroId(name) {
- return name.split(' ')[0].toLowerCase();
- }
- async function getLinuxInfo() {
-
-
-
- const linuxInfo = {
- kernel_version: os.release(),
- name: 'Linux',
- };
- try {
-
-
-
-
-
-
- const etcFiles = await readDirAsync('/etc');
- const distroFile = LINUX_DISTROS.find(file => etcFiles.includes(file.name));
- if (!distroFile) {
- return linuxInfo;
- }
-
-
-
-
- const distroPath = join('/etc', distroFile.name);
- const contents = ((await readFileAsync(distroPath, { encoding: 'utf-8' })) ).toLowerCase();
-
-
-
-
-
- const { distros } = distroFile;
- linuxInfo.name = distros.find(d => contents.indexOf(getLinuxDistroId(d)) >= 0) || distros[0];
-
-
-
- const id = getLinuxDistroId(linuxInfo.name);
- linuxInfo.version = LINUX_VERSIONS[id](contents);
- } catch (e) {
-
- }
- return linuxInfo;
- }
- function getCloudResourceContext() {
- if (process.env.VERCEL) {
-
- return {
- 'cloud.provider': 'vercel',
- 'cloud.region': process.env.VERCEL_REGION,
- };
- } else if (process.env.AWS_REGION) {
-
- return {
- 'cloud.provider': 'aws',
- 'cloud.region': process.env.AWS_REGION,
- 'cloud.platform': process.env.AWS_EXECUTION_ENV,
- };
- } else if (process.env.GCP_PROJECT) {
-
- return {
- 'cloud.provider': 'gcp',
- };
- } else if (process.env.ALIYUN_REGION_ID) {
-
- return {
- 'cloud.provider': 'alibaba_cloud',
- 'cloud.region': process.env.ALIYUN_REGION_ID,
- };
- } else if (process.env.WEBSITE_SITE_NAME && process.env.REGION_NAME) {
-
- return {
- 'cloud.provider': 'azure',
- 'cloud.region': process.env.REGION_NAME,
- };
- } else if (process.env.IBM_CLOUD_REGION) {
-
- return {
- 'cloud.provider': 'ibm_cloud',
- 'cloud.region': process.env.IBM_CLOUD_REGION,
- };
- } else if (process.env.TENCENTCLOUD_REGION) {
-
- return {
- 'cloud.provider': 'tencent_cloud',
- 'cloud.region': process.env.TENCENTCLOUD_REGION,
- 'cloud.account.id': process.env.TENCENTCLOUD_APPID,
- 'cloud.availability_zone': process.env.TENCENTCLOUD_ZONE,
- };
- } else if (process.env.NETLIFY) {
-
- return {
- 'cloud.provider': 'netlify',
- };
- } else if (process.env.FLY_REGION) {
-
- return {
- 'cloud.provider': 'fly.io',
- 'cloud.region': process.env.FLY_REGION,
- };
- } else if (process.env.DYNO) {
-
- return {
- 'cloud.provider': 'heroku',
- };
- } else {
- return undefined;
- }
- }
- export { Context, getDeviceContext, nodeContextIntegration, readDirAsync, readFileAsync };
|