@stainlessdev/xray-core 0.3.1 → 0.4.0-branch.bg-rework-exporters.8c5264b
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/dist/index.cjs +43 -128
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +53 -131
- package/dist/index.js.map +1 -1
- package/dist/internal.d.cts +2 -1
- package/dist/internal.d.ts +2 -1
- package/dist/{types-D3Vzw_TA.d.cts → types-BA4cE85r.d.cts} +10 -8
- package/dist/{types-D3Vzw_TA.d.ts → types-BA4cE85r.d.ts} +10 -8
- package/package.json +1 -3
package/dist/index.cjs
CHANGED
|
@@ -159,13 +159,10 @@ var defaultRoute = {
|
|
|
159
159
|
normalize: true,
|
|
160
160
|
normalizer: normalizeRoutePattern
|
|
161
161
|
};
|
|
162
|
-
var DEFAULT_ENDPOINT_URL = "http://localhost:4318";
|
|
163
162
|
var defaultExporterBase = {
|
|
164
|
-
endpointUrl: DEFAULT_ENDPOINT_URL,
|
|
165
163
|
headers: {},
|
|
166
|
-
timeoutMs:
|
|
167
|
-
spanProcessor: "batch"
|
|
168
|
-
sampler: { type: "ratio", ratio: 1 }
|
|
164
|
+
timeoutMs: 3e4,
|
|
165
|
+
spanProcessor: "batch"
|
|
169
166
|
};
|
|
170
167
|
var XrayConfigError = class extends Error {
|
|
171
168
|
constructor(code, message) {
|
|
@@ -258,29 +255,23 @@ function normalizeExporter(endpointUrl, cfg) {
|
|
|
258
255
|
const resolvedEndpoint = normalizeExporterEndpoint(cfg?.endpointUrl ?? endpointUrl);
|
|
259
256
|
const rawHeaders = cfg?.headers ?? defaultExporterBase.headers ?? {};
|
|
260
257
|
const parsed = applyEndpointAuth(resolvedEndpoint, rawHeaders);
|
|
261
|
-
const enabled = cfg?.enabled ?? true;
|
|
262
258
|
const exporter = {
|
|
263
|
-
...defaultExporterBase,
|
|
264
|
-
...cfg,
|
|
265
|
-
enabled,
|
|
266
259
|
endpointUrl: parsed.endpointUrl,
|
|
267
260
|
headers: parsed.headers,
|
|
268
261
|
timeoutMs: cfg?.timeoutMs ?? defaultExporterBase.timeoutMs,
|
|
269
|
-
spanProcessor: cfg?.spanProcessor ?? defaultExporterBase.spanProcessor
|
|
270
|
-
sampler: cfg?.sampler ?? defaultExporterBase.sampler
|
|
262
|
+
spanProcessor: cfg?.spanProcessor ?? defaultExporterBase.spanProcessor
|
|
271
263
|
};
|
|
272
|
-
if (exporter.sampler.type === "ratio") {
|
|
273
|
-
const ratio = exporter.sampler.ratio ?? 1;
|
|
274
|
-
if (!Number.isFinite(ratio) || ratio < 0 || ratio > 1) {
|
|
275
|
-
throw new XrayConfigError("INVALID_EXPORTER", "sampler.ratio must be between 0 and 1");
|
|
276
|
-
}
|
|
277
|
-
exporter.sampler = { type: "ratio", ratio };
|
|
278
|
-
}
|
|
279
264
|
return exporter;
|
|
280
265
|
}
|
|
281
266
|
function normalizeExporterEndpoint(endpointUrl) {
|
|
282
267
|
const envUrl = typeof process !== "undefined" ? process.env?.["STAINLESS_XRAY_ENDPOINT_URL"] : void 0;
|
|
283
|
-
const resolved = endpointUrl ?? envUrl
|
|
268
|
+
const resolved = endpointUrl ?? envUrl;
|
|
269
|
+
if (!resolved || !resolved.trim()) {
|
|
270
|
+
throw new XrayConfigError(
|
|
271
|
+
"INVALID_CONFIG",
|
|
272
|
+
"endpointUrl is required (set endpointUrl or STAINLESS_XRAY_ENDPOINT_URL)"
|
|
273
|
+
);
|
|
274
|
+
}
|
|
284
275
|
const trimmed = resolved.trim();
|
|
285
276
|
const withoutTrailingSlash = trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed;
|
|
286
277
|
if (withoutTrailingSlash.endsWith("/v1/traces")) {
|
|
@@ -750,6 +741,9 @@ function sanitizeHeaderValues(headers) {
|
|
|
750
741
|
return sanitized;
|
|
751
742
|
}
|
|
752
743
|
|
|
744
|
+
// src/attributes.ts
|
|
745
|
+
var import_incubating = require("@opentelemetry/semantic-conventions/incubating");
|
|
746
|
+
|
|
753
747
|
// src/attrkey.ts
|
|
754
748
|
var AttributeKeyRequestBody = "http.request.body";
|
|
755
749
|
var AttributeKeyRequestBodyEncoding = "http.request.body.encoding";
|
|
@@ -761,14 +755,6 @@ var AttributeKeyResponseBodyTruncated = "http.response.body.truncated";
|
|
|
761
755
|
var AttributeKeySpanDrop = "stainlessxray.internal.drop";
|
|
762
756
|
|
|
763
757
|
// src/attributes.ts
|
|
764
|
-
var attributeKeyEndUserId = "enduser.id";
|
|
765
|
-
var attributeKeyHttpRequestBodySize = "http.request.body.size";
|
|
766
|
-
var attributeKeyHttpRequestMethod = "http.request.method";
|
|
767
|
-
var attributeKeyHttpResponseBodySize = "http.response.body.size";
|
|
768
|
-
var attributeKeyHttpResponseStatusCode = "http.response.status_code";
|
|
769
|
-
var attributeKeyHttpRoute = "http.route";
|
|
770
|
-
var attributeKeyUrlPath = "url.path";
|
|
771
|
-
var attributeKeyUrlFull = "url.full";
|
|
772
758
|
function setHeaderAttributes(span, headers, prefix) {
|
|
773
759
|
if (!headers) {
|
|
774
760
|
return;
|
|
@@ -783,12 +769,12 @@ function setHeaderAttributes(span, headers, prefix) {
|
|
|
783
769
|
}
|
|
784
770
|
}
|
|
785
771
|
function setRequestAttributes(span, method, urlFull) {
|
|
786
|
-
span.setAttribute(
|
|
772
|
+
span.setAttribute(import_incubating.ATTR_HTTP_REQUEST_METHOD, method);
|
|
787
773
|
if (urlFull) {
|
|
788
|
-
span.setAttribute(
|
|
774
|
+
span.setAttribute(import_incubating.ATTR_URL_FULL, urlFull);
|
|
789
775
|
const path = extractPath(urlFull);
|
|
790
776
|
if (path) {
|
|
791
|
-
span.setAttribute(
|
|
777
|
+
span.setAttribute(import_incubating.ATTR_URL_PATH, path);
|
|
792
778
|
}
|
|
793
779
|
}
|
|
794
780
|
}
|
|
@@ -811,7 +797,7 @@ function setRequestBodyAttributes(span, body) {
|
|
|
811
797
|
}
|
|
812
798
|
}
|
|
813
799
|
function setRequestBodySizeAttribute(span, size) {
|
|
814
|
-
span.setAttribute(
|
|
800
|
+
span.setAttribute(import_incubating.ATTR_HTTP_REQUEST_BODY_SIZE, size);
|
|
815
801
|
}
|
|
816
802
|
function setResponseBodyAttributes(span, body) {
|
|
817
803
|
if (!body.value) {
|
|
@@ -824,18 +810,18 @@ function setResponseBodyAttributes(span, body) {
|
|
|
824
810
|
}
|
|
825
811
|
}
|
|
826
812
|
function setResponseBodySizeAttribute(span, size) {
|
|
827
|
-
span.setAttribute(
|
|
813
|
+
span.setAttribute(import_incubating.ATTR_HTTP_RESPONSE_BODY_SIZE, size);
|
|
828
814
|
}
|
|
829
815
|
function setResponseStatusAttribute(span, statusCode) {
|
|
830
|
-
span.setAttribute(
|
|
816
|
+
span.setAttribute(import_incubating.ATTR_HTTP_RESPONSE_STATUS_CODE, statusCode);
|
|
831
817
|
}
|
|
832
818
|
function setRouteAttribute(span, route) {
|
|
833
819
|
if (route) {
|
|
834
|
-
span.setAttribute(
|
|
820
|
+
span.setAttribute(import_incubating.ATTR_HTTP_ROUTE, route);
|
|
835
821
|
}
|
|
836
822
|
}
|
|
837
823
|
function setUserIdAttribute(span, userId) {
|
|
838
|
-
span.setAttribute(
|
|
824
|
+
span.setAttribute(import_incubating.ATTR_USER_ID, userId);
|
|
839
825
|
}
|
|
840
826
|
function setRequestIdAttribute(span, requestId) {
|
|
841
827
|
span.setAttribute(AttributeKeyRequestID, requestId);
|
|
@@ -843,16 +829,11 @@ function setRequestIdAttribute(span, requestId) {
|
|
|
843
829
|
|
|
844
830
|
// src/otel.ts
|
|
845
831
|
var import_api = require("@opentelemetry/api");
|
|
846
|
-
var import_core = require("@opentelemetry/core");
|
|
847
832
|
var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
848
833
|
var import_resources = require("@opentelemetry/resources");
|
|
849
834
|
var import_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
850
|
-
var import_otlp_transformer = require("@opentelemetry/otlp-transformer");
|
|
851
835
|
var defaultAttributeCountLimit = 128;
|
|
852
|
-
function createTracerProvider(config) {
|
|
853
|
-
if (!config.exporter.enabled || !config.exporter.endpointUrl) {
|
|
854
|
-
return null;
|
|
855
|
-
}
|
|
836
|
+
function createTracerProvider(config, exporter) {
|
|
856
837
|
if (config.exporter.endpointUrl.startsWith("http://")) {
|
|
857
838
|
import_api.diag.warn("xray: OTLP endpoint uses plaintext HTTP");
|
|
858
839
|
}
|
|
@@ -863,12 +844,6 @@ function createTracerProvider(config) {
|
|
|
863
844
|
[import_semantic_conventions.ATTR_TELEMETRY_SDK_NAME]: "stainless-xray",
|
|
864
845
|
[import_semantic_conventions.ATTR_TELEMETRY_SDK_VERSION]: sdkVersion()
|
|
865
846
|
});
|
|
866
|
-
const exporter = new FetchSpanExporter({
|
|
867
|
-
endpointUrl: config.exporter.endpointUrl,
|
|
868
|
-
headers: config.exporter.headers ?? {},
|
|
869
|
-
timeoutMillis: config.exporter.timeoutMs
|
|
870
|
-
});
|
|
871
|
-
const sampler = createSampler(config);
|
|
872
847
|
const spanProcessor = createSpanProcessor(config.exporter.spanProcessor, exporter);
|
|
873
848
|
const dropProcessor = new DropFilterSpanProcessor(spanProcessor);
|
|
874
849
|
const provider = new import_sdk_trace_base.BasicTracerProvider({
|
|
@@ -878,7 +853,7 @@ function createTracerProvider(config) {
|
|
|
878
853
|
attributeValueLengthLimit
|
|
879
854
|
},
|
|
880
855
|
resource,
|
|
881
|
-
sampler,
|
|
856
|
+
sampler: new import_sdk_trace_base.AlwaysOnSampler(),
|
|
882
857
|
spanLimits: {
|
|
883
858
|
attributeCountLimit: defaultAttributeCountLimit,
|
|
884
859
|
attributePerEventCountLimit: defaultAttributeCountLimit,
|
|
@@ -927,69 +902,6 @@ var DropFilterSpanProcessor = class {
|
|
|
927
902
|
return this.next.shutdown();
|
|
928
903
|
}
|
|
929
904
|
};
|
|
930
|
-
var FetchSpanExporter = class {
|
|
931
|
-
constructor(options) {
|
|
932
|
-
this.endpointUrl = options.endpointUrl;
|
|
933
|
-
this.headers = { ...options.headers };
|
|
934
|
-
this.timeoutMillis = options.timeoutMillis;
|
|
935
|
-
this.isShutdown = false;
|
|
936
|
-
const protobufSerializer = import_otlp_transformer.ProtobufTraceSerializer && typeof import_otlp_transformer.ProtobufTraceSerializer.serializeRequest === "function" ? import_otlp_transformer.ProtobufTraceSerializer : null;
|
|
937
|
-
this.serializer = protobufSerializer ?? import_otlp_transformer.JsonTraceSerializer;
|
|
938
|
-
this.contentType = protobufSerializer ? "application/x-protobuf" : "application/json";
|
|
939
|
-
}
|
|
940
|
-
export(spans, resultCallback) {
|
|
941
|
-
if (this.isShutdown) {
|
|
942
|
-
resultCallback({ code: import_core.ExportResultCode.FAILED });
|
|
943
|
-
return;
|
|
944
|
-
}
|
|
945
|
-
const payload = this.serializer.serializeRequest(spans);
|
|
946
|
-
if (!payload) {
|
|
947
|
-
resultCallback({
|
|
948
|
-
code: import_core.ExportResultCode.FAILED,
|
|
949
|
-
error: new Error("OTLP export failed: empty payload")
|
|
950
|
-
});
|
|
951
|
-
return;
|
|
952
|
-
}
|
|
953
|
-
const headers = {
|
|
954
|
-
...this.headers,
|
|
955
|
-
"Content-Type": this.contentType
|
|
956
|
-
};
|
|
957
|
-
const controller = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
958
|
-
let timeout;
|
|
959
|
-
if (controller) {
|
|
960
|
-
timeout = setTimeout(() => controller.abort(), this.timeoutMillis);
|
|
961
|
-
}
|
|
962
|
-
const doExport = async () => {
|
|
963
|
-
const response = await fetch(this.endpointUrl, {
|
|
964
|
-
method: "POST",
|
|
965
|
-
headers,
|
|
966
|
-
body: payload,
|
|
967
|
-
signal: controller?.signal
|
|
968
|
-
});
|
|
969
|
-
if (!response.ok) {
|
|
970
|
-
throw new Error(`OTLP export failed: ${response.status}`);
|
|
971
|
-
}
|
|
972
|
-
};
|
|
973
|
-
doExport().then(() => {
|
|
974
|
-
if (timeout) {
|
|
975
|
-
clearTimeout(timeout);
|
|
976
|
-
}
|
|
977
|
-
resultCallback({ code: import_core.ExportResultCode.SUCCESS });
|
|
978
|
-
}).catch((err) => {
|
|
979
|
-
if (timeout) {
|
|
980
|
-
clearTimeout(timeout);
|
|
981
|
-
}
|
|
982
|
-
import_api.diag.error("OTLP export failed", err);
|
|
983
|
-
resultCallback({ code: import_core.ExportResultCode.FAILED, error: err });
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
async forceFlush() {
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
async shutdown() {
|
|
990
|
-
this.isShutdown = true;
|
|
991
|
-
}
|
|
992
|
-
};
|
|
993
905
|
function createSpanProcessor(mode, exporter) {
|
|
994
906
|
if (mode === "simple") {
|
|
995
907
|
return new import_sdk_trace_base.SimpleSpanProcessor(exporter);
|
|
@@ -1001,19 +913,9 @@ function createSpanProcessor(mode, exporter) {
|
|
|
1001
913
|
exportTimeoutMillis: 3e4
|
|
1002
914
|
});
|
|
1003
915
|
}
|
|
1004
|
-
function createSampler(config) {
|
|
1005
|
-
const sampler = config.exporter.sampler;
|
|
1006
|
-
if (sampler.type === "always_off") {
|
|
1007
|
-
return new import_sdk_trace_base.AlwaysOffSampler();
|
|
1008
|
-
}
|
|
1009
|
-
if (sampler.type === "ratio") {
|
|
1010
|
-
return new import_sdk_trace_base.TraceIdRatioBasedSampler(sampler.ratio ?? 1);
|
|
1011
|
-
}
|
|
1012
|
-
return new import_sdk_trace_base.AlwaysOnSampler();
|
|
1013
|
-
}
|
|
1014
916
|
function sdkVersion() {
|
|
1015
917
|
if (true) {
|
|
1016
|
-
return "0.
|
|
918
|
+
return "0.4.0";
|
|
1017
919
|
}
|
|
1018
920
|
return "unknown";
|
|
1019
921
|
}
|
|
@@ -1051,16 +953,29 @@ function getContextState(ctx) {
|
|
|
1051
953
|
}
|
|
1052
954
|
|
|
1053
955
|
// src/emitter.ts
|
|
1054
|
-
function createEmitter(config) {
|
|
956
|
+
function createEmitter(config, exporter) {
|
|
1055
957
|
const resolved = normalizeConfig(config);
|
|
1056
|
-
|
|
1057
|
-
|
|
958
|
+
if (!exporter) {
|
|
959
|
+
throw new XrayConfigError(
|
|
960
|
+
"INVALID_CONFIG",
|
|
961
|
+
"exporter is required (use @stainlessdev/xray-node or @stainlessdev/xray-fetch)"
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
logWithLevel(resolved.logger, "info", resolved.logLevel, "xray: emitter configured", {
|
|
965
|
+
serviceName: resolved.serviceName,
|
|
966
|
+
environment: resolved.environment,
|
|
967
|
+
version: resolved.version,
|
|
968
|
+
exporterEndpoint: resolved.exporter.endpointUrl,
|
|
969
|
+
spanProcessor: resolved.exporter.spanProcessor
|
|
970
|
+
});
|
|
971
|
+
const tracerProvider = createTracerProvider(resolved, exporter);
|
|
972
|
+
const tracer = tracerFromProvider(tracerProvider);
|
|
1058
973
|
return {
|
|
1059
974
|
config: resolved,
|
|
1060
975
|
startRequest: (req) => startRequest(resolved, tracer, req),
|
|
1061
976
|
endRequest: (ctx, res, err) => endRequest(resolved, ctx, res, err),
|
|
1062
|
-
flush: () => tracerProvider
|
|
1063
|
-
shutdown: () => tracerProvider
|
|
977
|
+
flush: () => tracerProvider.forceFlush(),
|
|
978
|
+
shutdown: () => tracerProvider.shutdown()
|
|
1064
979
|
};
|
|
1065
980
|
}
|
|
1066
981
|
function startRequest(config, tracer, req) {
|
|
@@ -1071,7 +986,7 @@ function startRequest(config, tracer, req) {
|
|
|
1071
986
|
if (req.route && config.route.normalize) {
|
|
1072
987
|
req.route = config.route.normalizer ? config.route.normalizer(req.route) : normalizeRoutePattern(req.route);
|
|
1073
988
|
}
|
|
1074
|
-
const span =
|
|
989
|
+
const span = spanFromTracer(tracer, spanNameFromRequest(req));
|
|
1075
990
|
const context = {
|
|
1076
991
|
requestId,
|
|
1077
992
|
traceId: span?.spanContext().traceId,
|