This repository has been archived by the owner on Dec 6, 2022. It is now read-only.
forked from elastic/apm-agent-nodejs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshimmer.js
119 lines (98 loc) · 2.72 KB
/
shimmer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
'use strict'
/**
* This file is extracted from the 'shimmer' project copyright by Forrest L
* Norvell. It have been modified slightly to be used in the current context.
*
* https://github.com/othiym23/shimmer
*
* Original file:
*
* https://github.com/othiym23/shimmer/blob/master/index.js
*
* License:
*
* BSD-2-Clause, http://opensource.org/licenses/BSD-2-Clause
*/
var symbols = require('../symbols')
var isWrappedSym = Symbol('elasticAPMIsWrapped')
exports.wrap = wrap
exports.massWrap = massWrap
exports.unwrap = unwrap
exports.isWrapped = isWrapped
// Do not load agent until used to avoid circular dependency issues.
var _agent
function logger () {
if (!_agent) _agent = require('../../')
return _agent.logger
}
function isFunction (funktion) {
return funktion && {}.toString.call(funktion) === '[object Function]'
}
function wrap (nodule, name, wrapper) {
if (!nodule || !nodule[name]) {
logger().debug('no original function %s to wrap', name)
return
}
if (!wrapper) {
logger.debug('no wrapper function')
logger().debug((new Error()).stack)
return
}
if (!isFunction(nodule[name]) || !isFunction(wrapper)) {
logger().debug('original object and wrapper must be functions')
return
}
if (nodule[name][isWrappedSym]) {
logger().debug('function %s already wrapped', name)
return
}
var desc = Object.getOwnPropertyDescriptor(nodule, name)
if (desc && !desc.writable) {
logger().debug('function %s is not writable', name)
return
}
var original = nodule[name]
var wrapped = wrapper(original, name)
wrapped[isWrappedSym] = true
wrapped[symbols.unwrap] = function elasticAPMUnwrap () {
if (nodule[name] === wrapped) {
nodule[name] = original
wrapped[isWrappedSym] = false
}
}
nodule[name] = wrapped
return wrapped
}
function massWrap (nodules, names, wrapper) {
if (!nodules) {
logger().debug('must provide one or more modules to patch')
logger().debug((new Error()).stack)
return
} else if (!Array.isArray(nodules)) {
nodules = [nodules]
}
if (!(names && Array.isArray(names))) {
logger().debug('must provide one or more functions to wrap on modules')
return
}
nodules.forEach(function (nodule) {
names.forEach(function (name) {
wrap(nodule, name, wrapper)
})
})
}
function unwrap (nodule, name) {
if (!nodule || !nodule[name]) {
logger().debug('no function to unwrap.')
logger().debug((new Error()).stack)
return
}
if (!nodule[name][symbols.unwrap]) {
logger().debug('no original to unwrap to -- has %s already been unwrapped?', name)
} else {
return nodule[name][symbols.unwrap]()
}
}
function isWrapped (wrapped) {
return wrapped && wrapped[isWrappedSym]
}