or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auto-registration.mdbase-instrumentation.mdindex.mdmodule-definitions.mdsemconv-stability.mdutilities.md

module-definitions.mddocs/

0

# Module Definitions

1

2

The module definition system allows instrumentations to specify which modules and files to instrument, their supported versions, and how to patch/unpatch them.

3

4

## Capabilities

5

6

### InstrumentationNodeModuleDefinition

7

8

Defines instrumentation for an entire Node.js module with optional file-level patching.

9

10

```typescript { .api }

11

/**

12

* Implementation of InstrumentationModuleDefinition for Node.js modules

13

*/

14

class InstrumentationNodeModuleDefinition implements InstrumentationModuleDefinition {

15

files: InstrumentationModuleFile[];

16

17

constructor(

18

/** Module name or path */

19

public name: string,

20

/** Supported version ranges using semver syntax */

21

public supportedVersions: string[],

22

/** Optional module-level patch function */

23

public patch?: (exports: any, moduleVersion?: string) => any,

24

/** Optional module-level unpatch function */

25

public unpatch?: (exports: any, moduleVersion?: string) => void,

26

/** Optional file-level instrumentation definitions */

27

files?: InstrumentationModuleFile[]

28

);

29

}

30

```

31

32

**Usage Example:**

33

34

```typescript

35

import { InstrumentationNodeModuleDefinition } from "@opentelemetry/instrumentation";

36

37

// Simple module-level instrumentation

38

const httpDefinition = new InstrumentationNodeModuleDefinition(

39

"http",

40

["*"], // Support all versions

41

(moduleExports, moduleVersion) => {

42

// Patch http.request and http.get

43

shimmer.wrap(moduleExports, 'request', wrapRequest);

44

shimmer.wrap(moduleExports, 'get', wrapGet);

45

return moduleExports;

46

},

47

(moduleExports, moduleVersion) => {

48

// Unpatch http.request and http.get

49

shimmer.unwrap(moduleExports, 'request');

50

shimmer.unwrap(moduleExports, 'get');

51

}

52

);

53

54

// Module with version constraints

55

const expressDefinition = new InstrumentationNodeModuleDefinition(

56

"express",

57

[">=4.0.0 <6.0.0"], // Support Express 4.x and 5.x

58

(moduleExports, moduleVersion) => {

59

// Patch Express application

60

return moduleExports;

61

}

62

);

63

```

64

65

### InstrumentationNodeModuleFile

66

67

Defines instrumentation for specific files within a module.

68

69

```typescript { .api }

70

/**

71

* Implementation of InstrumentationModuleFile for Node.js module files

72

*/

73

class InstrumentationNodeModuleFile implements InstrumentationModuleFile {

74

public name: string;

75

76

constructor(

77

/** File name with relative path */

78

name: string,

79

/** Supported version ranges using semver syntax */

80

public supportedVersions: string[],

81

/** File-level patch function */

82

public patch: (moduleExports: any, moduleVersion?: string) => any,

83

/** File-level unpatch function */

84

public unpatch: (moduleExports?: any, moduleVersion?: string) => void

85

);

86

}

87

```

88

89

**Usage Example:**

90

91

```typescript

92

import { InstrumentationNodeModuleFile } from "@opentelemetry/instrumentation";

93

94

// File-level instrumentation

95

const routerFile = new InstrumentationNodeModuleFile(

96

"lib/router/index.js",

97

[">=4.0.0 <6.0.0"],

98

(moduleExports, moduleVersion) => {

99

// Patch specific router methods

100

shimmer.wrap(moduleExports.prototype, 'use', wrapUse);

101

return moduleExports;

102

},

103

(moduleExports, moduleVersion) => {

104

// Unpatch router methods

105

shimmer.unwrap(moduleExports.prototype, 'use');

106

}

107

);

108

109

// Combined module with file-level instrumentation

110

const expressWithFiles = new InstrumentationNodeModuleDefinition(

111

"express",

112

[">=4.0.0 <6.0.0"],

113

undefined, // No module-level patch

114

undefined, // No module-level unpatch

115

[routerFile] // File-level instrumentation

116

);

117

```

118

119

### Module Definition Interfaces

120

121

Core interfaces for module and file instrumentation definitions.

122

123

```typescript { .api }

124

/**

125

* Interface for module instrumentation definition

126

*/

127

interface InstrumentationModuleDefinition {

128

/** Module name or path */

129

name: string;

130

/** Module exports (set at runtime) */

131

moduleExports?: any;

132

/** Module version (set at runtime) */

133

moduleVersion?: string;

134

/** Supported version ranges */

135

supportedVersions: string[];

136

/** File-level instrumentation definitions */

137

files: InstrumentationModuleFile[];

138

/** Include prerelease versions in semver check */

139

includePrerelease?: boolean;

140

/** Optional module-level patch function */

141

patch?: (moduleExports: any, moduleVersion?: string) => any;

142

/** Optional module-level unpatch function */

143

unpatch?: (moduleExports: any, moduleVersion?: string) => void;

144

}

145

146

/**

147

* Interface for file instrumentation definition

148

*/

149

interface InstrumentationModuleFile {

150

/** File name with relative path */

151

name: string;

152

/** Module exports for this file (set at runtime) */

153

moduleExports?: unknown;

154

/** Supported version ranges */

155

supportedVersions: string[];

156

/** File-level patch function */

157

patch(moduleExports: unknown, moduleVersion?: string): unknown;

158

/** File-level unpatch function */

159

unpatch(moduleExports?: unknown, moduleVersion?: string): void;

160

}

161

```

162

163

### Version Constraint Patterns

164

165

Common patterns for specifying supported module versions using semver ranges.

166

167

**Usage Examples:**

168

169

```typescript

170

// Support all versions

171

new InstrumentationNodeModuleDefinition("lodash", ["*"]);

172

173

// Support specific major version

174

new InstrumentationNodeModuleDefinition("express", [">=4.0.0 <5.0.0"]);

175

176

// Support multiple major versions

177

new InstrumentationNodeModuleDefinition("mongoose", [">=5.0.0 <6.0.0", ">=6.0.0 <8.0.0"]);

178

179

// Support from specific version onwards

180

new InstrumentationNodeModuleDefinition("redis", [">=2.6.0"]);

181

182

// Support exact version

183

new InstrumentationNodeModuleDefinition("mysql", ["2.18.1"]);

184

185

// Support prerelease versions

186

const definition = new InstrumentationNodeModuleDefinition("beta-package", [">=1.0.0-beta"]);

187

definition.includePrerelease = true;

188

```

189

190

### Complex Module Definition

191

192

Advanced example showing module and file-level instrumentation together.

193

194

**Usage Example:**

195

196

```typescript

197

import {

198

InstrumentationNodeModuleDefinition,

199

InstrumentationNodeModuleFile

200

} from "@opentelemetry/instrumentation";

201

202

class ComplexInstrumentation extends InstrumentationBase {

203

protected init() {

204

// File-level instrumentations

205

const applicationFile = new InstrumentationNodeModuleFile(

206

"lib/application.js",

207

[">=4.0.0 <6.0.0"],

208

(moduleExports, moduleVersion) => {

209

shimmer.wrap(moduleExports, 'listen', this._patchListen.bind(this));

210

return moduleExports;

211

},

212

(moduleExports) => {

213

shimmer.unwrap(moduleExports, 'listen');

214

}

215

);

216

217

const routerFile = new InstrumentationNodeModuleFile(

218

"lib/router/index.js",

219

[">=4.0.0 <6.0.0"],

220

(moduleExports, moduleVersion) => {

221

shimmer.wrap(moduleExports.prototype, 'use', this._patchUse.bind(this));

222

return moduleExports;

223

},

224

(moduleExports) => {

225

shimmer.unwrap(moduleExports.prototype, 'use');

226

}

227

);

228

229

// Module definition with both module and file-level instrumentation

230

return new InstrumentationNodeModuleDefinition(

231

"express",

232

[">=4.0.0 <6.0.0"],

233

(moduleExports, moduleVersion) => {

234

// Module-level patches

235

shimmer.wrap(moduleExports, 'Router', this._patchRouter.bind(this));

236

return moduleExports;

237

},

238

(moduleExports) => {

239

// Module-level unpatches

240

shimmer.unwrap(moduleExports, 'Router');

241

},

242

[applicationFile, routerFile] // File-level instrumentation

243

);

244

}

245

246

private _patchListen(original: Function) {

247

return function(this: any, ...args: any[]) {

248

// Add server startup tracing

249

return original.apply(this, args);

250

};

251

}

252

253

private _patchUse(original: Function) {

254

return function(this: any, ...args: any[]) {

255

// Add middleware tracing

256

return original.apply(this, args);

257

};

258

}

259

260

private _patchRouter(original: Function) {

261

return function(this: any, ...args: any[]) {

262

// Add router creation tracing

263

return original.apply(this, args);

264

};

265

}

266

}

267

```

268

269

### Error Handling

270

271

Module definitions should handle version mismatches and missing modules gracefully.

272

273

**Usage Example:**

274

275

```typescript

276

class RobustInstrumentation extends InstrumentationBase {

277

protected init() {

278

return new InstrumentationNodeModuleDefinition(

279

"optional-module",

280

[">=1.0.0 <3.0.0"],

281

(moduleExports, moduleVersion) => {

282

try {

283

// Check if the expected API exists

284

if (typeof moduleExports.methodToWrap !== 'function') {

285

this._diag.warn('Expected method not found, skipping instrumentation');

286

return moduleExports;

287

}

288

289

shimmer.wrap(moduleExports, 'methodToWrap', this._wrapMethod.bind(this));

290

return moduleExports;

291

} catch (error) {

292

this._diag.error('Failed to patch module', error);

293

return moduleExports;

294

}

295

},

296

(moduleExports) => {

297

try {

298

if (moduleExports && typeof moduleExports.methodToWrap === 'function') {

299

shimmer.unwrap(moduleExports, 'methodToWrap');

300

}

301

} catch (error) {

302

this._diag.error('Failed to unpatch module', error);

303

}

304

}

305

);

306

}

307

}