Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .tav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ pug:

# @hapi/hapi
# - Package name: Starting with v17.9.0 and v18.2.0 the name changed from
# 'hapi' to '@hapi/hapi'. Instrumentation for the old 'hapi' is now deprecated
# and untested; it will be dropped in the next major version of the agent.
# 'hapi' to '@hapi/hapi'. Starting in elastic-apm-node@4, only the newer
# '@hapi/hapi' is instrumented.
# - Node version compat:
# - @hapi/hapi@19: supports node >=v12 (judging from commit 50d8d7d)
# - @hapi/hapi@20: appears (from travis template refs) to support node >=v12
Expand All @@ -345,29 +345,29 @@ pug:
versions: '>=17.0.0 <19.0.0'
node: '>=8.12.0 <16.0.0'
commands:
- node test/instrumentation/modules/hapi/basic.test.js
- node test/instrumentation/modules/hapi/set-framework-hapihapi.test.js
- node test/instrumentation/modules/hapi/hapi.test.js
- node test/instrumentation/modules/hapi/set-framework.test.js
'@hapi/hapi-v19-v20.1.2':
name: '@hapi/hapi'
versions: '>=19.0.0 <20.1.2'
node: '>=12.0.0 <16.0.0'
commands:
- node test/instrumentation/modules/hapi/basic.test.js
- node test/instrumentation/modules/hapi/set-framework-hapihapi.test.js
- node test/instrumentation/modules/hapi/hapi.test.js
- node test/instrumentation/modules/hapi/set-framework.test.js
'@hapi/hapi-v20.1.2-v21':
name: '@hapi/hapi'
versions: '>=20.1.2 <21.0.0'
node: '>=12.0.0'
commands:
- node test/instrumentation/modules/hapi/basic.test.js
- node test/instrumentation/modules/hapi/set-framework-hapihapi.test.js
- node test/instrumentation/modules/hapi/hapi.test.js
- node test/instrumentation/modules/hapi/set-framework.test.js
'@hapi/hapi-v21-':
name: '@hapi/hapi'
versions: '>=21.0.0'
node: '>=14.10.0'
commands:
- node test/instrumentation/modules/hapi/basic.test.js
- node test/instrumentation/modules/hapi/set-framework-hapihapi.test.js
- node test/instrumentation/modules/hapi/hapi.test.js
- node test/instrumentation/modules/hapi/set-framework.test.js

tedious-v1-v11:
name: tedious
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG4.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
* The config option <<filter-http-headers, filterHttpHeaders>> is now *removed*.
({pull}3539[#3539])

* Remove instrumentation support for the old 'hapi' package -- the current
'@hapi/hapi' package is still instrumented. ({issues}2691[#2691])

[float]
===== Features

Expand Down
2 changes: 0 additions & 2 deletions dev-utils/bitrot.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const EXCUSE_FROM_SUPPORTED_TECHNOLOGIES_DOC = {
const EXCUSE_FROM_TAV = {
'@elastic/elasticsearch-canary': true,
got: true, // got@12 is pure ESM so we state support up to got@11 only
hapi: true, // we deprecated 'hapi' (in favour of '@hapi/hapi')
jade: true, // we deprecated 'jade' (in favour of 'pug')
'mimic-response': true, // we instrument a single old version to indirectly support an old version of 'got'
mongojs: true, // last release was in 2019, we aren't going to add effort to this module now
Expand Down Expand Up @@ -169,7 +168,6 @@ function loadSupportedDoc() {
// The tables in supported-technologies.asciidoc have the module
// name in the first column, and version range in the second. There
// are two forms of the first cell to parse:
// [ '<<hapi,hapi>>', '>=9.0.0 <19.0.0' ],
// [ '<<hapi,@hapi/hapi>>', '>=17.9.0 <20.0.0' ],
// [ '<<koa,Koa>> via koa-router or @koa/router', '>=5.2.0 <10.0.0' ],
// [ '<<restify,Restify>>', '>=5.2.0' ],
Expand Down
15 changes: 0 additions & 15 deletions docs/agent-api.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -813,21 +813,6 @@ apm.addPatch('timers', (exports, agent, { version, enabled }) => {

// or ...

apm.addPatch(['hapi', '@hapi/hapi'], (exports, agent, { version, enabled }) => {
const setTimeout = exports.setTimeout
exports.setTimeout = (fn, ms) => {
const span = agent.startSpan('set-timeout')
return setTimeout(() => {
span.end()
fn()
}, ms)
}

return exports
})

// or ...

apm.addPatch('timers', './timer-patch')
----

Expand Down
2 changes: 1 addition & 1 deletion docs/hapi.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ npm install elastic-apm-node --save
[[hapi-initialization]]
==== Initialization

It's important that the agent is started before you require *any* other modules in your Node.js application - i.e. before `hapi`, `http`, etc.
It's important that the agent is started before you require *any* other modules in your Node.js application - i.e. before `@hapi/hapi`, `http`, etc.

This means that you should probably require and start the agent in your application's main file (usually `index.js`, `server.js` or `app.js`).

Expand Down
1 change: 0 additions & 1 deletion docs/supported-technologies.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ These are the frameworks that we officially support:
| <<express,Express>> | ^4.0.0 |
| <<fastify,Fastify>> | >=1.0.0 | See also https://www.fastify.io/docs/latest/Reference/LTS/[Fastify's own LTS documentation]
| <<hapi,@hapi/hapi>> | >=17.9.0 <22.0.0 |
| <<hapi,hapi>> | >=9.0.0 <19.0.0 | Deprecated. No longer tested.
| <<koa,Koa>> via koa-router or @koa/router | >=5.2.0 <13.0.0 | Koa doesn't have a built in router, so we can't support Koa directly since we rely on router information for full support. We currently support the most popular Koa router called https://github.com/koajs/koa-router[koa-router].
| <<nextjs,Next.js>> | >=11.1.0 <13.3.0 | (Technical Preview) This instruments Next.js routing to name transactions for incoming HTTP transactions; and reports errors in user pages. It supports the Next.js production server (`next start`) and development server (`next dev`). See the <<nextjs,Getting Started document>>.
| <<restify,Restify>> | >=5.2.0 <12.0.0 |
Expand Down
2 changes: 1 addition & 1 deletion lib/instrumentation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ var MODULES = [
'generic-pool',
'graphql',
'handlebars',
['hapi', '@hapi/hapi'],
'@hapi/hapi',
'http',
'https',
'http2',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,29 @@

var semver = require('semver');

var shimmer = require('../shimmer');
var shimmer = require('../../shimmer');

var onPreAuthSym = Symbol('ElasticAPMOnPreAuth');

module.exports = function (hapi, agent, { version, enabled }) {
if (!enabled) return hapi;

agent.setFramework({ name: 'hapi', version, overwrite: false });

if (!semver.satisfies(version, '>=9.0.0')) {
agent.logger.debug('hapi version %s not supported - aborting...', version);
if (!enabled) {
return hapi;
}
if (!semver.satisfies(version, '>=17.9.0 <22.0.0')) {
agent.logger.debug('@hapi/hapi@%s not supported, skipping', version);
return hapi;
}
const isHapiGte17 = semver.satisfies(version, '>=17');

agent.logger.debug('shimming hapi.Server.prototype.initialize');
agent.setFramework({ name: 'hapi', version, overwrite: false });

if (isHapiGte17) {
shimmer.massWrap(hapi, ['Server', 'server'], function (orig) {
return function (options) {
var res = orig.apply(this, arguments);
patchServer(res);
return res;
};
});
} else {
shimmer.wrap(hapi.Server.prototype, 'initialize', function (orig) {
return function () {
patchServer(this);
return orig.apply(this, arguments);
};
});
}
agent.logger.debug('shimming hapi.Server, hapi.server');
shimmer.massWrap(hapi, ['Server', 'server'], function (orig) {
return function (options) {
var res = orig.apply(this, arguments);
patchServer(res);
return res;
};
});

function patchServer(server) {
// Hooks that are always allowed
Expand All @@ -52,40 +42,14 @@ module.exports = function (hapi, agent, { version, enabled }) {
agent.logger.debug('unable to enable hapi error tracking');
}

// Prior to hapi 17, when the server has no connections we can't make
// connection lifecycle hooks (in hapi 17+ the server always has
// connections, though the `server.connections` property doesn't exists,
// so this if-statement wont fire)
var conns = server.connections;
if (conns && conns.length === 0) {
agent.logger.debug(
'unable to enable hapi instrumentation on connectionless server',
);
return;
}

// Hooks that are only allowed when the hapi server has connections
// (with hapi 17+ this is always the case)
if (typeof server.ext === 'function') {
server.ext('onPreAuth', onPreAuth);
server.ext('onPreResponse', onPreResponse);
if (agent._conf.captureBody !== 'off') {
server.ext('onPostAuth', onPostAuth);
}
} else {
agent.logger.debug('unable to enable automatic hapi transaction naming');
server.ext('onPreAuth', onPreAuth);
server.ext('onPreResponse', onPreResponse);
if (agent._conf.captureBody !== 'off') {
server.ext('onPostAuth', onPostAuth);
}
}

function attachEvents(emitter) {
if (!isHapiGte17) {
emitter.on('request-error', function (request, error) {
agent.captureError(error, {
request: request.raw && request.raw.req,
});
});
}

emitter.on('log', function (event, tags) {
captureError('log', null, event, tags);
});
Expand Down Expand Up @@ -150,15 +114,15 @@ module.exports = function (hapi, agent, { version, enabled }) {
}
}

return isHapiGte17 ? reply.continue : reply.continue();
return reply.continue;
}

function onPostAuth(request, reply) {
if (request.payload && request.raw && request.raw.req) {
// Save the parsed req body to be picked up by getContextFromRequest().
request.raw.req.payload = request.payload;
}
return isHapiGte17 ? reply.continue : reply.continue();
return reply.continue;
}

function onPreResponse(request, reply) {
Expand All @@ -182,7 +146,7 @@ module.exports = function (hapi, agent, { version, enabled }) {
agent._instrumentation.setDefaultTransactionName('CORS preflight');
}

return isHapiGte17 ? reply.continue : reply.continue();
return reply.continue;
}

return hapi;
Expand Down
9 changes: 4 additions & 5 deletions test/_is_hapi_incompat.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@

var semver = require('semver');

// 'hapi' and '@hapi/hapi' versions have some challenges with compat with
// various versions of node. This method tells you if the current versions
// are incompatible.
function isHapiIncompat(moduleName) {
var hapiVersion = require(`${moduleName}/package.json`).version;
// '@hapi/hapi' versions have some challenges with compat with various versions
// of node. This method tells you if the current versions are incompatible.
function isHapiIncompat() {
var hapiVersion = require(`@hapi/hapi/package.json`).version;

// hapi 17+ requires Node.js 8.9.0 or higher
if (
Expand Down
3 changes: 1 addition & 2 deletions test/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1177,9 +1177,8 @@ test('disableInstrumentations', function (t) {
[],
);
var modules = new Set(flattenedModules);
modules.delete('hapi'); // Deprecated, we no longer test this instrumentation.
modules.delete('jade'); // Deprecated, we no longer test this instrumentation.
if (isHapiIncompat('@hapi/hapi')) {
if (isHapiIncompat()) {
modules.delete('@hapi/hapi');
}
modules.delete('express-graphql');
Expand Down
9 changes: 0 additions & 9 deletions test/instrumentation/modules/hapi/basic.test.js

This file was deleted.

Loading