Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@supertenant/shared-metrics / src / dependencies.js
Size: Mime:
// (c) Copyright 2023 Supertenant Ltd. - all rights reserved.
// See LICENSE file in project root for license terms.
"use strict";const path=require("path"),fs=require("fs"),applicationUnderMonitoring=require("@supertenant/core").util["applicationUnderMonitoring"];let logger=require("@supertenant/core").logger.getLogger("metrics");const CountDownLatch=require("./util/CountDownLatch"),{DependencyDistanceCalculator,MAX_DEPTH}=require("./util/DependencyDistanceCalculator"),preliminaryPayload=(exports.setLogger=function(_logger){logger=_logger},exports.MAX_DEPENDENCIES=750,exports.payloadPrefix="dependencies",{}),DELAY=(exports.currentPayload={},exports.MAX_ATTEMPTS=20,1e3);let attempts=0;function addAllDependencies(dependencyDir,started,packageJsonPath){addDependenciesFromDir(dependencyDir,()=>{Object.keys(preliminaryPayload).length<=exports.MAX_DEPENDENCIES?(exports.currentPayload=preliminaryPayload,logger.debug(`Collection of dependencies took ${Date.now()-started} ms.`)):packageJsonPath?(new DependencyDistanceCalculator).calculateDistancesFrom(packageJsonPath,distancesFromRoot=>{logger.debug(`Collection of dependencies took ${Date.now()-started} ms.`),limitAndSet(distancesFromRoot)}):(logger.debug(`Collection of dependencies took ${Date.now()-started} ms.`),limitAndSet())})}function addDependenciesFromDir(dependencyDir,callback){fs.readdir(dependencyDir,(readDirErr,dependencies)=>{if(readDirErr||!dependencies)logger.warn("Cannot analyse dependencies due to %s",readDirErr.message),callback();else{readDirErr=dependencies.filter(dependency=>".bin"!==dependency);if(0===readDirErr.length)callback();else{const countDownLatch=new CountDownLatch(readDirErr.length);countDownLatch.once("done",()=>{callback()}),readDirErr.forEach(dependency=>{if(0===dependency.indexOf("@"))addDependenciesFromDir(path.join(dependencyDir,dependency),()=>{countDownLatch.countDown()});else{const fullDirPath=path.join(dependencyDir,dependency);fs.stat(fullDirPath,(statErr,stats)=>{statErr?(countDownLatch.countDown(),logger.warn("Cannot analyse dependency %s due to %s",fullDirPath,statErr.message)):stats.isDirectory()?addDependency(dependency,fullDirPath,countDownLatch):countDownLatch.countDown()})}})}}})}function addDependency(dependency,dependencyDirPath,countDownLatch){const packageJsonPath=path.join(dependencyDirPath,"package.json");fs.readFile(packageJsonPath,{encoding:"utf8"},(err,contents)=>{if(err&&"ENOENT"===err.code)countDownLatch.countDown(),logger.debug(`No package.json at ${packageJsonPath}, ignoring this directory.`);else if(err)countDownLatch.countDown(),logger.info("Failed to identify version of %s dependency due to: %s. This means that you will not be able to see details about this dependency within Instana.",dependency,err.message);else{try{var parsedPackageJson=JSON.parse(contents);preliminaryPayload[parsedPackageJson.name]||(preliminaryPayload[parsedPackageJson.name]=parsedPackageJson.version)}catch(parseErr){return logger.info("Failed to identify version of %s dependency due to: %s. This means that you will not be able to see details about this dependency within Instana.",dependency,parseErr.message)}const potentialNestedNodeModulesFolder=path.join(dependencyDirPath,"node_modules");fs.stat(potentialNestedNodeModulesFolder,(statErr,stats)=>{statErr||!stats.isDirectory()?countDownLatch.countDown():addDependenciesFromDir(potentialNestedNodeModulesFolder,()=>{countDownLatch.countDown()})})}})}function limitAndSet(distances={}){var keys=Object.keys(preliminaryPayload);keys.sort(sortByDistance.bind(null,distances));for(let i=0;i<keys.length-exports.MAX_DEPENDENCIES;i++)delete preliminaryPayload[keys[i]];exports.currentPayload=preliminaryPayload}function sortByDistance(distances,dependency1,dependency2){var isInstana1=0<=dependency1.indexOf("instana"),isInstana2=0<=dependency2.indexOf("instana");return isInstana1&&isInstana2?dependency2.localeCompare(dependency1):isInstana1?1:isInstana2?-1:(isInstana1=distances[dependency1]||MAX_DEPTH+1)===(isInstana2=distances[dependency2]||MAX_DEPTH+1)?dependency2.localeCompare(dependency1):isInstana2-isInstana1}exports.activate=function(){attempts++;const started=Date.now();applicationUnderMonitoring.getMainPackageJsonPathStartingAtMainModule((err,mainPackageJsonPath)=>{if(err)return logger.warn("Failed to determine main package.json. Reason: %s %s ",err.message,err.stack);if(!mainPackageJsonPath&&attempts<exports.MAX_ATTEMPTS)logger.debug(`Main package.json could not be found at ${mainPackageJsonPath}. Will try again later.`),setTimeout(exports.activate,DELAY).unref();else if(mainPackageJsonPath){let dependencyDir;addAllDependencies(dependencyDir=applicationUnderMonitoring.isAppInstalledIntoNodeModules()?path.join(path.dirname(mainPackageJsonPath),"..","..","node_modules"):path.join(path.dirname(mainPackageJsonPath),"node_modules"),started,mainPackageJsonPath)}else logger.info(`Main package.json could not be found after ${attempts} retries. Looking for node_modules folder now.`),applicationUnderMonitoring.findNodeModulesFolder((errNodeModules,nodeModulesFolder)=>errNodeModules?logger.warn("Failed to determine node_modules folder. Reason: %s %s ",err.message,err.stack):nodeModulesFolder?void addAllDependencies(path.join(nodeModulesFolder),started,null):logger.warn("Neither the package.json file nor the node_modules folder could be found. Stopping dependency analysis."))})};