5
5
import wrapt
6
6
import re
7
7
8
- from ....log import logger
9
- from .collectors import _storage_api
10
- from ....util .traceutils import get_tracer_tuple , tracing_is_off
8
+ from typing import Any , Callable , Dict , Tuple , Union
9
+ from instana .log import logger
10
+ from instana .instrumentation .google .cloud .collectors import _storage_api
11
+ from instana .util .traceutils import get_tracer_tuple , tracing_is_off
11
12
12
13
try :
13
14
from google .cloud import storage
14
15
15
- logger .debug (' Instrumenting google-cloud-storage' )
16
+ logger .debug (" Instrumenting google-cloud-storage" )
16
17
17
- def _collect_tags (api_request ):
18
+ def _collect_attributes (
19
+ api_request : Dict [str , Any ],
20
+ ) -> Dict [str , Any ]:
18
21
"""
19
22
Extract span tags from Google Cloud Storage API request. Returns None if the request is not
20
23
supported.
21
24
22
25
:param: dict
23
26
:return: dict or None
24
27
"""
25
- method , path = api_request .get (' method' , None ), api_request .get (' path' , None )
28
+ method , path = api_request .get (" method" , None ), api_request .get (" path" , None )
26
29
27
30
if method not in _storage_api :
28
31
return
29
32
30
33
try :
31
- params = api_request .get (' query_params' , {})
32
- data = api_request .get (' data' , {})
34
+ params = api_request .get (" query_params" , {})
35
+ data = api_request .get (" data" , {})
33
36
34
37
if path in _storage_api [method ]:
35
38
# check is any of string keys matches the path exactly
36
39
return _storage_api [method ][path ](params , data )
37
40
else :
38
41
# look for a regex that matches the string
39
- for ( matcher , collect ) in _storage_api [method ].items ():
42
+ for matcher , collect in _storage_api [method ].items ():
40
43
if not isinstance (matcher , re .Pattern ):
41
44
continue
42
45
@@ -46,108 +49,139 @@ def _collect_tags(api_request):
46
49
47
50
return collect (params , data , m )
48
51
except Exception :
49
- logger .debug ("instana.instrumentation.google.cloud.storage._collect_tags: " , exc_info = True )
50
-
51
- def execute_with_instana (wrapped , instance , args , kwargs ):
52
+ logger .debug (
53
+ "instana.instrumentation.google.cloud.storage._collect_attributes: " ,
54
+ exc_info = True ,
55
+ )
56
+
57
+ def execute_with_instana (
58
+ wrapped : Callable [..., object ],
59
+ instance : Union [storage .Batch , storage ._http .Connection ],
60
+ args : Tuple [object , ...],
61
+ kwargs : Dict [str , Any ],
62
+ ) -> object :
52
63
# batch requests are traced with finish_batch_with_instana()
53
64
# also return early if we're not tracing
54
65
if isinstance (instance , storage .Batch ) or tracing_is_off ():
55
66
return wrapped (* args , ** kwargs )
56
67
57
68
tracer , parent_span , _ = get_tracer_tuple ()
58
- tags = _collect_tags (kwargs )
59
-
60
- # don't trace if the call is not instrumented
61
- if tags is None :
62
- logger .debug ('uninstrumented Google Cloud Storage API request: %s' % kwargs )
63
- return wrapped (* args , ** kwargs )
64
-
65
- with tracer .start_active_span ('gcs' , child_of = parent_span ) as scope :
66
- for (k , v ) in tags .items ():
67
- scope .span .set_tag (k , v )
69
+ parent_context = parent_span .get_span_context () if parent_span else None
68
70
71
+ with tracer .start_as_current_span ("gcs" , span_context = parent_context ) as span :
69
72
try :
73
+ attributes = _collect_attributes (kwargs )
74
+
75
+ # don't trace if the call is not instrumented
76
+ if attributes is None :
77
+ logger .debug (
78
+ f"uninstrumented Google Cloud Storage API request: { kwargs } "
79
+ )
80
+ return wrapped (* args , ** kwargs )
81
+ span .set_attributes (attributes )
70
82
kv = wrapped (* args , ** kwargs )
71
- except Exception as e :
72
- scope .span .log_exception (e )
73
- raise
83
+ except Exception as exc :
84
+ span .record_exception (exc )
74
85
else :
75
86
return kv
76
87
77
- def download_with_instana (wrapped , instance , args , kwargs ):
88
+ def download_with_instana (
89
+ wrapped : Callable [..., object ],
90
+ instance : storage .Blob ,
91
+ args : Tuple [object , ...],
92
+ kwargs : Dict [str , Any ],
93
+ ) -> object :
78
94
# return early if we're not tracing
79
95
if tracing_is_off ():
80
96
return wrapped (* args , ** kwargs )
81
97
82
98
tracer , parent_span , _ = get_tracer_tuple ()
99
+ parent_context = parent_span .get_span_context () if parent_span else None
83
100
84
- with tracer .start_active_span ( ' gcs' , child_of = parent_span ) as scope :
85
- scope . span .set_tag ( ' gcs.op' , ' objects.get' )
86
- scope . span .set_tag ( ' gcs.bucket' , instance .bucket .name )
87
- scope . span .set_tag ( ' gcs.object' , instance .name )
101
+ with tracer .start_as_current_span ( " gcs" , span_context = parent_context ) as span :
102
+ span .set_attribute ( " gcs.op" , " objects.get" )
103
+ span .set_attribute ( " gcs.bucket" , instance .bucket .name )
104
+ span .set_attribute ( " gcs.object" , instance .name )
88
105
89
- start = len (args ) > 4 and args [4 ] or kwargs .get (' start' , None )
106
+ start = len (args ) > 4 and args [4 ] or kwargs .get (" start" , None )
90
107
if start is None :
91
- start = ''
108
+ start = ""
92
109
93
- end = len (args ) > 5 and args [5 ] or kwargs .get (' end' , None )
110
+ end = len (args ) > 5 and args [5 ] or kwargs .get (" end" , None )
94
111
if end is None :
95
- end = ''
112
+ end = ""
96
113
97
- if start != '' or end != '' :
98
- scope . span .set_tag ( ' gcs.range' , '-' .join ((start , end )))
114
+ if start != "" or end != "" :
115
+ span .set_attribute ( " gcs.range" , "-" .join ((start , end )))
99
116
100
117
try :
101
118
kv = wrapped (* args , ** kwargs )
102
119
except Exception as e :
103
- scope .span .log_exception (e )
104
- raise
120
+ span .record_exception (e )
105
121
else :
106
122
return kv
107
123
108
- def upload_with_instana (wrapped , instance , args , kwargs ):
124
+ def upload_with_instana (
125
+ wrapped : Callable [..., object ],
126
+ instance : storage .Blob ,
127
+ args : Tuple [object , ...],
128
+ kwargs : Dict [str , Any ],
129
+ ) -> object :
109
130
# return early if we're not tracing
110
131
if tracing_is_off ():
111
132
return wrapped (* args , ** kwargs )
112
133
113
134
tracer , parent_span , _ = get_tracer_tuple ()
135
+ parent_context = parent_span .get_span_context () if parent_span else None
114
136
115
- with tracer .start_active_span ( ' gcs' , child_of = parent_span ) as scope :
116
- scope . span .set_tag ( ' gcs.op' , ' objects.insert' )
117
- scope . span .set_tag ( ' gcs.bucket' , instance .bucket .name )
118
- scope . span .set_tag ( ' gcs.object' , instance .name )
137
+ with tracer .start_as_current_span ( " gcs" , span_context = parent_context ) as span :
138
+ span .set_attribute ( " gcs.op" , " objects.insert" )
139
+ span .set_attribute ( " gcs.bucket" , instance .bucket .name )
140
+ span .set_attribute ( " gcs.object" , instance .name )
119
141
120
142
try :
121
143
kv = wrapped (* args , ** kwargs )
122
144
except Exception as e :
123
- scope .span .log_exception (e )
124
- raise
145
+ span .record_exception (e )
125
146
else :
126
147
return kv
127
148
128
- def finish_batch_with_instana (wrapped , instance , args , kwargs ):
149
+ def finish_batch_with_instana (
150
+ wrapped : Callable [..., object ],
151
+ instance : storage .Batch ,
152
+ args : Tuple [object , ...],
153
+ kwargs : Dict [str , Any ],
154
+ ) -> object :
129
155
# return early if we're not tracing
130
156
if tracing_is_off ():
131
157
return wrapped (* args , ** kwargs )
132
158
133
159
tracer , parent_span , _ = get_tracer_tuple ()
160
+ parent_context = parent_span .get_span_context () if parent_span else None
134
161
135
- with tracer .start_active_span ( ' gcs' , child_of = parent_span ) as scope :
136
- scope . span .set_tag ( ' gcs.op' , ' batch' )
137
- scope . span .set_tag ( ' gcs.projectId' , instance ._client .project )
138
- scope . span .set_tag ( ' gcs.numberOfOperations' , len (instance ._requests ))
162
+ with tracer .start_as_current_span ( " gcs" , span_context = parent_context ) as span :
163
+ span .set_attribute ( " gcs.op" , " batch" )
164
+ span .set_attribute ( " gcs.projectId" , instance ._client .project )
165
+ span .set_attribute ( " gcs.numberOfOperations" , len (instance ._requests ))
139
166
140
167
try :
141
168
kv = wrapped (* args , ** kwargs )
142
169
except Exception as e :
143
- scope .span .log_exception (e )
144
- raise
170
+ span .record_exception (e )
145
171
else :
146
172
return kv
147
173
148
- wrapt .wrap_function_wrapper ('google.cloud.storage._http' , 'Connection.api_request' , execute_with_instana )
149
- wrapt .wrap_function_wrapper ('google.cloud.storage.blob' , 'Blob._do_download' , download_with_instana )
150
- wrapt .wrap_function_wrapper ('google.cloud.storage.blob' , 'Blob._do_upload' , upload_with_instana )
151
- wrapt .wrap_function_wrapper ('google.cloud.storage.batch' , 'Batch.finish' , finish_batch_with_instana )
174
+ wrapt .wrap_function_wrapper (
175
+ "google.cloud.storage._http" , "Connection.api_request" , execute_with_instana
176
+ )
177
+ wrapt .wrap_function_wrapper (
178
+ "google.cloud.storage.blob" , "Blob._do_download" , download_with_instana
179
+ )
180
+ wrapt .wrap_function_wrapper (
181
+ "google.cloud.storage.blob" , "Blob._do_upload" , upload_with_instana
182
+ )
183
+ wrapt .wrap_function_wrapper (
184
+ "google.cloud.storage.batch" , "Batch.finish" , finish_batch_with_instana
185
+ )
152
186
except ImportError :
153
187
pass
0 commit comments