From 546e0a05db8bb4180468b4f9d03435840fb67a4f Mon Sep 17 00:00:00 2001 From: Fatih Aydilek Date: Wed, 7 Aug 2019 10:24:41 +0300 Subject: [PATCH] Set HTTP span as erroneous when the response code is 4XX 5xx Node.js --- src/plugins/integrations/HttpIntegration.ts | 5 +++ test/integration/http.integration.test.js | 35 ++++++++++++++++++- .../utils/http.integration.utils.js | 18 ++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/plugins/integrations/HttpIntegration.ts b/src/plugins/integrations/HttpIntegration.ts index 2cca629d..2ad63f87 100644 --- a/src/plugins/integrations/HttpIntegration.ts +++ b/src/plugins/integrations/HttpIntegration.ts @@ -9,6 +9,7 @@ import Utils from '../utils/Utils'; import * as url from 'url'; import ThundraLogger from '../../ThundraLogger'; import InvocationSupport from '../support/InvocationSupport'; +import HttpError from '../error/HttpError'; const shimmer = require('shimmer'); const has = require('lodash.has'); @@ -136,6 +137,10 @@ class HttpIntegration implements Integration { const resourceName: string = res.headers[TriggerHeaderTags.RESOURCE_NAME]; span._setOperationName(resourceName); } + const statusCode = res.statusCode.toString(); + if (statusCode.startsWith('4') || statusCode.startsWith('5')) { + span.setErrorTag(new HttpError(res.statusMessage)); + } span.setTag(HttpTags.HTTP_STATUS, res.statusCode); }); diff --git a/test/integration/http.integration.test.js b/test/integration/http.integration.test.js index 33c93233..2e116863 100644 --- a/test/integration/http.integration.test.js +++ b/test/integration/http.integration.test.js @@ -16,7 +16,7 @@ describe('HTTP integration', () => { return Http.get(sdk).then(() => { const span = tracer.getRecorder().spanList[0]; - expect(span.operationName).toBe('jsonplaceholder.typicode.com/users/1') + expect(span.operationName).toBe('jsonplaceholder.typicode.com/users/1'); expect(span.className).toBe('HTTP'); expect(span.domainName).toBe('API'); @@ -35,6 +35,39 @@ describe('HTTP integration', () => { }); }); + test('should set 4XX 5XX errors on HTTP calls', () => { + const integration = new HttpIntegration({ + httpPathDepth: 2, + }); + const sdk = require('http'); + + const tracer = new ThundraTracer(); + InvocationSupport.setFunctionName('functionName'); + + return Http.getError(sdk).then(() => { + const span = tracer.getRecorder().spanList[0]; + + expect(span.operationName).toBe('httpstat.us/404'); + expect(span.className).toBe('HTTP'); + expect(span.domainName).toBe('API'); + + expect(span.tags['operation.type']).toBe('GET'); + expect(span.tags['http.method']).toBe('GET'); + expect(span.tags['http.host']).toBe('httpstat.us'); + expect(span.tags['http.path']).toBe('/404'); + expect(span.tags['http.url']).toBe('httpstat.us/404'); + expect(span.tags['http.status_code']).toBe(404); + expect(span.tags['error']).toBe(true); + expect(span.tags['error.kind']).toBe('HttpError'); + expect(span.tags['error.message']).toBe('Not Found'); + expect(span.tags['topology.vertex']).toEqual(true); + expect(span.tags['trigger.domainName']).toEqual('API'); + expect(span.tags['trigger.className']).toEqual('AWS-Lambda'); + expect(span.tags['trigger.operationNames']).toEqual(['functionName']); + expect(span.tags['http.body']).not.toBeTruthy(); + }); + }); + test('should instrument HTTPS POST calls', () => { const integration = new HttpIntegration({ httpPathDepth: 0, diff --git a/test/integration/utils/http.integration.utils.js b/test/integration/utils/http.integration.utils.js index a55b8968..48618e47 100644 --- a/test/integration/utils/http.integration.utils.js +++ b/test/integration/utils/http.integration.utils.js @@ -16,6 +16,24 @@ module.exports.get = (http) => { }); }; +module.exports.getError = (http) => { + return new Promise((resolve) => { + const url = 'http://httpstat.us/404'; + http.get(url, (resp) => { + let data = ''; + resp.on('data', (chunk) => { + data += chunk; + }); + resp.on('end', () => { + resolve(data); + }); + }).on('error', (err) => { + // We resolve with error. + resolve(err); + }); + }); +}; + module.exports.post = (https) => { return new Promise((resolve) => { const data = JSON.stringify({