-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1e3086d
commit 86b6acc
Showing
12 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { CommonUtils, ScrubContext } from '@lumigo/node-core'; | ||
import { Span } from '@opentelemetry/api'; | ||
import { FastifyInstrumentation, FastifyRequestInfo } from '@opentelemetry/instrumentation-fastify'; | ||
import { contentType, scrubHttpPayload } from '../../tools/payloads'; | ||
import { getSpanAttributeMaxLength } from '../../utils'; | ||
import { Instrumentor } from '../instrumentor'; | ||
|
||
export default class LumigoFastifyInstrumentation extends Instrumentor<FastifyInstrumentation> { | ||
getInstrumentedModule(): string { | ||
return 'fastify'; | ||
} | ||
|
||
getInstrumentation(): FastifyInstrumentation { | ||
return new FastifyInstrumentation({ | ||
requestHook: function (span: Span, info: FastifyRequestInfo) { | ||
span.setAttribute( | ||
'http.request.headers', | ||
CommonUtils.payloadStringify( | ||
info.request.headers, | ||
ScrubContext.HTTP_REQUEST_HEADERS, | ||
getSpanAttributeMaxLength() | ||
) | ||
); | ||
span.setAttribute( | ||
'http.request.query', | ||
CommonUtils.payloadStringify( | ||
info.request.query, | ||
ScrubContext.HTTP_REQUEST_QUERY, | ||
getSpanAttributeMaxLength() | ||
) | ||
); | ||
span.setAttribute( | ||
'http.request.body', | ||
scrubHttpPayload( | ||
info.request.body, | ||
contentType(info.request.headers), | ||
ScrubContext.HTTP_REQUEST_BODY | ||
) | ||
); | ||
}, | ||
}); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/instrumentations/fastify/fastifyInstrumentation.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import LumigoFastifyInstrumentation from './FastifyInstrumentation'; | ||
|
||
describe('LumigoFastifyInstrumentation', () => { | ||
let lumigoFastifyInstrumentation = new LumigoFastifyInstrumentation(); | ||
|
||
test('getInstrumentedModule should return "fastify"', () => { | ||
expect(lumigoFastifyInstrumentation.getInstrumentedModule()).toEqual('fastify'); | ||
}); | ||
|
||
// should not be skipped, see https://lumigo.atlassian.net/browse/RD-11195 | ||
test.skip('requireIfAvailable should return required name', () => { | ||
const child_process = require('child_process'); | ||
child_process.execSync('npm install fastify', { stdio: 'inherit' }); | ||
const fastify = require('fastify'); | ||
|
||
expect(lumigoFastifyInstrumentation.requireIfAvailable()).toEqual(fastify); | ||
child_process.execSync('npm uninstall fastify', { stdio: 'inherit' }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
3.29.0 | ||
4.0.0 | ||
4.0.1 | ||
4.0.2 | ||
4.0.3 | ||
4.1.0 | ||
4.2.0 | ||
3.29.1 | ||
4.2.1 | ||
4.3.0 | ||
4.4.0 | ||
4.5.0 | ||
4.5.1 | ||
4.5.2 | ||
4.5.3 | ||
3.29.2 | ||
4.6.0 | ||
4.7.0 | ||
4.8.0 | ||
4.8.1 | ||
3.29.3 | ||
4.9.0 | ||
4.9.1 | ||
4.9.2 | ||
4.10.0 | ||
4.10.1 | ||
4.10.2 | ||
3.29.4 | ||
4.11.0 | ||
3.29.5 | ||
4.12.0 | ||
4.13.0 | ||
4.14.0 | ||
4.14.1 | ||
4.15.0 | ||
4.16.0 | ||
4.16.1 | ||
4.16.2 | ||
4.16.3 | ||
4.17.0 | ||
4.18.0 | ||
4.19.0 | ||
4.19.1 | ||
4.19.2 | ||
4.20.0 | ||
4.21.0 | ||
4.22.0 | ||
4.22.1 | ||
4.22.2 | ||
4.23.0 | ||
4.23.1 | ||
4.23.2 | ||
4.24.0 | ||
4.24.1 | ||
4.24.2 | ||
4.24.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
spans |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const lumigo = require('@lumigo/opentelemetry'); | ||
const fastify = require('fastify')({ | ||
logger: true, | ||
}); | ||
|
||
require('log-timestamp'); | ||
|
||
let tracerProvider; | ||
|
||
fastify.get('/test-scrubbing', async (request, reply) => { | ||
reply.send({ | ||
Authorization: 'SECRET', | ||
}); | ||
}); | ||
|
||
fastify.get('/', async (request, reply) => { | ||
reply.send('server is ready'); | ||
}); | ||
|
||
fastify.get('/basic', async (request, reply) => { | ||
await tracerProvider.forceFlush(); | ||
reply.header('Content-Type', 'text/plain').send('Hello world'); | ||
}); | ||
|
||
fastify.get('/quit', async (request, reply) => { | ||
console.error('Received quit command'); | ||
await tracerProvider.forceFlush(); | ||
reply.send({}).then(async () => { | ||
// fastify.close() takes too long to do its thing | ||
process.exit(0); | ||
}); | ||
}); | ||
|
||
fastify.listen({ port: 0 }, async (err, address) => { | ||
if (err) throw err; | ||
tracerProvider = (await lumigo.init).tracerProvider; | ||
const port = fastify.server.address().port; | ||
console.error(`HTTP server listening on port ${port}`); | ||
if (process.send) { | ||
process.send(port); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "lumigo-fastify-test", | ||
"version": "1.0.0", | ||
"description": "", | ||
"scripts": { | ||
"start": "node -r @lumigo/opentelemetry fastify_app.js" | ||
}, | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@lumigo/opentelemetry": "file:../../../../distro.tgz", | ||
"fastify": "^3.29.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import * as fs from 'fs'; | ||
import 'jest-expect-message'; | ||
import 'jest-json'; | ||
import { join } from 'path'; | ||
|
||
import { SpanKind, SpanStatusCode } from '@opentelemetry/api'; | ||
|
||
import { itTest } from '../../integration/setup'; | ||
import { getSpanByKind } from '../../utils/spans'; | ||
import { TestApp } from '../../utils/test-apps'; | ||
import { installPackage, reinstallPackages, uninstallPackage } from '../../utils/test-setup'; | ||
import { versionsToTest } from '../../utils/versions'; | ||
|
||
const INSTRUMENTATION_NAME = `fastify`; | ||
const SPANS_DIR = join(__dirname, 'spans'); | ||
const TEST_APP_DIR = join(__dirname, 'app'); | ||
const TEST_TIMEOUT = 20_000; | ||
|
||
const expectedResourceAttributes = { | ||
attributes: { | ||
framework: 'node', | ||
'lumigo.distro.version': expect.stringMatching(/1\.\d+\.\d+/), | ||
'process.environ': expect.any(String), | ||
'process.executable.name': 'node', | ||
'process.pid': expect.any(Number), | ||
'process.runtime.name': 'nodejs', | ||
'process.runtime.version': expect.stringMatching(/\d+\.\d+\.\d+/), | ||
'service.name': 'fastify', | ||
'telemetry.sdk.language': 'nodejs', | ||
'telemetry.sdk.name': 'opentelemetry', | ||
'telemetry.sdk.version': expect.any(String), | ||
}, | ||
}; | ||
|
||
describe.each(versionsToTest(INSTRUMENTATION_NAME, INSTRUMENTATION_NAME))( | ||
`Instrumentation tests for the ${INSTRUMENTATION_NAME} package`, | ||
function (versionToTest) { | ||
let testApp: TestApp; | ||
|
||
beforeAll(function () { | ||
reinstallPackages({ appDir: TEST_APP_DIR }); | ||
fs.mkdirSync(SPANS_DIR, { recursive: true }); | ||
installPackage({ | ||
appDir: TEST_APP_DIR, | ||
packageName: INSTRUMENTATION_NAME, | ||
packageVersion: versionToTest, | ||
}); | ||
}); | ||
|
||
afterEach(async function () { | ||
try { | ||
await testApp.kill(); | ||
} catch (err) { | ||
console.warn('Failed to kill test app', err); | ||
} | ||
}); | ||
|
||
afterAll(function () { | ||
uninstallPackage({ | ||
appDir: TEST_APP_DIR, | ||
packageName: INSTRUMENTATION_NAME, | ||
packageVersion: versionToTest, | ||
}); | ||
}); | ||
|
||
itTest( | ||
{ | ||
testName: `basics: ${versionToTest}`, | ||
packageName: INSTRUMENTATION_NAME, | ||
version: versionToTest, | ||
timeout: TEST_TIMEOUT, | ||
}, | ||
async function () { | ||
const exporterFile = `${SPANS_DIR}/basics.${INSTRUMENTATION_NAME}@${versionToTest}.json`; | ||
|
||
testApp = new TestApp(TEST_APP_DIR, INSTRUMENTATION_NAME, exporterFile, { | ||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT: '4096', | ||
}); | ||
|
||
await testApp.invokeGetPath('/basic'); | ||
|
||
const spans = await testApp.getFinalSpans(2); | ||
|
||
expect(getSpanByKind(spans, SpanKind.SERVER)).toMatchObject({ | ||
traceId: expect.any(String), | ||
name: 'GET /basic', | ||
id: expect.any(String), | ||
kind: SpanKind.SERVER, | ||
timestamp: expect.any(Number), | ||
duration: expect.any(Number), | ||
resource: expectedResourceAttributes, | ||
attributes: { | ||
'http.method': 'GET', | ||
'http.target': '/basic', | ||
'http.host': expect.stringMatching(/localhost:\d+/), | ||
'http.scheme': 'http', | ||
'net.peer.ip': expect.any(String), | ||
'http.route': '/basic', | ||
'http.status_code': 200, | ||
}, | ||
status: { | ||
code: SpanStatusCode.UNSET, | ||
}, | ||
events: [], | ||
}); | ||
|
||
expect(getSpanByKind(spans, SpanKind.INTERNAL)).toMatchObject({ | ||
traceId: expect.any(String), | ||
parentId: expect.any(String), | ||
name: expect.stringMatching(/request handler - .+/), | ||
id: expect.any(String), | ||
kind: SpanKind.INTERNAL, | ||
timestamp: expect.any(Number), | ||
duration: expect.any(Number), | ||
resource: expectedResourceAttributes, | ||
attributes: { | ||
'http.request.query': '{}', | ||
'http.request.headers': expect.stringMatching(/\{.*\}/), | ||
// 'http.response.headers': expect.stringMatching(/\{.*\}/), | ||
// 'http.response.body': '"Hello world"', | ||
'http.route': '/basic', | ||
}, | ||
status: { | ||
code: SpanStatusCode.UNSET, | ||
}, | ||
events: [], | ||
}); | ||
} | ||
); | ||
} | ||
); |