feat(metapackage): copy official metapackage
last commit in official: 0e96b2acdb
			
			
This commit is contained in:
		
							parent
							
								
									e05fa1cf0f
								
							
						
					
					
						commit
						094e4d5813
					
				
							
								
								
									
										7
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| { | ||||
|     "cSpell.words": [ | ||||
|         "Metapackage", | ||||
|         "Tachy", | ||||
|         "tachybase" | ||||
|     ] | ||||
| } | ||||
| @ -1,3 +1,3 @@ | ||||
| # opentelemetry-instrumentation-tachybase | ||||
| # opentelemetry-auto-instrumentations | ||||
| 
 | ||||
| TachyBase 专属的 OpenTelemetry 插桩库 | ||||
| TachyBase 专属的 OpenTelemetry 自动插桩库 | ||||
|  | ||||
							
								
								
									
										105
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | ||||
| { | ||||
|   "name": "@tachybase/opentelemetry-auto-instrumentations", | ||||
|   "version": "0.0.1", | ||||
|   "description": "Metapackage of telemetry for TachyBase which bundles OpenTelemetry node core and instrumentations", | ||||
|   "author": "TachyBase Team", | ||||
|   "homepage": "https://git.daoyoucloud.com/TomyJan/opentelemetry-auto-instrumentations", | ||||
|   "license": "Apache-2.0", | ||||
|   "engines": { | ||||
|     "node": ">=14" | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   }, | ||||
|   "main": "build/src/index.js", | ||||
|   "types": "build/src/index.d.ts", | ||||
|   "exports": { | ||||
|     ".": "./build/src/index.js", | ||||
|     "./register": "./build/src/register.js" | ||||
|   }, | ||||
|   "repository": "https://git.daoyoucloud.com/TomyJan/opentelemetry-auto-instrumentations", | ||||
|   "scripts": { | ||||
|     "clean": "rimraf build/*", | ||||
|     "compile": "tsc -p .", | ||||
|     "lint": "eslint . --ext .ts", | ||||
|     "lint:fix": "eslint . --ext .ts --fix", | ||||
|     "precompile": "tsc --version && lerna run version:update --scope @opentelemetry/auto-instrumentations-node --include-dependencies", | ||||
|     "prewatch": "npm run precompile", | ||||
|     "prepublishOnly": "npm run compile", | ||||
|     "tdd": "yarn test -- --watch-extensions ts --watch", | ||||
|     "test": "nyc ts-mocha -p tsconfig.json 'test/**/*.ts'", | ||||
|     "watch": "tsc -w" | ||||
|   }, | ||||
|   "bugs": { | ||||
|     "url": "https://git.daoyoucloud.com/TomyJan/opentelemetry-auto-instrumentations/issues" | ||||
|   }, | ||||
|   "peerDependencies": { | ||||
|     "@opentelemetry/api": "^1.4.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@opentelemetry/api": "^1.4.1", | ||||
|     "@types/mocha": "7.0.2", | ||||
|     "@types/node": "18.6.5", | ||||
|     "@types/sinon": "10.0.18", | ||||
|     "mocha": "7.2.0", | ||||
|     "nyc": "15.1.0", | ||||
|     "rimraf": "5.0.5", | ||||
|     "sinon": "15.2.0", | ||||
|     "ts-mocha": "10.0.0", | ||||
|     "typescript": "4.4.4" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@opentelemetry/instrumentation": "^0.52.0", | ||||
|     "@opentelemetry/instrumentation-amqplib": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-aws-lambda": "^0.43.0", | ||||
|     "@opentelemetry/instrumentation-aws-sdk": "^0.43.1", | ||||
|     "@opentelemetry/instrumentation-bunyan": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-cassandra-driver": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-connect": "^0.38.0", | ||||
|     "@opentelemetry/instrumentation-cucumber": "^0.8.0", | ||||
|     "@opentelemetry/instrumentation-dataloader": "^0.11.0", | ||||
|     "@opentelemetry/instrumentation-dns": "^0.38.0", | ||||
|     "@opentelemetry/instrumentation-express": "^0.41.1", | ||||
|     "@opentelemetry/instrumentation-fastify": "^0.38.0", | ||||
|     "@opentelemetry/instrumentation-fs": "^0.14.0", | ||||
|     "@opentelemetry/instrumentation-generic-pool": "^0.38.0", | ||||
|     "@opentelemetry/instrumentation-graphql": "^0.42.0", | ||||
|     "@opentelemetry/instrumentation-grpc": "^0.52.0", | ||||
|     "@opentelemetry/instrumentation-hapi": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-http": "^0.52.0", | ||||
|     "@opentelemetry/instrumentation-ioredis": "^0.42.0", | ||||
|     "@opentelemetry/instrumentation-kafkajs": "^0.2.0", | ||||
|     "@opentelemetry/instrumentation-knex": "^0.39.0", | ||||
|     "@opentelemetry/instrumentation-koa": "^0.42.0", | ||||
|     "@opentelemetry/instrumentation-lru-memoizer": "^0.39.0", | ||||
|     "@opentelemetry/instrumentation-memcached": "^0.38.0", | ||||
|     "@opentelemetry/instrumentation-mongodb": "^0.46.0", | ||||
|     "@opentelemetry/instrumentation-mongoose": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-mysql": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-mysql2": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-nestjs-core": "^0.39.0", | ||||
|     "@opentelemetry/instrumentation-net": "^0.38.0", | ||||
|     "@opentelemetry/instrumentation-pg": "^0.43.0", | ||||
|     "@opentelemetry/instrumentation-pino": "^0.41.0", | ||||
|     "@opentelemetry/instrumentation-redis": "^0.41.0", | ||||
|     "@opentelemetry/instrumentation-redis-4": "^0.41.0", | ||||
|     "@opentelemetry/instrumentation-restify": "^0.40.0", | ||||
|     "@opentelemetry/instrumentation-router": "^0.39.0", | ||||
|     "@opentelemetry/instrumentation-socket.io": "^0.41.0", | ||||
|     "@opentelemetry/instrumentation-tedious": "^0.12.0", | ||||
|     "@opentelemetry/instrumentation-undici": "^0.4.0", | ||||
|     "@opentelemetry/instrumentation-winston": "^0.39.0", | ||||
|     "@opentelemetry/resource-detector-alibaba-cloud": "^0.28.10", | ||||
|     "@opentelemetry/resource-detector-aws": "^1.5.2", | ||||
|     "@opentelemetry/resource-detector-azure": "^0.2.9", | ||||
|     "@opentelemetry/resource-detector-container": "^0.3.11", | ||||
|     "@opentelemetry/resource-detector-gcp": "^0.29.10", | ||||
|     "@opentelemetry/resources": "^1.24.0", | ||||
|     "@opentelemetry/sdk-node": "^0.52.0" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "build/src/**/*.js", | ||||
|     "build/src/**/*.js.map", | ||||
|     "build/src/**/*.d.ts" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| export { | ||||
|   getNodeAutoInstrumentations, | ||||
|   getResourceDetectorsFromEnv as getResourceDetectors, | ||||
|   InstrumentationConfigMap, | ||||
| } from './utils'; | ||||
							
								
								
									
										48
									
								
								src/register.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/register.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| import * as opentelemetry from '@opentelemetry/sdk-node'; | ||||
| import { diag, DiagConsoleLogger } from '@opentelemetry/api'; | ||||
| import { | ||||
|   getNodeAutoInstrumentations, | ||||
|   getResourceDetectorsFromEnv, | ||||
| } from './utils'; | ||||
| 
 | ||||
| diag.setLogger( | ||||
|   new DiagConsoleLogger(), | ||||
|   opentelemetry.core.getEnv().OTEL_LOG_LEVEL | ||||
| ); | ||||
| 
 | ||||
| const sdk = new opentelemetry.NodeSDK({ | ||||
|   instrumentations: getNodeAutoInstrumentations(), | ||||
|   resourceDetectors: getResourceDetectorsFromEnv(), | ||||
| }); | ||||
| 
 | ||||
| try { | ||||
|   sdk.start(); | ||||
|   diag.info('OpenTelemetry automatic instrumentation started successfully'); | ||||
| } catch (error) { | ||||
|   diag.error( | ||||
|     'Error initializing OpenTelemetry SDK. Your application is not instrumented and will not produce telemetry', | ||||
|     error | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| process.on('SIGTERM', () => { | ||||
|   sdk | ||||
|     .shutdown() | ||||
|     .then(() => diag.debug('OpenTelemetry SDK terminated')) | ||||
|     .catch(error => diag.error('Error terminating OpenTelemetry SDK', error)); | ||||
| }); | ||||
							
								
								
									
										286
									
								
								src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								src/utils.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,286 @@ | ||||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { diag } from '@opentelemetry/api'; | ||||
| import { Instrumentation } from '@opentelemetry/instrumentation'; | ||||
| 
 | ||||
| import { AmqplibInstrumentation } from '@opentelemetry/instrumentation-amqplib'; | ||||
| import { AwsLambdaInstrumentation } from '@opentelemetry/instrumentation-aws-lambda'; | ||||
| import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'; | ||||
| import { BunyanInstrumentation } from '@opentelemetry/instrumentation-bunyan'; | ||||
| import { CassandraDriverInstrumentation } from '@opentelemetry/instrumentation-cassandra-driver'; | ||||
| import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect'; | ||||
| import { CucumberInstrumentation } from '@opentelemetry/instrumentation-cucumber'; | ||||
| import { DataloaderInstrumentation } from '@opentelemetry/instrumentation-dataloader'; | ||||
| import { DnsInstrumentation } from '@opentelemetry/instrumentation-dns'; | ||||
| import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; | ||||
| import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify'; | ||||
| import { FsInstrumentation } from '@opentelemetry/instrumentation-fs'; | ||||
| import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool'; | ||||
| import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql'; | ||||
| import { GrpcInstrumentation } from '@opentelemetry/instrumentation-grpc'; | ||||
| import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi'; | ||||
| import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; | ||||
| import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'; | ||||
| import { KafkaJsInstrumentation } from '@opentelemetry/instrumentation-kafkajs'; | ||||
| import { KnexInstrumentation } from '@opentelemetry/instrumentation-knex'; | ||||
| import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; | ||||
| import { LruMemoizerInstrumentation } from '@opentelemetry/instrumentation-lru-memoizer'; | ||||
| import { MemcachedInstrumentation } from '@opentelemetry/instrumentation-memcached'; | ||||
| import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'; | ||||
| import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose'; | ||||
| import { MySQL2Instrumentation } from '@opentelemetry/instrumentation-mysql2'; | ||||
| import { MySQLInstrumentation } from '@opentelemetry/instrumentation-mysql'; | ||||
| import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core'; | ||||
| import { NetInstrumentation } from '@opentelemetry/instrumentation-net'; | ||||
| import { PgInstrumentation } from '@opentelemetry/instrumentation-pg'; | ||||
| import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino'; | ||||
| import { RedisInstrumentation as RedisInstrumentationV2 } from '@opentelemetry/instrumentation-redis'; | ||||
| import { RedisInstrumentation as RedisInstrumentationV4 } from '@opentelemetry/instrumentation-redis-4'; | ||||
| import { RestifyInstrumentation } from '@opentelemetry/instrumentation-restify'; | ||||
| import { RouterInstrumentation } from '@opentelemetry/instrumentation-router'; | ||||
| import { SocketIoInstrumentation } from '@opentelemetry/instrumentation-socket.io'; | ||||
| import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious'; | ||||
| import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'; | ||||
| import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston'; | ||||
| 
 | ||||
| import { alibabaCloudEcsDetector } from '@opentelemetry/resource-detector-alibaba-cloud'; | ||||
| import { | ||||
|   awsBeanstalkDetector, | ||||
|   awsEc2Detector, | ||||
|   awsEcsDetector, | ||||
|   awsEksDetector, | ||||
|   awsLambdaDetector, | ||||
| } from '@opentelemetry/resource-detector-aws'; | ||||
| import { containerDetector } from '@opentelemetry/resource-detector-container'; | ||||
| import { gcpDetector } from '@opentelemetry/resource-detector-gcp'; | ||||
| import { | ||||
|   Detector, | ||||
|   DetectorSync, | ||||
|   envDetectorSync, | ||||
|   hostDetectorSync, | ||||
|   osDetectorSync, | ||||
|   processDetectorSync, | ||||
|   serviceInstanceIdDetectorSync, | ||||
| } from '@opentelemetry/resources'; | ||||
| import { | ||||
|   azureAppServiceDetector, | ||||
|   azureFunctionsDetector, | ||||
|   azureVmDetector, | ||||
| } from '@opentelemetry/resource-detector-azure'; | ||||
| 
 | ||||
| const RESOURCE_DETECTOR_CONTAINER = 'container'; | ||||
| const RESOURCE_DETECTOR_ENVIRONMENT = 'env'; | ||||
| const RESOURCE_DETECTOR_HOST = 'host'; | ||||
| const RESOURCE_DETECTOR_OS = 'os'; | ||||
| const RESOURCE_DETECTOR_SERVICE_INSTANCE_ID = 'serviceinstance'; | ||||
| const RESOURCE_DETECTOR_PROCESS = 'process'; | ||||
| const RESOURCE_DETECTOR_ALIBABA = 'alibaba'; | ||||
| const RESOURCE_DETECTOR_AWS = 'aws'; | ||||
| const RESOURCE_DETECTOR_AZURE = 'azure'; | ||||
| const RESOURCE_DETECTOR_GCP = 'gcp'; | ||||
| 
 | ||||
| const InstrumentationMap = { | ||||
|   '@opentelemetry/instrumentation-amqplib': AmqplibInstrumentation, | ||||
|   '@opentelemetry/instrumentation-aws-lambda': AwsLambdaInstrumentation, | ||||
|   '@opentelemetry/instrumentation-aws-sdk': AwsInstrumentation, | ||||
|   '@opentelemetry/instrumentation-bunyan': BunyanInstrumentation, | ||||
|   '@opentelemetry/instrumentation-cassandra-driver': | ||||
|     CassandraDriverInstrumentation, | ||||
|   '@opentelemetry/instrumentation-connect': ConnectInstrumentation, | ||||
|   '@opentelemetry/instrumentation-cucumber': CucumberInstrumentation, | ||||
|   '@opentelemetry/instrumentation-dataloader': DataloaderInstrumentation, | ||||
|   '@opentelemetry/instrumentation-dns': DnsInstrumentation, | ||||
|   '@opentelemetry/instrumentation-express': ExpressInstrumentation, | ||||
|   '@opentelemetry/instrumentation-fastify': FastifyInstrumentation, | ||||
|   '@opentelemetry/instrumentation-fs': FsInstrumentation, | ||||
|   '@opentelemetry/instrumentation-generic-pool': GenericPoolInstrumentation, | ||||
|   '@opentelemetry/instrumentation-graphql': GraphQLInstrumentation, | ||||
|   '@opentelemetry/instrumentation-grpc': GrpcInstrumentation, | ||||
|   '@opentelemetry/instrumentation-hapi': HapiInstrumentation, | ||||
|   '@opentelemetry/instrumentation-http': HttpInstrumentation, | ||||
|   '@opentelemetry/instrumentation-ioredis': IORedisInstrumentation, | ||||
|   '@opentelemetry/instrumentation-kafkajs': KafkaJsInstrumentation, | ||||
|   '@opentelemetry/instrumentation-knex': KnexInstrumentation, | ||||
|   '@opentelemetry/instrumentation-koa': KoaInstrumentation, | ||||
|   '@opentelemetry/instrumentation-lru-memoizer': LruMemoizerInstrumentation, | ||||
|   '@opentelemetry/instrumentation-memcached': MemcachedInstrumentation, | ||||
|   '@opentelemetry/instrumentation-mongodb': MongoDBInstrumentation, | ||||
|   '@opentelemetry/instrumentation-mongoose': MongooseInstrumentation, | ||||
|   '@opentelemetry/instrumentation-mysql2': MySQL2Instrumentation, | ||||
|   '@opentelemetry/instrumentation-mysql': MySQLInstrumentation, | ||||
|   '@opentelemetry/instrumentation-nestjs-core': NestInstrumentation, | ||||
|   '@opentelemetry/instrumentation-net': NetInstrumentation, | ||||
|   '@opentelemetry/instrumentation-pg': PgInstrumentation, | ||||
|   '@opentelemetry/instrumentation-pino': PinoInstrumentation, | ||||
|   '@opentelemetry/instrumentation-redis': RedisInstrumentationV2, | ||||
|   '@opentelemetry/instrumentation-redis-4': RedisInstrumentationV4, | ||||
|   '@opentelemetry/instrumentation-restify': RestifyInstrumentation, | ||||
|   '@opentelemetry/instrumentation-router': RouterInstrumentation, | ||||
|   '@opentelemetry/instrumentation-socket.io': SocketIoInstrumentation, | ||||
|   '@opentelemetry/instrumentation-tedious': TediousInstrumentation, | ||||
|   '@opentelemetry/instrumentation-undici': UndiciInstrumentation, | ||||
|   '@opentelemetry/instrumentation-winston': WinstonInstrumentation, | ||||
| }; | ||||
| 
 | ||||
| // Config types inferred automatically from the first argument of the constructor
 | ||||
| type ConfigArg<T> = T extends new (...args: infer U) => unknown ? U[0] : never; | ||||
| export type InstrumentationConfigMap = { | ||||
|   [Name in keyof typeof InstrumentationMap]?: ConfigArg< | ||||
|     (typeof InstrumentationMap)[Name] | ||||
|   >; | ||||
| }; | ||||
| 
 | ||||
| export function getNodeAutoInstrumentations( | ||||
|   inputConfigs: InstrumentationConfigMap = {} | ||||
| ): Instrumentation[] { | ||||
|   checkManuallyProvidedInstrumentationNames(Object.keys(inputConfigs)); | ||||
|   const enabledInstrumentationsFromEnv = getEnabledInstrumentationsFromEnv(); | ||||
|   const disabledInstrumentationsFromEnv = getDisabledInstrumentationsFromEnv(); | ||||
| 
 | ||||
|   const instrumentations: Instrumentation[] = []; | ||||
| 
 | ||||
|   for (const name of Object.keys(InstrumentationMap) as Array< | ||||
|     keyof typeof InstrumentationMap | ||||
|   >) { | ||||
|     const Instance = InstrumentationMap[name]; | ||||
|     // Defaults are defined by the instrumentation itself
 | ||||
|     const userConfig: any = inputConfigs[name] ?? {}; | ||||
| 
 | ||||
|     if ( | ||||
|       userConfig.enabled === false || | ||||
|       !enabledInstrumentationsFromEnv.includes(name) || | ||||
|       disabledInstrumentationsFromEnv.includes(name) | ||||
|     ) { | ||||
|       diag.debug(`Disabling instrumentation for ${name}`); | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       diag.debug(`Loading instrumentation for ${name}`); | ||||
|       instrumentations.push(new Instance(userConfig)); | ||||
|     } catch (e: any) { | ||||
|       diag.error(e); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return instrumentations; | ||||
| } | ||||
| 
 | ||||
| function checkManuallyProvidedInstrumentationNames( | ||||
|   manuallyProvidedInstrumentationNames: string[] | ||||
| ) { | ||||
|   for (const name of manuallyProvidedInstrumentationNames) { | ||||
|     if (!Object.prototype.hasOwnProperty.call(InstrumentationMap, name)) { | ||||
|       diag.error(`Provided instrumentation name "${name}" not found`); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function getInstrumentationsFromEnv(envVar: string): string[] { | ||||
|   const envVarValue = process.env[envVar]; | ||||
|   if (envVarValue == null) { | ||||
|     return []; | ||||
|   } | ||||
| 
 | ||||
|   const instrumentationsFromEnv = envVarValue | ||||
|     ?.split(',') | ||||
|     .map( | ||||
|       instrumentationPkgSuffix => | ||||
|         `@opentelemetry/instrumentation-${instrumentationPkgSuffix.trim()}` | ||||
|     ); | ||||
|   checkManuallyProvidedInstrumentationNames(instrumentationsFromEnv); | ||||
|   return instrumentationsFromEnv; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Returns the list of instrumentations that are enabled based on the environment variable. | ||||
|  */ | ||||
| function getEnabledInstrumentationsFromEnv() { | ||||
|   if (!process.env.OTEL_NODE_ENABLED_INSTRUMENTATIONS) { | ||||
|     return Object.keys(InstrumentationMap); | ||||
|   } | ||||
| 
 | ||||
|   const instrumentationsFromEnv = getInstrumentationsFromEnv( | ||||
|     'OTEL_NODE_ENABLED_INSTRUMENTATIONS' | ||||
|   ); | ||||
|   return instrumentationsFromEnv; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Returns the list of instrumentations that are disabled based on the environment variable. | ||||
|  */ | ||||
| function getDisabledInstrumentationsFromEnv() { | ||||
|   if (!process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS) { | ||||
|     return []; | ||||
|   } | ||||
| 
 | ||||
|   const instrumentationsFromEnv = getInstrumentationsFromEnv( | ||||
|     'OTEL_NODE_DISABLED_INSTRUMENTATIONS' | ||||
|   ); | ||||
|   return instrumentationsFromEnv; | ||||
| } | ||||
| 
 | ||||
| export function getResourceDetectorsFromEnv(): Array<Detector | DetectorSync> { | ||||
|   const resourceDetectors = new Map< | ||||
|     string, | ||||
|     Detector | DetectorSync | Detector[] | DetectorSync[] | ||||
|   >([ | ||||
|     [RESOURCE_DETECTOR_CONTAINER, containerDetector], | ||||
|     [RESOURCE_DETECTOR_ENVIRONMENT, envDetectorSync], | ||||
|     [RESOURCE_DETECTOR_HOST, hostDetectorSync], | ||||
|     [RESOURCE_DETECTOR_OS, osDetectorSync], | ||||
|     [RESOURCE_DETECTOR_SERVICE_INSTANCE_ID, serviceInstanceIdDetectorSync], | ||||
|     [RESOURCE_DETECTOR_PROCESS, processDetectorSync], | ||||
|     [RESOURCE_DETECTOR_ALIBABA, alibabaCloudEcsDetector], | ||||
|     [RESOURCE_DETECTOR_GCP, gcpDetector], | ||||
|     [ | ||||
|       RESOURCE_DETECTOR_AWS, | ||||
|       [ | ||||
|         awsEc2Detector, | ||||
|         awsEcsDetector, | ||||
|         awsEksDetector, | ||||
|         awsBeanstalkDetector, | ||||
|         awsLambdaDetector, | ||||
|       ], | ||||
|     ], | ||||
|     [ | ||||
|       RESOURCE_DETECTOR_AZURE, | ||||
|       [azureAppServiceDetector, azureFunctionsDetector, azureVmDetector], | ||||
|     ], | ||||
|   ]); | ||||
| 
 | ||||
|   const resourceDetectorsFromEnv = | ||||
|     process.env.OTEL_NODE_RESOURCE_DETECTORS?.split(',') ?? ['all']; | ||||
| 
 | ||||
|   if (resourceDetectorsFromEnv.includes('all')) { | ||||
|     return [...resourceDetectors.values()].flat(); | ||||
|   } | ||||
| 
 | ||||
|   if (resourceDetectorsFromEnv.includes('none')) { | ||||
|     return []; | ||||
|   } | ||||
| 
 | ||||
|   return resourceDetectorsFromEnv.flatMap(detector => { | ||||
|     const resourceDetector = resourceDetectors.get(detector); | ||||
|     if (!resourceDetector) { | ||||
|       diag.error( | ||||
|         `Invalid resource detector "${detector}" specified in the environment variable OTEL_NODE_RESOURCE_DETECTORS` | ||||
|       ); | ||||
|     } | ||||
|     return resourceDetector || []; | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										55
									
								
								test/register.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								test/register.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { spawnSync } from 'child_process'; | ||||
| import * as assert from 'assert'; | ||||
| 
 | ||||
| describe('Register', function () { | ||||
|   it('can load auto instrumentation from command line', () => { | ||||
|     const proc = spawnSync( | ||||
|       process.execPath, | ||||
|       ['--require', '../build/src/register.js', './test-app/app.js'], | ||||
|       { | ||||
|         cwd: __dirname, | ||||
|         timeout: 5000, | ||||
|         killSignal: 'SIGKILL', // SIGTERM is not sufficient to terminate some hangs
 | ||||
|         env: Object.assign({}, process.env, { | ||||
|           OTEL_NODE_RESOURCE_DETECTORS: 'none', | ||||
|           OTEL_TRACES_EXPORTER: 'console', | ||||
|           // nx (used by lerna run) defaults `FORCE_COLOR=true`, which in
 | ||||
|           // node v18.17.0, v20.3.0 and later results in ANSI color escapes
 | ||||
|           // in the ConsoleSpanExporter output that is checked below.
 | ||||
|           FORCE_COLOR: '0', | ||||
|         }), | ||||
|       } | ||||
|     ); | ||||
|     assert.ifError(proc.error); | ||||
|     assert.equal(proc.status, 0, `proc.status (${proc.status})`); | ||||
|     assert.equal(proc.signal, null, `proc.signal (${proc.signal})`); | ||||
| 
 | ||||
|     assert.ok( | ||||
|       proc.stdout.includes( | ||||
|         'OpenTelemetry automatic instrumentation started successfully' | ||||
|       ) | ||||
|     ); | ||||
| 
 | ||||
|     // Check a span has been generated for the GET request done in app.js
 | ||||
|     assert.ok( | ||||
|       proc.stdout.includes("name: 'GET'"), | ||||
|       'console span output in stdout' | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										29
									
								
								test/test-app/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								test/test-app/app.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| //Used in register.test.ts to mimic a JS app.
 | ||||
| const http = require('http'); | ||||
| 
 | ||||
| const options = { | ||||
|   hostname: 'example.com', | ||||
|   port: 80, | ||||
|   path: '/', | ||||
|   method: 'GET' | ||||
| }; | ||||
| 
 | ||||
| const req = http.request(options); | ||||
| 
 | ||||
| req.end(); | ||||
							
								
								
									
										208
									
								
								test/utils.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								test/utils.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,208 @@ | ||||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { diag } from '@opentelemetry/api'; | ||||
| import { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'; | ||||
| import * as assert from 'assert'; | ||||
| import * as sinon from 'sinon'; | ||||
| import { getNodeAutoInstrumentations } from '../src'; | ||||
| import { getResourceDetectorsFromEnv } from '../src/utils'; | ||||
| 
 | ||||
| describe('utils', () => { | ||||
|   describe('getNodeAutoInstrumentations', () => { | ||||
|     it('should include all installed instrumentations', () => { | ||||
|       const instrumentations = getNodeAutoInstrumentations(); | ||||
|       const installedInstrumentations = Object.keys( | ||||
|         require('../package.json').dependencies | ||||
|       ).filter(depName => { | ||||
|         return depName.startsWith('@opentelemetry/instrumentation-'); | ||||
|       }); | ||||
| 
 | ||||
|       assert.deepStrictEqual( | ||||
|         new Set(instrumentations.map(i => i.instrumentationName)), | ||||
|         new Set(installedInstrumentations) | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     it('should use user config', () => { | ||||
|       function applyCustomAttributesOnSpan() {} | ||||
| 
 | ||||
|       const instrumentations = getNodeAutoInstrumentations({ | ||||
|         '@opentelemetry/instrumentation-http': { | ||||
|           applyCustomAttributesOnSpan, | ||||
|         }, | ||||
|       }); | ||||
|       const instrumentation = instrumentations.find( | ||||
|         instr => | ||||
|           instr.instrumentationName === '@opentelemetry/instrumentation-http' | ||||
|       ) as any; | ||||
|       const configHttp = instrumentation._config as HttpInstrumentationConfig; | ||||
| 
 | ||||
|       assert.strictEqual( | ||||
|         configHttp.applyCustomAttributesOnSpan, | ||||
|         applyCustomAttributesOnSpan | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not return disabled instrumentation', () => { | ||||
|       const instrumentations = getNodeAutoInstrumentations({ | ||||
|         '@opentelemetry/instrumentation-grpc': { | ||||
|           enabled: false, | ||||
|         }, | ||||
|       }); | ||||
|       const instrumentation = instrumentations.find( | ||||
|         instr => | ||||
|           instr.instrumentationName === '@opentelemetry/instrumentation-grpc' | ||||
|       ); | ||||
|       assert.strictEqual(instrumentation, undefined); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return only instrumentations enabled via OTEL_NODE_ENABLED_INSTRUMENTATIONS environment variable', () => { | ||||
|       process.env.OTEL_NODE_ENABLED_INSTRUMENTATIONS = | ||||
|         'http,aws-sdk, nestjs-core'; // separator with and without whitespaces should be allowed
 | ||||
|       try { | ||||
|         const instrumentations = getNodeAutoInstrumentations(); | ||||
| 
 | ||||
|         assert.deepStrictEqual( | ||||
|           new Set(instrumentations.map(i => i.instrumentationName)), | ||||
|           new Set([ | ||||
|             '@opentelemetry/instrumentation-http', | ||||
|             '@opentelemetry/instrumentation-aws-sdk', | ||||
|             '@opentelemetry/instrumentation-nestjs-core', | ||||
|           ]) | ||||
|         ); | ||||
|       } finally { | ||||
|         delete process.env.OTEL_NODE_ENABLED_INSTRUMENTATIONS; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     it('should include all instrumentations except those disabled via OTEL_NODE_DISABLED_INSTRUMENTATIONS environment variable', () => { | ||||
|       process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS = | ||||
|         'fs,aws-sdk, aws-lambda'; // separator with and without whitespaces should be allowed
 | ||||
|       try { | ||||
|         const instrumentations = getNodeAutoInstrumentations(); | ||||
|         const disabledInstrumentations = new Set([ | ||||
|           '@opentelemetry/instrumentation-fs', | ||||
|           '@opentelemetry/instrumentation-aws-sdk', | ||||
|           '@opentelemetry/instrumentation-aws-lambda', | ||||
|         ]); | ||||
|         const enabledInstrumentationNames = new Set( | ||||
|           instrumentations.map(i => i.instrumentationName) | ||||
|         ); | ||||
| 
 | ||||
|         for (const disabledInstrumentation of disabledInstrumentations) { | ||||
|           assert.strictEqual( | ||||
|             enabledInstrumentationNames.has(disabledInstrumentation), | ||||
|             false | ||||
|           ); | ||||
|         } | ||||
|       } finally { | ||||
|         delete process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     it('should disable any instrumentations from OTEL_NODE_ENABLED_INSTRUMENTATIONS if set in OTEL_NODE_DISABLED_INSTRUMENTATIONS', () => { | ||||
|       process.env.OTEL_NODE_ENABLED_INSTRUMENTATIONS = 'http,express,net'; | ||||
|       process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS = 'fs,net'; // fs is no-op here, already disabled
 | ||||
|       try { | ||||
|         const instrumentations = getNodeAutoInstrumentations(); | ||||
| 
 | ||||
|         assert.deepStrictEqual( | ||||
|           new Set(instrumentations.map(i => i.instrumentationName)), | ||||
|           new Set([ | ||||
|             '@opentelemetry/instrumentation-http', | ||||
|             '@opentelemetry/instrumentation-express', | ||||
|           ]) | ||||
|         ); | ||||
|       } finally { | ||||
|         delete process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS; | ||||
|         delete process.env.OTEL_NODE_ENABLED_INSTRUMENTATIONS; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     it('should show error for none existing instrumentation', () => { | ||||
|       const spy = sinon.stub(diag, 'error'); | ||||
|       const name = '@opentelemetry/instrumentation-http2'; | ||||
|       const instrumentations = getNodeAutoInstrumentations({ | ||||
|         // @ts-expect-error verify that wrong name works
 | ||||
|         [name]: { | ||||
|           enabled: false, | ||||
|         }, | ||||
|       }); | ||||
|       const instrumentation = instrumentations.find( | ||||
|         instr => instr.instrumentationName === name | ||||
|       ); | ||||
|       assert.strictEqual(instrumentation, undefined); | ||||
| 
 | ||||
|       assert.strictEqual( | ||||
|         spy.args[0][0], | ||||
|         `Provided instrumentation name "${name}" not found` | ||||
|       ); | ||||
| 
 | ||||
|       spy.restore(); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   describe('getResourceDetectorsFromEnv', () => { | ||||
|     it('should return all resource detectors by default', () => { | ||||
|       assert.equal(getResourceDetectorsFromEnv().length, 16); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all resource detectors when OTEL_NODE_RESOURCE_DETECTORS contains "all"', () => { | ||||
|       process.env.OTEL_NODE_RESOURCE_DETECTORS = 'all'; | ||||
|       assert.equal(getResourceDetectorsFromEnv().length, 16); | ||||
| 
 | ||||
|       delete process.env.OTEL_NODE_RESOURCE_DETECTORS; | ||||
|     }); | ||||
| 
 | ||||
|     it('should return specific resource detectors depending on OTEL_NODE_RESOURCE_DETECTORS', () => { | ||||
|       process.env.OTEL_NODE_RESOURCE_DETECTORS = 'env,host,serviceinstance'; | ||||
| 
 | ||||
|       const resourceDetectors = getResourceDetectorsFromEnv(); | ||||
| 
 | ||||
|       assert.equal(resourceDetectors.length, 3); | ||||
|       assert.equal(resourceDetectors[0].constructor.name, 'EnvDetectorSync'); | ||||
|       assert.equal(resourceDetectors[1].constructor.name, 'HostDetectorSync'); | ||||
|       assert.equal( | ||||
|         resourceDetectors[2].constructor.name, | ||||
|         'ServiceInstanceIdDetectorSync' | ||||
|       ); | ||||
| 
 | ||||
|       delete process.env.OTEL_NODE_RESOURCE_DETECTORS; | ||||
|     }); | ||||
| 
 | ||||
|     it('should return no resource detectors when OTEL_NODE_RESOURCE_DETECTORS contains "none" or a typo', () => { | ||||
|       const spy = sinon.stub(diag, 'error'); | ||||
|       process.env.OTEL_NODE_RESOURCE_DETECTORS = 'none'; | ||||
| 
 | ||||
|       assert.equal(getResourceDetectorsFromEnv().length, 0); | ||||
| 
 | ||||
|       assert.strictEqual(spy.callCount, 0); | ||||
| 
 | ||||
|       process.env.OTEL_NODE_RESOURCE_DETECTORS = 'test'; | ||||
| 
 | ||||
|       assert.equal(getResourceDetectorsFromEnv().length, 0); | ||||
| 
 | ||||
|       assert.strictEqual( | ||||
|         spy.args[0][0], | ||||
|         'Invalid resource detector "test" specified in the environment variable OTEL_NODE_RESOURCE_DETECTORS' | ||||
|       ); | ||||
| 
 | ||||
|       spy.restore(); | ||||
|       delete process.env.OTEL_NODE_RESOURCE_DETECTORS; | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										26
									
								
								tsconfig.base.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								tsconfig.base.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "allowUnreachableCode": false, | ||||
|     "allowUnusedLabels": false, | ||||
|     "declaration": true, | ||||
|     "declarationMap": true, | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "inlineSources": true, | ||||
|     "module": "commonjs", | ||||
|     "noEmitOnError": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "noImplicitOverride": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "pretty": true, | ||||
|     "sourceMap": true, | ||||
|     "strict": true, | ||||
|     "strictNullChecks": true, | ||||
|     "target": "es2017", | ||||
|     "incremental": true, | ||||
|     "newLine": "LF" | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "node_modules" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										11
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| { | ||||
|   "extends": "tsconfig.base", | ||||
|   "compilerOptions": { | ||||
|     "rootDir": ".", | ||||
|     "outDir": "build" | ||||
|   }, | ||||
|   "include": [ | ||||
|     "src/**/*.ts", | ||||
|     "test/**/*.ts" | ||||
|   ] | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user