1515 */
1616
1717import * as gcpMetadata from 'gcp-metadata' ;
18- import { context , diag } from '@opentelemetry/api' ;
18+ import { context } from '@opentelemetry/api' ;
1919import { suppressTracing } from '@opentelemetry/core' ;
2020import {
21- DetectorSync ,
2221 ResourceDetectionConfig ,
23- Resource ,
24- ResourceAttributes ,
25- IResource ,
22+ ResourceDetector ,
23+ DetectedResource ,
24+ DetectedResourceAttributes ,
2625} from '@opentelemetry/resources' ;
2726import {
2827 CLOUDPROVIDERVALUES_GCP ,
@@ -42,61 +41,52 @@ import {
4241 * Cloud Platform and return a {@link Resource} populated with metadata about
4342 * the instance. Returns an empty Resource if detection fails.
4443 */
45- class GcpDetector implements DetectorSync {
46- detect ( _config ?: ResourceDetectionConfig ) : IResource {
44+ class GcpDetector implements ResourceDetector {
45+ detect ( _config ?: ResourceDetectionConfig ) : DetectedResource {
4746 const attributes = context . with ( suppressTracing ( context . active ( ) ) , ( ) =>
4847 this . _getAttributes ( )
4948 ) ;
50- return new Resource ( { } , attributes ) ;
49+ return { attributes } ;
5150 }
5251
5352 /**
54- * Attempts to connect and obtain instance configuration data from the GCP metadata service.
55- * If the connection is successful it returns a promise containing a {@link ResourceAttributes}
56- * object with instance metadata. Returns a promise containing an
57- * empty {@link ResourceAttributes} if the connection or parsing of the metadata fails.
53+ * Asynchronously gather GCP cloud metadata.
5854 */
59- private async _getAttributes ( ) : Promise < ResourceAttributes > {
60- if ( ! ( await gcpMetadata . isAvailable ( ) ) ) {
61- diag . debug ( 'GcpDetector failed: GCP Metadata unavailable.' ) ;
62- return { } ;
63- }
64-
65- const [ projectId , instanceId , zoneId , clusterName , hostname ] =
66- await Promise . all ( [
67- this . _getProjectId ( ) ,
68- this . _getInstanceId ( ) ,
69- this . _getZone ( ) ,
70- this . _getClusterName ( ) ,
71- this . _getHostname ( ) ,
72- ] ) ;
55+ private _getAttributes ( ) : DetectedResourceAttributes {
56+ const isAvail = gcpMetadata . isAvailable ( ) ;
7357
74- const attributes : ResourceAttributes = { } ;
75- attributes [ SEMRESATTRS_CLOUD_ACCOUNT_ID ] = projectId ;
76- attributes [ SEMRESATTRS_HOST_ID ] = instanceId ;
77- attributes [ SEMRESATTRS_HOST_NAME ] = hostname ;
78- attributes [ SEMRESATTRS_CLOUD_AVAILABILITY_ZONE ] = zoneId ;
79- attributes [ SEMRESATTRS_CLOUD_PROVIDER ] = CLOUDPROVIDERVALUES_GCP ;
58+ const attributes : DetectedResourceAttributes = {
59+ [ SEMRESATTRS_CLOUD_PROVIDER ] : ( async ( ) => {
60+ return await isAvail ? CLOUDPROVIDERVALUES_GCP : undefined ;
61+ } ) ( ) ,
62+ [ SEMRESATTRS_CLOUD_ACCOUNT_ID ] : this . _getProjectId ( isAvail ) ,
63+ [ SEMRESATTRS_HOST_ID ] : this . _getInstanceId ( isAvail ) ,
64+ [ SEMRESATTRS_HOST_NAME ] : this . _getHostname ( isAvail ) ,
65+ [ SEMRESATTRS_CLOUD_AVAILABILITY_ZONE ] : this . _getZone ( isAvail ) ,
66+ } ;
8067
81- if ( process . env . KUBERNETES_SERVICE_HOST )
82- this . _addK8sAttributes ( attributes , clusterName ) ;
68+ // Add resource attributes for K8s.
69+ if ( process . env . KUBERNETES_SERVICE_HOST ) {
70+ attributes [ SEMRESATTRS_K8S_CLUSTER_NAME ] = this . _getClusterName ( isAvail ) ;
71+ attributes [ SEMRESATTRS_K8S_NAMESPACE_NAME ] = ( async ( ) => {
72+ return await isAvail ? process . env . NAMESPACE : undefined ;
73+ } ) ( ) ;
74+ attributes [ SEMRESATTRS_K8S_POD_NAME ] = ( async ( ) => {
75+ return await isAvail ? process . env . HOSTNAME : undefined ;
76+ } ) ( ) ;
77+ attributes [ SEMRESATTRS_CONTAINER_NAME ] = ( async ( ) => {
78+ return await isAvail ? process . env . CONTAINER_NAME : undefined ;
79+ } ) ( ) ;
80+ }
8381
8482 return attributes ;
8583 }
8684
87- /** Add resource attributes for K8s */
88- private _addK8sAttributes (
89- attributes : ResourceAttributes ,
90- clusterName : string
91- ) : void {
92- attributes [ SEMRESATTRS_K8S_CLUSTER_NAME ] = clusterName ;
93- attributes [ SEMRESATTRS_K8S_NAMESPACE_NAME ] = process . env . NAMESPACE ?? '' ;
94- attributes [ SEMRESATTRS_K8S_POD_NAME ] = process . env . HOSTNAME ?? '' ;
95- attributes [ SEMRESATTRS_CONTAINER_NAME ] = process . env . CONTAINER_NAME ?? '' ;
96- }
97-
9885 /** Gets project id from GCP project metadata. */
99- private async _getProjectId ( ) : Promise < string > {
86+ private async _getProjectId ( isAvail : Promise < boolean > ) : Promise < string | undefined > {
87+ if ( ! ( await isAvail ) ) {
88+ return undefined ;
89+ }
10090 try {
10191 return await gcpMetadata . project ( 'project-id' ) ;
10292 } catch {
@@ -105,7 +95,10 @@ class GcpDetector implements DetectorSync {
10595 }
10696
10797 /** Gets instance id from GCP instance metadata. */
108- private async _getInstanceId ( ) : Promise < string > {
98+ private async _getInstanceId ( isAvail : Promise < boolean > ) : Promise < string | undefined > {
99+ if ( ! ( await isAvail ) ) {
100+ return undefined ;
101+ }
109102 try {
110103 const id = await gcpMetadata . instance ( 'id' ) ;
111104 return id . toString ( ) ;
@@ -115,7 +108,10 @@ class GcpDetector implements DetectorSync {
115108 }
116109
117110 /** Gets zone from GCP instance metadata. */
118- private async _getZone ( ) : Promise < string > {
111+ private async _getZone ( isAvail : Promise < boolean > ) : Promise < string | undefined > {
112+ if ( ! ( await isAvail ) ) {
113+ return undefined ;
114+ }
119115 try {
120116 const zoneId = await gcpMetadata . instance ( 'zone' ) ;
121117 if ( zoneId ) {
@@ -128,7 +124,10 @@ class GcpDetector implements DetectorSync {
128124 }
129125
130126 /** Gets cluster name from GCP instance metadata. */
131- private async _getClusterName ( ) : Promise < string > {
127+ private async _getClusterName ( isAvail : Promise < boolean > ) : Promise < string | undefined > {
128+ if ( ! ( await isAvail ) ) {
129+ return undefined ;
130+ }
132131 try {
133132 return await gcpMetadata . instance ( 'attributes/cluster-name' ) ;
134133 } catch {
@@ -137,7 +136,10 @@ class GcpDetector implements DetectorSync {
137136 }
138137
139138 /** Gets hostname from GCP instance metadata. */
140- private async _getHostname ( ) : Promise < string > {
139+ private async _getHostname ( isAvail : Promise < boolean > ) : Promise < string | undefined > {
140+ if ( ! ( await isAvail ) ) {
141+ return undefined ;
142+ }
141143 try {
142144 return await gcpMetadata . instance ( 'hostname' ) ;
143145 } catch {
0 commit comments