autotel-mongoose 8.0.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -1
- package/dist/index.cjs +823 -602
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -37
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +119 -37
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +822 -600
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/constants.ts +14 -0
- package/src/custom-methods.integration.test.ts +344 -0
- package/src/index.ts +8 -1
- package/src/instrumentation.ts +447 -0
- package/src/statement.ts +105 -1
- package/src/types.ts +110 -0
package/README.md
CHANGED
|
@@ -77,6 +77,117 @@ userSchema.pre('save', async function () {
|
|
|
77
77
|
});
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
## Custom Statics, Methods & Query Helpers
|
|
81
|
+
|
|
82
|
+
The functions you add via `schema.statics`, `schema.methods`, and `schema.query`
|
|
83
|
+
are invisible to the built-in Model/Query instrumentation. This package traces
|
|
84
|
+
them automatically — **no manual `trace()` calls** and no behavioral side
|
|
85
|
+
effects (same `this`, same return value, same error propagation). Each call
|
|
86
|
+
gets an `INTERNAL` span named `mongoose.<Model>.<fn>`.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
userSchema.statics.findByEmail = function (email: string) {
|
|
90
|
+
return this.findOne({ email }); // span: mongoose.User.findByEmail
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
userSchema.methods.describe = function () {
|
|
94
|
+
return `${this.name} <${this.email}>`; // span: mongoose.User.describe
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
userSchema.query.byEmailDomain = function (domain: string) {
|
|
98
|
+
return this.where({ email: new RegExp(`@${domain}$`) }); // span: mongoose.User.byEmailDomain
|
|
99
|
+
};
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Example spans (from `apps/example-mongoose`, debug output). Note that a static
|
|
103
|
+
returning a Query becomes the **parent** of the underlying operation span, and
|
|
104
|
+
parameters are redacted by default:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
✓ findOne users 1ms [autotel-mongoose]
|
|
108
|
+
db.system.name=mongodb, db.operation.name=findOne, db.collection.name=users, db.query.text={"condition":{"email":"A***@***.com"},...
|
|
109
|
+
✓ mongoose.User.findByEmail 2ms [autotel-mongoose]
|
|
110
|
+
db.system.name=mongodb, code.function.name=findByEmail, mongoose.method.name=findByEmail, mongoose.method.type=static, mongoose.method.model=User, db.collection.name=users, mongoose.method.parameter_count=1, mongoose.method.parameters=["A***@***.com"]
|
|
111
|
+
|
|
112
|
+
✓ mongoose.User.describe 27µs [autotel-mongoose]
|
|
113
|
+
db.system.name=mongodb, code.function.name=describe, mongoose.method.name=describe, mongoose.method.type=instance, mongoose.method.model=User, db.collection.name=users, mongoose.method.parameter_count=0
|
|
114
|
+
|
|
115
|
+
✓ mongoose.User.countByDomain 2ms [autotel-mongoose]
|
|
116
|
+
db.system.name=mongodb, code.function.name=countByDomain, mongoose.method.name=countByDomain, mongoose.method.type=static, mongoose.method.model=User, db.collection.name=users, mongoose.method.parameter_count=1, mongoose.method.parameters=["hotmail.com"]
|
|
117
|
+
|
|
118
|
+
✓ mongoose.User.byEmailDomain 82µs [autotel-mongoose]
|
|
119
|
+
db.system.name=mongodb, code.function.name=byEmailDomain, mongoose.method.name=byEmailDomain, mongoose.method.type=query, mongoose.method.model=User, db.collection.name=users, mongoose.method.parameter_count=1, mongoose.method.parameters=["hotmail.com"]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
As JSON:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"name": "mongoose.User.findByEmail",
|
|
127
|
+
"kind": "INTERNAL",
|
|
128
|
+
"instrumentationScope": { "name": "autotel-mongoose" },
|
|
129
|
+
"attributes": {
|
|
130
|
+
"db.system.name": "mongodb",
|
|
131
|
+
"code.function.name": "findByEmail",
|
|
132
|
+
"mongoose.method.name": "findByEmail",
|
|
133
|
+
"mongoose.method.type": "static",
|
|
134
|
+
"mongoose.method.model": "User",
|
|
135
|
+
"db.collection.name": "users",
|
|
136
|
+
"mongoose.method.parameter_count": 1,
|
|
137
|
+
"mongoose.method.parameters": "[\"A***@***.com\"]"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Span attributes: `mongoose.method.name`, `mongoose.method.type`
|
|
143
|
+
(`static` | `instance` | `query`), `mongoose.method.model`, `code.function.name`,
|
|
144
|
+
and — when parameter capture is on — `mongoose.method.parameters` (+
|
|
145
|
+
`mongoose.method.parameter_count`).
|
|
146
|
+
|
|
147
|
+
> **Behavior note (default on):** With no `customMethods` option, `instrumentMongoose(mongoose)`
|
|
148
|
+
> wraps **all** custom functions and captures their arguments by default
|
|
149
|
+
> (maximum observability). Arguments pass through the same redactor as
|
|
150
|
+
> `db.query.text`, but custom-function args are often business payloads rather
|
|
151
|
+
> than DB filters — redaction won't catch arbitrary fields. Use the options
|
|
152
|
+
> below to scope this down for privacy/compliance.
|
|
153
|
+
|
|
154
|
+
### Opting out / scoping (privacy & compliance)
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// Disable entirely
|
|
158
|
+
instrumentMongoose(mongoose, { customMethods: false });
|
|
159
|
+
|
|
160
|
+
// Per-category control. Anything not explicitly disabled stays on.
|
|
161
|
+
instrumentMongoose(mongoose, {
|
|
162
|
+
customMethods: {
|
|
163
|
+
statics: { exclude: ['chargeCard'] }, // opt-out specific statics
|
|
164
|
+
methods: ['describe'], // opt-in: only these instance methods
|
|
165
|
+
query: false, // no query helpers
|
|
166
|
+
captureParameters: false, // trace calls, don't serialize args
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Keep tracing, but never serialize arguments anywhere
|
|
171
|
+
instrumentMongoose(mongoose, { customMethods: { captureParameters: false } });
|
|
172
|
+
|
|
173
|
+
// Custom parameter serializer / longer cap / dedicated redactor
|
|
174
|
+
instrumentMongoose(mongoose, {
|
|
175
|
+
customMethods: {
|
|
176
|
+
captureParameters: {
|
|
177
|
+
maxLength: 4096,
|
|
178
|
+
redactor: 'default',
|
|
179
|
+
serializer: (args, { methodName }) =>
|
|
180
|
+
methodName === 'chargeCard' ? undefined : JSON.stringify(args),
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
A selector accepts `true` (all), `false` (none), `string[]` (opt-in to those
|
|
187
|
+
names), or `{ include?, exclude? }`. Config is resolved **per Mongoose
|
|
188
|
+
instance** at call time, so a schema object reused across multiple
|
|
189
|
+
instances/connections honors each instance's own configuration.
|
|
190
|
+
|
|
80
191
|
## Configuration
|
|
81
192
|
|
|
82
193
|
```typescript
|
|
@@ -91,6 +202,7 @@ const config: InstrumentMongooseConfig = {
|
|
|
91
202
|
instrumentHooks: false,
|
|
92
203
|
dbStatementSerializer: false,
|
|
93
204
|
statementRedactor: 'default',
|
|
205
|
+
customMethods: true, // wrap all custom statics/methods/query helpers (default)
|
|
94
206
|
};
|
|
95
207
|
```
|
|
96
208
|
|
|
@@ -137,13 +249,15 @@ instrumentMongoose(mongoose, {
|
|
|
137
249
|
- `instrumentMongoose(mongoose, config?)`
|
|
138
250
|
- `InstrumentMongooseConfig`
|
|
139
251
|
- `SerializerPayload`
|
|
252
|
+
- `CustomMethodsConfig`, `CustomMethodType`, `MethodSelector`, `ParameterCaptureConfig`
|
|
140
253
|
|
|
141
254
|
## Notes
|
|
142
255
|
|
|
143
256
|
- Query and aggregate operations are traced automatically
|
|
144
257
|
- Instance methods like `save()` and `deleteOne()` are traced
|
|
145
258
|
- Static methods like `create()`, `insertMany()`, `aggregate()`, and `bulkWrite()` are traced
|
|
146
|
-
-
|
|
259
|
+
- User-defined statics, instance methods, and query helpers are traced automatically (see above)
|
|
260
|
+
- Hook and custom-function spans use `SpanKind.INTERNAL`
|
|
147
261
|
|
|
148
262
|
## License
|
|
149
263
|
|