UNPKG

@opentelemetry/resource-detector-alibaba-cloud

Version:
141 lines 6.42 kB
"use strict"; /* * 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. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.alibabaCloudEcsDetector = void 0; const api_1 = require("@opentelemetry/api"); const core_1 = require("@opentelemetry/core"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); const http = require("http"); /** * The AlibabaCloudEcsDetector can be used to detect if a process is running in * AlibabaCloud ECS and return a {@link Resource} populated with metadata about * the ECS instance. Returns an empty Resource if detection fails. */ class AlibabaCloudEcsDetector { /** * See https://www.alibabacloud.com/help/doc-detail/67254.htm for * documentation about the AlibabaCloud instance identity document. */ ALIBABA_CLOUD_IDMS_ENDPOINT = '100.100.100.200'; ALIBABA_CLOUD_INSTANCE_IDENTITY_DOCUMENT_PATH = '/latest/dynamic/instance-identity/document'; ALIBABA_CLOUD_INSTANCE_HOST_DOCUMENT_PATH = '/latest/meta-data/hostname'; MILLISECONDS_TIME_OUT = 1000; /** * Attempts to connect and obtain an AlibabaCloud instance Identity document. * If the connection is successful it returns a promise containing a * {@link Resource} populated with instance metadata. * * @param config (unused) The resource detection config */ detect() { const dataPromise = api_1.context.with((0, core_1.suppressTracing)(api_1.context.active()), () => this._gatherData()); const attrNames = [ semantic_conventions_1.SEMRESATTRS_CLOUD_PROVIDER, semantic_conventions_1.SEMRESATTRS_CLOUD_PLATFORM, semantic_conventions_1.SEMRESATTRS_CLOUD_ACCOUNT_ID, semantic_conventions_1.SEMRESATTRS_CLOUD_REGION, semantic_conventions_1.SEMRESATTRS_CLOUD_AVAILABILITY_ZONE, semantic_conventions_1.SEMRESATTRS_HOST_ID, semantic_conventions_1.SEMRESATTRS_HOST_TYPE, semantic_conventions_1.SEMRESATTRS_HOST_NAME, ]; const attributes = {}; attrNames.forEach(name => { // Each resource attribute is determined asynchronously in _gatherData(). attributes[name] = dataPromise.then(data => data[name]); }); return { attributes }; } /** Gets identity and host info and returns them as attribs. Empty object if fails */ async _gatherData() { try { const { 'owner-account-id': accountId, 'instance-id': instanceId, 'instance-type': instanceType, 'region-id': region, 'zone-id': availabilityZone, } = await this._fetchIdentity(); const hostname = await this._fetchHost(); return { [semantic_conventions_1.SEMRESATTRS_CLOUD_PROVIDER]: semantic_conventions_1.CLOUDPROVIDERVALUES_ALIBABA_CLOUD, [semantic_conventions_1.SEMRESATTRS_CLOUD_PLATFORM]: semantic_conventions_1.CLOUDPLATFORMVALUES_ALIBABA_CLOUD_ECS, [semantic_conventions_1.SEMRESATTRS_CLOUD_ACCOUNT_ID]: accountId, [semantic_conventions_1.SEMRESATTRS_CLOUD_REGION]: region, [semantic_conventions_1.SEMRESATTRS_CLOUD_AVAILABILITY_ZONE]: availabilityZone, [semantic_conventions_1.SEMRESATTRS_HOST_ID]: instanceId, [semantic_conventions_1.SEMRESATTRS_HOST_TYPE]: instanceType, [semantic_conventions_1.SEMRESATTRS_HOST_NAME]: hostname, }; } catch (err) { api_1.diag.debug(`${this.constructor.name}: did not detect resource: ${err?.message}`); return {}; } } /** * Fetch AlibabaCloud instance document url with http requests. If the * application is running on an ECS instance, we should be able to get back a * valid JSON document. Parses that document and stores the identity * properties in a local map. */ async _fetchIdentity() { const options = { host: this.ALIBABA_CLOUD_IDMS_ENDPOINT, path: this.ALIBABA_CLOUD_INSTANCE_IDENTITY_DOCUMENT_PATH, method: 'GET', timeout: this.MILLISECONDS_TIME_OUT, }; const identity = await this._fetchString(options); return JSON.parse(identity); } async _fetchHost() { const options = { host: this.ALIBABA_CLOUD_IDMS_ENDPOINT, path: this.ALIBABA_CLOUD_INSTANCE_HOST_DOCUMENT_PATH, method: 'GET', timeout: this.MILLISECONDS_TIME_OUT, }; return await this._fetchString(options); } async _fetchString(options) { return new Promise((resolve, reject) => { const timeoutId = setTimeout(() => { req.destroy(new Error('ECS metadata api request timed out.')); }, this.MILLISECONDS_TIME_OUT); const req = http.request(options, res => { clearTimeout(timeoutId); const { statusCode } = res; if (typeof statusCode !== 'number' || !(statusCode >= 200 && statusCode < 300)) { res.destroy(); return reject(new Error(`Failed to load page, status code: ${statusCode}`)); } res.setEncoding('utf8'); let rawData = ''; res.on('data', chunk => (rawData += chunk)); res.on('error', err => { reject(err); }); res.on('end', () => { resolve(rawData); }); }); req.on('error', err => { clearTimeout(timeoutId); reject(err); }); req.end(); }); } } exports.alibabaCloudEcsDetector = new AlibabaCloudEcsDetector(); //# sourceMappingURL=AlibabaCloudEcsDetector.js.map