@@ -144,11 +144,15 @@ describe('LoggerHelper', () => {
144144 'rpc.system.name' : 'grpc' ,
145145 'rpc.method' : 'google.storage.v2.Storage/GetObject' ,
146146 'url.domain' : 'storage.googleapis.com' ,
147+ 'server.address' : 'storage.googleapis.com' ,
147148 'rpc.response.status_code' : 'INVALID_ARGUMENT' ,
148149 'error.type' : 'INVALID_FIELD' ,
149150 'gcp.errors.domain' : 'googleapis.com' ,
150151 'gcp.errors.metadata.service' : 'storage.googleapis.com' ,
151152 'gcp.errors.metadata.field' : 'bucket' ,
153+ 'exception.type' : 'GoogleError' ,
154+ 'exception.message' : 'Field name is invalid' ,
155+ 'exception.stacktrace' : err . stack ,
152156 } ) ;
153157 } ) ;
154158
@@ -173,13 +177,14 @@ describe('LoggerHelper', () => {
173177 'rpc.response.status_code' : 'NOT_FOUND' ,
174178 'http.response.status_code' : 404 ,
175179 'error.type' : '404' ,
180+ 'exception.type' : 'GoogleError' ,
181+ 'exception.message' : 'Not Found' ,
182+ 'exception.stacktrace' : httpErr . stack ,
176183 } ) ;
177184 assert . strictEqual ( 'gcp.client.service' in attributes , false ) ;
178185 assert . strictEqual ( 'rpc.method' in attributes , false ) ;
186+ assert . strictEqual ( 'server.address' in attributes , false ) ;
179187 assert . strictEqual ( 'gcp.errors.domain' in attributes , false ) ;
180- assert . strictEqual ( 'exception.type' in attributes , false ) ;
181- assert . strictEqual ( 'exception.message' in attributes , false ) ;
182- assert . strictEqual ( 'exception.stacktrace' in attributes , false ) ;
183188
184189 // Prefers explicit gRPC status code parsed from Google HTTP error body over generic HTTP bucket.
185190 const specificHttpErr = Object . assign (
@@ -195,6 +200,7 @@ describe('LoggerHelper', () => {
195200 clientName : 'StorageClient' ,
196201 methodName : 'GetObject' ,
197202 rpcType : 'http' ,
203+ serverAddress : 'custom.storage.googleapis.com:8443' ,
198204 } ,
199205 { } ,
200206 ) ;
@@ -203,24 +209,60 @@ describe('LoggerHelper', () => {
203209 'FAILED_PRECONDITION' ,
204210 ) ;
205211 assert . strictEqual ( specificAttrs [ 'http.response.status_code' ] , 400 ) ;
212+ assert . strictEqual (
213+ specificAttrs [ 'server.address' ] ,
214+ 'custom.storage.googleapis.com' ,
215+ ) ;
206216
207- // Translates HTTP transport errors carrying a gRPC status code without an HTTP status.
208- const httpTransportErr = Object . assign ( new GoogleError ( 'Unavailable' ) , {
209- code : Status . UNAVAILABLE ,
210- } ) ;
217+ // Omits rpc.response.status_code on HTTP timeouts and pre-response transport
218+ // errors where fallbackServiceStub sets a synthetic retry Status code without httpStatusCode.
219+ const httpTimeoutErr = Object . assign (
220+ new GoogleError (
221+ 'Deadline exceeded: GetObject did not respond within 1000 milliseconds.' ,
222+ ) ,
223+ {
224+ code : Status . DEADLINE_EXCEEDED ,
225+ } ,
226+ ) ;
227+ const timeoutAttrs = buildLogAttributes (
228+ httpTimeoutErr ,
229+ {
230+ clientName : 'StorageClient' ,
231+ methodName : 'GetObject' ,
232+ rpcType : 'http' ,
233+ } ,
234+ staticArgs ,
235+ ) ;
236+ assert . strictEqual ( timeoutAttrs [ 'error.type' ] , 'CLIENT_TIMEOUT' ) ;
237+ assert . strictEqual ( 'rpc.response.status_code' in timeoutAttrs , false ) ;
238+ assert . strictEqual ( 'http.response.status_code' in timeoutAttrs , false ) ;
239+
240+ const econnRefusedCause = Object . assign (
241+ new Error ( 'connect ECONNREFUSED' ) ,
242+ {
243+ code : 'ECONNREFUSED' ,
244+ } ,
245+ ) ;
246+ const httpTransportErr = Object . assign (
247+ new GoogleError ( 'connect ECONNREFUSED' , { cause : econnRefusedCause } ) ,
248+ {
249+ code : Status . UNAVAILABLE ,
250+ } ,
251+ ) ;
211252 const transportAttrs = buildLogAttributes (
212253 httpTransportErr ,
213254 {
214255 clientName : 'StorageClient' ,
215256 methodName : 'GetObject' ,
216257 rpcType : 'http' ,
217258 } ,
218- { } ,
259+ staticArgs ,
219260 ) ;
220261 assert . strictEqual (
221- transportAttrs [ 'rpc.response.status_code ' ] ,
222- 'UNAVAILABLE ' ,
262+ transportAttrs [ 'error.type ' ] ,
263+ 'CLIENT_CONNECTION_ERROR ' ,
223264 ) ;
265+ assert . strictEqual ( 'rpc.response.status_code' in transportAttrs , false ) ;
224266 assert . strictEqual ( 'http.response.status_code' in transportAttrs , false ) ;
225267 } ) ;
226268
@@ -232,8 +274,21 @@ describe('LoggerHelper', () => {
232274 staticArgs ,
233275 ) ;
234276 assert . strictEqual ( clientAttrs [ 'error.type' ] , 'TypeError' ) ;
277+ assert . strictEqual ( clientAttrs [ 'exception.type' ] , 'TypeError' ) ;
278+ assert . strictEqual ( clientAttrs [ 'exception.message' ] , 'invalid argument' ) ;
279+ assert . strictEqual ( clientAttrs [ 'exception.stacktrace' ] , clientErr . stack ) ;
280+ assert . strictEqual ( clientAttrs [ 'url.domain' ] , 'storage.googleapis.com' ) ;
281+ assert . strictEqual ( 'server.address' in clientAttrs , false ) ;
235282 assert . strictEqual ( 'rpc.response.status_code' in clientAttrs , false ) ;
236283
284+ const dnsErr = Object . assign ( new Error ( 'getaddrinfo ENOTFOUND' ) , {
285+ code : 'ENOTFOUND' ,
286+ } ) ;
287+ const dnsAttrs = buildLogAttributes ( dnsErr , dynamicArgs , staticArgs ) ;
288+ assert . strictEqual ( dnsAttrs [ 'error.type' ] , 'CLIENT_CONNECTION_ERROR' ) ;
289+ assert . strictEqual ( dnsAttrs [ 'url.domain' ] , 'storage.googleapis.com' ) ;
290+ assert . strictEqual ( 'server.address' in dnsAttrs , false ) ;
291+
237292 const httpClientAttrs = buildLogAttributes (
238293 clientErr ,
239294 { ...dynamicArgs , rpcType : 'http' } ,
@@ -249,6 +304,10 @@ describe('LoggerHelper', () => {
249304 staticArgs ,
250305 ) ;
251306 assert . strictEqual ( primitiveAttrs [ 'error.type' ] , 'INTERNAL' ) ;
307+ assert . strictEqual ( primitiveAttrs [ 'exception.type' ] , 'Error' ) ;
308+ assert . strictEqual ( primitiveAttrs [ 'exception.message' ] , 'string failure' ) ;
309+ assert . strictEqual ( 'exception.stacktrace' in primitiveAttrs , false ) ;
310+ assert . strictEqual ( 'server.address' in primitiveAttrs , false ) ;
252311 } ) ;
253312 } ) ;
254313
@@ -336,6 +395,7 @@ describe('LoggerHelper', () => {
336395 'rpc.system.name' : 'grpc' ,
337396 'rpc.method' : 'google.storage.v2.Storage/GetObject' ,
338397 'url.domain' : 'storage.googleapis.com' ,
398+ 'server.address' : 'storage.googleapis.com' ,
339399 'rpc.response.status_code' : 'PERMISSION_DENIED' ,
340400 'error.type' : 'IAM_PERMISSION_DENIED' ,
341401 'gcp.errors.domain' : 'googleapis.com' ,
0 commit comments