@arcote.tech/arc-cli 0.7.5 → 0.7.7
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.js +1614 -165
- package/package.json +22 -9
- package/src/builder/dependency-collector.ts +34 -1
- package/src/commands/platform-deploy.ts +16 -0
- package/src/deploy/bootstrap.ts +94 -2
- package/src/deploy/caddyfile.ts +45 -2
- package/src/deploy/compose.ts +147 -2
- package/src/deploy/config.ts +55 -0
- package/src/deploy/env-file.ts +14 -8
- package/src/deploy/htpasswd.ts +20 -0
- package/src/deploy/observability-configs.ts +958 -0
- package/src/platform/server.ts +65 -4
package/dist/index.js
CHANGED
|
@@ -2754,17 +2754,15 @@ var init_strip_ansi = __esm(() => {
|
|
|
2754
2754
|
regex = ansiRegex();
|
|
2755
2755
|
});
|
|
2756
2756
|
|
|
2757
|
-
// ../../node_modules/.bun/get-east-asian-width@1.
|
|
2758
|
-
var ambiguousRanges, fullwidthRanges,
|
|
2757
|
+
// ../../node_modules/.bun/get-east-asian-width@1.6.0/node_modules/get-east-asian-width/lookup-data.js
|
|
2758
|
+
var ambiguousMinimalCodePoint = 161, ambiguousMaximumCodePoint = 1114109, ambiguousRanges, fullwidthMinimalCodePoint = 12288, fullwidthMaximumCodePoint = 65510, fullwidthRanges, wideMinimalCodePoint = 4352, wideMaximumCodePoint = 262141, wideRanges;
|
|
2759
2759
|
var init_lookup_data = __esm(() => {
|
|
2760
2760
|
ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
|
|
2761
2761
|
fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
|
|
2762
|
-
halfwidthRanges = [8361, 8361, 65377, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65512, 65518];
|
|
2763
|
-
narrowRanges = [32, 126, 162, 163, 165, 166, 172, 172, 175, 175, 10214, 10221, 10629, 10630];
|
|
2764
2762
|
wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
|
|
2765
2763
|
});
|
|
2766
2764
|
|
|
2767
|
-
// ../../node_modules/.bun/get-east-asian-width@1.
|
|
2765
|
+
// ../../node_modules/.bun/get-east-asian-width@1.6.0/node_modules/get-east-asian-width/utilities.js
|
|
2768
2766
|
var isInRange = (ranges, codePoint) => {
|
|
2769
2767
|
let low = 0;
|
|
2770
2768
|
let high = Math.floor(ranges.length / 2) - 1;
|
|
@@ -2782,7 +2780,7 @@ var isInRange = (ranges, codePoint) => {
|
|
|
2782
2780
|
return false;
|
|
2783
2781
|
};
|
|
2784
2782
|
|
|
2785
|
-
// ../../node_modules/.bun/get-east-asian-width@1.
|
|
2783
|
+
// ../../node_modules/.bun/get-east-asian-width@1.6.0/node_modules/get-east-asian-width/lookup.js
|
|
2786
2784
|
function findWideFastPathRange(ranges) {
|
|
2787
2785
|
let fastPathStart = ranges[0];
|
|
2788
2786
|
let fastPathEnd = ranges[1];
|
|
@@ -2799,13 +2797,13 @@ function findWideFastPathRange(ranges) {
|
|
|
2799
2797
|
}
|
|
2800
2798
|
return [fastPathStart, fastPathEnd];
|
|
2801
2799
|
}
|
|
2802
|
-
var
|
|
2803
|
-
if (codePoint <
|
|
2800
|
+
var commonCjkCodePoint = 19968, wideFastPathStart, wideFastPathEnd, isAmbiguous = (codePoint) => {
|
|
2801
|
+
if (codePoint < ambiguousMinimalCodePoint || codePoint > ambiguousMaximumCodePoint) {
|
|
2804
2802
|
return false;
|
|
2805
2803
|
}
|
|
2806
2804
|
return isInRange(ambiguousRanges, codePoint);
|
|
2807
2805
|
}, isFullWidth = (codePoint) => {
|
|
2808
|
-
if (codePoint <
|
|
2806
|
+
if (codePoint < fullwidthMinimalCodePoint || codePoint > fullwidthMaximumCodePoint) {
|
|
2809
2807
|
return false;
|
|
2810
2808
|
}
|
|
2811
2809
|
return isInRange(fullwidthRanges, codePoint);
|
|
@@ -2813,27 +2811,17 @@ var minimumAmbiguousCodePoint, maximumAmbiguousCodePoint, minimumFullWidthCodePo
|
|
|
2813
2811
|
if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
|
|
2814
2812
|
return true;
|
|
2815
2813
|
}
|
|
2816
|
-
if (codePoint <
|
|
2814
|
+
if (codePoint < wideMinimalCodePoint || codePoint > wideMaximumCodePoint) {
|
|
2817
2815
|
return false;
|
|
2818
2816
|
}
|
|
2819
2817
|
return isInRange(wideRanges, codePoint);
|
|
2820
2818
|
};
|
|
2821
2819
|
var init_lookup = __esm(() => {
|
|
2822
2820
|
init_lookup_data();
|
|
2823
|
-
|
|
2824
|
-
maximumAmbiguousCodePoint = ambiguousRanges.at(-1);
|
|
2825
|
-
minimumFullWidthCodePoint = fullwidthRanges[0];
|
|
2826
|
-
maximumFullWidthCodePoint = fullwidthRanges.at(-1);
|
|
2827
|
-
minimumHalfWidthCodePoint = halfwidthRanges[0];
|
|
2828
|
-
maximumHalfWidthCodePoint = halfwidthRanges.at(-1);
|
|
2829
|
-
minimumNarrowCodePoint = narrowRanges[0];
|
|
2830
|
-
maximumNarrowCodePoint = narrowRanges.at(-1);
|
|
2831
|
-
minimumWideCodePoint = wideRanges[0];
|
|
2832
|
-
maximumWideCodePoint = wideRanges.at(-1);
|
|
2833
|
-
[wideFastPathStart, wideFastPathEnd] = findWideFastPathRange(wideRanges);
|
|
2821
|
+
[wideFastPathStart, wideFastPathEnd] = /* @__PURE__ */ findWideFastPathRange(wideRanges);
|
|
2834
2822
|
});
|
|
2835
2823
|
|
|
2836
|
-
// ../../node_modules/.bun/get-east-asian-width@1.
|
|
2824
|
+
// ../../node_modules/.bun/get-east-asian-width@1.6.0/node_modules/get-east-asian-width/index.js
|
|
2837
2825
|
function validate(codePoint) {
|
|
2838
2826
|
if (!Number.isSafeInteger(codePoint)) {
|
|
2839
2827
|
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
|
|
@@ -3687,7 +3675,7 @@ var require_balanced_match = __commonJS((exports, module) => {
|
|
|
3687
3675
|
}
|
|
3688
3676
|
});
|
|
3689
3677
|
|
|
3690
|
-
// ../../node_modules/.bun/brace-expansion@2.0
|
|
3678
|
+
// ../../node_modules/.bun/brace-expansion@2.1.0/node_modules/brace-expansion/index.js
|
|
3691
3679
|
var require_brace_expansion = __commonJS((exports, module) => {
|
|
3692
3680
|
var balanced = require_balanced_match();
|
|
3693
3681
|
module.exports = expandTop;
|
|
@@ -3725,13 +3713,15 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
3725
3713
|
parts.push.apply(parts, p);
|
|
3726
3714
|
return parts;
|
|
3727
3715
|
}
|
|
3728
|
-
function expandTop(str) {
|
|
3716
|
+
function expandTop(str, options) {
|
|
3729
3717
|
if (!str)
|
|
3730
3718
|
return [];
|
|
3719
|
+
options = options || {};
|
|
3720
|
+
var max = options.max == null ? Infinity : options.max;
|
|
3731
3721
|
if (str.substr(0, 2) === "{}") {
|
|
3732
3722
|
str = "\\{\\}" + str.substr(2);
|
|
3733
3723
|
}
|
|
3734
|
-
return expand(escapeBraces(str), true).map(unescapeBraces);
|
|
3724
|
+
return expand(escapeBraces(str), max, true).map(unescapeBraces);
|
|
3735
3725
|
}
|
|
3736
3726
|
function embrace(str) {
|
|
3737
3727
|
return "{" + str + "}";
|
|
@@ -3745,15 +3735,15 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
3745
3735
|
function gte(i, y) {
|
|
3746
3736
|
return i >= y;
|
|
3747
3737
|
}
|
|
3748
|
-
function expand(str, isTop) {
|
|
3738
|
+
function expand(str, max, isTop) {
|
|
3749
3739
|
var expansions = [];
|
|
3750
3740
|
var m = balanced("{", "}", str);
|
|
3751
3741
|
if (!m)
|
|
3752
3742
|
return [str];
|
|
3753
3743
|
var pre = m.pre;
|
|
3754
|
-
var post = m.post.length ? expand(m.post, false) : [""];
|
|
3744
|
+
var post = m.post.length ? expand(m.post, max, false) : [""];
|
|
3755
3745
|
if (/\$$/.test(m.pre)) {
|
|
3756
|
-
for (var k = 0;k < post.length; k++) {
|
|
3746
|
+
for (var k = 0;k < post.length && k < max; k++) {
|
|
3757
3747
|
var expansion = pre + "{" + m.body + "}" + post[k];
|
|
3758
3748
|
expansions.push(expansion);
|
|
3759
3749
|
}
|
|
@@ -3765,7 +3755,7 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
3765
3755
|
if (!isSequence && !isOptions) {
|
|
3766
3756
|
if (m.post.match(/,(?!,).*\}/)) {
|
|
3767
3757
|
str = m.pre + "{" + m.body + escClose + m.post;
|
|
3768
|
-
return expand(str);
|
|
3758
|
+
return expand(str, max, true);
|
|
3769
3759
|
}
|
|
3770
3760
|
return [str];
|
|
3771
3761
|
}
|
|
@@ -3775,7 +3765,7 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
3775
3765
|
} else {
|
|
3776
3766
|
n = parseCommaParts(m.body);
|
|
3777
3767
|
if (n.length === 1) {
|
|
3778
|
-
n = expand(n[0], false).map(embrace);
|
|
3768
|
+
n = expand(n[0], max, false).map(embrace);
|
|
3779
3769
|
if (n.length === 1) {
|
|
3780
3770
|
return post.map(function(p) {
|
|
3781
3771
|
return m.pre + n[0] + p;
|
|
@@ -3821,11 +3811,11 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
3821
3811
|
} else {
|
|
3822
3812
|
N = [];
|
|
3823
3813
|
for (var j = 0;j < n.length; j++) {
|
|
3824
|
-
N.push.apply(N, expand(n[j], false));
|
|
3814
|
+
N.push.apply(N, expand(n[j], max, false));
|
|
3825
3815
|
}
|
|
3826
3816
|
}
|
|
3827
3817
|
for (var j = 0;j < N.length; j++) {
|
|
3828
|
-
for (var k = 0;k < post.length; k++) {
|
|
3818
|
+
for (var k = 0;k < post.length && expansions.length < max; k++) {
|
|
3829
3819
|
var expansion = pre + N[j] + post[k];
|
|
3830
3820
|
if (!isTop || isSequence || expansion)
|
|
3831
3821
|
expansions.push(expansion);
|
|
@@ -10327,7 +10317,7 @@ var require_timespan = __commonJS((exports, module) => {
|
|
|
10327
10317
|
};
|
|
10328
10318
|
});
|
|
10329
10319
|
|
|
10330
|
-
// ../../node_modules/.bun/semver@7.
|
|
10320
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/internal/constants.js
|
|
10331
10321
|
var require_constants4 = __commonJS((exports, module) => {
|
|
10332
10322
|
var SEMVER_SPEC_VERSION = "2.0.0";
|
|
10333
10323
|
var MAX_LENGTH = 256;
|
|
@@ -10355,13 +10345,13 @@ var require_constants4 = __commonJS((exports, module) => {
|
|
|
10355
10345
|
};
|
|
10356
10346
|
});
|
|
10357
10347
|
|
|
10358
|
-
// ../../node_modules/.bun/semver@7.
|
|
10348
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/internal/debug.js
|
|
10359
10349
|
var require_debug = __commonJS((exports, module) => {
|
|
10360
10350
|
var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {};
|
|
10361
10351
|
module.exports = debug;
|
|
10362
10352
|
});
|
|
10363
10353
|
|
|
10364
|
-
// ../../node_modules/.bun/semver@7.
|
|
10354
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/internal/re.js
|
|
10365
10355
|
var require_re = __commonJS((exports, module) => {
|
|
10366
10356
|
var {
|
|
10367
10357
|
MAX_SAFE_COMPONENT_LENGTH,
|
|
@@ -10446,7 +10436,7 @@ var require_re = __commonJS((exports, module) => {
|
|
|
10446
10436
|
createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$");
|
|
10447
10437
|
});
|
|
10448
10438
|
|
|
10449
|
-
// ../../node_modules/.bun/semver@7.
|
|
10439
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/internal/parse-options.js
|
|
10450
10440
|
var require_parse_options = __commonJS((exports, module) => {
|
|
10451
10441
|
var looseOption = Object.freeze({ loose: true });
|
|
10452
10442
|
var emptyOpts = Object.freeze({});
|
|
@@ -10462,7 +10452,7 @@ var require_parse_options = __commonJS((exports, module) => {
|
|
|
10462
10452
|
module.exports = parseOptions;
|
|
10463
10453
|
});
|
|
10464
10454
|
|
|
10465
|
-
// ../../node_modules/.bun/semver@7.
|
|
10455
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/internal/identifiers.js
|
|
10466
10456
|
var require_identifiers = __commonJS((exports, module) => {
|
|
10467
10457
|
var numeric = /^[0-9]+$/;
|
|
10468
10458
|
var compareIdentifiers = (a2, b2) => {
|
|
@@ -10484,7 +10474,7 @@ var require_identifiers = __commonJS((exports, module) => {
|
|
|
10484
10474
|
};
|
|
10485
10475
|
});
|
|
10486
10476
|
|
|
10487
|
-
// ../../node_modules/.bun/semver@7.
|
|
10477
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/classes/semver.js
|
|
10488
10478
|
var require_semver = __commonJS((exports, module) => {
|
|
10489
10479
|
var debug = require_debug();
|
|
10490
10480
|
var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants4();
|
|
@@ -10753,7 +10743,7 @@ var require_semver = __commonJS((exports, module) => {
|
|
|
10753
10743
|
module.exports = SemVer;
|
|
10754
10744
|
});
|
|
10755
10745
|
|
|
10756
|
-
// ../../node_modules/.bun/semver@7.
|
|
10746
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/parse.js
|
|
10757
10747
|
var require_parse3 = __commonJS((exports, module) => {
|
|
10758
10748
|
var SemVer = require_semver();
|
|
10759
10749
|
var parse = (version, options, throwErrors = false) => {
|
|
@@ -10772,7 +10762,7 @@ var require_parse3 = __commonJS((exports, module) => {
|
|
|
10772
10762
|
module.exports = parse;
|
|
10773
10763
|
});
|
|
10774
10764
|
|
|
10775
|
-
// ../../node_modules/.bun/semver@7.
|
|
10765
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/valid.js
|
|
10776
10766
|
var require_valid = __commonJS((exports, module) => {
|
|
10777
10767
|
var parse = require_parse3();
|
|
10778
10768
|
var valid = (version, options) => {
|
|
@@ -10782,7 +10772,7 @@ var require_valid = __commonJS((exports, module) => {
|
|
|
10782
10772
|
module.exports = valid;
|
|
10783
10773
|
});
|
|
10784
10774
|
|
|
10785
|
-
// ../../node_modules/.bun/semver@7.
|
|
10775
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/clean.js
|
|
10786
10776
|
var require_clean = __commonJS((exports, module) => {
|
|
10787
10777
|
var parse = require_parse3();
|
|
10788
10778
|
var clean = (version, options) => {
|
|
@@ -10792,7 +10782,7 @@ var require_clean = __commonJS((exports, module) => {
|
|
|
10792
10782
|
module.exports = clean;
|
|
10793
10783
|
});
|
|
10794
10784
|
|
|
10795
|
-
// ../../node_modules/.bun/semver@7.
|
|
10785
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/inc.js
|
|
10796
10786
|
var require_inc = __commonJS((exports, module) => {
|
|
10797
10787
|
var SemVer = require_semver();
|
|
10798
10788
|
var inc = (version, release, options, identifier, identifierBase) => {
|
|
@@ -10810,7 +10800,7 @@ var require_inc = __commonJS((exports, module) => {
|
|
|
10810
10800
|
module.exports = inc;
|
|
10811
10801
|
});
|
|
10812
10802
|
|
|
10813
|
-
// ../../node_modules/.bun/semver@7.
|
|
10803
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/diff.js
|
|
10814
10804
|
var require_diff = __commonJS((exports, module) => {
|
|
10815
10805
|
var parse = require_parse3();
|
|
10816
10806
|
var diff = (version1, version2) => {
|
|
@@ -10851,28 +10841,28 @@ var require_diff = __commonJS((exports, module) => {
|
|
|
10851
10841
|
module.exports = diff;
|
|
10852
10842
|
});
|
|
10853
10843
|
|
|
10854
|
-
// ../../node_modules/.bun/semver@7.
|
|
10844
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/major.js
|
|
10855
10845
|
var require_major = __commonJS((exports, module) => {
|
|
10856
10846
|
var SemVer = require_semver();
|
|
10857
10847
|
var major = (a2, loose) => new SemVer(a2, loose).major;
|
|
10858
10848
|
module.exports = major;
|
|
10859
10849
|
});
|
|
10860
10850
|
|
|
10861
|
-
// ../../node_modules/.bun/semver@7.
|
|
10851
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/minor.js
|
|
10862
10852
|
var require_minor = __commonJS((exports, module) => {
|
|
10863
10853
|
var SemVer = require_semver();
|
|
10864
10854
|
var minor = (a2, loose) => new SemVer(a2, loose).minor;
|
|
10865
10855
|
module.exports = minor;
|
|
10866
10856
|
});
|
|
10867
10857
|
|
|
10868
|
-
// ../../node_modules/.bun/semver@7.
|
|
10858
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/patch.js
|
|
10869
10859
|
var require_patch = __commonJS((exports, module) => {
|
|
10870
10860
|
var SemVer = require_semver();
|
|
10871
10861
|
var patch = (a2, loose) => new SemVer(a2, loose).patch;
|
|
10872
10862
|
module.exports = patch;
|
|
10873
10863
|
});
|
|
10874
10864
|
|
|
10875
|
-
// ../../node_modules/.bun/semver@7.
|
|
10865
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/prerelease.js
|
|
10876
10866
|
var require_prerelease = __commonJS((exports, module) => {
|
|
10877
10867
|
var parse = require_parse3();
|
|
10878
10868
|
var prerelease = (version, options) => {
|
|
@@ -10882,28 +10872,28 @@ var require_prerelease = __commonJS((exports, module) => {
|
|
|
10882
10872
|
module.exports = prerelease;
|
|
10883
10873
|
});
|
|
10884
10874
|
|
|
10885
|
-
// ../../node_modules/.bun/semver@7.
|
|
10875
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/compare.js
|
|
10886
10876
|
var require_compare = __commonJS((exports, module) => {
|
|
10887
10877
|
var SemVer = require_semver();
|
|
10888
10878
|
var compare = (a2, b2, loose) => new SemVer(a2, loose).compare(new SemVer(b2, loose));
|
|
10889
10879
|
module.exports = compare;
|
|
10890
10880
|
});
|
|
10891
10881
|
|
|
10892
|
-
// ../../node_modules/.bun/semver@7.
|
|
10882
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/rcompare.js
|
|
10893
10883
|
var require_rcompare = __commonJS((exports, module) => {
|
|
10894
10884
|
var compare = require_compare();
|
|
10895
10885
|
var rcompare = (a2, b2, loose) => compare(b2, a2, loose);
|
|
10896
10886
|
module.exports = rcompare;
|
|
10897
10887
|
});
|
|
10898
10888
|
|
|
10899
|
-
// ../../node_modules/.bun/semver@7.
|
|
10889
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/compare-loose.js
|
|
10900
10890
|
var require_compare_loose = __commonJS((exports, module) => {
|
|
10901
10891
|
var compare = require_compare();
|
|
10902
10892
|
var compareLoose = (a2, b2) => compare(a2, b2, true);
|
|
10903
10893
|
module.exports = compareLoose;
|
|
10904
10894
|
});
|
|
10905
10895
|
|
|
10906
|
-
// ../../node_modules/.bun/semver@7.
|
|
10896
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/compare-build.js
|
|
10907
10897
|
var require_compare_build = __commonJS((exports, module) => {
|
|
10908
10898
|
var SemVer = require_semver();
|
|
10909
10899
|
var compareBuild = (a2, b2, loose) => {
|
|
@@ -10914,63 +10904,63 @@ var require_compare_build = __commonJS((exports, module) => {
|
|
|
10914
10904
|
module.exports = compareBuild;
|
|
10915
10905
|
});
|
|
10916
10906
|
|
|
10917
|
-
// ../../node_modules/.bun/semver@7.
|
|
10907
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/sort.js
|
|
10918
10908
|
var require_sort = __commonJS((exports, module) => {
|
|
10919
10909
|
var compareBuild = require_compare_build();
|
|
10920
10910
|
var sort = (list, loose) => list.sort((a2, b2) => compareBuild(a2, b2, loose));
|
|
10921
10911
|
module.exports = sort;
|
|
10922
10912
|
});
|
|
10923
10913
|
|
|
10924
|
-
// ../../node_modules/.bun/semver@7.
|
|
10914
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/rsort.js
|
|
10925
10915
|
var require_rsort = __commonJS((exports, module) => {
|
|
10926
10916
|
var compareBuild = require_compare_build();
|
|
10927
10917
|
var rsort = (list, loose) => list.sort((a2, b2) => compareBuild(b2, a2, loose));
|
|
10928
10918
|
module.exports = rsort;
|
|
10929
10919
|
});
|
|
10930
10920
|
|
|
10931
|
-
// ../../node_modules/.bun/semver@7.
|
|
10921
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/gt.js
|
|
10932
10922
|
var require_gt = __commonJS((exports, module) => {
|
|
10933
10923
|
var compare = require_compare();
|
|
10934
10924
|
var gt = (a2, b2, loose) => compare(a2, b2, loose) > 0;
|
|
10935
10925
|
module.exports = gt;
|
|
10936
10926
|
});
|
|
10937
10927
|
|
|
10938
|
-
// ../../node_modules/.bun/semver@7.
|
|
10928
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/lt.js
|
|
10939
10929
|
var require_lt = __commonJS((exports, module) => {
|
|
10940
10930
|
var compare = require_compare();
|
|
10941
10931
|
var lt = (a2, b2, loose) => compare(a2, b2, loose) < 0;
|
|
10942
10932
|
module.exports = lt;
|
|
10943
10933
|
});
|
|
10944
10934
|
|
|
10945
|
-
// ../../node_modules/.bun/semver@7.
|
|
10935
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/eq.js
|
|
10946
10936
|
var require_eq = __commonJS((exports, module) => {
|
|
10947
10937
|
var compare = require_compare();
|
|
10948
10938
|
var eq = (a2, b2, loose) => compare(a2, b2, loose) === 0;
|
|
10949
10939
|
module.exports = eq;
|
|
10950
10940
|
});
|
|
10951
10941
|
|
|
10952
|
-
// ../../node_modules/.bun/semver@7.
|
|
10942
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/neq.js
|
|
10953
10943
|
var require_neq = __commonJS((exports, module) => {
|
|
10954
10944
|
var compare = require_compare();
|
|
10955
10945
|
var neq = (a2, b2, loose) => compare(a2, b2, loose) !== 0;
|
|
10956
10946
|
module.exports = neq;
|
|
10957
10947
|
});
|
|
10958
10948
|
|
|
10959
|
-
// ../../node_modules/.bun/semver@7.
|
|
10949
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/gte.js
|
|
10960
10950
|
var require_gte = __commonJS((exports, module) => {
|
|
10961
10951
|
var compare = require_compare();
|
|
10962
10952
|
var gte = (a2, b2, loose) => compare(a2, b2, loose) >= 0;
|
|
10963
10953
|
module.exports = gte;
|
|
10964
10954
|
});
|
|
10965
10955
|
|
|
10966
|
-
// ../../node_modules/.bun/semver@7.
|
|
10956
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/lte.js
|
|
10967
10957
|
var require_lte = __commonJS((exports, module) => {
|
|
10968
10958
|
var compare = require_compare();
|
|
10969
10959
|
var lte = (a2, b2, loose) => compare(a2, b2, loose) <= 0;
|
|
10970
10960
|
module.exports = lte;
|
|
10971
10961
|
});
|
|
10972
10962
|
|
|
10973
|
-
// ../../node_modules/.bun/semver@7.
|
|
10963
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/cmp.js
|
|
10974
10964
|
var require_cmp = __commonJS((exports, module) => {
|
|
10975
10965
|
var eq = require_eq();
|
|
10976
10966
|
var neq = require_neq();
|
|
@@ -11017,7 +11007,7 @@ var require_cmp = __commonJS((exports, module) => {
|
|
|
11017
11007
|
module.exports = cmp;
|
|
11018
11008
|
});
|
|
11019
11009
|
|
|
11020
|
-
// ../../node_modules/.bun/semver@7.
|
|
11010
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/coerce.js
|
|
11021
11011
|
var require_coerce = __commonJS((exports, module) => {
|
|
11022
11012
|
var SemVer = require_semver();
|
|
11023
11013
|
var parse = require_parse3();
|
|
@@ -11060,7 +11050,45 @@ var require_coerce = __commonJS((exports, module) => {
|
|
|
11060
11050
|
module.exports = coerce;
|
|
11061
11051
|
});
|
|
11062
11052
|
|
|
11063
|
-
// ../../node_modules/.bun/semver@7.
|
|
11053
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/truncate.js
|
|
11054
|
+
var require_truncate = __commonJS((exports, module) => {
|
|
11055
|
+
var parse = require_parse3();
|
|
11056
|
+
var constants = require_constants4();
|
|
11057
|
+
var SemVer = require_semver();
|
|
11058
|
+
var truncate = (version, truncation, options) => {
|
|
11059
|
+
if (!constants.RELEASE_TYPES.includes(truncation)) {
|
|
11060
|
+
return null;
|
|
11061
|
+
}
|
|
11062
|
+
const clonedVersion = cloneInputVersion(version, options);
|
|
11063
|
+
return clonedVersion && doTruncation(clonedVersion, truncation);
|
|
11064
|
+
};
|
|
11065
|
+
var cloneInputVersion = (version, options) => {
|
|
11066
|
+
const versionStringToParse = version instanceof SemVer ? version.version : version;
|
|
11067
|
+
return parse(versionStringToParse, options);
|
|
11068
|
+
};
|
|
11069
|
+
var doTruncation = (version, truncation) => {
|
|
11070
|
+
if (isPrerelease(truncation)) {
|
|
11071
|
+
return version.version;
|
|
11072
|
+
}
|
|
11073
|
+
version.prerelease = [];
|
|
11074
|
+
switch (truncation) {
|
|
11075
|
+
case "major":
|
|
11076
|
+
version.minor = 0;
|
|
11077
|
+
version.patch = 0;
|
|
11078
|
+
break;
|
|
11079
|
+
case "minor":
|
|
11080
|
+
version.patch = 0;
|
|
11081
|
+
break;
|
|
11082
|
+
}
|
|
11083
|
+
return version.format();
|
|
11084
|
+
};
|
|
11085
|
+
var isPrerelease = (type) => {
|
|
11086
|
+
return type.startsWith("pre");
|
|
11087
|
+
};
|
|
11088
|
+
module.exports = truncate;
|
|
11089
|
+
});
|
|
11090
|
+
|
|
11091
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/internal/lrucache.js
|
|
11064
11092
|
var require_lrucache = __commonJS((exports, module) => {
|
|
11065
11093
|
class LRUCache2 {
|
|
11066
11094
|
constructor() {
|
|
@@ -11095,7 +11123,7 @@ var require_lrucache = __commonJS((exports, module) => {
|
|
|
11095
11123
|
module.exports = LRUCache2;
|
|
11096
11124
|
});
|
|
11097
11125
|
|
|
11098
|
-
// ../../node_modules/.bun/semver@7.
|
|
11126
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/classes/range.js
|
|
11099
11127
|
var require_range = __commonJS((exports, module) => {
|
|
11100
11128
|
var SPACE_CHARACTERS = /\s+/g;
|
|
11101
11129
|
|
|
@@ -11469,7 +11497,7 @@ var require_range = __commonJS((exports, module) => {
|
|
|
11469
11497
|
};
|
|
11470
11498
|
});
|
|
11471
11499
|
|
|
11472
|
-
// ../../node_modules/.bun/semver@7.
|
|
11500
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/classes/comparator.js
|
|
11473
11501
|
var require_comparator = __commonJS((exports, module) => {
|
|
11474
11502
|
var ANY = Symbol("SemVer ANY");
|
|
11475
11503
|
|
|
@@ -11580,7 +11608,7 @@ var require_comparator = __commonJS((exports, module) => {
|
|
|
11580
11608
|
var Range = require_range();
|
|
11581
11609
|
});
|
|
11582
11610
|
|
|
11583
|
-
// ../../node_modules/.bun/semver@7.
|
|
11611
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/functions/satisfies.js
|
|
11584
11612
|
var require_satisfies = __commonJS((exports, module) => {
|
|
11585
11613
|
var Range = require_range();
|
|
11586
11614
|
var satisfies = (version, range, options) => {
|
|
@@ -11594,14 +11622,14 @@ var require_satisfies = __commonJS((exports, module) => {
|
|
|
11594
11622
|
module.exports = satisfies;
|
|
11595
11623
|
});
|
|
11596
11624
|
|
|
11597
|
-
// ../../node_modules/.bun/semver@7.
|
|
11625
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/to-comparators.js
|
|
11598
11626
|
var require_to_comparators = __commonJS((exports, module) => {
|
|
11599
11627
|
var Range = require_range();
|
|
11600
11628
|
var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c2) => c2.value).join(" ").trim().split(" "));
|
|
11601
11629
|
module.exports = toComparators;
|
|
11602
11630
|
});
|
|
11603
11631
|
|
|
11604
|
-
// ../../node_modules/.bun/semver@7.
|
|
11632
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/max-satisfying.js
|
|
11605
11633
|
var require_max_satisfying = __commonJS((exports, module) => {
|
|
11606
11634
|
var SemVer = require_semver();
|
|
11607
11635
|
var Range = require_range();
|
|
@@ -11627,7 +11655,7 @@ var require_max_satisfying = __commonJS((exports, module) => {
|
|
|
11627
11655
|
module.exports = maxSatisfying;
|
|
11628
11656
|
});
|
|
11629
11657
|
|
|
11630
|
-
// ../../node_modules/.bun/semver@7.
|
|
11658
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/min-satisfying.js
|
|
11631
11659
|
var require_min_satisfying = __commonJS((exports, module) => {
|
|
11632
11660
|
var SemVer = require_semver();
|
|
11633
11661
|
var Range = require_range();
|
|
@@ -11653,7 +11681,7 @@ var require_min_satisfying = __commonJS((exports, module) => {
|
|
|
11653
11681
|
module.exports = minSatisfying;
|
|
11654
11682
|
});
|
|
11655
11683
|
|
|
11656
|
-
// ../../node_modules/.bun/semver@7.
|
|
11684
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/min-version.js
|
|
11657
11685
|
var require_min_version = __commonJS((exports, module) => {
|
|
11658
11686
|
var SemVer = require_semver();
|
|
11659
11687
|
var Range = require_range();
|
|
@@ -11707,7 +11735,7 @@ var require_min_version = __commonJS((exports, module) => {
|
|
|
11707
11735
|
module.exports = minVersion;
|
|
11708
11736
|
});
|
|
11709
11737
|
|
|
11710
|
-
// ../../node_modules/.bun/semver@7.
|
|
11738
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/valid.js
|
|
11711
11739
|
var require_valid2 = __commonJS((exports, module) => {
|
|
11712
11740
|
var Range = require_range();
|
|
11713
11741
|
var validRange = (range, options) => {
|
|
@@ -11720,7 +11748,7 @@ var require_valid2 = __commonJS((exports, module) => {
|
|
|
11720
11748
|
module.exports = validRange;
|
|
11721
11749
|
});
|
|
11722
11750
|
|
|
11723
|
-
// ../../node_modules/.bun/semver@7.
|
|
11751
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/outside.js
|
|
11724
11752
|
var require_outside = __commonJS((exports, module) => {
|
|
11725
11753
|
var SemVer = require_semver();
|
|
11726
11754
|
var Comparator = require_comparator();
|
|
@@ -11786,21 +11814,21 @@ var require_outside = __commonJS((exports, module) => {
|
|
|
11786
11814
|
module.exports = outside;
|
|
11787
11815
|
});
|
|
11788
11816
|
|
|
11789
|
-
// ../../node_modules/.bun/semver@7.
|
|
11817
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/gtr.js
|
|
11790
11818
|
var require_gtr = __commonJS((exports, module) => {
|
|
11791
11819
|
var outside = require_outside();
|
|
11792
11820
|
var gtr = (version, range, options) => outside(version, range, ">", options);
|
|
11793
11821
|
module.exports = gtr;
|
|
11794
11822
|
});
|
|
11795
11823
|
|
|
11796
|
-
// ../../node_modules/.bun/semver@7.
|
|
11824
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/ltr.js
|
|
11797
11825
|
var require_ltr = __commonJS((exports, module) => {
|
|
11798
11826
|
var outside = require_outside();
|
|
11799
11827
|
var ltr = (version, range, options) => outside(version, range, "<", options);
|
|
11800
11828
|
module.exports = ltr;
|
|
11801
11829
|
});
|
|
11802
11830
|
|
|
11803
|
-
// ../../node_modules/.bun/semver@7.
|
|
11831
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/intersects.js
|
|
11804
11832
|
var require_intersects = __commonJS((exports, module) => {
|
|
11805
11833
|
var Range = require_range();
|
|
11806
11834
|
var intersects = (r1, r2, options) => {
|
|
@@ -11811,7 +11839,7 @@ var require_intersects = __commonJS((exports, module) => {
|
|
|
11811
11839
|
module.exports = intersects;
|
|
11812
11840
|
});
|
|
11813
11841
|
|
|
11814
|
-
// ../../node_modules/.bun/semver@7.
|
|
11842
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/simplify.js
|
|
11815
11843
|
var require_simplify = __commonJS((exports, module) => {
|
|
11816
11844
|
var satisfies = require_satisfies();
|
|
11817
11845
|
var compare = require_compare();
|
|
@@ -11858,7 +11886,7 @@ var require_simplify = __commonJS((exports, module) => {
|
|
|
11858
11886
|
};
|
|
11859
11887
|
});
|
|
11860
11888
|
|
|
11861
|
-
// ../../node_modules/.bun/semver@7.
|
|
11889
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/ranges/subset.js
|
|
11862
11890
|
var require_subset = __commonJS((exports, module) => {
|
|
11863
11891
|
var Range = require_range();
|
|
11864
11892
|
var Comparator = require_comparator();
|
|
@@ -12018,7 +12046,7 @@ var require_subset = __commonJS((exports, module) => {
|
|
|
12018
12046
|
module.exports = subset;
|
|
12019
12047
|
});
|
|
12020
12048
|
|
|
12021
|
-
// ../../node_modules/.bun/semver@7.
|
|
12049
|
+
// ../../node_modules/.bun/semver@7.8.0/node_modules/semver/index.js
|
|
12022
12050
|
var require_semver2 = __commonJS((exports, module) => {
|
|
12023
12051
|
var internalRe = require_re();
|
|
12024
12052
|
var constants = require_constants4();
|
|
@@ -12047,6 +12075,7 @@ var require_semver2 = __commonJS((exports, module) => {
|
|
|
12047
12075
|
var lte = require_lte();
|
|
12048
12076
|
var cmp = require_cmp();
|
|
12049
12077
|
var coerce = require_coerce();
|
|
12078
|
+
var truncate = require_truncate();
|
|
12050
12079
|
var Comparator = require_comparator();
|
|
12051
12080
|
var Range = require_range();
|
|
12052
12081
|
var satisfies = require_satisfies();
|
|
@@ -12085,6 +12114,7 @@ var require_semver2 = __commonJS((exports, module) => {
|
|
|
12085
12114
|
lte,
|
|
12086
12115
|
cmp,
|
|
12087
12116
|
coerce,
|
|
12117
|
+
truncate,
|
|
12088
12118
|
Comparator,
|
|
12089
12119
|
Range,
|
|
12090
12120
|
satisfies,
|
|
@@ -25734,6 +25764,394 @@ var init_dist2 = __esm(() => {
|
|
|
25734
25764
|
};
|
|
25735
25765
|
});
|
|
25736
25766
|
|
|
25767
|
+
// ../observability/dist/init-server.js
|
|
25768
|
+
var exports_init_server = {};
|
|
25769
|
+
__export(exports_init_server, {
|
|
25770
|
+
wrapDbAdapter: () => wrapDbAdapter,
|
|
25771
|
+
initServerTelemetry: () => initServerTelemetry
|
|
25772
|
+
});
|
|
25773
|
+
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
25774
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
25775
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
25776
|
+
import { Resource } from "@opentelemetry/resources";
|
|
25777
|
+
import {
|
|
25778
|
+
BatchLogRecordProcessor,
|
|
25779
|
+
LoggerProvider
|
|
25780
|
+
} from "@opentelemetry/sdk-logs";
|
|
25781
|
+
import {
|
|
25782
|
+
MeterProvider,
|
|
25783
|
+
PeriodicExportingMetricReader
|
|
25784
|
+
} from "@opentelemetry/sdk-metrics";
|
|
25785
|
+
import {
|
|
25786
|
+
BatchSpanProcessor,
|
|
25787
|
+
ParentBasedSampler,
|
|
25788
|
+
TraceIdRatioBasedSampler
|
|
25789
|
+
} from "@opentelemetry/sdk-trace-base";
|
|
25790
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
25791
|
+
import {
|
|
25792
|
+
ATTR_DEPLOYMENT_ENVIRONMENT_NAME,
|
|
25793
|
+
ATTR_SERVICE_NAME,
|
|
25794
|
+
ATTR_SERVICE_VERSION
|
|
25795
|
+
} from "@opentelemetry/semantic-conventions/incubating";
|
|
25796
|
+
import {
|
|
25797
|
+
context,
|
|
25798
|
+
propagation,
|
|
25799
|
+
SpanStatusCode,
|
|
25800
|
+
trace
|
|
25801
|
+
} from "@opentelemetry/api";
|
|
25802
|
+
import {
|
|
25803
|
+
logs,
|
|
25804
|
+
SeverityNumber
|
|
25805
|
+
} from "@opentelemetry/api-logs";
|
|
25806
|
+
function sanitizeAttrs(input, opts = {}) {
|
|
25807
|
+
if (!input)
|
|
25808
|
+
return {};
|
|
25809
|
+
const redactPattern = opts.redactKeyPattern ?? DEFAULT_REDACT_KEY_PATTERN;
|
|
25810
|
+
const maxStr = opts.maxStringLen ?? DEFAULT_MAX_STRING_LEN;
|
|
25811
|
+
const maxJson = opts.maxJsonLen ?? DEFAULT_MAX_JSON_LEN;
|
|
25812
|
+
const out = {};
|
|
25813
|
+
for (const [key, raw] of Object.entries(input)) {
|
|
25814
|
+
if (redactPattern.test(key))
|
|
25815
|
+
continue;
|
|
25816
|
+
const value = sanitizeValue(raw, redactPattern, maxStr, maxJson);
|
|
25817
|
+
if (value !== undefined)
|
|
25818
|
+
out[key] = value;
|
|
25819
|
+
}
|
|
25820
|
+
return out;
|
|
25821
|
+
}
|
|
25822
|
+
function sanitizeValue(raw, redactPattern, maxStr, maxJson) {
|
|
25823
|
+
if (raw === null || raw === undefined)
|
|
25824
|
+
return;
|
|
25825
|
+
if (typeof raw === "boolean" || typeof raw === "number")
|
|
25826
|
+
return raw;
|
|
25827
|
+
if (typeof raw === "string") {
|
|
25828
|
+
return raw.length > maxStr ? `${raw.slice(0, maxStr)}\u2026(truncated:${raw.length})` : raw;
|
|
25829
|
+
}
|
|
25830
|
+
try {
|
|
25831
|
+
const filtered = filterRedacted(raw, redactPattern);
|
|
25832
|
+
const json = JSON.stringify(filtered);
|
|
25833
|
+
if (json === undefined)
|
|
25834
|
+
return;
|
|
25835
|
+
return json.length > maxJson ? `${json.slice(0, maxJson)}\u2026(truncated:${json.length})` : json;
|
|
25836
|
+
} catch {
|
|
25837
|
+
return "[unserializable]";
|
|
25838
|
+
}
|
|
25839
|
+
}
|
|
25840
|
+
function filterRedacted(node, pattern, seen = new WeakSet) {
|
|
25841
|
+
if (node === null || typeof node !== "object")
|
|
25842
|
+
return node;
|
|
25843
|
+
if (seen.has(node))
|
|
25844
|
+
return "[circular]";
|
|
25845
|
+
seen.add(node);
|
|
25846
|
+
if (Array.isArray(node)) {
|
|
25847
|
+
return node.map((v3) => filterRedacted(v3, pattern, seen));
|
|
25848
|
+
}
|
|
25849
|
+
const out = {};
|
|
25850
|
+
for (const [k4, v3] of Object.entries(node)) {
|
|
25851
|
+
if (pattern.test(k4))
|
|
25852
|
+
continue;
|
|
25853
|
+
out[k4] = filterRedacted(v3, pattern, seen);
|
|
25854
|
+
}
|
|
25855
|
+
return out;
|
|
25856
|
+
}
|
|
25857
|
+
|
|
25858
|
+
class ArcTelemetry {
|
|
25859
|
+
config;
|
|
25860
|
+
tracer = null;
|
|
25861
|
+
logger = null;
|
|
25862
|
+
meter = null;
|
|
25863
|
+
histograms = new Map;
|
|
25864
|
+
counters = new Map;
|
|
25865
|
+
constructor(config) {
|
|
25866
|
+
const mode = config.mode ?? "development";
|
|
25867
|
+
const enabled = config.enabled ?? mode !== "disabled";
|
|
25868
|
+
const sampleRate = config.sampleRate ?? (config.environment === "server" ? 1 : 0.1);
|
|
25869
|
+
this.config = {
|
|
25870
|
+
...config,
|
|
25871
|
+
enabled,
|
|
25872
|
+
sampleRate,
|
|
25873
|
+
mode,
|
|
25874
|
+
debug: config.debug ?? false
|
|
25875
|
+
};
|
|
25876
|
+
}
|
|
25877
|
+
attach(opts) {
|
|
25878
|
+
this.tracer = opts.tracer;
|
|
25879
|
+
this.logger = opts.logger ?? null;
|
|
25880
|
+
this.meter = opts.meter ?? null;
|
|
25881
|
+
}
|
|
25882
|
+
get active() {
|
|
25883
|
+
return this.config.enabled && this.tracer !== null;
|
|
25884
|
+
}
|
|
25885
|
+
shouldIncludePayloads() {
|
|
25886
|
+
if (this.config.includePayloads !== undefined)
|
|
25887
|
+
return this.config.includePayloads;
|
|
25888
|
+
return this.config.mode === "development";
|
|
25889
|
+
}
|
|
25890
|
+
async startSpan(name, fn, options = {}) {
|
|
25891
|
+
if (!this.active || !this.tracer) {
|
|
25892
|
+
return fn(trace.getActiveSpan() ?? noopSpan());
|
|
25893
|
+
}
|
|
25894
|
+
const attributes = this.toAttributes(options.attributes, options.unsafeAttrs);
|
|
25895
|
+
return this.tracer.startActiveSpan(name, { kind: options.kind, attributes }, async (span) => {
|
|
25896
|
+
try {
|
|
25897
|
+
const result = await fn(span);
|
|
25898
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
25899
|
+
return result;
|
|
25900
|
+
} catch (error) {
|
|
25901
|
+
this.recordError(span, error);
|
|
25902
|
+
throw error;
|
|
25903
|
+
} finally {
|
|
25904
|
+
span.end();
|
|
25905
|
+
}
|
|
25906
|
+
});
|
|
25907
|
+
}
|
|
25908
|
+
createSpan(name, options = {}) {
|
|
25909
|
+
if (!this.active || !this.tracer)
|
|
25910
|
+
return noopSpan();
|
|
25911
|
+
const attributes = this.toAttributes(options.attributes, options.unsafeAttrs);
|
|
25912
|
+
return this.tracer.startSpan(name, { kind: options.kind, attributes });
|
|
25913
|
+
}
|
|
25914
|
+
getCurrentSpan() {
|
|
25915
|
+
return trace.getActiveSpan();
|
|
25916
|
+
}
|
|
25917
|
+
withSpan(parent, fn) {
|
|
25918
|
+
return context.with(trace.setSpan(context.active(), parent), fn);
|
|
25919
|
+
}
|
|
25920
|
+
runWithExtractedContext(carrier, fn) {
|
|
25921
|
+
if (!this.active)
|
|
25922
|
+
return fn();
|
|
25923
|
+
const flat = {};
|
|
25924
|
+
if (typeof Headers !== "undefined" && carrier instanceof Headers) {
|
|
25925
|
+
carrier.forEach((value, key) => {
|
|
25926
|
+
flat[key.toLowerCase()] = value;
|
|
25927
|
+
});
|
|
25928
|
+
} else if (carrier) {
|
|
25929
|
+
for (const [k4, v3] of Object.entries(carrier)) {
|
|
25930
|
+
if (typeof v3 === "string")
|
|
25931
|
+
flat[k4.toLowerCase()] = v3;
|
|
25932
|
+
}
|
|
25933
|
+
}
|
|
25934
|
+
const parent = propagation.extract(context.active(), flat);
|
|
25935
|
+
return context.with(parent, fn);
|
|
25936
|
+
}
|
|
25937
|
+
recordError(span, error) {
|
|
25938
|
+
const err3 = error instanceof Error ? error : new Error(String(error ?? "unknown error"));
|
|
25939
|
+
try {
|
|
25940
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: err3.message });
|
|
25941
|
+
span.recordException(err3);
|
|
25942
|
+
} catch {}
|
|
25943
|
+
}
|
|
25944
|
+
addAttributes(attrs, unsafeAttrs = false) {
|
|
25945
|
+
const span = this.getCurrentSpan();
|
|
25946
|
+
if (!span)
|
|
25947
|
+
return;
|
|
25948
|
+
span.setAttributes(this.toAttributes(attrs, unsafeAttrs));
|
|
25949
|
+
}
|
|
25950
|
+
log(level, body, attrs = {}, unsafeAttrs = false) {
|
|
25951
|
+
if (!this.active)
|
|
25952
|
+
return;
|
|
25953
|
+
const logger = this.logger ?? logs.getLogger(this.config.serviceName);
|
|
25954
|
+
const record = {
|
|
25955
|
+
severityNumber: severityFor(level),
|
|
25956
|
+
severityText: level.toUpperCase(),
|
|
25957
|
+
body,
|
|
25958
|
+
attributes: this.toAttributes(attrs, unsafeAttrs)
|
|
25959
|
+
};
|
|
25960
|
+
try {
|
|
25961
|
+
logger.emit(record);
|
|
25962
|
+
} catch {}
|
|
25963
|
+
}
|
|
25964
|
+
incrementCounter(name, value = 1, attrs = {}) {
|
|
25965
|
+
if (!this.active || !this.meter)
|
|
25966
|
+
return;
|
|
25967
|
+
let counter = this.counters.get(name);
|
|
25968
|
+
if (!counter) {
|
|
25969
|
+
counter = this.meter.createCounter(name);
|
|
25970
|
+
this.counters.set(name, counter);
|
|
25971
|
+
}
|
|
25972
|
+
try {
|
|
25973
|
+
counter.add(value, attrs);
|
|
25974
|
+
} catch {}
|
|
25975
|
+
}
|
|
25976
|
+
recordHistogram(name, value, attrs = {}) {
|
|
25977
|
+
if (!this.active || !this.meter)
|
|
25978
|
+
return;
|
|
25979
|
+
let histogram = this.histograms.get(name);
|
|
25980
|
+
if (!histogram) {
|
|
25981
|
+
histogram = this.meter.createHistogram(name, { unit: "ms" });
|
|
25982
|
+
this.histograms.set(name, histogram);
|
|
25983
|
+
}
|
|
25984
|
+
try {
|
|
25985
|
+
histogram.record(value, attrs);
|
|
25986
|
+
} catch {}
|
|
25987
|
+
}
|
|
25988
|
+
measureSince(name, start, attrs = {}) {
|
|
25989
|
+
this.recordHistogram(name, Date.now() - start, attrs);
|
|
25990
|
+
}
|
|
25991
|
+
toAttributes(raw, unsafe) {
|
|
25992
|
+
if (!raw)
|
|
25993
|
+
return {};
|
|
25994
|
+
if (unsafe)
|
|
25995
|
+
return raw;
|
|
25996
|
+
return sanitizeAttrs(raw, this.config.sanitize);
|
|
25997
|
+
}
|
|
25998
|
+
}
|
|
25999
|
+
function severityFor(level) {
|
|
26000
|
+
switch (level) {
|
|
26001
|
+
case "debug":
|
|
26002
|
+
return SeverityNumber.DEBUG;
|
|
26003
|
+
case "info":
|
|
26004
|
+
return SeverityNumber.INFO;
|
|
26005
|
+
case "warn":
|
|
26006
|
+
return SeverityNumber.WARN;
|
|
26007
|
+
case "error":
|
|
26008
|
+
return SeverityNumber.ERROR;
|
|
26009
|
+
default:
|
|
26010
|
+
return SeverityNumber.INFO;
|
|
26011
|
+
}
|
|
26012
|
+
}
|
|
26013
|
+
function noopSpan() {
|
|
26014
|
+
return trace.getActiveSpan() ?? trace.wrapSpanContext({
|
|
26015
|
+
traceId: "00000000000000000000000000000000",
|
|
26016
|
+
spanId: "0000000000000000",
|
|
26017
|
+
traceFlags: 0
|
|
26018
|
+
});
|
|
26019
|
+
}
|
|
26020
|
+
function wrapDbAdapter(adapter, telemetry, dbSystem) {
|
|
26021
|
+
if (!telemetry || !telemetry.active)
|
|
26022
|
+
return adapter;
|
|
26023
|
+
const wrapRead = (tx) => ({
|
|
26024
|
+
find: async (store, options) => telemetry.startSpan(`db.find ${store}`, async (span) => {
|
|
26025
|
+
const start = Date.now();
|
|
26026
|
+
try {
|
|
26027
|
+
const rows = await tx.find(store, options);
|
|
26028
|
+
span.setAttribute("db.response.row_count", rows.length);
|
|
26029
|
+
return rows;
|
|
26030
|
+
} finally {
|
|
26031
|
+
telemetry.measureSince("arc.db.find_ms", start, {
|
|
26032
|
+
"db.system": dbSystem,
|
|
26033
|
+
"db.collection.name": store
|
|
26034
|
+
});
|
|
26035
|
+
}
|
|
26036
|
+
}, {
|
|
26037
|
+
kind: 3,
|
|
26038
|
+
attributes: {
|
|
26039
|
+
"db.system": dbSystem,
|
|
26040
|
+
"db.operation.name": "find",
|
|
26041
|
+
"db.collection.name": store
|
|
26042
|
+
}
|
|
26043
|
+
})
|
|
26044
|
+
});
|
|
26045
|
+
const wrapReadWrite = (tx) => ({
|
|
26046
|
+
...wrapRead(tx),
|
|
26047
|
+
set: async (store, data) => telemetry.startSpan(`db.set ${store}`, () => tx.set(store, data), {
|
|
26048
|
+
kind: 3,
|
|
26049
|
+
attributes: {
|
|
26050
|
+
"db.system": dbSystem,
|
|
26051
|
+
"db.operation.name": "set",
|
|
26052
|
+
"db.collection.name": store
|
|
26053
|
+
}
|
|
26054
|
+
}),
|
|
26055
|
+
remove: async (store, id3) => telemetry.startSpan(`db.remove ${store}`, () => tx.remove(store, id3), {
|
|
26056
|
+
kind: 3,
|
|
26057
|
+
attributes: {
|
|
26058
|
+
"db.system": dbSystem,
|
|
26059
|
+
"db.operation.name": "remove",
|
|
26060
|
+
"db.collection.name": store
|
|
26061
|
+
}
|
|
26062
|
+
}),
|
|
26063
|
+
commit: async () => telemetry.startSpan("db.commit", () => tx.commit(), {
|
|
26064
|
+
kind: 3,
|
|
26065
|
+
attributes: {
|
|
26066
|
+
"db.system": dbSystem,
|
|
26067
|
+
"db.operation.name": "commit"
|
|
26068
|
+
}
|
|
26069
|
+
})
|
|
26070
|
+
});
|
|
26071
|
+
return new Proxy(adapter, {
|
|
26072
|
+
get(target, prop) {
|
|
26073
|
+
const orig = target[prop];
|
|
26074
|
+
if (prop === "readTransaction") {
|
|
26075
|
+
return (...args) => wrapRead(orig.apply(target, args));
|
|
26076
|
+
}
|
|
26077
|
+
if (prop === "readWriteTransaction") {
|
|
26078
|
+
return (...args) => wrapReadWrite(orig.apply(target, args));
|
|
26079
|
+
}
|
|
26080
|
+
return typeof orig === "function" ? orig.bind(target) : orig;
|
|
26081
|
+
}
|
|
26082
|
+
});
|
|
26083
|
+
}
|
|
26084
|
+
function initServerTelemetry(config) {
|
|
26085
|
+
const telemetry = new ArcTelemetry({ ...config, environment: "server" });
|
|
26086
|
+
if (!telemetry.config.enabled) {
|
|
26087
|
+
return { telemetry, shutdown: async () => {} };
|
|
26088
|
+
}
|
|
26089
|
+
const endpoint = config.endpoint ?? process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://localhost:4318";
|
|
26090
|
+
const resource = new Resource({
|
|
26091
|
+
[ATTR_SERVICE_NAME]: config.serviceName,
|
|
26092
|
+
[ATTR_SERVICE_VERSION]: process.env.ARC_VERSION ?? "unknown",
|
|
26093
|
+
[ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: "development"
|
|
26094
|
+
});
|
|
26095
|
+
const tracerProvider = new NodeTracerProvider({
|
|
26096
|
+
resource,
|
|
26097
|
+
sampler: new ParentBasedSampler({
|
|
26098
|
+
root: new TraceIdRatioBasedSampler(telemetry.config.sampleRate)
|
|
26099
|
+
}),
|
|
26100
|
+
spanProcessors: [
|
|
26101
|
+
new BatchSpanProcessor(new OTLPTraceExporter({ url: `${endpoint}/v1/traces` }), {
|
|
26102
|
+
maxQueueSize: 1000,
|
|
26103
|
+
maxExportBatchSize: 50,
|
|
26104
|
+
scheduledDelayMillis: 5000
|
|
26105
|
+
})
|
|
26106
|
+
]
|
|
26107
|
+
});
|
|
26108
|
+
tracerProvider.register();
|
|
26109
|
+
const loggerProvider = new LoggerProvider({ resource });
|
|
26110
|
+
loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(new OTLPLogExporter({ url: `${endpoint}/v1/logs` }), {
|
|
26111
|
+
maxQueueSize: 1000,
|
|
26112
|
+
maxExportBatchSize: 50,
|
|
26113
|
+
scheduledDelayMillis: 5000
|
|
26114
|
+
}));
|
|
26115
|
+
const meterProvider = new MeterProvider({
|
|
26116
|
+
resource,
|
|
26117
|
+
readers: [
|
|
26118
|
+
new PeriodicExportingMetricReader({
|
|
26119
|
+
exporter: new OTLPMetricExporter({ url: `${endpoint}/v1/metrics` }),
|
|
26120
|
+
exportIntervalMillis: 15000
|
|
26121
|
+
})
|
|
26122
|
+
]
|
|
26123
|
+
});
|
|
26124
|
+
telemetry.attach({
|
|
26125
|
+
tracer: tracerProvider.getTracer(config.serviceName),
|
|
26126
|
+
logger: loggerProvider.getLogger(config.serviceName),
|
|
26127
|
+
meter: meterProvider.getMeter(config.serviceName)
|
|
26128
|
+
});
|
|
26129
|
+
if (telemetry.config.debug) {
|
|
26130
|
+
console.log("[arc-otel] server init", {
|
|
26131
|
+
serviceName: config.serviceName,
|
|
26132
|
+
endpoint,
|
|
26133
|
+
sampleRate: telemetry.config.sampleRate,
|
|
26134
|
+
mode: telemetry.config.mode
|
|
26135
|
+
});
|
|
26136
|
+
}
|
|
26137
|
+
const shutdown = async () => {
|
|
26138
|
+
try {
|
|
26139
|
+
await Promise.all([
|
|
26140
|
+
tracerProvider.shutdown(),
|
|
26141
|
+
loggerProvider.shutdown(),
|
|
26142
|
+
meterProvider.shutdown()
|
|
26143
|
+
]);
|
|
26144
|
+
} catch (err3) {
|
|
26145
|
+
console.error("[arc-otel] shutdown error", err3);
|
|
26146
|
+
}
|
|
26147
|
+
};
|
|
26148
|
+
return { telemetry, shutdown };
|
|
26149
|
+
}
|
|
26150
|
+
var DEFAULT_REDACT_KEY_PATTERN, DEFAULT_MAX_STRING_LEN = 2048, DEFAULT_MAX_JSON_LEN = 4096;
|
|
26151
|
+
var init_init_server = __esm(() => {
|
|
26152
|
+
DEFAULT_REDACT_KEY_PATTERN = /(password|passwd|token|secret|authorization|jwt|api[_-]?key|cookie|email|credit[_-]?card|ssn)/i;
|
|
26153
|
+
});
|
|
26154
|
+
|
|
25737
26155
|
// ../../node_modules/.bun/commander@11.1.0/node_modules/commander/esm.mjs
|
|
25738
26156
|
var import__ = __toESM(require_commander(), 1);
|
|
25739
26157
|
var {
|
|
@@ -33964,7 +34382,7 @@ ${colors3.yellow}Type declaration errors:${colors3.reset}`);
|
|
|
33964
34382
|
|
|
33965
34383
|
// src/platform/shared.ts
|
|
33966
34384
|
import { copyFileSync, existsSync as existsSync10, mkdirSync as mkdirSync9, readdirSync as readdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
33967
|
-
import { dirname as
|
|
34385
|
+
import { dirname as dirname8, join as join11 } from "path";
|
|
33968
34386
|
|
|
33969
34387
|
// src/builder/module-builder.ts
|
|
33970
34388
|
import { execSync } from "child_process";
|
|
@@ -34794,13 +35212,27 @@ function resolveChunk(moduleName, access) {
|
|
|
34794
35212
|
// src/builder/dependency-collector.ts
|
|
34795
35213
|
import { createHash } from "crypto";
|
|
34796
35214
|
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
34797
|
-
import { basename as basename4, join as join10 } from "path";
|
|
35215
|
+
import { basename as basename4, dirname as dirname7, join as join10 } from "path";
|
|
35216
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
34798
35217
|
function collectFrameworkDeps(arcDir, rootDir, packages, sharedDeps = []) {
|
|
34799
35218
|
mkdirSync8(arcDir, { recursive: true });
|
|
34800
35219
|
const versions = resolveFrameworkVersions(rootDir, packages);
|
|
34801
35220
|
for (const { name, version } of sharedDeps) {
|
|
34802
35221
|
versions[name] = version;
|
|
34803
35222
|
}
|
|
35223
|
+
try {
|
|
35224
|
+
const cliDir = dirname7(fileURLToPath6(import.meta.url));
|
|
35225
|
+
const arcOtelPkgPath = Bun.resolveSync("@arcote.tech/arc-otel/package.json", cliDir);
|
|
35226
|
+
const arcOtelPkg = JSON.parse(readFileSync9(arcOtelPkgPath, "utf-8"));
|
|
35227
|
+
for (const [name, spec] of Object.entries(arcOtelPkg.dependencies ?? {})) {
|
|
35228
|
+
if (name.startsWith("@opentelemetry/")) {
|
|
35229
|
+
versions[name] = spec;
|
|
35230
|
+
}
|
|
35231
|
+
}
|
|
35232
|
+
versions["@arcote.tech/arc-otel"] = `^${arcOtelPkg.version}`;
|
|
35233
|
+
} catch (e) {
|
|
35234
|
+
console.warn(`[arc-otel] could not resolve @arcote.tech/arc-otel \u2014 image will run without telemetry deps: ${e.message}`);
|
|
35235
|
+
}
|
|
34804
35236
|
const manifest = {
|
|
34805
35237
|
name: "arc-platform-framework",
|
|
34806
35238
|
private: true,
|
|
@@ -34877,7 +35309,7 @@ function resolveWorkspace() {
|
|
|
34877
35309
|
err("No package.json found");
|
|
34878
35310
|
process.exit(1);
|
|
34879
35311
|
}
|
|
34880
|
-
const rootDir =
|
|
35312
|
+
const rootDir = dirname8(packageJsonPath);
|
|
34881
35313
|
const rootPkg = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
34882
35314
|
const appName = rootPkg.name ?? "Arc App";
|
|
34883
35315
|
const arcDir = join11(rootDir, ".arc", "platform");
|
|
@@ -35054,7 +35486,7 @@ async function copyBrowserAssets(ws, cache, noCache) {
|
|
|
35054
35486
|
const outputHashes = {};
|
|
35055
35487
|
for (const asset of assets) {
|
|
35056
35488
|
const dest = join11(ws.assetsDir, asset.to);
|
|
35057
|
-
mkdirSync9(
|
|
35489
|
+
mkdirSync9(dirname8(dest), { recursive: true });
|
|
35058
35490
|
copyFileSync(asset.src, dest);
|
|
35059
35491
|
outputHashes[asset.to] = sha256Hex(readFileSync10(dest));
|
|
35060
35492
|
}
|
|
@@ -35113,14 +35545,14 @@ async function platformBuild(opts = {}) {
|
|
|
35113
35545
|
|
|
35114
35546
|
// src/commands/platform-deploy.ts
|
|
35115
35547
|
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
|
|
35116
|
-
import { dirname as
|
|
35117
|
-
import { fileURLToPath as
|
|
35548
|
+
import { dirname as dirname11, join as join19 } from "path";
|
|
35549
|
+
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
35118
35550
|
|
|
35119
35551
|
// src/deploy/bootstrap.ts
|
|
35120
35552
|
var {spawn: spawn4 } = globalThis.Bun;
|
|
35121
35553
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
35122
35554
|
import { tmpdir as tmpdir2 } from "os";
|
|
35123
|
-
import { join as join17 } from "path";
|
|
35555
|
+
import { dirname as dirname9, join as join17 } from "path";
|
|
35124
35556
|
|
|
35125
35557
|
// src/deploy/ansible.ts
|
|
35126
35558
|
import { spawn as nodeSpawn } from "child_process";
|
|
@@ -35477,10 +35909,34 @@ function generateCaddyfile(cfg) {
|
|
|
35477
35909
|
lines.push("");
|
|
35478
35910
|
for (const [name, env2] of Object.entries(cfg.envs)) {
|
|
35479
35911
|
lines.push(`${env2.domain} {${tlsDirective}`);
|
|
35480
|
-
|
|
35912
|
+
if (cfg.observability?.enabled) {
|
|
35913
|
+
lines.push(" handle_path /otel/* {");
|
|
35914
|
+
lines.push(" reverse_proxy otel-collector:4318");
|
|
35915
|
+
lines.push(" }");
|
|
35916
|
+
lines.push(" handle {");
|
|
35917
|
+
lines.push(` reverse_proxy arc-${name}:5005`);
|
|
35918
|
+
lines.push(" }");
|
|
35919
|
+
} else {
|
|
35920
|
+
lines.push(` reverse_proxy arc-${name}:5005`);
|
|
35921
|
+
}
|
|
35481
35922
|
lines.push("}");
|
|
35482
35923
|
lines.push("");
|
|
35483
35924
|
}
|
|
35925
|
+
if (cfg.observability?.enabled) {
|
|
35926
|
+
const firstEnv = Object.values(cfg.envs)[0];
|
|
35927
|
+
if (firstEnv) {
|
|
35928
|
+
const subdomain = cfg.observability.subdomain ?? "observability";
|
|
35929
|
+
const apex = apexOf(firstEnv.domain);
|
|
35930
|
+
const observabilityDomain = `${subdomain}.${apex}`;
|
|
35931
|
+
lines.push(`${observabilityDomain} {${tlsDirective}`);
|
|
35932
|
+
lines.push(" basic_auth {");
|
|
35933
|
+
lines.push(" import /etc/caddy/observability-htpasswd");
|
|
35934
|
+
lines.push(" }");
|
|
35935
|
+
lines.push(" reverse_proxy grafana:3000");
|
|
35936
|
+
lines.push("}");
|
|
35937
|
+
lines.push("");
|
|
35938
|
+
}
|
|
35939
|
+
}
|
|
35484
35940
|
lines.push(`${cfg.registry.domain} {${tlsDirective}`);
|
|
35485
35941
|
lines.push(" reverse_proxy registry:5000 {");
|
|
35486
35942
|
lines.push(" header_up Host {host}");
|
|
@@ -35493,6 +35949,12 @@ function generateCaddyfile(cfg) {
|
|
|
35493
35949
|
`) + `
|
|
35494
35950
|
`;
|
|
35495
35951
|
}
|
|
35952
|
+
function apexOf(host) {
|
|
35953
|
+
const parts = host.split(".");
|
|
35954
|
+
if (parts.length <= 2)
|
|
35955
|
+
return host;
|
|
35956
|
+
return parts.slice(-2).join(".");
|
|
35957
|
+
}
|
|
35496
35958
|
|
|
35497
35959
|
// src/deploy/compose.ts
|
|
35498
35960
|
function generateCompose({ cfg }) {
|
|
@@ -35508,6 +35970,9 @@ function generateCompose({ cfg }) {
|
|
|
35508
35970
|
lines.push(' - "443:443"');
|
|
35509
35971
|
lines.push(" volumes:");
|
|
35510
35972
|
lines.push(" - ./Caddyfile:/etc/caddy/Caddyfile:ro");
|
|
35973
|
+
if (cfg.observability?.enabled) {
|
|
35974
|
+
lines.push(" - ./observability-htpasswd:/etc/caddy/observability-htpasswd:ro");
|
|
35975
|
+
}
|
|
35511
35976
|
lines.push(" - caddy_data:/data");
|
|
35512
35977
|
lines.push(" - caddy_config:/config");
|
|
35513
35978
|
lines.push(" networks:");
|
|
@@ -35554,7 +36019,20 @@ function generateCompose({ cfg }) {
|
|
|
35554
36019
|
if (usePostgres) {
|
|
35555
36020
|
lines.push(` DATABASE_URL: "postgresql://arc:\${ARC_PG_PASSWORD_${upperName}:?missing ARC_PG_PASSWORD_${upperName}}@arc-db-${name}:5432/arc"`);
|
|
35556
36021
|
}
|
|
35557
|
-
|
|
36022
|
+
if (cfg.observability?.enabled) {
|
|
36023
|
+
lines.push(' ARC_OTEL_ENABLED: "true"');
|
|
36024
|
+
lines.push(" OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4318");
|
|
36025
|
+
lines.push(` OTEL_SERVICE_NAME: arc-${name}`);
|
|
36026
|
+
lines.push(` OTEL_RESOURCE_ATTRIBUTES: "service.namespace=arc,deployment.environment=${name}"`);
|
|
36027
|
+
}
|
|
36028
|
+
const reserved = new Set([
|
|
36029
|
+
"PORT",
|
|
36030
|
+
"DATABASE_URL",
|
|
36031
|
+
"ARC_OTEL_ENABLED",
|
|
36032
|
+
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
|
36033
|
+
"OTEL_SERVICE_NAME",
|
|
36034
|
+
"OTEL_RESOURCE_ATTRIBUTES"
|
|
36035
|
+
]);
|
|
35558
36036
|
for (const [k, v] of Object.entries(userEnv)) {
|
|
35559
36037
|
if (reserved.has(k))
|
|
35560
36038
|
continue;
|
|
@@ -35590,6 +36068,93 @@ function generateCompose({ cfg }) {
|
|
|
35590
36068
|
lines.push(" - arc-net");
|
|
35591
36069
|
lines.push("");
|
|
35592
36070
|
}
|
|
36071
|
+
if (cfg.observability?.enabled) {
|
|
36072
|
+
lines.push(" otel-collector:");
|
|
36073
|
+
lines.push(" image: otel/opentelemetry-collector-contrib:0.114.0");
|
|
36074
|
+
lines.push(" container_name: arc-otel-collector");
|
|
36075
|
+
lines.push(" restart: unless-stopped");
|
|
36076
|
+
lines.push(' command: ["--config=/etc/otelcol-contrib/config.yaml"]');
|
|
36077
|
+
lines.push(" volumes:");
|
|
36078
|
+
lines.push(" - ./observability/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml:ro");
|
|
36079
|
+
lines.push(" networks: [arc-net]");
|
|
36080
|
+
lines.push(" expose:");
|
|
36081
|
+
lines.push(' - "4317" # OTLP gRPC');
|
|
36082
|
+
lines.push(' - "4318" # OTLP HTTP');
|
|
36083
|
+
lines.push(' - "8888" # collector self-metrics (Prom scrape)');
|
|
36084
|
+
lines.push(" depends_on:");
|
|
36085
|
+
lines.push(" - tempo");
|
|
36086
|
+
lines.push(" - loki");
|
|
36087
|
+
lines.push(" - prometheus");
|
|
36088
|
+
lines.push("");
|
|
36089
|
+
lines.push(" tempo:");
|
|
36090
|
+
lines.push(" image: grafana/tempo:2.6.1");
|
|
36091
|
+
lines.push(" container_name: arc-tempo");
|
|
36092
|
+
lines.push(" restart: unless-stopped");
|
|
36093
|
+
lines.push(' command: ["-config.file=/etc/tempo.yaml"]');
|
|
36094
|
+
lines.push(' user: "0" # tempo writes to /var/tempo, owned by root in the image');
|
|
36095
|
+
lines.push(" volumes:");
|
|
36096
|
+
lines.push(" - ./observability/tempo.yaml:/etc/tempo.yaml:ro");
|
|
36097
|
+
lines.push(" - tempo_data:/var/tempo");
|
|
36098
|
+
lines.push(" networks: [arc-net]");
|
|
36099
|
+
lines.push(" expose:");
|
|
36100
|
+
lines.push(' - "3200" # HTTP API for Grafana');
|
|
36101
|
+
lines.push(' - "4317" # OTLP from collector');
|
|
36102
|
+
lines.push("");
|
|
36103
|
+
lines.push(" loki:");
|
|
36104
|
+
lines.push(" image: grafana/loki:3.3.2");
|
|
36105
|
+
lines.push(" container_name: arc-loki");
|
|
36106
|
+
lines.push(" restart: unless-stopped");
|
|
36107
|
+
lines.push(' command: ["-config.file=/etc/loki/local-config.yaml"]');
|
|
36108
|
+
lines.push(' user: "0"');
|
|
36109
|
+
lines.push(" volumes:");
|
|
36110
|
+
lines.push(" - ./observability/loki-config.yaml:/etc/loki/local-config.yaml:ro");
|
|
36111
|
+
lines.push(" - loki_data:/loki");
|
|
36112
|
+
lines.push(" networks: [arc-net]");
|
|
36113
|
+
lines.push(" expose:");
|
|
36114
|
+
lines.push(' - "3100" # HTTP API');
|
|
36115
|
+
lines.push("");
|
|
36116
|
+
const metricsRetention = cfg.observability.retention?.metrics ?? "30d";
|
|
36117
|
+
lines.push(" prometheus:");
|
|
36118
|
+
lines.push(" image: prom/prometheus:v2.55.1");
|
|
36119
|
+
lines.push(" container_name: arc-prometheus");
|
|
36120
|
+
lines.push(" restart: unless-stopped");
|
|
36121
|
+
lines.push(" command:");
|
|
36122
|
+
lines.push(' - "--config.file=/etc/prometheus/prometheus.yml"');
|
|
36123
|
+
lines.push(' - "--storage.tsdb.path=/prometheus"');
|
|
36124
|
+
lines.push(` - "--storage.tsdb.retention.time=${metricsRetention}"`);
|
|
36125
|
+
lines.push(' - "--web.enable-remote-write-receiver"');
|
|
36126
|
+
lines.push(' - "--enable-feature=exemplar-storage"');
|
|
36127
|
+
lines.push(" volumes:");
|
|
36128
|
+
lines.push(" - ./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro");
|
|
36129
|
+
lines.push(" - prometheus_data:/prometheus");
|
|
36130
|
+
lines.push(" networks: [arc-net]");
|
|
36131
|
+
lines.push(" expose:");
|
|
36132
|
+
lines.push(' - "9090" # HTTP API + remote_write receiver');
|
|
36133
|
+
lines.push("");
|
|
36134
|
+
const adminPasswordEnv = cfg.observability.adminPasswordEnv ?? "ARC_OBSERVABILITY_PASSWORD";
|
|
36135
|
+
lines.push(" grafana:");
|
|
36136
|
+
lines.push(" image: grafana/grafana:11.4.0");
|
|
36137
|
+
lines.push(" container_name: arc-grafana");
|
|
36138
|
+
lines.push(" restart: unless-stopped");
|
|
36139
|
+
lines.push(" environment:");
|
|
36140
|
+
lines.push(" GF_SECURITY_ADMIN_USER: admin");
|
|
36141
|
+
lines.push(` GF_SECURITY_ADMIN_PASSWORD: \${${adminPasswordEnv}:?missing ${adminPasswordEnv}}`);
|
|
36142
|
+
lines.push(' GF_USERS_ALLOW_SIGN_UP: "false"');
|
|
36143
|
+
lines.push(' GF_AUTH_ANONYMOUS_ENABLED: "false"');
|
|
36144
|
+
lines.push(" volumes:");
|
|
36145
|
+
lines.push(" - ./observability/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml:ro");
|
|
36146
|
+
lines.push(" - ./observability/grafana-dashboards.yaml:/etc/grafana/provisioning/dashboards/dashboards.yaml:ro");
|
|
36147
|
+
lines.push(" - ./observability/grafana-dashboards:/etc/grafana/provisioning/dashboards/arc:ro");
|
|
36148
|
+
lines.push(" - grafana_data:/var/lib/grafana");
|
|
36149
|
+
lines.push(" networks: [arc-net]");
|
|
36150
|
+
lines.push(" expose:");
|
|
36151
|
+
lines.push(' - "3000" # Grafana UI (behind Caddy basic-auth)');
|
|
36152
|
+
lines.push(" depends_on:");
|
|
36153
|
+
lines.push(" - tempo");
|
|
36154
|
+
lines.push(" - loki");
|
|
36155
|
+
lines.push(" - prometheus");
|
|
36156
|
+
lines.push("");
|
|
36157
|
+
}
|
|
35593
36158
|
lines.push("networks:");
|
|
35594
36159
|
lines.push(" arc-net:");
|
|
35595
36160
|
lines.push("");
|
|
@@ -35604,6 +36169,12 @@ function generateCompose({ cfg }) {
|
|
|
35604
36169
|
lines.push(` arc-data-${name}:`);
|
|
35605
36170
|
}
|
|
35606
36171
|
}
|
|
36172
|
+
if (cfg.observability?.enabled) {
|
|
36173
|
+
lines.push(" tempo_data:");
|
|
36174
|
+
lines.push(" loki_data:");
|
|
36175
|
+
lines.push(" prometheus_data:");
|
|
36176
|
+
lines.push(" grafana_data:");
|
|
36177
|
+
}
|
|
35607
36178
|
return lines.join(`
|
|
35608
36179
|
`) + `
|
|
35609
36180
|
`;
|
|
@@ -35633,6 +36204,707 @@ async function generateHtpasswd(user, password) {
|
|
|
35633
36204
|
return `${user}:${hash}
|
|
35634
36205
|
`;
|
|
35635
36206
|
}
|
|
36207
|
+
async function generateCaddyBasicAuthLine(user, password) {
|
|
36208
|
+
if (!user || !password) {
|
|
36209
|
+
throw new Error("caddy basic_auth: user and password must both be non-empty");
|
|
36210
|
+
}
|
|
36211
|
+
const hash = await Bun.password.hash(password, {
|
|
36212
|
+
algorithm: "bcrypt",
|
|
36213
|
+
cost: 10
|
|
36214
|
+
});
|
|
36215
|
+
return `${user} ${hash}
|
|
36216
|
+
`;
|
|
36217
|
+
}
|
|
36218
|
+
|
|
36219
|
+
// src/deploy/observability-configs.ts
|
|
36220
|
+
var DEFAULT_RETENTION = {
|
|
36221
|
+
traces: "168h",
|
|
36222
|
+
logs: "168h",
|
|
36223
|
+
metrics: "30d"
|
|
36224
|
+
};
|
|
36225
|
+
function pickRetention(o) {
|
|
36226
|
+
return {
|
|
36227
|
+
traces: o?.retention?.traces ?? DEFAULT_RETENTION.traces,
|
|
36228
|
+
logs: o?.retention?.logs ?? DEFAULT_RETENTION.logs,
|
|
36229
|
+
metrics: o?.retention?.metrics ?? DEFAULT_RETENTION.metrics
|
|
36230
|
+
};
|
|
36231
|
+
}
|
|
36232
|
+
function generateOtelCollectorConfig(cfg) {
|
|
36233
|
+
const envNames = Object.keys(cfg.envs);
|
|
36234
|
+
return `# Generated by \`arc platform deploy\` \u2014 do not edit by hand.
|
|
36235
|
+
receivers:
|
|
36236
|
+
otlp:
|
|
36237
|
+
protocols:
|
|
36238
|
+
grpc:
|
|
36239
|
+
endpoint: 0.0.0.0:4317
|
|
36240
|
+
http:
|
|
36241
|
+
endpoint: 0.0.0.0:4318
|
|
36242
|
+
cors:
|
|
36243
|
+
allowed_origins:
|
|
36244
|
+
${envNames.map((name) => ` - "https://${cfg.envs[name].domain}"`).join(`
|
|
36245
|
+
`)}
|
|
36246
|
+
allowed_headers:
|
|
36247
|
+
- traceparent
|
|
36248
|
+
- tracestate
|
|
36249
|
+
- content-type
|
|
36250
|
+
|
|
36251
|
+
processors:
|
|
36252
|
+
batch:
|
|
36253
|
+
timeout: 5s
|
|
36254
|
+
send_batch_size: 512
|
|
36255
|
+
send_batch_max_size: 1024
|
|
36256
|
+
|
|
36257
|
+
# Tail-based sampling \u2014 applied after a full trace has been assembled.
|
|
36258
|
+
# Errors and slow traces are kept 100%, everything else at 10%.
|
|
36259
|
+
tail_sampling:
|
|
36260
|
+
decision_wait: 10s
|
|
36261
|
+
num_traces: 50000
|
|
36262
|
+
expected_new_traces_per_sec: 100
|
|
36263
|
+
policies:
|
|
36264
|
+
- name: errors
|
|
36265
|
+
type: status_code
|
|
36266
|
+
status_code: { status_codes: [ERROR] }
|
|
36267
|
+
- name: slow
|
|
36268
|
+
type: latency
|
|
36269
|
+
latency: { threshold_ms: 500 }
|
|
36270
|
+
- name: random_10pct
|
|
36271
|
+
type: probabilistic
|
|
36272
|
+
probabilistic: { sampling_percentage: 10 }
|
|
36273
|
+
|
|
36274
|
+
# Drop high-cardinality / PII attributes that might slip past app-side
|
|
36275
|
+
# sanitization. Belt-and-suspenders before they hit long-term storage.
|
|
36276
|
+
attributes:
|
|
36277
|
+
actions:
|
|
36278
|
+
- key: http.request.header.authorization
|
|
36279
|
+
action: delete
|
|
36280
|
+
- key: http.request.header.cookie
|
|
36281
|
+
action: delete
|
|
36282
|
+
|
|
36283
|
+
exporters:
|
|
36284
|
+
otlp/tempo:
|
|
36285
|
+
endpoint: tempo:4317
|
|
36286
|
+
tls:
|
|
36287
|
+
insecure: true
|
|
36288
|
+
|
|
36289
|
+
otlphttp/loki:
|
|
36290
|
+
endpoint: http://loki:3100/otlp
|
|
36291
|
+
tls:
|
|
36292
|
+
insecure: true
|
|
36293
|
+
|
|
36294
|
+
prometheusremotewrite:
|
|
36295
|
+
endpoint: http://prometheus:9090/api/v1/write
|
|
36296
|
+
tls:
|
|
36297
|
+
insecure: true
|
|
36298
|
+
|
|
36299
|
+
extensions:
|
|
36300
|
+
health_check: {}
|
|
36301
|
+
zpages: {}
|
|
36302
|
+
|
|
36303
|
+
service:
|
|
36304
|
+
extensions: [health_check, zpages]
|
|
36305
|
+
pipelines:
|
|
36306
|
+
traces:
|
|
36307
|
+
receivers: [otlp]
|
|
36308
|
+
processors: [tail_sampling, attributes, batch]
|
|
36309
|
+
exporters: [otlp/tempo]
|
|
36310
|
+
logs:
|
|
36311
|
+
receivers: [otlp]
|
|
36312
|
+
processors: [attributes, batch]
|
|
36313
|
+
exporters: [otlphttp/loki]
|
|
36314
|
+
metrics:
|
|
36315
|
+
receivers: [otlp]
|
|
36316
|
+
processors: [batch]
|
|
36317
|
+
exporters: [prometheusremotewrite]
|
|
36318
|
+
`;
|
|
36319
|
+
}
|
|
36320
|
+
function generateTempoConfig(cfg) {
|
|
36321
|
+
const retention = pickRetention(cfg.observability);
|
|
36322
|
+
return `# Generated by \`arc platform deploy\` \u2014 do not edit by hand.
|
|
36323
|
+
server:
|
|
36324
|
+
http_listen_port: 3200
|
|
36325
|
+
grpc_listen_port: 9095
|
|
36326
|
+
|
|
36327
|
+
distributor:
|
|
36328
|
+
receivers:
|
|
36329
|
+
otlp:
|
|
36330
|
+
protocols:
|
|
36331
|
+
grpc:
|
|
36332
|
+
endpoint: 0.0.0.0:4317
|
|
36333
|
+
http:
|
|
36334
|
+
endpoint: 0.0.0.0:4318
|
|
36335
|
+
|
|
36336
|
+
ingester:
|
|
36337
|
+
trace_idle_period: 10s
|
|
36338
|
+
max_block_bytes: 1048576
|
|
36339
|
+
max_block_duration: 5m
|
|
36340
|
+
|
|
36341
|
+
compactor:
|
|
36342
|
+
compaction:
|
|
36343
|
+
block_retention: ${retention.traces}
|
|
36344
|
+
|
|
36345
|
+
storage:
|
|
36346
|
+
trace:
|
|
36347
|
+
backend: local
|
|
36348
|
+
local:
|
|
36349
|
+
path: /var/tempo/blocks
|
|
36350
|
+
wal:
|
|
36351
|
+
path: /var/tempo/wal
|
|
36352
|
+
|
|
36353
|
+
metrics_generator:
|
|
36354
|
+
registry:
|
|
36355
|
+
external_labels:
|
|
36356
|
+
source: tempo
|
|
36357
|
+
storage:
|
|
36358
|
+
path: /var/tempo/generator/wal
|
|
36359
|
+
remote_write:
|
|
36360
|
+
- url: http://prometheus:9090/api/v1/write
|
|
36361
|
+
send_exemplars: true
|
|
36362
|
+
|
|
36363
|
+
overrides:
|
|
36364
|
+
defaults:
|
|
36365
|
+
metrics_generator:
|
|
36366
|
+
processors: [service-graphs, span-metrics]
|
|
36367
|
+
`;
|
|
36368
|
+
}
|
|
36369
|
+
function generateLokiConfig(cfg) {
|
|
36370
|
+
const retention = pickRetention(cfg.observability);
|
|
36371
|
+
return `# Generated by \`arc platform deploy\` \u2014 do not edit by hand.
|
|
36372
|
+
auth_enabled: false
|
|
36373
|
+
|
|
36374
|
+
server:
|
|
36375
|
+
http_listen_port: 3100
|
|
36376
|
+
|
|
36377
|
+
common:
|
|
36378
|
+
instance_addr: 127.0.0.1
|
|
36379
|
+
path_prefix: /loki
|
|
36380
|
+
storage:
|
|
36381
|
+
filesystem:
|
|
36382
|
+
chunks_directory: /loki/chunks
|
|
36383
|
+
rules_directory: /loki/rules
|
|
36384
|
+
replication_factor: 1
|
|
36385
|
+
ring:
|
|
36386
|
+
kvstore:
|
|
36387
|
+
store: inmemory
|
|
36388
|
+
|
|
36389
|
+
schema_config:
|
|
36390
|
+
configs:
|
|
36391
|
+
- from: 2024-01-01
|
|
36392
|
+
store: tsdb
|
|
36393
|
+
object_store: filesystem
|
|
36394
|
+
schema: v13
|
|
36395
|
+
index:
|
|
36396
|
+
prefix: index_
|
|
36397
|
+
period: 24h
|
|
36398
|
+
|
|
36399
|
+
limits_config:
|
|
36400
|
+
retention_period: ${retention.logs}
|
|
36401
|
+
allow_structured_metadata: true
|
|
36402
|
+
|
|
36403
|
+
compactor:
|
|
36404
|
+
working_directory: /loki/compactor
|
|
36405
|
+
retention_enabled: true
|
|
36406
|
+
delete_request_store: filesystem
|
|
36407
|
+
`;
|
|
36408
|
+
}
|
|
36409
|
+
function generatePrometheusConfig(_cfg) {
|
|
36410
|
+
return `# Generated by \`arc platform deploy\` \u2014 do not edit by hand.
|
|
36411
|
+
global:
|
|
36412
|
+
scrape_interval: 15s
|
|
36413
|
+
evaluation_interval: 15s
|
|
36414
|
+
|
|
36415
|
+
scrape_configs:
|
|
36416
|
+
- job_name: prometheus
|
|
36417
|
+
static_configs:
|
|
36418
|
+
- targets: [localhost:9090]
|
|
36419
|
+
- job_name: otel-collector
|
|
36420
|
+
static_configs:
|
|
36421
|
+
- targets: [otel-collector:8888]
|
|
36422
|
+
|
|
36423
|
+
# remote-write inbound is enabled via the --web.enable-remote-write-receiver
|
|
36424
|
+
# command-line flag (compose.ts). Retention via --storage.tsdb.retention.time.
|
|
36425
|
+
`;
|
|
36426
|
+
}
|
|
36427
|
+
function generateGrafanaDatasources() {
|
|
36428
|
+
return `# Generated by \`arc platform deploy\` \u2014 do not edit by hand.
|
|
36429
|
+
apiVersion: 1
|
|
36430
|
+
datasources:
|
|
36431
|
+
- name: Tempo
|
|
36432
|
+
type: tempo
|
|
36433
|
+
access: proxy
|
|
36434
|
+
url: http://tempo:3200
|
|
36435
|
+
uid: tempo
|
|
36436
|
+
jsonData:
|
|
36437
|
+
tracesToLogsV2:
|
|
36438
|
+
datasourceUid: loki
|
|
36439
|
+
spanStartTimeShift: -5m
|
|
36440
|
+
spanEndTimeShift: 5m
|
|
36441
|
+
serviceMap:
|
|
36442
|
+
datasourceUid: prometheus
|
|
36443
|
+
- name: Loki
|
|
36444
|
+
type: loki
|
|
36445
|
+
access: proxy
|
|
36446
|
+
url: http://loki:3100
|
|
36447
|
+
uid: loki
|
|
36448
|
+
jsonData:
|
|
36449
|
+
derivedFields:
|
|
36450
|
+
- datasourceUid: tempo
|
|
36451
|
+
matcherRegex: "trace_id=(\\\\w+)"
|
|
36452
|
+
name: TraceID
|
|
36453
|
+
url: $\${__value.raw}
|
|
36454
|
+
- name: Prometheus
|
|
36455
|
+
type: prometheus
|
|
36456
|
+
access: proxy
|
|
36457
|
+
url: http://prometheus:9090
|
|
36458
|
+
uid: prometheus
|
|
36459
|
+
isDefault: true
|
|
36460
|
+
`;
|
|
36461
|
+
}
|
|
36462
|
+
function generateGrafanaDashboardsProvider() {
|
|
36463
|
+
return `# Generated by \`arc platform deploy\` \u2014 do not edit by hand.
|
|
36464
|
+
apiVersion: 1
|
|
36465
|
+
providers:
|
|
36466
|
+
- name: arc
|
|
36467
|
+
orgId: 1
|
|
36468
|
+
folder: Arc
|
|
36469
|
+
type: file
|
|
36470
|
+
disableDeletion: false
|
|
36471
|
+
editable: true
|
|
36472
|
+
updateIntervalSeconds: 30
|
|
36473
|
+
allowUiUpdates: true
|
|
36474
|
+
options:
|
|
36475
|
+
path: /etc/grafana/provisioning/dashboards/arc
|
|
36476
|
+
foldersFromFilesStructure: false
|
|
36477
|
+
`;
|
|
36478
|
+
}
|
|
36479
|
+
function generateArcOverviewDashboard() {
|
|
36480
|
+
const dashboard = {
|
|
36481
|
+
title: "Arc Service Overview",
|
|
36482
|
+
uid: "arc-overview",
|
|
36483
|
+
schemaVersion: 39,
|
|
36484
|
+
version: 1,
|
|
36485
|
+
refresh: "30s",
|
|
36486
|
+
time: { from: "now-1h", to: "now" },
|
|
36487
|
+
timepicker: {},
|
|
36488
|
+
tags: ["arc", "auto-provisioned"],
|
|
36489
|
+
templating: {
|
|
36490
|
+
list: [
|
|
36491
|
+
{
|
|
36492
|
+
name: "service",
|
|
36493
|
+
label: "Service",
|
|
36494
|
+
type: "query",
|
|
36495
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36496
|
+
query: "label_values(traces_spanmetrics_calls_total, service_name)",
|
|
36497
|
+
refresh: 2,
|
|
36498
|
+
includeAll: false,
|
|
36499
|
+
multi: false,
|
|
36500
|
+
current: { text: "arc-prod", value: "arc-prod" }
|
|
36501
|
+
}
|
|
36502
|
+
]
|
|
36503
|
+
},
|
|
36504
|
+
panels: [
|
|
36505
|
+
panelStat("Request rate (req/s)", { x: 0, y: 0, w: 6, h: 4 }, 'sum(rate(traces_spanmetrics_calls_total{service_name="$service", span_kind="SPAN_KIND_SERVER"}[5m]))', "reqps"),
|
|
36506
|
+
panelStat("Error rate (%)", { x: 6, y: 0, w: 6, h: 4 }, 'sum(rate(traces_spanmetrics_calls_total{service_name="$service", span_kind="SPAN_KIND_SERVER", status_code="STATUS_CODE_ERROR"}[5m])) / clamp_min(sum(rate(traces_spanmetrics_calls_total{service_name="$service", span_kind="SPAN_KIND_SERVER"}[5m])), 0.001) * 100', "percent", { red: 1, orange: 0.1 }),
|
|
36507
|
+
panelStat("P99 latency", { x: 12, y: 0, w: 6, h: 4 }, 'histogram_quantile(0.99, sum(rate(traces_spanmetrics_latency_bucket{service_name="$service", span_kind="SPAN_KIND_SERVER"}[5m])) by (le))', "ms", { red: 1000, orange: 300 }),
|
|
36508
|
+
panelStat("Active commands/sec", { x: 18, y: 0, w: 6, h: 4 }, 'sum(rate(arc_commands_total{service_name="$service"}[5m]))', "ops"),
|
|
36509
|
+
panelTimeseries("Request rate by route", { x: 0, y: 4, w: 12, h: 8 }, 'sum by (span_name) (rate(traces_spanmetrics_calls_total{service_name="$service", span_kind="SPAN_KIND_SERVER"}[1m]))', "{{span_name}}", "reqps"),
|
|
36510
|
+
panelTimeseries("Latency percentiles", { x: 12, y: 4, w: 12, h: 8 }, [
|
|
36511
|
+
{
|
|
36512
|
+
expr: 'histogram_quantile(0.5, sum(rate(traces_spanmetrics_latency_bucket{service_name="$service", span_kind="SPAN_KIND_SERVER"}[5m])) by (le))',
|
|
36513
|
+
legend: "p50"
|
|
36514
|
+
},
|
|
36515
|
+
{
|
|
36516
|
+
expr: 'histogram_quantile(0.95, sum(rate(traces_spanmetrics_latency_bucket{service_name="$service", span_kind="SPAN_KIND_SERVER"}[5m])) by (le))',
|
|
36517
|
+
legend: "p95"
|
|
36518
|
+
},
|
|
36519
|
+
{
|
|
36520
|
+
expr: 'histogram_quantile(0.99, sum(rate(traces_spanmetrics_latency_bucket{service_name="$service", span_kind="SPAN_KIND_SERVER"}[5m])) by (le))',
|
|
36521
|
+
legend: "p99"
|
|
36522
|
+
}
|
|
36523
|
+
], "ms"),
|
|
36524
|
+
panelTimeseries("Commands per second", { x: 0, y: 12, w: 12, h: 8 }, 'sum by (arc_command_name) (rate(arc_commands_total{service_name="$service"}[1m]))', "{{arc_command_name}}", "ops"),
|
|
36525
|
+
panelTimeseries("Command p95 latency", { x: 12, y: 12, w: 12, h: 8 }, 'histogram_quantile(0.95, sum by (arc_command_name, le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service"}[5m])))', "{{arc_command_name}}", "ms"),
|
|
36526
|
+
panelTimeseries("DB find ops/sec by collection", { x: 0, y: 20, w: 12, h: 8 }, 'sum by (db_collection_name) (rate(arc_db_find_ms_milliseconds_count{service_name="$service"}[1m]))', "{{db_collection_name}}", "ops"),
|
|
36527
|
+
panelTimeseries("DB find p95 latency", { x: 12, y: 20, w: 12, h: 8 }, 'histogram_quantile(0.95, sum by (db_collection_name, le) (rate(arc_db_find_ms_milliseconds_bucket{service_name="$service"}[5m])))', "{{db_collection_name}}", "ms"),
|
|
36528
|
+
{
|
|
36529
|
+
title: "Recent error logs",
|
|
36530
|
+
type: "logs",
|
|
36531
|
+
gridPos: { x: 0, y: 28, w: 24, h: 8 },
|
|
36532
|
+
datasource: { type: "loki", uid: "loki" },
|
|
36533
|
+
targets: [
|
|
36534
|
+
{
|
|
36535
|
+
expr: '{service_name="$service"} |= `ERROR`',
|
|
36536
|
+
refId: "A"
|
|
36537
|
+
}
|
|
36538
|
+
],
|
|
36539
|
+
options: {
|
|
36540
|
+
showTime: true,
|
|
36541
|
+
showLabels: false,
|
|
36542
|
+
showCommonLabels: false,
|
|
36543
|
+
wrapLogMessage: true,
|
|
36544
|
+
enableLogDetails: true,
|
|
36545
|
+
dedupStrategy: "none",
|
|
36546
|
+
sortOrder: "Descending"
|
|
36547
|
+
}
|
|
36548
|
+
}
|
|
36549
|
+
]
|
|
36550
|
+
};
|
|
36551
|
+
return JSON.stringify(dashboard, null, 2);
|
|
36552
|
+
}
|
|
36553
|
+
function generateArcTracesDashboard() {
|
|
36554
|
+
const dashboard = {
|
|
36555
|
+
title: "Arc Recent Traces",
|
|
36556
|
+
uid: "arc-traces",
|
|
36557
|
+
schemaVersion: 39,
|
|
36558
|
+
version: 1,
|
|
36559
|
+
refresh: "1m",
|
|
36560
|
+
time: { from: "now-1h", to: "now" },
|
|
36561
|
+
tags: ["arc", "auto-provisioned"],
|
|
36562
|
+
templating: {
|
|
36563
|
+
list: [
|
|
36564
|
+
{
|
|
36565
|
+
name: "service",
|
|
36566
|
+
label: "Service",
|
|
36567
|
+
type: "query",
|
|
36568
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36569
|
+
query: "label_values(traces_spanmetrics_calls_total, service_name)",
|
|
36570
|
+
refresh: 2,
|
|
36571
|
+
current: { text: "arc-prod", value: "arc-prod" }
|
|
36572
|
+
}
|
|
36573
|
+
]
|
|
36574
|
+
},
|
|
36575
|
+
panels: [
|
|
36576
|
+
{
|
|
36577
|
+
title: "Slowest traces (p95 \u2265 500ms)",
|
|
36578
|
+
type: "traces",
|
|
36579
|
+
gridPos: { x: 0, y: 0, w: 24, h: 14 },
|
|
36580
|
+
datasource: { type: "tempo", uid: "tempo" },
|
|
36581
|
+
targets: [
|
|
36582
|
+
{
|
|
36583
|
+
queryType: "traceql",
|
|
36584
|
+
query: '{resource.service.name = "$service" && duration > 500ms}',
|
|
36585
|
+
refId: "A",
|
|
36586
|
+
limit: 20
|
|
36587
|
+
}
|
|
36588
|
+
]
|
|
36589
|
+
},
|
|
36590
|
+
{
|
|
36591
|
+
title: "Recent errors",
|
|
36592
|
+
type: "traces",
|
|
36593
|
+
gridPos: { x: 0, y: 14, w: 24, h: 14 },
|
|
36594
|
+
datasource: { type: "tempo", uid: "tempo" },
|
|
36595
|
+
targets: [
|
|
36596
|
+
{
|
|
36597
|
+
queryType: "traceql",
|
|
36598
|
+
query: '{resource.service.name = "$service" && status = error}',
|
|
36599
|
+
refId: "A",
|
|
36600
|
+
limit: 20
|
|
36601
|
+
}
|
|
36602
|
+
]
|
|
36603
|
+
}
|
|
36604
|
+
]
|
|
36605
|
+
};
|
|
36606
|
+
return JSON.stringify(dashboard, null, 2);
|
|
36607
|
+
}
|
|
36608
|
+
function generateArcServiceMapDashboard() {
|
|
36609
|
+
const dashboard = {
|
|
36610
|
+
title: "Arc Service Map",
|
|
36611
|
+
uid: "arc-service-map",
|
|
36612
|
+
schemaVersion: 39,
|
|
36613
|
+
version: 1,
|
|
36614
|
+
refresh: "30s",
|
|
36615
|
+
time: { from: "now-1h", to: "now" },
|
|
36616
|
+
tags: ["arc", "auto-provisioned"],
|
|
36617
|
+
panels: [
|
|
36618
|
+
panelTimeseries("Service-to-service request rate", { x: 0, y: 0, w: 24, h: 9 }, "sum by (client, server) (rate(traces_service_graph_request_total[1m]))", "{{client}} \u2192 {{server}}", "reqps"),
|
|
36619
|
+
panelTimeseries("Inter-service p95 latency", { x: 0, y: 9, w: 24, h: 9 }, "histogram_quantile(0.95, sum by (client, server, le) (rate(traces_service_graph_request_server_seconds_bucket[5m]))) * 1000", "{{client}} \u2192 {{server}}", "ms"),
|
|
36620
|
+
{
|
|
36621
|
+
title: "Service-graph edges (last 5m)",
|
|
36622
|
+
type: "table",
|
|
36623
|
+
gridPos: { x: 0, y: 18, w: 24, h: 8 },
|
|
36624
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36625
|
+
targets: [
|
|
36626
|
+
{
|
|
36627
|
+
expr: "sum by (client, server) (increase(traces_service_graph_request_total[5m]))",
|
|
36628
|
+
refId: "A",
|
|
36629
|
+
instant: true,
|
|
36630
|
+
format: "table"
|
|
36631
|
+
}
|
|
36632
|
+
],
|
|
36633
|
+
transformations: [
|
|
36634
|
+
{ id: "organize", options: { excludeByName: { Time: true } } },
|
|
36635
|
+
{ id: "sortBy", options: { sort: [{ field: "Value", desc: true }] } }
|
|
36636
|
+
]
|
|
36637
|
+
}
|
|
36638
|
+
]
|
|
36639
|
+
};
|
|
36640
|
+
return JSON.stringify(dashboard, null, 2);
|
|
36641
|
+
}
|
|
36642
|
+
function generateArcLogsDashboard() {
|
|
36643
|
+
const dashboard = {
|
|
36644
|
+
title: "Arc Logs Explorer",
|
|
36645
|
+
uid: "arc-logs",
|
|
36646
|
+
schemaVersion: 39,
|
|
36647
|
+
version: 1,
|
|
36648
|
+
refresh: "30s",
|
|
36649
|
+
time: { from: "now-1h", to: "now" },
|
|
36650
|
+
tags: ["arc", "auto-provisioned"],
|
|
36651
|
+
templating: {
|
|
36652
|
+
list: [
|
|
36653
|
+
{
|
|
36654
|
+
name: "service",
|
|
36655
|
+
label: "Service",
|
|
36656
|
+
type: "query",
|
|
36657
|
+
datasource: { type: "loki", uid: "loki" },
|
|
36658
|
+
query: "label_values(service_name)",
|
|
36659
|
+
refresh: 2,
|
|
36660
|
+
current: { text: "arc-prod", value: "arc-prod" }
|
|
36661
|
+
},
|
|
36662
|
+
{
|
|
36663
|
+
name: "search",
|
|
36664
|
+
label: "Filter",
|
|
36665
|
+
type: "textbox",
|
|
36666
|
+
query: "",
|
|
36667
|
+
current: { text: "", value: "" }
|
|
36668
|
+
}
|
|
36669
|
+
]
|
|
36670
|
+
},
|
|
36671
|
+
panels: [
|
|
36672
|
+
panelStat("Logs ingested (1h)", { x: 0, y: 0, w: 6, h: 4 }, 'sum(increase({service_name="$service"}[1h]))', "short"),
|
|
36673
|
+
panelStat("Errors (1h)", { x: 6, y: 0, w: 6, h: 4 }, 'sum(increase({service_name="$service", severity_text=~"ERROR|FATAL"}[1h]))', "short", { orange: 1, red: 50 }),
|
|
36674
|
+
{
|
|
36675
|
+
title: "Log volume by severity",
|
|
36676
|
+
type: "timeseries",
|
|
36677
|
+
gridPos: { x: 12, y: 0, w: 12, h: 8 },
|
|
36678
|
+
datasource: { type: "loki", uid: "loki" },
|
|
36679
|
+
targets: [
|
|
36680
|
+
{
|
|
36681
|
+
expr: 'sum by (severity_text) (count_over_time({service_name="$service"} |~ "$search" [$__interval]))',
|
|
36682
|
+
refId: "A",
|
|
36683
|
+
legendFormat: "{{severity_text}}"
|
|
36684
|
+
}
|
|
36685
|
+
],
|
|
36686
|
+
fieldConfig: {
|
|
36687
|
+
defaults: {
|
|
36688
|
+
unit: "short",
|
|
36689
|
+
custom: {
|
|
36690
|
+
drawStyle: "bars",
|
|
36691
|
+
fillOpacity: 50,
|
|
36692
|
+
lineWidth: 0,
|
|
36693
|
+
stacking: { mode: "normal", group: "A" }
|
|
36694
|
+
}
|
|
36695
|
+
},
|
|
36696
|
+
overrides: []
|
|
36697
|
+
},
|
|
36698
|
+
options: {
|
|
36699
|
+
legend: { displayMode: "list", placement: "bottom", showLegend: true },
|
|
36700
|
+
tooltip: { mode: "multi", sort: "desc" }
|
|
36701
|
+
}
|
|
36702
|
+
},
|
|
36703
|
+
{
|
|
36704
|
+
title: "Live tail (filtered by $search)",
|
|
36705
|
+
type: "logs",
|
|
36706
|
+
gridPos: { x: 0, y: 8, w: 24, h: 18 },
|
|
36707
|
+
datasource: { type: "loki", uid: "loki" },
|
|
36708
|
+
targets: [
|
|
36709
|
+
{
|
|
36710
|
+
expr: '{service_name="$service"} |~ "$search"',
|
|
36711
|
+
refId: "A"
|
|
36712
|
+
}
|
|
36713
|
+
],
|
|
36714
|
+
options: {
|
|
36715
|
+
showTime: true,
|
|
36716
|
+
showLabels: false,
|
|
36717
|
+
showCommonLabels: false,
|
|
36718
|
+
wrapLogMessage: true,
|
|
36719
|
+
enableLogDetails: true,
|
|
36720
|
+
dedupStrategy: "none",
|
|
36721
|
+
sortOrder: "Descending"
|
|
36722
|
+
}
|
|
36723
|
+
}
|
|
36724
|
+
]
|
|
36725
|
+
};
|
|
36726
|
+
return JSON.stringify(dashboard, null, 2);
|
|
36727
|
+
}
|
|
36728
|
+
function generateArcSamplingDashboard() {
|
|
36729
|
+
const dashboard = {
|
|
36730
|
+
title: "Arc Tail Sampling & Collector Health",
|
|
36731
|
+
uid: "arc-sampling",
|
|
36732
|
+
schemaVersion: 39,
|
|
36733
|
+
version: 1,
|
|
36734
|
+
refresh: "30s",
|
|
36735
|
+
time: { from: "now-3h", to: "now" },
|
|
36736
|
+
tags: ["arc", "auto-provisioned"],
|
|
36737
|
+
panels: [
|
|
36738
|
+
panelStat("Spans received/sec", { x: 0, y: 0, w: 6, h: 4 }, "sum(rate(otelcol_receiver_accepted_spans[5m]))", "ops"),
|
|
36739
|
+
panelStat("Spans exported/sec (sampled)", { x: 6, y: 0, w: 6, h: 4 }, "sum(rate(otelcol_exporter_sent_spans[5m]))", "ops"),
|
|
36740
|
+
panelStat("Spans dropped (refused) / 5m", { x: 12, y: 0, w: 6, h: 4 }, "sum(increase(otelcol_receiver_refused_spans[5m]))", "short", { orange: 1, red: 100 }),
|
|
36741
|
+
panelStat("Export failures / 5m", { x: 18, y: 0, w: 6, h: 4 }, "sum(increase(otelcol_exporter_send_failed_spans[5m]))", "short", { orange: 1, red: 50 }),
|
|
36742
|
+
panelTimeseries("Tail-sampling policy decisions", { x: 0, y: 4, w: 12, h: 8 }, 'sum by (policy) (rate(otelcol_processor_tail_sampling_count_traces_sampled{sampled="true"}[1m]))', "{{policy}} sampled", "ops"),
|
|
36743
|
+
panelTimeseries("Receiver vs Exporter (effective sampling rate)", { x: 12, y: 4, w: 12, h: 8 }, [
|
|
36744
|
+
{
|
|
36745
|
+
expr: "sum(rate(otelcol_receiver_accepted_spans[1m]))",
|
|
36746
|
+
legend: "received"
|
|
36747
|
+
},
|
|
36748
|
+
{
|
|
36749
|
+
expr: "sum(rate(otelcol_exporter_sent_spans[1m]))",
|
|
36750
|
+
legend: "exported"
|
|
36751
|
+
}
|
|
36752
|
+
], "ops"),
|
|
36753
|
+
panelTimeseries("Collector queue size (BatchSpanProcessor)", { x: 0, y: 12, w: 12, h: 8 }, "otelcol_processor_batch_batch_send_size_sum / clamp_min(otelcol_processor_batch_batch_send_size_count, 1)", "avg batch size", "short"),
|
|
36754
|
+
panelTimeseries("Collector process memory", { x: 12, y: 12, w: 12, h: 8 }, 'process_resident_memory_bytes{job="otel-collector"}', "RSS", "bytes")
|
|
36755
|
+
]
|
|
36756
|
+
};
|
|
36757
|
+
return JSON.stringify(dashboard, null, 2);
|
|
36758
|
+
}
|
|
36759
|
+
function generateArcCommandDashboard() {
|
|
36760
|
+
const dashboard = {
|
|
36761
|
+
title: "Arc Command Drill-Down",
|
|
36762
|
+
uid: "arc-command",
|
|
36763
|
+
schemaVersion: 39,
|
|
36764
|
+
version: 1,
|
|
36765
|
+
refresh: "30s",
|
|
36766
|
+
time: { from: "now-3h", to: "now" },
|
|
36767
|
+
tags: ["arc", "auto-provisioned"],
|
|
36768
|
+
templating: {
|
|
36769
|
+
list: [
|
|
36770
|
+
{
|
|
36771
|
+
name: "service",
|
|
36772
|
+
label: "Service",
|
|
36773
|
+
type: "query",
|
|
36774
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36775
|
+
query: "label_values(arc_commands_total, service_name)",
|
|
36776
|
+
refresh: 2,
|
|
36777
|
+
current: { text: "arc-prod", value: "arc-prod" }
|
|
36778
|
+
},
|
|
36779
|
+
{
|
|
36780
|
+
name: "command",
|
|
36781
|
+
label: "Command",
|
|
36782
|
+
type: "query",
|
|
36783
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36784
|
+
query: 'label_values(arc_commands_total{service_name="$service"}, arc_command_name)',
|
|
36785
|
+
refresh: 2,
|
|
36786
|
+
includeAll: false,
|
|
36787
|
+
multi: false
|
|
36788
|
+
}
|
|
36789
|
+
]
|
|
36790
|
+
},
|
|
36791
|
+
panels: [
|
|
36792
|
+
panelStat("Call rate", { x: 0, y: 0, w: 6, h: 4 }, 'sum(rate(arc_commands_total{service_name="$service", arc_command_name="$command"}[5m]))', "ops"),
|
|
36793
|
+
panelStat("P50 latency", { x: 6, y: 0, w: 6, h: 4 }, 'histogram_quantile(0.5, sum by (le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service", arc_command_name="$command"}[5m])))', "ms"),
|
|
36794
|
+
panelStat("P95 latency", { x: 12, y: 0, w: 6, h: 4 }, 'histogram_quantile(0.95, sum by (le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service", arc_command_name="$command"}[5m])))', "ms", { orange: 200, red: 1000 }),
|
|
36795
|
+
panelStat("P99 latency", { x: 18, y: 0, w: 6, h: 4 }, 'histogram_quantile(0.99, sum by (le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service", arc_command_name="$command"}[5m])))', "ms", { orange: 500, red: 2000 }),
|
|
36796
|
+
panelTimeseries("Call rate over time", { x: 0, y: 4, w: 12, h: 8 }, 'sum(rate(arc_commands_total{service_name="$service", arc_command_name="$command"}[1m]))', "calls/s", "ops"),
|
|
36797
|
+
panelTimeseries("Latency percentiles", { x: 12, y: 4, w: 12, h: 8 }, [
|
|
36798
|
+
{
|
|
36799
|
+
expr: 'histogram_quantile(0.5, sum by (le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service", arc_command_name="$command"}[5m])))',
|
|
36800
|
+
legend: "p50"
|
|
36801
|
+
},
|
|
36802
|
+
{
|
|
36803
|
+
expr: 'histogram_quantile(0.95, sum by (le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service", arc_command_name="$command"}[5m])))',
|
|
36804
|
+
legend: "p95"
|
|
36805
|
+
},
|
|
36806
|
+
{
|
|
36807
|
+
expr: 'histogram_quantile(0.99, sum by (le) (rate(arc_command_duration_ms_milliseconds_bucket{service_name="$service", arc_command_name="$command"}[5m])))',
|
|
36808
|
+
legend: "p99"
|
|
36809
|
+
}
|
|
36810
|
+
], "ms"),
|
|
36811
|
+
{
|
|
36812
|
+
title: "Recent traces (sampled)",
|
|
36813
|
+
type: "traces",
|
|
36814
|
+
gridPos: { x: 0, y: 12, w: 24, h: 14 },
|
|
36815
|
+
datasource: { type: "tempo", uid: "tempo" },
|
|
36816
|
+
targets: [
|
|
36817
|
+
{
|
|
36818
|
+
queryType: "traceql",
|
|
36819
|
+
query: '{resource.service.name = "$service" && name = "command.$command"}',
|
|
36820
|
+
refId: "A",
|
|
36821
|
+
limit: 20
|
|
36822
|
+
}
|
|
36823
|
+
]
|
|
36824
|
+
}
|
|
36825
|
+
]
|
|
36826
|
+
};
|
|
36827
|
+
return JSON.stringify(dashboard, null, 2);
|
|
36828
|
+
}
|
|
36829
|
+
function generateObservabilityConfigs(cfg) {
|
|
36830
|
+
return {
|
|
36831
|
+
"observability/otel-collector-config.yaml": generateOtelCollectorConfig(cfg),
|
|
36832
|
+
"observability/tempo.yaml": generateTempoConfig(cfg),
|
|
36833
|
+
"observability/loki-config.yaml": generateLokiConfig(cfg),
|
|
36834
|
+
"observability/prometheus.yml": generatePrometheusConfig(cfg),
|
|
36835
|
+
"observability/grafana-datasources.yaml": generateGrafanaDatasources(),
|
|
36836
|
+
"observability/grafana-dashboards.yaml": generateGrafanaDashboardsProvider(),
|
|
36837
|
+
"observability/grafana-dashboards/arc-overview.json": generateArcOverviewDashboard(),
|
|
36838
|
+
"observability/grafana-dashboards/arc-traces.json": generateArcTracesDashboard(),
|
|
36839
|
+
"observability/grafana-dashboards/arc-service-map.json": generateArcServiceMapDashboard(),
|
|
36840
|
+
"observability/grafana-dashboards/arc-logs.json": generateArcLogsDashboard(),
|
|
36841
|
+
"observability/grafana-dashboards/arc-sampling.json": generateArcSamplingDashboard(),
|
|
36842
|
+
"observability/grafana-dashboards/arc-command.json": generateArcCommandDashboard()
|
|
36843
|
+
};
|
|
36844
|
+
}
|
|
36845
|
+
function panelStat(title, gridPos, expr, unit, thresholds) {
|
|
36846
|
+
const steps = [
|
|
36847
|
+
{ color: "green", value: null }
|
|
36848
|
+
];
|
|
36849
|
+
if (thresholds?.orange !== undefined) {
|
|
36850
|
+
steps.push({ color: "orange", value: thresholds.orange });
|
|
36851
|
+
}
|
|
36852
|
+
if (thresholds?.red !== undefined) {
|
|
36853
|
+
steps.push({ color: "red", value: thresholds.red });
|
|
36854
|
+
}
|
|
36855
|
+
return {
|
|
36856
|
+
title,
|
|
36857
|
+
type: "stat",
|
|
36858
|
+
gridPos,
|
|
36859
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36860
|
+
targets: [{ expr, refId: "A", legendFormat: title }],
|
|
36861
|
+
fieldConfig: {
|
|
36862
|
+
defaults: {
|
|
36863
|
+
unit,
|
|
36864
|
+
thresholds: { mode: "absolute", steps }
|
|
36865
|
+
},
|
|
36866
|
+
overrides: []
|
|
36867
|
+
},
|
|
36868
|
+
options: {
|
|
36869
|
+
colorMode: "value",
|
|
36870
|
+
graphMode: "area",
|
|
36871
|
+
justifyMode: "auto",
|
|
36872
|
+
reduceOptions: { calcs: ["lastNotNull"], fields: "", values: false },
|
|
36873
|
+
textMode: "auto"
|
|
36874
|
+
}
|
|
36875
|
+
};
|
|
36876
|
+
}
|
|
36877
|
+
function panelTimeseries(title, gridPos, query, legend, unit) {
|
|
36878
|
+
const targets = Array.isArray(query) ? query.map((q, i) => ({
|
|
36879
|
+
expr: q.expr,
|
|
36880
|
+
refId: String.fromCharCode(65 + i),
|
|
36881
|
+
legendFormat: q.legend
|
|
36882
|
+
})) : [{ expr: query, refId: "A", legendFormat: legend }];
|
|
36883
|
+
return {
|
|
36884
|
+
title,
|
|
36885
|
+
type: "timeseries",
|
|
36886
|
+
gridPos,
|
|
36887
|
+
datasource: { type: "prometheus", uid: "prometheus" },
|
|
36888
|
+
targets,
|
|
36889
|
+
fieldConfig: {
|
|
36890
|
+
defaults: {
|
|
36891
|
+
unit,
|
|
36892
|
+
custom: {
|
|
36893
|
+
drawStyle: "line",
|
|
36894
|
+
lineInterpolation: "smooth",
|
|
36895
|
+
lineWidth: 1.5,
|
|
36896
|
+
fillOpacity: 10,
|
|
36897
|
+
showPoints: "never"
|
|
36898
|
+
}
|
|
36899
|
+
},
|
|
36900
|
+
overrides: []
|
|
36901
|
+
},
|
|
36902
|
+
options: {
|
|
36903
|
+
legend: { displayMode: "list", placement: "bottom", showLegend: true },
|
|
36904
|
+
tooltip: { mode: "multi", sort: "desc" }
|
|
36905
|
+
}
|
|
36906
|
+
};
|
|
36907
|
+
}
|
|
35636
36908
|
|
|
35637
36909
|
// src/deploy/terraform.ts
|
|
35638
36910
|
import { spawn as nodeSpawn2 } from "child_process";
|
|
@@ -35742,10 +37014,11 @@ function applyDeployGlobals(globals) {
|
|
|
35742
37014
|
}
|
|
35743
37015
|
}
|
|
35744
37016
|
}
|
|
35745
|
-
function ensurePersistedSecret(rootDir,
|
|
37017
|
+
function ensurePersistedSecret(rootDir, scope, key, generate) {
|
|
35746
37018
|
if (process.env[key])
|
|
35747
37019
|
return process.env[key];
|
|
35748
|
-
const
|
|
37020
|
+
const fileName = scope === "globals" ? "deploy.arc.env" : `deploy.arc.${scope}.env`;
|
|
37021
|
+
const path4 = join14(rootDir, fileName);
|
|
35749
37022
|
if (existsSync13(path4)) {
|
|
35750
37023
|
const existing = parseEnvFile(readFileSync11(path4, "utf-8"), path4);
|
|
35751
37024
|
if (existing[key]) {
|
|
@@ -35923,6 +37196,31 @@ function validateDeployConfig(input) {
|
|
|
35923
37196
|
}
|
|
35924
37197
|
validated.envs[name] = { domain, envVars, db };
|
|
35925
37198
|
}
|
|
37199
|
+
const observabilityRaw = input.observability;
|
|
37200
|
+
if (observabilityRaw !== undefined) {
|
|
37201
|
+
if (!isObject(observabilityRaw))
|
|
37202
|
+
throw cfgErr("observability", "object");
|
|
37203
|
+
const enabledRaw = observabilityRaw.enabled;
|
|
37204
|
+
if (typeof enabledRaw !== "boolean")
|
|
37205
|
+
throw cfgErr("observability.enabled", "boolean");
|
|
37206
|
+
const retentionRaw = observabilityRaw.retention;
|
|
37207
|
+
let retention;
|
|
37208
|
+
if (retentionRaw !== undefined) {
|
|
37209
|
+
if (!isObject(retentionRaw))
|
|
37210
|
+
throw cfgErr("observability.retention", "object");
|
|
37211
|
+
retention = {
|
|
37212
|
+
traces: optionalString(retentionRaw, "observability.retention.traces"),
|
|
37213
|
+
logs: optionalString(retentionRaw, "observability.retention.logs"),
|
|
37214
|
+
metrics: optionalString(retentionRaw, "observability.retention.metrics")
|
|
37215
|
+
};
|
|
37216
|
+
}
|
|
37217
|
+
validated.observability = {
|
|
37218
|
+
enabled: enabledRaw,
|
|
37219
|
+
subdomain: optionalString(observabilityRaw, "observability.subdomain") ?? "observability",
|
|
37220
|
+
adminPasswordEnv: optionalString(observabilityRaw, "observability.adminPasswordEnv") ?? "ARC_OBSERVABILITY_PASSWORD",
|
|
37221
|
+
retention
|
|
37222
|
+
};
|
|
37223
|
+
}
|
|
35926
37224
|
const provision = input.provision;
|
|
35927
37225
|
if (provision !== undefined) {
|
|
35928
37226
|
if (!isObject(provision))
|
|
@@ -36221,6 +37519,12 @@ async function bootstrap(inputs) {
|
|
|
36221
37519
|
await upStack(inputs);
|
|
36222
37520
|
ok("Docker stack up");
|
|
36223
37521
|
}
|
|
37522
|
+
if (cfg.observability?.enabled) {
|
|
37523
|
+
log2("Ensuring observability sidecars are running...");
|
|
37524
|
+
const obsServices = ["otel-collector", "tempo", "loki", "prometheus", "grafana"];
|
|
37525
|
+
await assertExec(cfg.target, `cd ${cfg.target.remoteDir} && docker compose pull --ignore-pull-failures ${obsServices.join(" ")} && docker compose up -d ${obsServices.join(" ")}`);
|
|
37526
|
+
ok("Observability stack up");
|
|
37527
|
+
}
|
|
36224
37528
|
await writeStateMarker(cfg.target, {
|
|
36225
37529
|
cliVersion: inputs.cliVersion,
|
|
36226
37530
|
configHash: inputs.configHash,
|
|
@@ -36258,6 +37562,23 @@ async function upStack(inputs) {
|
|
|
36258
37562
|
writeFileSync13(join17(workDir, "htpasswd"), htpasswdLine);
|
|
36259
37563
|
writeFileSync13(join17(workDir, "Caddyfile"), generateCaddyfile(cfg));
|
|
36260
37564
|
writeFileSync13(join17(workDir, "docker-compose.yml"), generateCompose({ cfg }));
|
|
37565
|
+
let observabilityFiles = null;
|
|
37566
|
+
let observabilityHtpasswd = null;
|
|
37567
|
+
if (cfg.observability?.enabled) {
|
|
37568
|
+
observabilityFiles = generateObservabilityConfigs(cfg);
|
|
37569
|
+
const adminPasswordEnv = cfg.observability.adminPasswordEnv ?? "ARC_OBSERVABILITY_PASSWORD";
|
|
37570
|
+
const adminPassword = process.env[adminPasswordEnv];
|
|
37571
|
+
if (!adminPassword) {
|
|
37572
|
+
throw new Error(`bootstrap: ${adminPasswordEnv} not set \u2014 observability needs a Grafana admin password.`);
|
|
37573
|
+
}
|
|
37574
|
+
observabilityHtpasswd = await generateCaddyBasicAuthLine("admin", adminPassword);
|
|
37575
|
+
for (const [relPath, contents] of Object.entries(observabilityFiles)) {
|
|
37576
|
+
const fullPath = join17(workDir, relPath);
|
|
37577
|
+
mkdirSync12(dirname9(fullPath), { recursive: true });
|
|
37578
|
+
writeFileSync13(fullPath, contents);
|
|
37579
|
+
}
|
|
37580
|
+
writeFileSync13(join17(workDir, "observability-htpasswd"), observabilityHtpasswd);
|
|
37581
|
+
}
|
|
36261
37582
|
await assertExec(cfg.target, `sudo mkdir -p ${cfg.target.remoteDir} && sudo chown ${cfg.target.user}:${cfg.target.user} ${cfg.target.remoteDir}`);
|
|
36262
37583
|
for (const name of Object.keys(cfg.envs)) {
|
|
36263
37584
|
await assertExec(cfg.target, `mkdir -p ${cfg.target.remoteDir}/${name}`);
|
|
@@ -36266,7 +37587,26 @@ async function upStack(inputs) {
|
|
|
36266
37587
|
await scpUpload(cfg.target, join17(workDir, "Caddyfile"), `${cfg.target.remoteDir}/Caddyfile`);
|
|
36267
37588
|
await scpUpload(cfg.target, join17(workDir, "docker-compose.yml"), `${cfg.target.remoteDir}/docker-compose.yml`);
|
|
36268
37589
|
await scpUpload(cfg.target, join17(workDir, "htpasswd"), `${cfg.target.remoteDir}/registry-auth/htpasswd`);
|
|
37590
|
+
if (observabilityFiles && observabilityHtpasswd) {
|
|
37591
|
+
await assertExec(cfg.target, `mkdir -p ${cfg.target.remoteDir}/observability/grafana-dashboards`);
|
|
37592
|
+
for (const relPath of Object.keys(observabilityFiles)) {
|
|
37593
|
+
const localDir = dirname9(join17(workDir, relPath));
|
|
37594
|
+
mkdirSync12(localDir, { recursive: true });
|
|
37595
|
+
}
|
|
37596
|
+
for (const relPath of Object.keys(observabilityFiles)) {
|
|
37597
|
+
await scpUpload(cfg.target, join17(workDir, relPath), `${cfg.target.remoteDir}/${relPath}`);
|
|
37598
|
+
}
|
|
37599
|
+
await scpUpload(cfg.target, join17(workDir, "observability-htpasswd"), `${cfg.target.remoteDir}/observability-htpasswd`);
|
|
37600
|
+
}
|
|
36269
37601
|
await assertExec(cfg.target, `touch ${cfg.target.remoteDir}/.env`);
|
|
37602
|
+
if (cfg.observability?.enabled) {
|
|
37603
|
+
const key = cfg.observability.adminPasswordEnv ?? "ARC_OBSERVABILITY_PASSWORD";
|
|
37604
|
+
const value = process.env[key];
|
|
37605
|
+
if (!value) {
|
|
37606
|
+
throw new Error(`bootstrap: ${key} not set \u2014 observability needs a Grafana admin password.`);
|
|
37607
|
+
}
|
|
37608
|
+
await writeEnvLine(cfg.target, `${cfg.target.remoteDir}/.env`, key, value);
|
|
37609
|
+
}
|
|
36270
37610
|
for (const [name, env2] of Object.entries(cfg.envs)) {
|
|
36271
37611
|
if (env2.db?.type !== "postgres")
|
|
36272
37612
|
continue;
|
|
@@ -36429,8 +37769,8 @@ import {
|
|
|
36429
37769
|
writeFileSync as writeFileSync14
|
|
36430
37770
|
} from "fs";
|
|
36431
37771
|
import { tmpdir as tmpdir3 } from "os";
|
|
36432
|
-
import { dirname as
|
|
36433
|
-
import { fileURLToPath as
|
|
37772
|
+
import { dirname as dirname10, join as join18 } from "path";
|
|
37773
|
+
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
36434
37774
|
|
|
36435
37775
|
// src/deploy/image-template.ts
|
|
36436
37776
|
function generateDockerfile(inputs) {
|
|
@@ -36522,8 +37862,8 @@ function embedCliBundle(ws) {
|
|
|
36522
37862
|
copyFileSync2(source, target);
|
|
36523
37863
|
}
|
|
36524
37864
|
function locateCliBundle() {
|
|
36525
|
-
const here =
|
|
36526
|
-
let cur =
|
|
37865
|
+
const here = fileURLToPath7(import.meta.url);
|
|
37866
|
+
let cur = dirname10(here);
|
|
36527
37867
|
while (cur !== "/" && cur !== "") {
|
|
36528
37868
|
const candidate = join18(cur, "package.json");
|
|
36529
37869
|
if (existsSync16(candidate)) {
|
|
@@ -36541,7 +37881,7 @@ function locateCliBundle() {
|
|
|
36541
37881
|
throw e;
|
|
36542
37882
|
}
|
|
36543
37883
|
}
|
|
36544
|
-
const parent =
|
|
37884
|
+
const parent = dirname10(cur);
|
|
36545
37885
|
if (parent === cur)
|
|
36546
37886
|
break;
|
|
36547
37887
|
cur = parent;
|
|
@@ -37394,6 +38734,10 @@ async function platformDeploy(envArg, options = {}) {
|
|
|
37394
38734
|
for (const pg of pgEnvs) {
|
|
37395
38735
|
ensurePersistedSecret(ws.rootDir, pg.name, pg.passwordKey, () => crypto.randomUUID().replace(/-/g, ""));
|
|
37396
38736
|
}
|
|
38737
|
+
if (cfg.observability?.enabled) {
|
|
38738
|
+
const key = cfg.observability.adminPasswordEnv ?? "ARC_OBSERVABILITY_PASSWORD";
|
|
38739
|
+
ensurePersistedSecret(ws.rootDir, "globals", key, () => crypto.randomUUID().replace(/-/g, ""));
|
|
38740
|
+
}
|
|
37397
38741
|
const targetEnvs = envArg ? envArg in cfg.envs ? [envArg] : (() => {
|
|
37398
38742
|
err(`Unknown env "${envArg}". Known: ${Object.keys(cfg.envs).join(", ")}`);
|
|
37399
38743
|
process.exit(1);
|
|
@@ -37468,8 +38812,8 @@ async function platformDeploy(envArg, options = {}) {
|
|
|
37468
38812
|
}
|
|
37469
38813
|
function readCliVersion2() {
|
|
37470
38814
|
try {
|
|
37471
|
-
let cur =
|
|
37472
|
-
const root =
|
|
38815
|
+
let cur = dirname11(fileURLToPath8(import.meta.url));
|
|
38816
|
+
const root = dirname11(cur).startsWith("/") ? "/" : ".";
|
|
37473
38817
|
while (cur !== root && cur !== "") {
|
|
37474
38818
|
const candidate = join19(cur, "package.json");
|
|
37475
38819
|
if (existsSync17(candidate)) {
|
|
@@ -37478,7 +38822,7 @@ function readCliVersion2() {
|
|
|
37478
38822
|
return pkg.version ?? "unknown";
|
|
37479
38823
|
}
|
|
37480
38824
|
}
|
|
37481
|
-
const parent =
|
|
38825
|
+
const parent = dirname11(cur);
|
|
37482
38826
|
if (parent === cur)
|
|
37483
38827
|
break;
|
|
37484
38828
|
cur = parent;
|
|
@@ -37493,6 +38837,7 @@ async function hashDeployConfig(rootDir) {
|
|
|
37493
38837
|
const content = readFileSync14(p2);
|
|
37494
38838
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
37495
38839
|
hasher.update(content);
|
|
38840
|
+
hasher.update(readCliVersion2());
|
|
37496
38841
|
return hasher.digest("hex").slice(0, 16);
|
|
37497
38842
|
}
|
|
37498
38843
|
|
|
@@ -37668,14 +39013,16 @@ function filterEventsForTokens(tokens, events, eventDefinitions) {
|
|
|
37668
39013
|
// ../host/src/context-handler.ts
|
|
37669
39014
|
class ContextHandler {
|
|
37670
39015
|
context;
|
|
39016
|
+
telemetry;
|
|
37671
39017
|
model;
|
|
37672
39018
|
dataStorage;
|
|
37673
39019
|
eventPublisher;
|
|
37674
39020
|
eventDefinitions = new Map;
|
|
37675
39021
|
hostEventIdCounter = 0;
|
|
37676
39022
|
initialized = false;
|
|
37677
|
-
constructor(context, dbAdapter) {
|
|
39023
|
+
constructor(context, dbAdapter, telemetry) {
|
|
37678
39024
|
this.context = context;
|
|
39025
|
+
this.telemetry = telemetry;
|
|
37679
39026
|
this.dataStorage = new MasterDataStorage(dbAdapter);
|
|
37680
39027
|
this.eventPublisher = new LocalEventPublisher(this.dataStorage);
|
|
37681
39028
|
this.model = new Model(context, {
|
|
@@ -37723,27 +39070,49 @@ class ContextHandler {
|
|
|
37723
39070
|
}
|
|
37724
39071
|
}
|
|
37725
39072
|
async executeCommand(commandName, params, rawToken) {
|
|
37726
|
-
const
|
|
37727
|
-
|
|
37728
|
-
|
|
37729
|
-
|
|
37730
|
-
|
|
37731
|
-
|
|
37732
|
-
|
|
37733
|
-
|
|
37734
|
-
|
|
37735
|
-
|
|
37736
|
-
|
|
37737
|
-
|
|
37738
|
-
|
|
37739
|
-
|
|
37740
|
-
|
|
39073
|
+
const includePayloads = this.telemetry?.shouldIncludePayloads() ?? false;
|
|
39074
|
+
const baseAttrs = {
|
|
39075
|
+
"rpc.system": "arc",
|
|
39076
|
+
"rpc.method": commandName,
|
|
39077
|
+
"arc.command.name": commandName,
|
|
39078
|
+
"arc.command.params_size": params ? JSON.stringify(params).length : 0,
|
|
39079
|
+
...includePayloads ? { "arc.command.params": params } : {}
|
|
39080
|
+
};
|
|
39081
|
+
const runCommand = async () => {
|
|
39082
|
+
const scoped = new ScopedModel(this.model, "request");
|
|
39083
|
+
if (rawToken)
|
|
39084
|
+
scoped.setToken(rawToken);
|
|
39085
|
+
const mutations = mutationExecutor(scoped);
|
|
39086
|
+
let command;
|
|
39087
|
+
if (commandName.includes(".")) {
|
|
39088
|
+
const [elementName, methodName] = commandName.split(".");
|
|
39089
|
+
const element = mutations[elementName];
|
|
39090
|
+
command = element?.[methodName];
|
|
39091
|
+
} else {
|
|
39092
|
+
command = mutations[commandName];
|
|
39093
|
+
}
|
|
39094
|
+
if (!command) {
|
|
39095
|
+
throw new Error(`Command '${commandName}' not found`);
|
|
39096
|
+
}
|
|
39097
|
+
try {
|
|
39098
|
+
return await command(params);
|
|
39099
|
+
} catch (error) {
|
|
39100
|
+
console.error(`[ARC] Command '${commandName}' failed:`, error);
|
|
39101
|
+
throw error;
|
|
39102
|
+
}
|
|
39103
|
+
};
|
|
39104
|
+
if (!this.telemetry)
|
|
39105
|
+
return runCommand();
|
|
39106
|
+
const start = Date.now();
|
|
37741
39107
|
try {
|
|
37742
|
-
|
|
37743
|
-
|
|
37744
|
-
|
|
37745
|
-
|
|
37746
|
-
|
|
39108
|
+
return await this.telemetry.startSpan(`command.${commandName}`, runCommand, { attributes: baseAttrs });
|
|
39109
|
+
} finally {
|
|
39110
|
+
this.telemetry.measureSince("arc.command.duration_ms", start, {
|
|
39111
|
+
"arc.command.name": commandName
|
|
39112
|
+
});
|
|
39113
|
+
this.telemetry.incrementCounter("arc.commands.total", 1, {
|
|
39114
|
+
"arc.command.name": commandName
|
|
39115
|
+
});
|
|
37747
39116
|
}
|
|
37748
39117
|
}
|
|
37749
39118
|
async persistEvents(events, clientId, token) {
|
|
@@ -38806,7 +40175,7 @@ async function createArcServer(config) {
|
|
|
38806
40175
|
const jwtSecret = config.jwtSecret || process.env.JWT_SECRET || "arc-host-secret-change-in-production";
|
|
38807
40176
|
const port = config.port || 5005;
|
|
38808
40177
|
const dbAdapter = config.dbAdapterFactory(config.context);
|
|
38809
|
-
const contextHandler = new ContextHandler(config.context, dbAdapter);
|
|
40178
|
+
const contextHandler = new ContextHandler(config.context, dbAdapter, config.telemetry);
|
|
38810
40179
|
await contextHandler.init();
|
|
38811
40180
|
const cronScheduler = new CronScheduler(contextHandler);
|
|
38812
40181
|
cronScheduler.start();
|
|
@@ -38871,39 +40240,51 @@ async function createArcServer(config) {
|
|
|
38871
40240
|
if (req.method === "OPTIONS") {
|
|
38872
40241
|
return new Response(null, { headers: corsHeaders2 });
|
|
38873
40242
|
}
|
|
38874
|
-
const
|
|
38875
|
-
|
|
38876
|
-
|
|
38877
|
-
|
|
38878
|
-
|
|
38879
|
-
|
|
38880
|
-
|
|
38881
|
-
|
|
40243
|
+
const handleRequest = async (span) => {
|
|
40244
|
+
const authHeader = req.headers.get("Authorization");
|
|
40245
|
+
let rawToken = authHeader?.replace("Bearer ", "") || url.searchParams.get("token");
|
|
40246
|
+
if (!rawToken) {
|
|
40247
|
+
const cookieHeader = req.headers.get("Cookie");
|
|
40248
|
+
if (cookieHeader) {
|
|
40249
|
+
const match2 = cookieHeader.match(/arc_token=([^;]+)/);
|
|
40250
|
+
if (match2)
|
|
40251
|
+
rawToken = decodeURIComponent(match2[1]);
|
|
40252
|
+
}
|
|
38882
40253
|
}
|
|
38883
|
-
|
|
38884
|
-
|
|
38885
|
-
|
|
38886
|
-
|
|
38887
|
-
return
|
|
38888
|
-
|
|
38889
|
-
|
|
38890
|
-
|
|
38891
|
-
}
|
|
38892
|
-
|
|
38893
|
-
|
|
38894
|
-
|
|
38895
|
-
|
|
38896
|
-
|
|
40254
|
+
const tokenPayload = rawToken ? verifyToken(rawToken) : null;
|
|
40255
|
+
if (url.pathname === "/ws" && req.headers.get("Upgrade") === "websocket") {
|
|
40256
|
+
if (server2.upgrade(req, { data: { clientId: "" } }))
|
|
40257
|
+
return;
|
|
40258
|
+
return new Response("WebSocket upgrade failed", {
|
|
40259
|
+
status: 500,
|
|
40260
|
+
headers: corsHeaders2
|
|
40261
|
+
});
|
|
40262
|
+
}
|
|
40263
|
+
const reqCtx = { rawToken, tokenPayload, corsHeaders: corsHeaders2 };
|
|
40264
|
+
for (const handler of httpHandlers) {
|
|
40265
|
+
const response = await handler(req, url, reqCtx);
|
|
40266
|
+
if (response) {
|
|
40267
|
+
span?.setAttribute("http.response.status_code", response.status);
|
|
40268
|
+
return response;
|
|
40269
|
+
}
|
|
40270
|
+
}
|
|
40271
|
+
span?.setAttribute("http.response.status_code", 404);
|
|
40272
|
+
return new Response("Not Found", { status: 404, headers: corsHeaders2 });
|
|
38897
40273
|
};
|
|
38898
|
-
|
|
38899
|
-
|
|
38900
|
-
|
|
38901
|
-
|
|
38902
|
-
|
|
38903
|
-
|
|
38904
|
-
|
|
38905
|
-
|
|
38906
|
-
|
|
40274
|
+
const telemetry = config.telemetry;
|
|
40275
|
+
if (!telemetry)
|
|
40276
|
+
return handleRequest(undefined);
|
|
40277
|
+
return telemetry.runWithExtractedContext(req.headers, () => telemetry.startSpan(`${req.method} ${url.pathname}`, (span) => handleRequest(span), {
|
|
40278
|
+
kind: 2,
|
|
40279
|
+
attributes: {
|
|
40280
|
+
"http.request.method": req.method,
|
|
40281
|
+
"http.route": url.pathname,
|
|
40282
|
+
"url.scheme": url.protocol.replace(":", ""),
|
|
40283
|
+
"url.path": url.pathname,
|
|
40284
|
+
"server.address": url.host,
|
|
40285
|
+
"user_agent.original": req.headers.get("user-agent") ?? undefined
|
|
40286
|
+
}
|
|
40287
|
+
}));
|
|
38907
40288
|
},
|
|
38908
40289
|
websocket: {
|
|
38909
40290
|
open(ws) {
|
|
@@ -38913,16 +40294,43 @@ async function createArcServer(config) {
|
|
|
38913
40294
|
const client = connectionManager.getClientByWs(ws);
|
|
38914
40295
|
if (!client)
|
|
38915
40296
|
return;
|
|
40297
|
+
let message;
|
|
38916
40298
|
try {
|
|
38917
|
-
|
|
38918
|
-
for (const handler of wsHandlers) {
|
|
38919
|
-
const handled = await handler(client, message, wsCtx);
|
|
38920
|
-
if (handled)
|
|
38921
|
-
break;
|
|
38922
|
-
}
|
|
40299
|
+
message = JSON.parse(messageStr);
|
|
38923
40300
|
} catch (error) {
|
|
38924
40301
|
console.error("Failed to parse WS message:", error);
|
|
40302
|
+
return;
|
|
40303
|
+
}
|
|
40304
|
+
const dispatch = async () => {
|
|
40305
|
+
try {
|
|
40306
|
+
for (const handler of wsHandlers) {
|
|
40307
|
+
const handled = await handler(client, message, wsCtx);
|
|
40308
|
+
if (handled)
|
|
40309
|
+
break;
|
|
40310
|
+
}
|
|
40311
|
+
} catch (error) {
|
|
40312
|
+
console.error("WS handler error:", error);
|
|
40313
|
+
}
|
|
40314
|
+
};
|
|
40315
|
+
const telemetry = config.telemetry;
|
|
40316
|
+
if (!telemetry) {
|
|
40317
|
+
await dispatch();
|
|
40318
|
+
return;
|
|
38925
40319
|
}
|
|
40320
|
+
const carrier = {};
|
|
40321
|
+
if (typeof message?.traceparent === "string")
|
|
40322
|
+
carrier.traceparent = message.traceparent;
|
|
40323
|
+
if (typeof message?.tracestate === "string")
|
|
40324
|
+
carrier.tracestate = message.tracestate;
|
|
40325
|
+
await telemetry.runWithExtractedContext(carrier, () => telemetry.startSpan(`ws.${message?.type ?? "message"}`, () => dispatch(), {
|
|
40326
|
+
kind: 2,
|
|
40327
|
+
attributes: {
|
|
40328
|
+
"messaging.system": "arc-ws",
|
|
40329
|
+
"messaging.operation": "process",
|
|
40330
|
+
"messaging.message.type": message?.type,
|
|
40331
|
+
"arc.ws.client_id": client.id
|
|
40332
|
+
}
|
|
40333
|
+
}));
|
|
38926
40334
|
},
|
|
38927
40335
|
close(ws) {
|
|
38928
40336
|
const client = connectionManager.getClientByWs(ws);
|
|
@@ -38964,6 +40372,15 @@ async function resolveDbAdapterFactory(dbPath) {
|
|
|
38964
40372
|
return createBunSQLiteAdapterFactory2(dbPath);
|
|
38965
40373
|
}
|
|
38966
40374
|
function generateShellHtml(appName, manifest, initial, stylesHash) {
|
|
40375
|
+
const otelConfig = process.env.ARC_OTEL_ENABLED === "true" ? {
|
|
40376
|
+
enabled: true,
|
|
40377
|
+
endpoint: "/otel",
|
|
40378
|
+
serviceName: process.env.OTEL_SERVICE_NAME ?? `${appName}-browser`,
|
|
40379
|
+
environment: "development",
|
|
40380
|
+
sampleRate: Number(process.env.ARC_OTEL_BROWSER_SAMPLE_RATE ?? "0.1")
|
|
40381
|
+
} : null;
|
|
40382
|
+
const otelTag = otelConfig ? `
|
|
40383
|
+
<script>window.__ARC_OTEL_CONFIG=${JSON.stringify(otelConfig)};</script>` : "";
|
|
38967
40384
|
const initialUrl = initial ? `/browser/${initial.file}` : null;
|
|
38968
40385
|
if (!initialUrl) {
|
|
38969
40386
|
throw new Error("generateShellHtml: initial bundle missing from manifest");
|
|
@@ -38979,7 +40396,7 @@ function generateShellHtml(appName, manifest, initial, stylesHash) {
|
|
|
38979
40396
|
<link rel="manifest" href="/manifest.json">` : ""}
|
|
38980
40397
|
<link rel="stylesheet" href="/styles.css${stylesQs}" />
|
|
38981
40398
|
<link rel="stylesheet" href="/theme.css${stylesQs}" />
|
|
38982
|
-
<link rel="modulepreload" href="${initialUrl}"
|
|
40399
|
+
<link rel="modulepreload" href="${initialUrl}" />${otelTag}
|
|
38983
40400
|
</head>
|
|
38984
40401
|
<body>
|
|
38985
40402
|
<div id="root"></div>
|
|
@@ -39227,8 +40644,27 @@ function spaFallbackHandler(getShellHtml) {
|
|
|
39227
40644
|
};
|
|
39228
40645
|
}
|
|
39229
40646
|
async function startPlatformServer(opts) {
|
|
39230
|
-
const { ws, port, devMode, context } = opts;
|
|
40647
|
+
const { ws, port, devMode, context: context2 } = opts;
|
|
39231
40648
|
ensureModuleSigSecret(ws, !!devMode);
|
|
40649
|
+
let telemetry;
|
|
40650
|
+
let telemetryShutdown;
|
|
40651
|
+
if (process.env.ARC_OTEL_ENABLED === "true") {
|
|
40652
|
+
try {
|
|
40653
|
+
const { initServerTelemetry: initServerTelemetry2 } = await Promise.resolve().then(() => (init_init_server(), exports_init_server));
|
|
40654
|
+
const init2 = initServerTelemetry2({
|
|
40655
|
+
serviceName: process.env.OTEL_SERVICE_NAME ?? ws.appName,
|
|
40656
|
+
environment: "server",
|
|
40657
|
+
endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
40658
|
+
mode: devMode ? "development" : "production",
|
|
40659
|
+
sampleRate: devMode ? 1 : 1
|
|
40660
|
+
});
|
|
40661
|
+
telemetry = init2.telemetry;
|
|
40662
|
+
telemetryShutdown = init2.shutdown;
|
|
40663
|
+
ok("Telemetry enabled \u2014 exporting to " + process.env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
40664
|
+
} catch (e2) {
|
|
40665
|
+
err(`Failed to init telemetry: ${e2.message}`);
|
|
40666
|
+
}
|
|
40667
|
+
}
|
|
39232
40668
|
const moduleAccessMap = opts.moduleAccess ?? new Map;
|
|
39233
40669
|
let manifest = opts.manifest;
|
|
39234
40670
|
const getManifest = () => manifest;
|
|
@@ -39249,7 +40685,7 @@ async function startPlatformServer(opts) {
|
|
|
39249
40685
|
}
|
|
39250
40686
|
}
|
|
39251
40687
|
};
|
|
39252
|
-
if (!
|
|
40688
|
+
if (!context2) {
|
|
39253
40689
|
const cors = {
|
|
39254
40690
|
"Access-Control-Allow-Origin": "*",
|
|
39255
40691
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
@@ -39293,9 +40729,18 @@ async function startPlatformServer(opts) {
|
|
|
39293
40729
|
};
|
|
39294
40730
|
}
|
|
39295
40731
|
const dbPath = opts.dbPath || join20(ws.arcDir, "data", "arc.db");
|
|
39296
|
-
const
|
|
40732
|
+
const baseDbFactory = await resolveDbAdapterFactory(dbPath);
|
|
40733
|
+
let dbAdapterFactory = baseDbFactory;
|
|
40734
|
+
if (telemetry) {
|
|
40735
|
+
const { wrapDbAdapter: wrapDbAdapter2 } = await Promise.resolve().then(() => (init_init_server(), exports_init_server));
|
|
40736
|
+
const dbSystem = process.env.DATABASE_URL ? "postgresql" : "sqlite";
|
|
40737
|
+
dbAdapterFactory = async (ctx) => {
|
|
40738
|
+
const a2 = await baseDbFactory(ctx);
|
|
40739
|
+
return wrapDbAdapter2(a2, telemetry, dbSystem);
|
|
40740
|
+
};
|
|
40741
|
+
}
|
|
39297
40742
|
const arcServer = await createArcServer({
|
|
39298
|
-
context,
|
|
40743
|
+
context: context2,
|
|
39299
40744
|
dbAdapterFactory,
|
|
39300
40745
|
port,
|
|
39301
40746
|
httpHandlers: [
|
|
@@ -39304,7 +40749,8 @@ async function startPlatformServer(opts) {
|
|
|
39304
40749
|
staticFilesHandler(ws, !!devMode, getManifest),
|
|
39305
40750
|
spaFallbackHandler(getShellHtml)
|
|
39306
40751
|
],
|
|
39307
|
-
onWsClose: (clientId) => cleanupClientSubs(clientId)
|
|
40752
|
+
onWsClose: (clientId) => cleanupClientSubs(clientId),
|
|
40753
|
+
telemetry
|
|
39308
40754
|
});
|
|
39309
40755
|
return {
|
|
39310
40756
|
server: arcServer.server,
|
|
@@ -39312,7 +40758,10 @@ async function startPlatformServer(opts) {
|
|
|
39312
40758
|
connectionManager: arcServer.connectionManager,
|
|
39313
40759
|
setManifest,
|
|
39314
40760
|
notifyReload,
|
|
39315
|
-
stop: () =>
|
|
40761
|
+
stop: () => {
|
|
40762
|
+
arcServer.stop();
|
|
40763
|
+
telemetryShutdown?.();
|
|
40764
|
+
}
|
|
39316
40765
|
};
|
|
39317
40766
|
}
|
|
39318
40767
|
|
|
@@ -39333,8 +40782,8 @@ async function startPlatform(opts) {
|
|
|
39333
40782
|
manifest = JSON.parse(readFileSync15(manifestPath, "utf-8"));
|
|
39334
40783
|
}
|
|
39335
40784
|
log2("Loading server context...");
|
|
39336
|
-
const { context, moduleAccess } = await loadServerContext(ws);
|
|
39337
|
-
if (
|
|
40785
|
+
const { context: context2, moduleAccess } = await loadServerContext(ws);
|
|
40786
|
+
if (context2) {
|
|
39338
40787
|
ok("Context loaded");
|
|
39339
40788
|
} else {
|
|
39340
40789
|
log2("No context \u2014 server endpoints skipped");
|
|
@@ -39343,7 +40792,7 @@ async function startPlatform(opts) {
|
|
|
39343
40792
|
ws,
|
|
39344
40793
|
port,
|
|
39345
40794
|
manifest,
|
|
39346
|
-
context,
|
|
40795
|
+
context: context2,
|
|
39347
40796
|
moduleAccess,
|
|
39348
40797
|
dbPath,
|
|
39349
40798
|
devMode
|