Skip to content

Commit

Permalink
feat(otel-node): instr-hapi (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
trentm authored May 2, 2024
1 parent fa1d446 commit c38b2e3
Show file tree
Hide file tree
Showing 8 changed files with 921 additions and 2 deletions.
778 changes: 777 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/opentelemetry-node/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

(nothing yet)
- feat: Add instrumentation for `@hapi/hapi` (instrumentation-hapi).

## v0.1.3

Expand Down
1 change: 1 addition & 0 deletions packages/opentelemetry-node/docs/supported-technologies.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This follows from the [OpenTelemetry JS supported runtimes](https://github.com/o
| `@opentelemetry/instrumentation-http` | Instruments Node.js `http` module for all supported versions | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-http#readme) |
| `@opentelemetry/instrumentation-express` | Instruments `express` package for version range `^4.0.0` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-express#readme) |
| `@opentelemetry/instrumentation-fastify` | Instruments `fastify` package for version range `>=3 <5` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-fastify#readme) |
| `@opentelemetry/instrumentation-hapi` | Instruments `@hapi/hapi >=17.0.0 <21` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-hapi#readme) |
| `@opentelemetry/instrumentation-ioredis` | Instruments `ioredis` package for version range `>=2 <6` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-ioredis#readme) |
| `@opentelemetry/instrumentation-pg` | Instruments `pg` package for version range `>=8 <9` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-pg#readme) |
| `@opentelemetry/instrumentation-mongodb` | Instruments `mongodb` package for version range `>=3.3 <7` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-mongodb#readme) |
Expand Down
4 changes: 4 additions & 0 deletions packages/opentelemetry-node/lib/instrumentations.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* "@opentelemetry/instrumentation-ioredis": import('@opentelemetry/instrumentation-ioredis').IORedisInstrumentationConfig | InstrumentationFactory,
* "@opentelemetry/instrumentation-express": import('@opentelemetry/instrumentation-express').ExpressInstrumentationConfig | InstrumentationFactory,
* "@opentelemetry/instrumentation-fastify": import('@opentelemetry/instrumentation-fastify').FastifyInstrumentation | InstrumentationFactory,
* "@opentelemetry/instrumentation-hapi": import('@opentelemetry/instrumentation-hapi').HapiInstrumentation | InstrumentationFactory,
* "@opentelemetry/instrumentation-mongodb": import('@opentelemetry/instrumentation-mongodb').MongoDBInstrumentation | InstrumentationFactory
* "@opentelemetry/instrumentation-pg": import('@opentelemetry/instrumentation-pg').PgInstrumentation | InstrumentationFactory
* "@opentelemetry/instrumentation-winston": import('@opentelemetry/instrumentation-winston').WinstonInstrumentationConfig | InstrumentationFactory,
Expand All @@ -44,6 +45,7 @@ const {
BunyanInstrumentation,
} = require('@opentelemetry/instrumentation-bunyan');
const {HttpInstrumentation} = require('@opentelemetry/instrumentation-http');
const {HapiInstrumentation} = require('@opentelemetry/instrumentation-hapi');
const {
IORedisInstrumentation,
} = require('@opentelemetry/instrumentation-ioredis');
Expand Down Expand Up @@ -81,6 +83,8 @@ const INSTRUMENTATIONS = {
new ExpressInstrumentation(cfg),
'@opentelemetry/instrumentation-fastify': (cfg) =>
new FastifyInstrumentation(cfg),
'@opentelemetry/instrumentation-hapi': (cfg) =>
new HapiInstrumentation(cfg),
'@opentelemetry/instrumentation-http': (cfg) =>
new HttpInstrumentation(cfg),
'@opentelemetry/instrumentation-ioredis': (cfg) =>
Expand Down
2 changes: 2 additions & 0 deletions packages/opentelemetry-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"@opentelemetry/instrumentation-bunyan": "^0.38.0",
"@opentelemetry/instrumentation-express": "^0.38.0",
"@opentelemetry/instrumentation-fastify": "^0.36.0",
"@opentelemetry/instrumentation-hapi": "^0.37.0",
"@opentelemetry/instrumentation-http": "^0.51.0",
"@opentelemetry/instrumentation-ioredis": "^0.40.0",
"@opentelemetry/instrumentation-mongodb": "^0.43.0",
Expand All @@ -86,6 +87,7 @@
},
"devDependencies": {
"@elastic/mockotlpserver": "*",
"@hapi/hapi": "^20.3.0",
"@opentelemetry/api": "^1.3.0",
"@types/tape": "^5.6.4",
"bunyan": "^1.8.15",
Expand Down
62 changes: 62 additions & 0 deletions packages/opentelemetry-node/test/fixtures/use-hapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Usage: node -r @elastic/opentelemetry-node use-hapi.js

const http = require('http');
const Hapi = require('@hapi/hapi');

async function main() {
const PORT = 3000;
const server = Hapi.server({port: PORT, host: 'localhost'});
server.route({
method: 'GET',
path: '/ping',
handler: (request, h) => {
return '/pong';
},
});
server.route({
method: 'GET',
path: '/hi/{name}',
handler: (request, h) => {
return `Hi, ${request.params.name || 'buddy'}.`;
},
});
await server.start();

await new Promise((resolve) => {
http.get(`http://localhost:${PORT}/ping`, (res) => {
console.log('GET /ping: statusCode=%s', res.statusCode);
res.resume();
res.on('end', resolve);
});
});
await new Promise((resolve) => {
http.get(`http://localhost:${PORT}/hi/Bob`, (res) => {
console.log('GET /hi/Bob: statusCode=%s', res.statusCode);
res.resume();
res.on('end', resolve);
});
});

await server.stop({timeout: 1000});
}

main();
73 changes: 73 additions & 0 deletions packages/opentelemetry-node/test/instr-hapi.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Test that 'hapi' instrumentation generates the telemetry we expect.

const test = require('tape');
const {runTestFixtures, findObjInArray} = require('./testutils');

/** @type {import('./testutils').TestFixture[]} */
const testFixtures = [
{
name: 'use-hapi',
args: ['./fixtures/use-hapi.js'],
cwd: __dirname,
env: {
NODE_OPTIONS: '--require=@elastic/opentelemetry-node',
},
versionRanges: {
node: '>=14.18.0',
},
// verbose: true,
checkTelemetry: (t, col) => {
// We expect spans like this:
// ------ trace f72866 (3 spans) ------
// span b30dea "GET" (7.5ms, SPAN_KIND_CLIENT, GET http://localhost:3000/ping -> 200)
// +3ms `- span 2fedbc "GET /ping" (3.4ms, SPAN_KIND_SERVER, GET http://localhost:3000/ping -> 200)
// +2ms `- span a690b0 "route - /ping" (0.1ms, SPAN_KIND_INTERNAL, GET)
// ------ trace 02f825 (3 spans) ------
// span 9a96c1 "GET" (2.0ms, SPAN_KIND_CLIENT, GET http://localhost:3000/hi/Bob -> 200)
// +1ms `- span dfacba "GET /hi/{name}" (0.5ms, SPAN_KIND_SERVER, GET http://localhost:3000/hi/Bob -> 200)
// +0ms `- span 71a126 "route - /hi/{name}" (0.0ms, SPAN_KIND_INTERNAL, GET)
const spans = col.sortedSpans;
t.equal(spans.length, 6);

t.equal(spans[0].scope.name, '@opentelemetry/instrumentation-http');
t.equal(spans[0].name, 'GET');
t.equal(spans[0].kind, 'SPAN_KIND_CLIENT');

t.equal(spans[1].name, 'GET /ping');
t.equal(spans[1].kind, 'SPAN_KIND_SERVER');
t.equal(spans[1].traceId, spans[0].traceId, 'same trace');
t.equal(spans[1].parentSpanId, spans[0].spanId);

t.equal(spans[2].scope.name, '@opentelemetry/instrumentation-hapi');
t.equal(spans[2].name, 'route - /ping');
t.equal(spans[2].kind, 'SPAN_KIND_INTERNAL');

const span = findObjInArray(spans, 'name', 'GET /hi/{name}');
t.ok(span); // route with param
},
},
];

test('hapi instrumentation', (suite) => {
runTestFixtures(suite, testFixtures);
suite.end();
});
1 change: 1 addition & 0 deletions packages/opentelemetry-node/types/instrumentations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type InstrumentaionsMap = {
"@opentelemetry/instrumentation-ioredis": import('@opentelemetry/instrumentation-ioredis').IORedisInstrumentationConfig | InstrumentationFactory;
"@opentelemetry/instrumentation-express": import('@opentelemetry/instrumentation-express').ExpressInstrumentationConfig | InstrumentationFactory;
"@opentelemetry/instrumentation-fastify": import('@opentelemetry/instrumentation-fastify').FastifyInstrumentation | InstrumentationFactory;
"@opentelemetry/instrumentation-hapi": import('@opentelemetry/instrumentation-hapi').HapiInstrumentation | InstrumentationFactory;
"@opentelemetry/instrumentation-mongodb": import('@opentelemetry/instrumentation-mongodb').MongoDBInstrumentation | InstrumentationFactory;
"@opentelemetry/instrumentation-pg": import('@opentelemetry/instrumentation-pg').PgInstrumentation | InstrumentationFactory;
"@opentelemetry/instrumentation-winston": import('@opentelemetry/instrumentation-winston').WinstonInstrumentationConfig | InstrumentationFactory;
Expand Down

0 comments on commit c38b2e3

Please sign in to comment.