@rootcat/node 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/README.md +213 -2
- package/dist/callsite.d.ts +109 -0
- package/dist/callsite.js +565 -0
- package/dist/callsite.js.map +1 -0
- package/dist/config.d.ts +75 -0
- package/dist/config.js +182 -0
- package/dist/config.js.map +1 -0
- package/dist/drizzle.d.ts +21 -0
- package/dist/drizzle.js +124 -0
- package/dist/drizzle.js.map +1 -0
- package/dist/esm.mjs +41 -0
- package/dist/esmhook.d.ts +12 -0
- package/dist/esmhook.js +84 -0
- package/dist/esmhook.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/intake.d.ts +40 -0
- package/dist/intake.js +164 -0
- package/dist/intake.js.map +1 -0
- package/dist/keys.d.ts +9 -0
- package/dist/keys.js +15 -0
- package/dist/keys.js.map +1 -0
- package/dist/notices.d.ts +2 -0
- package/dist/notices.js +21 -0
- package/dist/notices.js.map +1 -0
- package/dist/otlp.d.ts +75 -0
- package/dist/otlp.js +449 -0
- package/dist/otlp.js.map +1 -0
- package/dist/pg.d.ts +16 -0
- package/dist/pg.js +165 -0
- package/dist/pg.js.map +1 -0
- package/dist/pgpool.d.ts +13 -0
- package/dist/pgpool.js +85 -0
- package/dist/pgpool.js.map +1 -0
- package/dist/postgresjs.d.ts +33 -0
- package/dist/postgresjs.js +272 -0
- package/dist/postgresjs.js.map +1 -0
- package/dist/privacy.d.ts +38 -0
- package/dist/privacy.js +147 -0
- package/dist/privacy.js.map +1 -0
- package/dist/processor.d.ts +94 -0
- package/dist/processor.js +252 -0
- package/dist/processor.js.map +1 -0
- package/dist/register.d.ts +1 -0
- package/dist/register.js +12 -0
- package/dist/register.js.map +1 -0
- package/dist/sampler.d.ts +12 -0
- package/dist/sampler.js +52 -0
- package/dist/sampler.js.map +1 -0
- package/dist/sdk.d.ts +88 -0
- package/dist/sdk.js +305 -0
- package/dist/sdk.js.map +1 -0
- package/package.json +65 -4
package/dist/config.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.otlpPort = exports.callsiteDepth = exports.defaultCallsiteSample = exports.defaultSampleRatio = exports.maxPackageJSONBytes = void 0;
|
|
37
|
+
exports.serviceIdentity = serviceIdentity;
|
|
38
|
+
exports.nearestPackageJSON = nearestPackageJSON;
|
|
39
|
+
exports.clean = clean;
|
|
40
|
+
exports.nonNegativeInt = nonNegativeInt;
|
|
41
|
+
exports.tracesURL = tracesURL;
|
|
42
|
+
exports.ratio = ratio;
|
|
43
|
+
exports.readConfig = readConfig;
|
|
44
|
+
// Configuration: what the environment says, with every value validated
|
|
45
|
+
// once here and passed inward as a parsed value. The package reads only
|
|
46
|
+
// ROOTCAT_* variables (and OTEL_SERVICE_NAME for the service name); the
|
|
47
|
+
// OTEL_EXPORTER_OTLP_* variables are ignored so that spans go to the host
|
|
48
|
+
// agent and nowhere else.
|
|
49
|
+
const fs = __importStar(require("node:fs"));
|
|
50
|
+
const path = __importStar(require("node:path"));
|
|
51
|
+
/** Bounds on what is read while looking for the service identity. */
|
|
52
|
+
exports.maxPackageJSONBytes = 64 * 1024;
|
|
53
|
+
const maxPackageJSONLevels = 8;
|
|
54
|
+
/** Defaults; the two sampling values are the knobs the environment has. */
|
|
55
|
+
exports.defaultSampleRatio = 1;
|
|
56
|
+
exports.defaultCallsiteSample = 1;
|
|
57
|
+
exports.callsiteDepth = 32;
|
|
58
|
+
exports.otlpPort = 4318;
|
|
59
|
+
/**
|
|
60
|
+
* serviceIdentity resolves the service name from ROOTCAT_SERVICE, then
|
|
61
|
+
* OTEL_SERVICE_NAME, then the nearest package.json above cwd (at most
|
|
62
|
+
* eight levels, 64 KiB), else "unknown_service:node"; the version comes
|
|
63
|
+
* from the same package.json when it has one.
|
|
64
|
+
*/
|
|
65
|
+
function serviceIdentity(env, cwd) {
|
|
66
|
+
const pkg = nearestPackageJSON(cwd);
|
|
67
|
+
const fromEnv = clean(env.ROOTCAT_SERVICE) || clean(env.OTEL_SERVICE_NAME);
|
|
68
|
+
return {
|
|
69
|
+
name: fromEnv || pkg?.name || 'unknown_service:node',
|
|
70
|
+
version: pkg?.version ?? '',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** nearestPackageJSON reads name and version from the closest package.json. */
|
|
74
|
+
function nearestPackageJSON(cwd) {
|
|
75
|
+
let dir = path.resolve(cwd);
|
|
76
|
+
for (let level = 0; level < maxPackageJSONLevels; level++) {
|
|
77
|
+
const file = path.join(dir, 'package.json');
|
|
78
|
+
const parsed = readPackageJSON(file);
|
|
79
|
+
if (parsed) {
|
|
80
|
+
return parsed;
|
|
81
|
+
}
|
|
82
|
+
const parent = path.dirname(dir);
|
|
83
|
+
if (parent === dir) {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
dir = parent;
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
function readPackageJSON(file) {
|
|
91
|
+
let text;
|
|
92
|
+
try {
|
|
93
|
+
const stat = fs.statSync(file);
|
|
94
|
+
if (!stat.isFile() || stat.size > exports.maxPackageJSONBytes) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
text = fs.readFileSync(file, 'utf8');
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const parsed = JSON.parse(text);
|
|
104
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const record = parsed;
|
|
108
|
+
return {
|
|
109
|
+
name: clean(typeof record.name === 'string' ? record.name : undefined) || undefined,
|
|
110
|
+
version: clean(typeof record.version === 'string' ? record.version : undefined) || undefined,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** clean trims a value and bounds it to 256 characters; "" when unset. */
|
|
118
|
+
function clean(value) {
|
|
119
|
+
if (!value) {
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
122
|
+
return value.trim().slice(0, 256);
|
|
123
|
+
}
|
|
124
|
+
/** positiveInt parses a non-negative integer, else returns fallback. */
|
|
125
|
+
function nonNegativeInt(value, fallback, max) {
|
|
126
|
+
const text = clean(value);
|
|
127
|
+
if (!/^\d{1,9}$/.test(text)) {
|
|
128
|
+
return fallback;
|
|
129
|
+
}
|
|
130
|
+
const n = Number(text);
|
|
131
|
+
return n > max ? max : n;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* tracesURL turns the configured intake address into the traces endpoint:
|
|
135
|
+
* a bare origin gets /v1/traces, a URL already ending in /v1/traces is kept.
|
|
136
|
+
*/
|
|
137
|
+
function tracesURL(base) {
|
|
138
|
+
const trimmed = base.trim().replace(/\/+$/, '');
|
|
139
|
+
if (trimmed.endsWith('/v1/traces')) {
|
|
140
|
+
return trimmed;
|
|
141
|
+
}
|
|
142
|
+
return trimmed + '/v1/traces';
|
|
143
|
+
}
|
|
144
|
+
/** ratio parses a share between 0 and 1, else returns fallback. */
|
|
145
|
+
function ratio(value, fallback) {
|
|
146
|
+
const text = clean(value);
|
|
147
|
+
if (!/^(0|1|0?\.\d{1,6}|1\.0+)$/.test(text)) {
|
|
148
|
+
return fallback;
|
|
149
|
+
}
|
|
150
|
+
return Number(text);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* readConfig parses the environment. discover is asked for the intake
|
|
154
|
+
* origin only when ROOTCAT_OTLP_URL is unset.
|
|
155
|
+
*/
|
|
156
|
+
function readConfig(env, cwd, discover) {
|
|
157
|
+
const identity = serviceIdentity(env, cwd);
|
|
158
|
+
const base = clean(env.ROOTCAT_OTLP_URL) || discover();
|
|
159
|
+
const disabled = new Set(clean(env.ROOTCAT_DISABLE)
|
|
160
|
+
.split(',')
|
|
161
|
+
.map((name) => name.trim().toLowerCase())
|
|
162
|
+
.filter((name) => name !== ''));
|
|
163
|
+
return {
|
|
164
|
+
enabled: !isSet(env.ROOTCAT_DISABLED),
|
|
165
|
+
url: tracesURL(base),
|
|
166
|
+
serviceName: identity.name,
|
|
167
|
+
serviceVersion: identity.version,
|
|
168
|
+
environment: clean(env.ROOTCAT_ENVIRONMENT) || clean(env.NODE_ENV),
|
|
169
|
+
sampleRatio: ratio(env.ROOTCAT_SAMPLE, exports.defaultSampleRatio),
|
|
170
|
+
callsiteSample: nonNegativeInt(env.ROOTCAT_CALLSITE_SAMPLE, exports.defaultCallsiteSample, 1_000_000),
|
|
171
|
+
callsiteDepth: exports.callsiteDepth,
|
|
172
|
+
statement: clean(env.ROOTCAT_DB_STATEMENT).toLowerCase() === 'off' ? 'off' : 'masked',
|
|
173
|
+
debug: isSet(env.ROOTCAT_DEBUG),
|
|
174
|
+
disabled,
|
|
175
|
+
cwd: path.resolve(cwd),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function isSet(value) {
|
|
179
|
+
const text = clean(value).toLowerCase();
|
|
180
|
+
return text !== '' && text !== '0' && text !== 'false' && text !== 'off' && text !== 'no';
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InstrumentationBase, type InstrumentationConfig, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
|
|
2
|
+
import type { CallSiteSampling } from './processor.js';
|
|
3
|
+
/** DrizzleEntryOptions bounds and gates the capture. */
|
|
4
|
+
export interface DrizzleEntryOptions extends InstrumentationConfig {
|
|
5
|
+
depth: number;
|
|
6
|
+
sampling: CallSiteSampling;
|
|
7
|
+
isApp?: (file: string) => boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class DrizzleEntryInstrumentation extends InstrumentationBase<DrizzleEntryOptions> {
|
|
10
|
+
/** built holds the call site and root decision of every builder constructed. */
|
|
11
|
+
private readonly built;
|
|
12
|
+
constructor(options: DrizzleEntryOptions);
|
|
13
|
+
protected init(): InstrumentationNodeModuleDefinition;
|
|
14
|
+
/**
|
|
15
|
+
* patchClass replaces the named export with a capturing subclass. An ES
|
|
16
|
+
* module namespace takes the assignment; the CommonJS build exports
|
|
17
|
+
* getters, so a fresh exports object is returned in its place.
|
|
18
|
+
*/
|
|
19
|
+
private patchClass;
|
|
20
|
+
private capturing;
|
|
21
|
+
}
|
package/dist/drizzle.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DrizzleEntryInstrumentation = void 0;
|
|
4
|
+
// Drizzle entry: a Drizzle query is a thenable built in application code
|
|
5
|
+
// (db.select().from(t), db.insert(t).values(v), db.query.t.findMany(),
|
|
6
|
+
// db.execute(sql)) and run when awaited, from a job where no application
|
|
7
|
+
// frame remains. The builders descend from two classes the package
|
|
8
|
+
// exports, QueryPromise (insert, update, delete, raw, relational queries)
|
|
9
|
+
// and TypedQueryBuilder (selects, which take QueryPromise's then/catch/
|
|
10
|
+
// finally as mixins). Both are replaced, at module load, by subclasses
|
|
11
|
+
// that capture the call site when a builder is constructed, and then()
|
|
12
|
+
// runs under a context carrying that site, so the driver span started
|
|
13
|
+
// later (pg, postgres.js, mysql2, or Drizzle's own drizzle.* spans) is
|
|
14
|
+
// given it. Nothing else of Drizzle is touched; a Drizzle bundled into an
|
|
15
|
+
// application file is not seen and keeps working untraced.
|
|
16
|
+
const api_1 = require("@opentelemetry/api");
|
|
17
|
+
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
18
|
+
const callsite_js_1 = require("./callsite.js");
|
|
19
|
+
const keys_js_1 = require("./keys.js");
|
|
20
|
+
const supportedVersions = ['>=0.28.0 <2'];
|
|
21
|
+
class DrizzleEntryInstrumentation extends instrumentation_1.InstrumentationBase {
|
|
22
|
+
/** built holds the call site and root decision of every builder constructed. */
|
|
23
|
+
built = new WeakMap();
|
|
24
|
+
constructor(options) {
|
|
25
|
+
super('@rootcat/node/drizzle-entry', '0.1.0', options);
|
|
26
|
+
}
|
|
27
|
+
init() {
|
|
28
|
+
// Both loaders name an internal file by its path inside the package:
|
|
29
|
+
// the .cjs build under require, the .js build under import (the ESM
|
|
30
|
+
// entry includes Drizzle's files in the loader's list for this). A
|
|
31
|
+
// file that does not export the class is left alone.
|
|
32
|
+
const file = (name, exportName, withThen) => new instrumentation_1.InstrumentationNodeModuleFile(name, supportedVersions, (moduleExports) => this.patchClass(moduleExports, exportName, withThen), () => undefined);
|
|
33
|
+
return new instrumentation_1.InstrumentationNodeModuleDefinition('drizzle-orm', supportedVersions, undefined, undefined, [
|
|
34
|
+
file('drizzle-orm/query-promise.js', 'QueryPromise', true),
|
|
35
|
+
file('drizzle-orm/query-promise.cjs', 'QueryPromise', true),
|
|
36
|
+
file('drizzle-orm/query-builders/query-builder.js', 'TypedQueryBuilder', false),
|
|
37
|
+
file('drizzle-orm/query-builders/query-builder.cjs', 'TypedQueryBuilder', false),
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* patchClass replaces the named export with a capturing subclass. An ES
|
|
42
|
+
* module namespace takes the assignment; the CommonJS build exports
|
|
43
|
+
* getters, so a fresh exports object is returned in its place.
|
|
44
|
+
*/
|
|
45
|
+
patchClass(moduleExports, exportName, withThen) {
|
|
46
|
+
const ns = moduleExports;
|
|
47
|
+
const Original = ns?.[exportName];
|
|
48
|
+
if (typeof Original !== 'function') {
|
|
49
|
+
return moduleExports;
|
|
50
|
+
}
|
|
51
|
+
const Traced = this.capturing(Original, withThen);
|
|
52
|
+
try {
|
|
53
|
+
ns[exportName] = Traced;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// getters only: replaced below
|
|
57
|
+
}
|
|
58
|
+
if (ns[exportName] === Traced) {
|
|
59
|
+
return moduleExports;
|
|
60
|
+
}
|
|
61
|
+
const replacement = {};
|
|
62
|
+
for (const key of Object.getOwnPropertyNames(ns)) {
|
|
63
|
+
replacement[key] = key === exportName ? Traced : ns[key];
|
|
64
|
+
}
|
|
65
|
+
return replacement;
|
|
66
|
+
}
|
|
67
|
+
capturing(Original, withThen) {
|
|
68
|
+
const instrumentation = this;
|
|
69
|
+
const Traced = class extends Original {
|
|
70
|
+
constructor(...args) {
|
|
71
|
+
super(...args);
|
|
72
|
+
try {
|
|
73
|
+
const config = instrumentation.getConfig();
|
|
74
|
+
const carried = config.sampling.carry(() => (0, callsite_js_1.captureCallSite)(config.depth, config.isApp, Traced));
|
|
75
|
+
const site = carried?.getValue(keys_js_1.callSiteContextKey);
|
|
76
|
+
const decided = carried?.getValue(keys_js_1.rootDecisionKey);
|
|
77
|
+
if (site || decided !== undefined) {
|
|
78
|
+
instrumentation.built.set(this, { site, decided });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// a builder without a site
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
Object.defineProperty(Traced, 'name', { value: Original.name });
|
|
87
|
+
if (withThen) {
|
|
88
|
+
// Selects take these as mixins (own properties copied by name), so
|
|
89
|
+
// they must be own properties here. then() runs the query under the
|
|
90
|
+
// context where it is awaited, with the builder's own site (which
|
|
91
|
+
// wins over any other: a query built in the continuation of another
|
|
92
|
+
// is its own) and its root decision; the caller's callbacks are
|
|
93
|
+
// bound to the caller's context, so nothing carried leaks into them.
|
|
94
|
+
const proto = Original.prototype;
|
|
95
|
+
const originalThen = proto.then;
|
|
96
|
+
Object.defineProperty(Traced.prototype, 'then', {
|
|
97
|
+
configurable: true,
|
|
98
|
+
writable: true,
|
|
99
|
+
value: function then(onFulfilled, onRejected) {
|
|
100
|
+
const built = instrumentation.built.get(this);
|
|
101
|
+
if (!built) {
|
|
102
|
+
return originalThen.call(this, onFulfilled, onRejected);
|
|
103
|
+
}
|
|
104
|
+
const outer = api_1.context.active();
|
|
105
|
+
let carried = built.site ? outer.setValue(keys_js_1.callSiteContextKey, built.site) : outer;
|
|
106
|
+
if (built.decided !== undefined && !api_1.trace.getSpanContext(outer)) {
|
|
107
|
+
carried = carried.setValue(keys_js_1.rootDecisionKey, built.decided);
|
|
108
|
+
}
|
|
109
|
+
const bound = (fn) => (typeof fn === 'function' ? api_1.context.bind(outer, fn) : fn);
|
|
110
|
+
return api_1.context.with(carried, () => originalThen.call(this, bound(onFulfilled), bound(onRejected)));
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
for (const name of ['catch', 'finally']) {
|
|
114
|
+
const descriptor = Object.getOwnPropertyDescriptor(proto, name);
|
|
115
|
+
if (descriptor) {
|
|
116
|
+
Object.defineProperty(Traced.prototype, name, descriptor);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return Traced;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.DrizzleEntryInstrumentation = DrizzleEntryInstrumentation;
|
|
124
|
+
//# sourceMappingURL=drizzle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle.js","sourceRoot":"","sources":["../src/drizzle.ts"],"names":[],"mappings":"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"}
|
package/dist/esm.mjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// The --import entry for ES module applications:
|
|
2
|
+
// NODE_OPTIONS="--import @rootcat/node/esm"
|
|
3
|
+
// Registers the module loader hook the instrumentations need to patch ES
|
|
4
|
+
// module imports, tells the loader which modules to watch, waits for it
|
|
5
|
+
// to acknowledge them before the application's first import resolves,
|
|
6
|
+
// then starts the same tracing as the CommonJS entry. The hook module and
|
|
7
|
+
// its message channel come from the same import-in-the-middle copy that
|
|
8
|
+
// the instrumentation package uses, so the two sides always agree.
|
|
9
|
+
import { createRequire, register } from 'node:module';
|
|
10
|
+
import { pathToFileURL } from 'node:url';
|
|
11
|
+
import { isMainThread } from 'node:worker_threads';
|
|
12
|
+
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
|
|
15
|
+
async function main() {
|
|
16
|
+
if (!isMainThread) {
|
|
17
|
+
return; // the loader hooks thread runs the same preloads; nothing to do there
|
|
18
|
+
}
|
|
19
|
+
let waitForAllMessagesAcknowledged = async () => undefined;
|
|
20
|
+
try {
|
|
21
|
+
const { hookedPackages, esmHookMarker } = require('./esmhook.js');
|
|
22
|
+
const iitmPath = createRequire(require.resolve('@opentelemetry/instrumentation/package.json')).resolve('import-in-the-middle');
|
|
23
|
+
const iitm = await import(pathToFileURL(iitmPath).href);
|
|
24
|
+
const channel = iitm.createAddHookMessageChannel();
|
|
25
|
+
// The channel lists only the packages the instrumentations name, by
|
|
26
|
+
// bare specifier; a package patched through one of its internal files
|
|
27
|
+
// (Drizzle's query classes) must be matched by path as well.
|
|
28
|
+
channel.registerOptions.data.include.push(hookedPackages);
|
|
29
|
+
const hook = require.resolve('@opentelemetry/instrumentation/hook.mjs');
|
|
30
|
+
register(pathToFileURL(hook).href, import.meta.url, channel.registerOptions);
|
|
31
|
+
globalThis[esmHookMarker] = true;
|
|
32
|
+
waitForAllMessagesAcknowledged = channel.waitForAllMessagesAcknowledged;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
35
|
+
process.stderr.write(`rootcat: ES module hook not registered (${reason.slice(0, 200)}); CommonJS modules are still traced\n`);
|
|
36
|
+
}
|
|
37
|
+
require('./register.js');
|
|
38
|
+
await waitForAllMessagesAcknowledged();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await main();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** esmHookMarker is set on globalThis once a hook is registered. */
|
|
2
|
+
export declare const esmHookMarker: unique symbol;
|
|
3
|
+
/** hookedPackages are the packages the loader wraps for the instrumentations. */
|
|
4
|
+
export declare const hookedPackages: RegExp;
|
|
5
|
+
/** ESMHook says whether the hook was registered. */
|
|
6
|
+
export type ESMHook = 'on' | 'off';
|
|
7
|
+
/**
|
|
8
|
+
* registerESMHook registers the instrumentation loader hook once and
|
|
9
|
+
* reports whether it is in place. A failure to register never reaches the
|
|
10
|
+
* application.
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerESMHook(report?: (reason: string) => void): ESMHook;
|
package/dist/esmhook.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.hookedPackages = exports.esmHookMarker = void 0;
|
|
37
|
+
exports.registerESMHook = registerESMHook;
|
|
38
|
+
// The ES module loader hook from the CommonJS entry. A CommonJS
|
|
39
|
+
// application still loads ES module packages through the ESM loader
|
|
40
|
+
// (postgres.js is ESM first; Next.js imports its external packages as
|
|
41
|
+
// ES modules), and only a loader hook can patch those. The hook watches
|
|
42
|
+
// a fixed list of packages, so nothing else pays for it.
|
|
43
|
+
//
|
|
44
|
+
// It runs on the loader's hooks thread (module.register), which costs
|
|
45
|
+
// about 0.2 s of startup (every module load waits on the thread; see the
|
|
46
|
+
// benchmark). The in-thread synchronous hooks (module.registerHooks) save
|
|
47
|
+
// most of that, but in a Next.js standalone server they left postgres.js
|
|
48
|
+
// and Drizzle unpatched.
|
|
49
|
+
const nodeModule = __importStar(require("node:module"));
|
|
50
|
+
const node_url_1 = require("node:url");
|
|
51
|
+
/** esmHookMarker is set on globalThis once a hook is registered. */
|
|
52
|
+
exports.esmHookMarker = Symbol.for('rootcat.node.esmHook');
|
|
53
|
+
/** hookedPackages are the packages the loader wraps for the instrumentations. */
|
|
54
|
+
exports.hookedPackages = /[\\/]node_modules[\\/](pg|pg-pool|postgres|drizzle-orm|mysql2|mongodb|ioredis|redis|@redis|undici|@prisma)[\\/]/;
|
|
55
|
+
/**
|
|
56
|
+
* registerESMHook registers the instrumentation loader hook once and
|
|
57
|
+
* reports whether it is in place. A failure to register never reaches the
|
|
58
|
+
* application.
|
|
59
|
+
*/
|
|
60
|
+
function registerESMHook(report = () => undefined) {
|
|
61
|
+
const global = globalThis;
|
|
62
|
+
if (global[exports.esmHookMarker]) {
|
|
63
|
+
return 'on';
|
|
64
|
+
}
|
|
65
|
+
const registrar = nodeModule;
|
|
66
|
+
if (typeof registrar.register !== 'function') {
|
|
67
|
+
report('module.register is not available in this Node version');
|
|
68
|
+
return 'off';
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
// Resolved here, by path: a file tracer (Next.js standalone output)
|
|
72
|
+
// follows require.resolve and ships the hook with the package, which
|
|
73
|
+
// a bare specifier handed to module.register alone would not get.
|
|
74
|
+
const hook = require.resolve('@opentelemetry/instrumentation/hook.mjs');
|
|
75
|
+
registrar.register((0, node_url_1.pathToFileURL)(hook).href, (0, node_url_1.pathToFileURL)(__filename).href, { data: { include: [exports.hookedPackages] } });
|
|
76
|
+
global[exports.esmHookMarker] = true;
|
|
77
|
+
return 'on';
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
report(error instanceof Error ? error.message : String(error));
|
|
81
|
+
return 'off';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=esmhook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esmhook.js","sourceRoot":"","sources":["../src/esmhook.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,0CAsBC;AApDD,gEAAgE;AAChE,oEAAoE;AACpE,sEAAsE;AACtE,wEAAwE;AACxE,yDAAyD;AACzD,EAAE;AACF,sEAAsE;AACtE,yEAAyE;AACzE,0EAA0E;AAC1E,yEAAyE;AACzE,yBAAyB;AACzB,wDAA0C;AAC1C,uCAAyC;AAEzC,oEAAoE;AACvD,QAAA,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAEhE,iFAAiF;AACpE,QAAA,cAAc,GAAG,iHAAiH,CAAC;AAOhJ;;;;GAIG;AACH,SAAgB,eAAe,CAAC,SAAmC,GAAG,EAAE,CAAC,SAAS;IAChF,MAAM,MAAM,GAAG,UAAqC,CAAC;IACrD,IAAI,MAAM,CAAC,qBAAa,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,UAAkC,CAAC;IACrD,IAAI,OAAO,SAAS,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC7C,MAAM,CAAC,uDAAuD,CAAC,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,oEAAoE;QACpE,qEAAqE;QACrE,kEAAkE;QAClE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC;QACxE,SAAS,CAAC,QAAQ,CAAC,IAAA,wBAAa,EAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAA,wBAAa,EAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,sBAAc,CAAC,EAAE,EAAE,CAAC,CAAC;QACtH,MAAM,CAAC,qBAAa,CAAC,GAAG,IAAI,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { start, current, curatedInstrumentations, instrumentationNames, otlpExporter, redisStatement, type Started, type StartOptions } from './sdk.js';
|
|
2
|
+
export { rootcatSampler } from './sampler.js';
|
|
3
|
+
export { readConfig, serviceIdentity, tracesURL, type Config } from './config.js';
|
|
4
|
+
export { discoverIntake, defaultGateway, inContainer, type Files } from './intake.js';
|
|
5
|
+
export { captureCallSite, captureFrames, firstAppFrame, parseStack, resolveLocation, isAppFile, type CallSiteLocation } from './callsite.js';
|
|
6
|
+
export { CallSiteProcessor, CallSiteSampling, callSiteContextKey, eligible, type CallSiteProcessorOptions } from './processor.js';
|
|
7
|
+
export { PgInstrumentation } from './pg.js';
|
|
8
|
+
export { PostgresJsInstrumentation } from './postgresjs.js';
|
|
9
|
+
export { PgPoolEntryInstrumentation } from './pgpool.js';
|
|
10
|
+
export { DrizzleEntryInstrumentation } from './drizzle.js';
|
|
11
|
+
export { registerESMHook, hookedPackages, type ESMHook } from './esmhook.js';
|
|
12
|
+
export { scrubbed, stripQuery, statementKeyword } from './privacy.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.statementKeyword = exports.stripQuery = exports.scrubbed = exports.hookedPackages = exports.registerESMHook = exports.DrizzleEntryInstrumentation = exports.PgPoolEntryInstrumentation = exports.PostgresJsInstrumentation = exports.PgInstrumentation = exports.eligible = exports.callSiteContextKey = exports.CallSiteSampling = exports.CallSiteProcessor = exports.isAppFile = exports.resolveLocation = exports.parseStack = exports.firstAppFrame = exports.captureFrames = exports.captureCallSite = exports.inContainer = exports.defaultGateway = exports.discoverIntake = exports.tracesURL = exports.serviceIdentity = exports.readConfig = exports.rootcatSampler = exports.redisStatement = exports.otlpExporter = exports.instrumentationNames = exports.curatedInstrumentations = exports.current = exports.start = void 0;
|
|
4
|
+
// Programmatic surface (@rootcat/node/sdk): the same start the entries
|
|
5
|
+
// call, and the pieces an application or a test may want on their own.
|
|
6
|
+
var sdk_js_1 = require("./sdk.js");
|
|
7
|
+
Object.defineProperty(exports, "start", { enumerable: true, get: function () { return sdk_js_1.start; } });
|
|
8
|
+
Object.defineProperty(exports, "current", { enumerable: true, get: function () { return sdk_js_1.current; } });
|
|
9
|
+
Object.defineProperty(exports, "curatedInstrumentations", { enumerable: true, get: function () { return sdk_js_1.curatedInstrumentations; } });
|
|
10
|
+
Object.defineProperty(exports, "instrumentationNames", { enumerable: true, get: function () { return sdk_js_1.instrumentationNames; } });
|
|
11
|
+
Object.defineProperty(exports, "otlpExporter", { enumerable: true, get: function () { return sdk_js_1.otlpExporter; } });
|
|
12
|
+
Object.defineProperty(exports, "redisStatement", { enumerable: true, get: function () { return sdk_js_1.redisStatement; } });
|
|
13
|
+
var sampler_js_1 = require("./sampler.js");
|
|
14
|
+
Object.defineProperty(exports, "rootcatSampler", { enumerable: true, get: function () { return sampler_js_1.rootcatSampler; } });
|
|
15
|
+
var config_js_1 = require("./config.js");
|
|
16
|
+
Object.defineProperty(exports, "readConfig", { enumerable: true, get: function () { return config_js_1.readConfig; } });
|
|
17
|
+
Object.defineProperty(exports, "serviceIdentity", { enumerable: true, get: function () { return config_js_1.serviceIdentity; } });
|
|
18
|
+
Object.defineProperty(exports, "tracesURL", { enumerable: true, get: function () { return config_js_1.tracesURL; } });
|
|
19
|
+
var intake_js_1 = require("./intake.js");
|
|
20
|
+
Object.defineProperty(exports, "discoverIntake", { enumerable: true, get: function () { return intake_js_1.discoverIntake; } });
|
|
21
|
+
Object.defineProperty(exports, "defaultGateway", { enumerable: true, get: function () { return intake_js_1.defaultGateway; } });
|
|
22
|
+
Object.defineProperty(exports, "inContainer", { enumerable: true, get: function () { return intake_js_1.inContainer; } });
|
|
23
|
+
var callsite_js_1 = require("./callsite.js");
|
|
24
|
+
Object.defineProperty(exports, "captureCallSite", { enumerable: true, get: function () { return callsite_js_1.captureCallSite; } });
|
|
25
|
+
Object.defineProperty(exports, "captureFrames", { enumerable: true, get: function () { return callsite_js_1.captureFrames; } });
|
|
26
|
+
Object.defineProperty(exports, "firstAppFrame", { enumerable: true, get: function () { return callsite_js_1.firstAppFrame; } });
|
|
27
|
+
Object.defineProperty(exports, "parseStack", { enumerable: true, get: function () { return callsite_js_1.parseStack; } });
|
|
28
|
+
Object.defineProperty(exports, "resolveLocation", { enumerable: true, get: function () { return callsite_js_1.resolveLocation; } });
|
|
29
|
+
Object.defineProperty(exports, "isAppFile", { enumerable: true, get: function () { return callsite_js_1.isAppFile; } });
|
|
30
|
+
var processor_js_1 = require("./processor.js");
|
|
31
|
+
Object.defineProperty(exports, "CallSiteProcessor", { enumerable: true, get: function () { return processor_js_1.CallSiteProcessor; } });
|
|
32
|
+
Object.defineProperty(exports, "CallSiteSampling", { enumerable: true, get: function () { return processor_js_1.CallSiteSampling; } });
|
|
33
|
+
Object.defineProperty(exports, "callSiteContextKey", { enumerable: true, get: function () { return processor_js_1.callSiteContextKey; } });
|
|
34
|
+
Object.defineProperty(exports, "eligible", { enumerable: true, get: function () { return processor_js_1.eligible; } });
|
|
35
|
+
var pg_js_1 = require("./pg.js");
|
|
36
|
+
Object.defineProperty(exports, "PgInstrumentation", { enumerable: true, get: function () { return pg_js_1.PgInstrumentation; } });
|
|
37
|
+
var postgresjs_js_1 = require("./postgresjs.js");
|
|
38
|
+
Object.defineProperty(exports, "PostgresJsInstrumentation", { enumerable: true, get: function () { return postgresjs_js_1.PostgresJsInstrumentation; } });
|
|
39
|
+
var pgpool_js_1 = require("./pgpool.js");
|
|
40
|
+
Object.defineProperty(exports, "PgPoolEntryInstrumentation", { enumerable: true, get: function () { return pgpool_js_1.PgPoolEntryInstrumentation; } });
|
|
41
|
+
var drizzle_js_1 = require("./drizzle.js");
|
|
42
|
+
Object.defineProperty(exports, "DrizzleEntryInstrumentation", { enumerable: true, get: function () { return drizzle_js_1.DrizzleEntryInstrumentation; } });
|
|
43
|
+
var esmhook_js_1 = require("./esmhook.js");
|
|
44
|
+
Object.defineProperty(exports, "registerESMHook", { enumerable: true, get: function () { return esmhook_js_1.registerESMHook; } });
|
|
45
|
+
Object.defineProperty(exports, "hookedPackages", { enumerable: true, get: function () { return esmhook_js_1.hookedPackages; } });
|
|
46
|
+
var privacy_js_1 = require("./privacy.js");
|
|
47
|
+
Object.defineProperty(exports, "scrubbed", { enumerable: true, get: function () { return privacy_js_1.scrubbed; } });
|
|
48
|
+
Object.defineProperty(exports, "stripQuery", { enumerable: true, get: function () { return privacy_js_1.stripQuery; } });
|
|
49
|
+
Object.defineProperty(exports, "statementKeyword", { enumerable: true, get: function () { return privacy_js_1.statementKeyword; } });
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uEAAuE;AACvE,uEAAuE;AACvE,mCAAwJ;AAA/I,+FAAA,KAAK,OAAA;AAAE,iGAAA,OAAO,OAAA;AAAE,iHAAA,uBAAuB,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,wGAAA,cAAc,OAAA;AACpG,2CAA8C;AAArC,4GAAA,cAAc,OAAA;AACvB,yCAAkF;AAAzE,uGAAA,UAAU,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,sGAAA,SAAS,OAAA;AAC/C,yCAAsF;AAA7E,2GAAA,cAAc,OAAA;AAAE,2GAAA,cAAc,OAAA;AAAE,wGAAA,WAAW,OAAA;AACpD,6CAA6I;AAApI,8GAAA,eAAe,OAAA;AAAE,4GAAA,aAAa,OAAA;AAAE,4GAAA,aAAa,OAAA;AAAE,yGAAA,UAAU,OAAA;AAAE,8GAAA,eAAe,OAAA;AAAE,wGAAA,SAAS,OAAA;AAC9F,+CAAkI;AAAzH,iHAAA,iBAAiB,OAAA;AAAE,gHAAA,gBAAgB,OAAA;AAAE,kHAAA,kBAAkB,OAAA;AAAE,wGAAA,QAAQ,OAAA;AAC1E,iCAA4C;AAAnC,0GAAA,iBAAiB,OAAA;AAC1B,iDAA4D;AAAnD,0HAAA,yBAAyB,OAAA;AAClC,yCAAyD;AAAhD,uHAAA,0BAA0B,OAAA;AACnC,2CAA2D;AAAlD,yHAAA,2BAA2B,OAAA;AACpC,2CAA6E;AAApE,6GAAA,eAAe,OAAA;AAAE,4GAAA,cAAc,OAAA;AACxC,2CAAsE;AAA7D,sGAAA,QAAQ,OAAA;AAAE,wGAAA,UAAU,OAAA;AAAE,8GAAA,gBAAgB,OAAA"}
|
package/dist/intake.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Files is the small file-system surface discovery needs; tests fake it. */
|
|
2
|
+
export interface Files {
|
|
3
|
+
exists(file: string): boolean;
|
|
4
|
+
read(file: string, maxBytes: number): string | undefined;
|
|
5
|
+
/** list names a directory's entries, [] when it cannot be read. */
|
|
6
|
+
list(dir: string): string[];
|
|
7
|
+
}
|
|
8
|
+
/** procFiles reads the real /proc, /sys and root. */
|
|
9
|
+
export declare const procFiles: Files;
|
|
10
|
+
/**
|
|
11
|
+
* defaultGateway parses /proc/net/route and returns the IPv4 gateway of
|
|
12
|
+
* the default route (destination 0.0.0.0 with the gateway flag set), or
|
|
13
|
+
* undefined when there is none.
|
|
14
|
+
*/
|
|
15
|
+
export declare function defaultGateway(routeTable: string): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* inContainer reports whether the process runs in a container: Docker's
|
|
18
|
+
* /.dockerenv, podman's /run/.containerenv, or a cgroup path naming a
|
|
19
|
+
* container runtime.
|
|
20
|
+
*/
|
|
21
|
+
export declare function inContainer(files: Files): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* hostNetwork reports whether the process sees the host's own network:
|
|
24
|
+
* a Docker bridge (docker0, docker_gwbridge, br-*) among the interfaces
|
|
25
|
+
* in /sys/class/net, which in a container's own network namespace lists
|
|
26
|
+
* only that namespace's interfaces. A container started with
|
|
27
|
+
* network_mode: host has /.dockerenv and the host's routing table, whose
|
|
28
|
+
* default gateway is the LAN's or the provider's router.
|
|
29
|
+
*/
|
|
30
|
+
export declare function hostNetwork(files: Files): boolean;
|
|
31
|
+
/** privateAddress reports whether an IPv4 address is in a private or shared range. */
|
|
32
|
+
export declare function privateAddress(address: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* discoverIntake returns the agent intake's origin: the default gateway
|
|
35
|
+
* inside a container on a bridge (the bridge address the agent listens
|
|
36
|
+
* on), else loopback. A container on the host's network, or a gateway
|
|
37
|
+
* outside the private ranges, gets loopback: spans are never sent off
|
|
38
|
+
* the host by discovery.
|
|
39
|
+
*/
|
|
40
|
+
export declare function discoverIntake(files?: Files): string;
|