rails-profiler 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/builds/profiler.js +211 -246
- data/lib/profiler/instrumentation/net_http_instrumentation.rb +3 -0
- data/lib/profiler/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a755b6d8e9f74901cac774282d218553d40fe1c59efe7e9a7973e2a6c7cf38ca
|
|
4
|
+
data.tar.gz: 5f157e934571a297d1aa6484312cbc001478b71b776c940179d91f4b04f31d85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 02b2e42cb2409c7db8a54277323d7c13483b10884ebd041c60aef6b8f874cde66d90cf3d02e0b60d65b526ad8e5d8d58bc52e19c7a60943ddfe65f97b1e655e3
|
|
7
|
+
data.tar.gz: 7c13611e50dc1ada83e5e61f0cbee9f5cf1bf256a16d776012ff59c6a07abe6fff7b3a636f702e1445f44f6750207bbcf0fce25fcc3234d2f5008ad0c7be8f02
|
|
@@ -396,6 +396,24 @@
|
|
|
396
396
|
return "function" == typeof t3 ? t3(n2) : t3;
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
+
// app/assets/typescript/profiler/components/dashboard/tabs/shared/utils.ts
|
|
400
|
+
function methodBadge(method) {
|
|
401
|
+
const map = { GET: "info", POST: "success", PUT: "warning", PATCH: "warning", DELETE: "error" };
|
|
402
|
+
return map[method] || "default";
|
|
403
|
+
}
|
|
404
|
+
function statusBadge(status) {
|
|
405
|
+
if (status === 0) return "error";
|
|
406
|
+
if (status >= 200 && status < 300) return "success";
|
|
407
|
+
if (status >= 400) return "error";
|
|
408
|
+
return "warning";
|
|
409
|
+
}
|
|
410
|
+
function formatBytes(bytes) {
|
|
411
|
+
if (bytes < 0) return "\u2014";
|
|
412
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
413
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
414
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
415
|
+
}
|
|
416
|
+
|
|
399
417
|
// node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js
|
|
400
418
|
var f3 = 0;
|
|
401
419
|
function u3(e3, t3, n2, o3, i3, u4) {
|
|
@@ -407,21 +425,53 @@
|
|
|
407
425
|
return l.vnode && l.vnode(l3), l3;
|
|
408
426
|
}
|
|
409
427
|
|
|
410
|
-
// app/assets/typescript/profiler/components/dashboard/tabs/
|
|
411
|
-
function
|
|
412
|
-
const
|
|
413
|
-
|
|
428
|
+
// app/assets/typescript/profiler/components/dashboard/tabs/shared/HttpComponents.tsx
|
|
429
|
+
function CopyButton({ text }) {
|
|
430
|
+
const [copied, setCopied] = d2(false);
|
|
431
|
+
function copy() {
|
|
432
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
433
|
+
setCopied(true);
|
|
434
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
return /* @__PURE__ */ u3("button", { onClick: copy, class: "profiler-body-download-btn profiler-text--xs", style: "cursor:pointer", children: copied ? "Copied!" : "Copy" });
|
|
414
438
|
}
|
|
415
|
-
function
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
439
|
+
function mimeToExt(mime) {
|
|
440
|
+
const m3 = mime.split(";")[0].trim().toLowerCase();
|
|
441
|
+
const map = {
|
|
442
|
+
"application/json": ".json",
|
|
443
|
+
"application/ld+json": ".jsonld",
|
|
444
|
+
"application/xml": ".xml",
|
|
445
|
+
"text/xml": ".xml",
|
|
446
|
+
"text/csv": ".csv",
|
|
447
|
+
"application/csv": ".csv",
|
|
448
|
+
"text/html": ".html",
|
|
449
|
+
"text/plain": ".txt",
|
|
450
|
+
"text/css": ".css",
|
|
451
|
+
"application/javascript": ".js",
|
|
452
|
+
"text/javascript": ".js",
|
|
453
|
+
"image/svg+xml": ".svg",
|
|
454
|
+
"image/png": ".png",
|
|
455
|
+
"image/jpeg": ".jpg",
|
|
456
|
+
"image/gif": ".gif",
|
|
457
|
+
"image/webp": ".webp",
|
|
458
|
+
"image/avif": ".avif",
|
|
459
|
+
"application/pdf": ".pdf",
|
|
460
|
+
"application/zip": ".zip",
|
|
461
|
+
"application/gzip": ".gz",
|
|
462
|
+
"application/octet-stream": ".bin"
|
|
463
|
+
};
|
|
464
|
+
return map[m3] || ".bin";
|
|
420
465
|
}
|
|
421
|
-
function
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
466
|
+
function DownloadTextButton({ text, mime }) {
|
|
467
|
+
const [url, setUrl] = d2(null);
|
|
468
|
+
y2(() => {
|
|
469
|
+
const objectUrl = URL.createObjectURL(new Blob([text], { type: mime }));
|
|
470
|
+
setUrl(objectUrl);
|
|
471
|
+
return () => URL.revokeObjectURL(objectUrl);
|
|
472
|
+
}, [text, mime]);
|
|
473
|
+
if (!url) return null;
|
|
474
|
+
return /* @__PURE__ */ u3("a", { href: url, download: `body${mimeToExt(mime)}`, class: "profiler-body-download-btn profiler-text--xs", children: "Download" });
|
|
425
475
|
}
|
|
426
476
|
function HeadersTable({ headers }) {
|
|
427
477
|
const entries = Object.entries(headers);
|
|
@@ -494,8 +544,6 @@
|
|
|
494
544
|
if (category === "xml") return formatXml(body);
|
|
495
545
|
return body;
|
|
496
546
|
}
|
|
497
|
-
var PREVIEW_LIMIT = 500;
|
|
498
|
-
var CSV_ROW_LIMIT = 10;
|
|
499
547
|
function categoryMime(category) {
|
|
500
548
|
const map = {
|
|
501
549
|
json: "application/json",
|
|
@@ -506,53 +554,8 @@
|
|
|
506
554
|
};
|
|
507
555
|
return map[category] || "text/plain";
|
|
508
556
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const map = {
|
|
512
|
-
"application/json": ".json",
|
|
513
|
-
"application/ld+json": ".jsonld",
|
|
514
|
-
"application/xml": ".xml",
|
|
515
|
-
"text/xml": ".xml",
|
|
516
|
-
"text/csv": ".csv",
|
|
517
|
-
"application/csv": ".csv",
|
|
518
|
-
"text/html": ".html",
|
|
519
|
-
"text/plain": ".txt",
|
|
520
|
-
"text/css": ".css",
|
|
521
|
-
"application/javascript": ".js",
|
|
522
|
-
"text/javascript": ".js",
|
|
523
|
-
"image/svg+xml": ".svg",
|
|
524
|
-
"image/png": ".png",
|
|
525
|
-
"image/jpeg": ".jpg",
|
|
526
|
-
"image/gif": ".gif",
|
|
527
|
-
"image/webp": ".webp",
|
|
528
|
-
"image/avif": ".avif",
|
|
529
|
-
"application/pdf": ".pdf",
|
|
530
|
-
"application/zip": ".zip",
|
|
531
|
-
"application/gzip": ".gz",
|
|
532
|
-
"application/octet-stream": ".bin"
|
|
533
|
-
};
|
|
534
|
-
return map[m3] || ".bin";
|
|
535
|
-
}
|
|
536
|
-
function CopyButton({ text }) {
|
|
537
|
-
const [copied, setCopied] = d2(false);
|
|
538
|
-
function copy() {
|
|
539
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
540
|
-
setCopied(true);
|
|
541
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
return /* @__PURE__ */ u3("button", { onClick: copy, class: "profiler-body-download-btn profiler-text--xs", style: "cursor:pointer", children: copied ? "Copied!" : "Copy" });
|
|
545
|
-
}
|
|
546
|
-
function DownloadTextButton({ text, mime }) {
|
|
547
|
-
const [url, setUrl] = d2(null);
|
|
548
|
-
y2(() => {
|
|
549
|
-
const objectUrl = URL.createObjectURL(new Blob([text], { type: mime }));
|
|
550
|
-
setUrl(objectUrl);
|
|
551
|
-
return () => URL.revokeObjectURL(objectUrl);
|
|
552
|
-
}, [text, mime]);
|
|
553
|
-
if (!url) return null;
|
|
554
|
-
return /* @__PURE__ */ u3("a", { href: url, download: `body${mimeToExt(mime)}`, class: "profiler-body-download-btn profiler-text--xs", children: "Download" });
|
|
555
|
-
}
|
|
557
|
+
var PREVIEW_LIMIT = 500;
|
|
558
|
+
var CSV_ROW_LIMIT = 10;
|
|
556
559
|
function SmartBodyPreview({ body, encoding, headers }) {
|
|
557
560
|
const [expanded, setExpanded] = d2(false);
|
|
558
561
|
const [objectUrl, setObjectUrl] = d2(null);
|
|
@@ -611,7 +614,7 @@
|
|
|
611
614
|
)
|
|
612
615
|
] });
|
|
613
616
|
}
|
|
614
|
-
const formatted = formatTextBody(body, category)
|
|
617
|
+
const formatted = formatTextBody(body, category);
|
|
615
618
|
const preview = expanded ? formatted : formatted.slice(0, PREVIEW_LIMIT);
|
|
616
619
|
const truncated = formatted.length > PREVIEW_LIMIT && !expanded;
|
|
617
620
|
return /* @__PURE__ */ u3("div", { children: [
|
|
@@ -634,6 +637,98 @@
|
|
|
634
637
|
)
|
|
635
638
|
] });
|
|
636
639
|
}
|
|
640
|
+
function HttpReqRespDetail({ request, response, backtrace }) {
|
|
641
|
+
return /* @__PURE__ */ u3("div", { style: "padding:12px 4px 4px;border-top:1px solid rgba(0,0,0,0.08);margin-top:8px", children: [
|
|
642
|
+
/* @__PURE__ */ u3("div", { style: "margin-bottom:16px", children: [
|
|
643
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--sm", style: "font-weight:600;margin-bottom:8px;color:var(--profiler-muted)", children: "REQUEST" }),
|
|
644
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Headers" }),
|
|
645
|
+
/* @__PURE__ */ u3(HeadersTable, { headers: request.headers }),
|
|
646
|
+
request.params && Object.keys(request.params).length > 0 && !request.body && /* @__PURE__ */ u3(k, { children: [
|
|
647
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-top:10px;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Params" }),
|
|
648
|
+
/* @__PURE__ */ u3("pre", { class: "profiler-code profiler-text--xs", style: "margin:0", children: JSON.stringify(request.params, null, 2) })
|
|
649
|
+
] }),
|
|
650
|
+
request.body && /* @__PURE__ */ u3(k, { children: [
|
|
651
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-top:10px;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Body" }),
|
|
652
|
+
/* @__PURE__ */ u3(SmartBodyPreview, { body: request.body, encoding: request.body_encoding, headers: request.headers })
|
|
653
|
+
] })
|
|
654
|
+
] }),
|
|
655
|
+
/* @__PURE__ */ u3("div", { children: [
|
|
656
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--sm", style: "font-weight:600;margin-bottom:8px;color:var(--profiler-muted)", children: "RESPONSE" }),
|
|
657
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Headers" }),
|
|
658
|
+
/* @__PURE__ */ u3(HeadersTable, { headers: response.headers }),
|
|
659
|
+
response.body && /* @__PURE__ */ u3(k, { children: [
|
|
660
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-top:10px;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Body" }),
|
|
661
|
+
/* @__PURE__ */ u3(SmartBodyPreview, { body: response.body, encoding: response.body_encoding, headers: response.headers })
|
|
662
|
+
] })
|
|
663
|
+
] }),
|
|
664
|
+
backtrace && backtrace.length > 1 && /* @__PURE__ */ u3("div", { style: "margin-top:12px", children: [
|
|
665
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Backtrace" }),
|
|
666
|
+
backtrace.map((frame, i3) => /* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "padding:2px 0", children: frame }, i3))
|
|
667
|
+
] })
|
|
668
|
+
] });
|
|
669
|
+
}
|
|
670
|
+
function HttpCardHeader({ method, url, copyUrl: copyUrlOverride, status, duration, curlCommand, expandable, open, onToggle }) {
|
|
671
|
+
const [copiedUrl, setCopiedUrl] = d2(false);
|
|
672
|
+
const [copiedCurl, setCopiedCurl] = d2(false);
|
|
673
|
+
function handleCopyUrl(e3) {
|
|
674
|
+
e3.stopPropagation();
|
|
675
|
+
navigator.clipboard.writeText(copyUrlOverride ?? url).then(() => {
|
|
676
|
+
setCopiedUrl(true);
|
|
677
|
+
setTimeout(() => setCopiedUrl(false), 2e3);
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
function handleCopyCurl(e3) {
|
|
681
|
+
e3.stopPropagation();
|
|
682
|
+
navigator.clipboard.writeText(curlCommand).then(() => {
|
|
683
|
+
setCopiedCurl(true);
|
|
684
|
+
setTimeout(() => setCopiedCurl(false), 2e3);
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
return /* @__PURE__ */ u3(
|
|
688
|
+
"div",
|
|
689
|
+
{
|
|
690
|
+
class: "profiler-ajax-card__row",
|
|
691
|
+
style: expandable ? "cursor:pointer;user-select:none" : void 0,
|
|
692
|
+
onClick: expandable ? onToggle : void 0,
|
|
693
|
+
children: [
|
|
694
|
+
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-3", style: "min-width:0;flex:1", children: [
|
|
695
|
+
expandable && /* @__PURE__ */ u3("span", { style: "font-size:11px;color:var(--profiler-muted)", children: open ? "\u25BE" : "\u25B8" }),
|
|
696
|
+
/* @__PURE__ */ u3("span", { class: `profiler-ajax-card__method badge-${methodBadge(method)}`, children: method }),
|
|
697
|
+
/* @__PURE__ */ u3("strong", { class: "profiler-ajax-card__path", style: "word-break:break-all", children: url }),
|
|
698
|
+
/* @__PURE__ */ u3(
|
|
699
|
+
"button",
|
|
700
|
+
{
|
|
701
|
+
onClick: handleCopyUrl,
|
|
702
|
+
class: "profiler-body-download-btn profiler-text--xs",
|
|
703
|
+
style: "flex-shrink:0;cursor:pointer",
|
|
704
|
+
title: "Copy URL",
|
|
705
|
+
children: copiedUrl ? "Copied!" : "Copy URL"
|
|
706
|
+
}
|
|
707
|
+
),
|
|
708
|
+
/* @__PURE__ */ u3(
|
|
709
|
+
"button",
|
|
710
|
+
{
|
|
711
|
+
onClick: handleCopyCurl,
|
|
712
|
+
class: "profiler-body-download-btn profiler-text--xs",
|
|
713
|
+
style: "flex-shrink:0;cursor:pointer",
|
|
714
|
+
title: "Copy as cURL",
|
|
715
|
+
children: copiedCurl ? "Copied!" : "Copy as cURL"
|
|
716
|
+
}
|
|
717
|
+
)
|
|
718
|
+
] }),
|
|
719
|
+
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-2", style: "flex-shrink:0", children: [
|
|
720
|
+
/* @__PURE__ */ u3("span", { class: `badge-${statusBadge(status)}`, children: status === 0 ? "ERR" : status }),
|
|
721
|
+
/* @__PURE__ */ u3("span", { class: duration >= 500 ? "badge-error" : duration >= 100 ? "badge-warning" : "badge-success", children: [
|
|
722
|
+
duration.toFixed(2),
|
|
723
|
+
" ms"
|
|
724
|
+
] })
|
|
725
|
+
] })
|
|
726
|
+
]
|
|
727
|
+
}
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// app/assets/typescript/profiler/components/dashboard/tabs/HttpTab.tsx
|
|
637
732
|
function waterfallBarColor(status, duration) {
|
|
638
733
|
if (status === 0 || status >= 500) return "var(--profiler-error, #ef4444)";
|
|
639
734
|
if (status >= 400) return "var(--profiler-warning, #f59e0b)";
|
|
@@ -711,55 +806,21 @@
|
|
|
711
806
|
}
|
|
712
807
|
function HttpRequestDetail({ req, index, threshold }) {
|
|
713
808
|
const [open, setOpen] = d2(false);
|
|
714
|
-
const [copiedUrl, setCopiedUrl] = d2(false);
|
|
715
|
-
const [copiedCurl, setCopiedCurl] = d2(false);
|
|
716
809
|
const isError = req.status >= 400 || req.status === 0;
|
|
717
810
|
const isSlow = req.duration >= threshold;
|
|
718
811
|
const cardCls = isError ? "profiler-ajax-card--error" : isSlow ? "profiler-ajax-card--warning" : "profiler-ajax-card--success";
|
|
719
|
-
function copyUrl(e3) {
|
|
720
|
-
e3.stopPropagation();
|
|
721
|
-
navigator.clipboard.writeText(req.url).then(() => {
|
|
722
|
-
setCopiedUrl(true);
|
|
723
|
-
setTimeout(() => setCopiedUrl(false), 2e3);
|
|
724
|
-
});
|
|
725
|
-
}
|
|
726
|
-
function copyCurl() {
|
|
727
|
-
navigator.clipboard.writeText(buildCurl(req)).then(() => {
|
|
728
|
-
setCopiedCurl(true);
|
|
729
|
-
setTimeout(() => setCopiedCurl(false), 2e3);
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
812
|
return /* @__PURE__ */ u3("div", { class: `profiler-ajax-card ${cardCls}`, style: "margin-bottom:8px", children: [
|
|
733
813
|
/* @__PURE__ */ u3(
|
|
734
|
-
|
|
814
|
+
HttpCardHeader,
|
|
735
815
|
{
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
/* @__PURE__ */ u3(
|
|
745
|
-
"button",
|
|
746
|
-
{
|
|
747
|
-
onClick: copyUrl,
|
|
748
|
-
class: "profiler-body-download-btn profiler-text--xs",
|
|
749
|
-
style: "flex-shrink:0;cursor:pointer",
|
|
750
|
-
title: "Copy URL",
|
|
751
|
-
children: copiedUrl ? "Copied!" : "Copy URL"
|
|
752
|
-
}
|
|
753
|
-
)
|
|
754
|
-
] }),
|
|
755
|
-
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-2", style: "flex-shrink:0", children: [
|
|
756
|
-
/* @__PURE__ */ u3("span", { class: `badge-${statusBadge(req.status)}`, children: req.status === 0 ? "ERR" : req.status }),
|
|
757
|
-
/* @__PURE__ */ u3("span", { class: req.duration >= 500 ? "badge-error" : req.duration >= 100 ? "badge-warning" : "badge-success", children: [
|
|
758
|
-
req.duration.toFixed(2),
|
|
759
|
-
" ms"
|
|
760
|
-
] })
|
|
761
|
-
] })
|
|
762
|
-
]
|
|
816
|
+
method: req.method,
|
|
817
|
+
url: req.url,
|
|
818
|
+
status: req.status,
|
|
819
|
+
duration: req.duration,
|
|
820
|
+
curlCommand: buildCurl(req),
|
|
821
|
+
expandable: true,
|
|
822
|
+
open,
|
|
823
|
+
onToggle: () => setOpen((o3) => !o3)
|
|
763
824
|
}
|
|
764
825
|
),
|
|
765
826
|
/* @__PURE__ */ u3("div", { class: "profiler-ajax-card__row", children: [
|
|
@@ -772,31 +833,14 @@
|
|
|
772
833
|
req.backtrace && req.backtrace.length > 0 && /* @__PURE__ */ u3("span", { class: "profiler-text--xs profiler-text--muted", style: "margin-left:12px", children: req.backtrace[0] })
|
|
773
834
|
] }),
|
|
774
835
|
req.error && /* @__PURE__ */ u3("div", { class: "profiler-ajax-card__row", children: /* @__PURE__ */ u3("span", { class: "profiler-text--xs profiler-text--error", children: req.error }) }),
|
|
775
|
-
open && /* @__PURE__ */ u3(
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
/* @__PURE__ */ u3(SmartBodyPreview, { body: req.request_body, encoding: req.request_body_encoding, headers: req.request_headers || {} })
|
|
784
|
-
] })
|
|
785
|
-
] }),
|
|
786
|
-
/* @__PURE__ */ u3("div", { children: [
|
|
787
|
-
/* @__PURE__ */ u3("div", { class: "profiler-text--sm", style: "font-weight:600;margin-bottom:8px;color:var(--profiler-muted)", children: "RESPONSE" }),
|
|
788
|
-
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Headers" }),
|
|
789
|
-
/* @__PURE__ */ u3(HeadersTable, { headers: req.response_headers || {} }),
|
|
790
|
-
req.response_body && /* @__PURE__ */ u3(k, { children: [
|
|
791
|
-
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-top:10px;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Body" }),
|
|
792
|
-
/* @__PURE__ */ u3(SmartBodyPreview, { body: req.response_body, encoding: req.response_body_encoding, headers: req.response_headers || {} })
|
|
793
|
-
] })
|
|
794
|
-
] }),
|
|
795
|
-
req.backtrace && req.backtrace.length > 1 && /* @__PURE__ */ u3("div", { style: "margin-top:12px", children: [
|
|
796
|
-
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Backtrace" }),
|
|
797
|
-
req.backtrace.map((frame, i3) => /* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "padding:2px 0", children: frame }, i3))
|
|
798
|
-
] })
|
|
799
|
-
] })
|
|
836
|
+
open && /* @__PURE__ */ u3(
|
|
837
|
+
HttpReqRespDetail,
|
|
838
|
+
{
|
|
839
|
+
request: { headers: req.request_headers || {}, body: req.request_body, body_encoding: req.request_body_encoding },
|
|
840
|
+
response: { headers: req.response_headers || {}, body: req.response_body, body_encoding: req.response_body_encoding },
|
|
841
|
+
backtrace: req.backtrace
|
|
842
|
+
}
|
|
843
|
+
)
|
|
800
844
|
] });
|
|
801
845
|
}
|
|
802
846
|
function HttpTab({ httpData }) {
|
|
@@ -2100,107 +2144,43 @@
|
|
|
2100
2144
|
return parts.join(" \\\n");
|
|
2101
2145
|
}
|
|
2102
2146
|
function RequestTab({ profile }) {
|
|
2103
|
-
const [copied, setCopied] = d2(false);
|
|
2104
|
-
const curl = buildCurl2(profile);
|
|
2105
2147
|
const routeData = profile.collectors_data?.request ?? {};
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", children: "Status" }),
|
|
2125
|
-
/* @__PURE__ */ u3("td", { children: profile.status })
|
|
2126
|
-
] }),
|
|
2127
|
-
/* @__PURE__ */ u3("tr", { children: [
|
|
2128
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", children: "Duration" }),
|
|
2129
|
-
/* @__PURE__ */ u3("td", { children: [
|
|
2130
|
-
profile.duration.toFixed(2),
|
|
2131
|
-
" ms"
|
|
2132
|
-
] })
|
|
2133
|
-
] }),
|
|
2134
|
-
routeData.controller_action && /* @__PURE__ */ u3("tr", { children: [
|
|
2135
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", children: "Controller#Action" }),
|
|
2136
|
-
/* @__PURE__ */ u3("td", { class: "profiler-text--mono profiler-text--xs", children: routeData.controller_action })
|
|
2137
|
-
] }),
|
|
2138
|
-
routeData.route_name && /* @__PURE__ */ u3("tr", { children: [
|
|
2139
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", children: "Route Name" }),
|
|
2140
|
-
/* @__PURE__ */ u3("td", { class: "profiler-text--mono profiler-text--xs", children: routeData.route_name })
|
|
2141
|
-
] }),
|
|
2142
|
-
routeData.route_pattern && /* @__PURE__ */ u3("tr", { children: [
|
|
2143
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", children: "Route Pattern" }),
|
|
2144
|
-
/* @__PURE__ */ u3("td", { class: "profiler-text--mono profiler-text--xs", children: routeData.route_pattern })
|
|
2145
|
-
] }),
|
|
2146
|
-
routeData.route_params && Object.keys(routeData.route_params).length > 0 && /* @__PURE__ */ u3("tr", { children: [
|
|
2147
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", children: "Route Params" }),
|
|
2148
|
-
/* @__PURE__ */ u3("td", { class: "profiler-text--mono profiler-text--xs", children: Object.entries(routeData.route_params).map(([k3, v3]) => `${k3}: ${v3}`).join(", ") })
|
|
2148
|
+
const hasParams = profile.params && Object.keys(profile.params).length > 0;
|
|
2149
|
+
return /* @__PURE__ */ u3("div", { class: "profiler-ajax-card profiler-ajax-card--success", style: "margin-bottom:8px;background:var(--profiler-bg-elevated);transform:translateX(3px);box-shadow:var(--profiler-shadow-sm);transition:none", children: [
|
|
2150
|
+
/* @__PURE__ */ u3(
|
|
2151
|
+
HttpCardHeader,
|
|
2152
|
+
{
|
|
2153
|
+
method: profile.method,
|
|
2154
|
+
url: profile.path,
|
|
2155
|
+
copyUrl: `http://localhost:3000${profile.path}`,
|
|
2156
|
+
status: profile.status,
|
|
2157
|
+
duration: profile.duration,
|
|
2158
|
+
curlCommand: buildCurl2(profile)
|
|
2159
|
+
}
|
|
2160
|
+
),
|
|
2161
|
+
(routeData.controller_action || routeData.route_pattern) && /* @__PURE__ */ u3("div", { class: "profiler-ajax-card__row", children: [
|
|
2162
|
+
routeData.controller_action && /* @__PURE__ */ u3("span", { class: "profiler-text--xs profiler-text--muted", style: "margin-right:16px", children: routeData.controller_action }),
|
|
2163
|
+
routeData.route_pattern && /* @__PURE__ */ u3("span", { class: "profiler-text--xs profiler-text--muted", style: "font-family:monospace", children: [
|
|
2164
|
+
routeData.route_name ? `${routeData.route_name} \xB7 ` : "",
|
|
2165
|
+
routeData.route_pattern
|
|
2149
2166
|
] })
|
|
2150
2167
|
] }),
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
] }, k3)) })
|
|
2157
|
-
] }),
|
|
2158
|
-
profile.params && Object.keys(profile.params).length > 0 && /* @__PURE__ */ u3(k, { children: [
|
|
2159
|
-
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Request Params" }),
|
|
2160
|
-
/* @__PURE__ */ u3("pre", { class: "profiler-code profiler-text--xs", children: JSON.stringify(profile.params, null, 2) })
|
|
2161
|
-
] }),
|
|
2162
|
-
profile.request_body && /* @__PURE__ */ u3(k, { children: [
|
|
2163
|
-
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Request Body" }),
|
|
2164
|
-
/* @__PURE__ */ u3(
|
|
2165
|
-
SmartBodyPreview,
|
|
2166
|
-
{
|
|
2168
|
+
/* @__PURE__ */ u3(
|
|
2169
|
+
HttpReqRespDetail,
|
|
2170
|
+
{
|
|
2171
|
+
request: {
|
|
2172
|
+
headers: profile.headers ?? {},
|
|
2167
2173
|
body: profile.request_body,
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
}
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
profile.response_headers && Object.keys(profile.response_headers).length > 0 && /* @__PURE__ */ u3(k, { children: [
|
|
2174
|
-
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Response Headers" }),
|
|
2175
|
-
/* @__PURE__ */ u3("table", { children: Object.entries(profile.response_headers).map(([k3, v3]) => /* @__PURE__ */ u3("tr", { children: [
|
|
2176
|
-
/* @__PURE__ */ u3("th", { class: "profiler-text--sm", style: "width: 200px;", children: k3 }),
|
|
2177
|
-
/* @__PURE__ */ u3("td", { class: "profiler-text--mono profiler-text--xs", children: String(v3) })
|
|
2178
|
-
] }, k3)) })
|
|
2179
|
-
] }),
|
|
2180
|
-
profile.response_body && /* @__PURE__ */ u3(k, { children: [
|
|
2181
|
-
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Response Body" }),
|
|
2182
|
-
/* @__PURE__ */ u3(
|
|
2183
|
-
SmartBodyPreview,
|
|
2184
|
-
{
|
|
2174
|
+
body_encoding: profile.request_body_encoding,
|
|
2175
|
+
params: hasParams ? profile.params : void 0
|
|
2176
|
+
},
|
|
2177
|
+
response: {
|
|
2178
|
+
headers: profile.response_headers ?? {},
|
|
2185
2179
|
body: profile.response_body,
|
|
2186
|
-
|
|
2187
|
-
headers: profile.response_headers ?? {}
|
|
2180
|
+
body_encoding: profile.response_body_encoding
|
|
2188
2181
|
}
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Curl Command" }),
|
|
2192
|
-
/* @__PURE__ */ u3("div", { style: "position: relative;", children: [
|
|
2193
|
-
/* @__PURE__ */ u3(
|
|
2194
|
-
"button",
|
|
2195
|
-
{
|
|
2196
|
-
onClick: copyToClipboard,
|
|
2197
|
-
class: "profiler-body-download-btn",
|
|
2198
|
-
style: "position: absolute; top: 8px; right: 8px; z-index: 1;",
|
|
2199
|
-
children: copied ? "Copied!" : "Copy"
|
|
2200
|
-
}
|
|
2201
|
-
),
|
|
2202
|
-
/* @__PURE__ */ u3("pre", { class: "profiler-code profiler-text--xs", style: "padding-right: 80px;", children: curl })
|
|
2203
|
-
] })
|
|
2182
|
+
}
|
|
2183
|
+
)
|
|
2204
2184
|
] });
|
|
2205
2185
|
}
|
|
2206
2186
|
|
|
@@ -3081,12 +3061,6 @@
|
|
|
3081
3061
|
custom: "Custom",
|
|
3082
3062
|
method: "Method"
|
|
3083
3063
|
};
|
|
3084
|
-
function formatBytes3(bytes) {
|
|
3085
|
-
if (bytes < 0) return "\u2014";
|
|
3086
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
3087
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
3088
|
-
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
3089
|
-
}
|
|
3090
3064
|
function FlameGraphTab({ flamegraphData, perfData, functionProfileData }) {
|
|
3091
3065
|
const canvasRef = A2(null);
|
|
3092
3066
|
const containerRef = A2(null);
|
|
@@ -3592,7 +3566,7 @@
|
|
|
3592
3566
|
] }),
|
|
3593
3567
|
showMemory && /* @__PURE__ */ u3("div", { class: "stat-item", children: [
|
|
3594
3568
|
/* @__PURE__ */ u3("span", { class: "stat-label", children: "Memory" }),
|
|
3595
|
-
/* @__PURE__ */ u3("span", { class: "stat-value", children:
|
|
3569
|
+
/* @__PURE__ */ u3("span", { class: "stat-value", children: formatBytes(data.total_memory_bytes ?? 0) })
|
|
3596
3570
|
] })
|
|
3597
3571
|
] }),
|
|
3598
3572
|
rootCalls.length > 0 && /* @__PURE__ */ u3(
|
|
@@ -3698,7 +3672,7 @@
|
|
|
3698
3672
|
" ",
|
|
3699
3673
|
/* @__PURE__ */ u3("small", { children: "obj" })
|
|
3700
3674
|
] }),
|
|
3701
|
-
showMemory && /* @__PURE__ */ u3("td", { class: "profiler-text--right profiler-text--muted", children:
|
|
3675
|
+
showMemory && /* @__PURE__ */ u3("td", { class: "profiler-text--right profiler-text--muted", children: formatBytes(fn.memory_bytes) })
|
|
3702
3676
|
]
|
|
3703
3677
|
},
|
|
3704
3678
|
i3
|
|
@@ -3835,15 +3809,6 @@
|
|
|
3835
3809
|
}
|
|
3836
3810
|
|
|
3837
3811
|
// app/assets/typescript/profiler/components/dashboard/tabs/AjaxTab.tsx
|
|
3838
|
-
function methodBadge2(method) {
|
|
3839
|
-
const map = { GET: "info", POST: "success", PUT: "warning", PATCH: "warning", DELETE: "error" };
|
|
3840
|
-
return map[method] || "default";
|
|
3841
|
-
}
|
|
3842
|
-
function statusBadge2(status) {
|
|
3843
|
-
if (status >= 200 && status < 300) return "success";
|
|
3844
|
-
if (status >= 400) return "error";
|
|
3845
|
-
return "warning";
|
|
3846
|
-
}
|
|
3847
3812
|
function AjaxTab({ ajaxData }) {
|
|
3848
3813
|
if (!ajaxData?.requests?.length) {
|
|
3849
3814
|
return /* @__PURE__ */ u3("div", { class: "profiler-empty", children: [
|
|
@@ -3879,7 +3844,7 @@
|
|
|
3879
3844
|
/* @__PURE__ */ u3("div", { class: "profiler-panel profiler-panel--sm", children: [
|
|
3880
3845
|
/* @__PURE__ */ u3("h3", { class: "profiler-text--sm profiler-text--muted profiler-text--uppercase profiler-mb-3", children: "By Method" }),
|
|
3881
3846
|
Object.entries(ajaxData.by_method).map(([method, count]) => /* @__PURE__ */ u3("div", { class: "profiler-kv-row", children: [
|
|
3882
|
-
/* @__PURE__ */ u3("span", { class: `badge-${
|
|
3847
|
+
/* @__PURE__ */ u3("span", { class: `badge-${methodBadge(method)}`, children: method }),
|
|
3883
3848
|
/* @__PURE__ */ u3("strong", { children: count })
|
|
3884
3849
|
] }, method))
|
|
3885
3850
|
] }),
|
|
@@ -3895,11 +3860,11 @@
|
|
|
3895
3860
|
ajaxData.requests.map((req, index) => /* @__PURE__ */ u3("div", { class: `profiler-ajax-card profiler-ajax-card--${req.status >= 200 && req.status < 300 ? "success" : "error"}`, children: [
|
|
3896
3861
|
/* @__PURE__ */ u3("div", { class: "profiler-ajax-card__row", children: [
|
|
3897
3862
|
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-3", children: [
|
|
3898
|
-
/* @__PURE__ */ u3("span", { class: `profiler-ajax-card__method badge-${
|
|
3863
|
+
/* @__PURE__ */ u3("span", { class: `profiler-ajax-card__method badge-${methodBadge(req.method)}`, children: req.method }),
|
|
3899
3864
|
/* @__PURE__ */ u3("strong", { class: "profiler-ajax-card__path", children: req.path })
|
|
3900
3865
|
] }),
|
|
3901
3866
|
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-2", children: [
|
|
3902
|
-
/* @__PURE__ */ u3("span", { class: `badge-${
|
|
3867
|
+
/* @__PURE__ */ u3("span", { class: `badge-${statusBadge(req.status)}`, children: req.status }),
|
|
3903
3868
|
/* @__PURE__ */ u3("span", { class: req.duration >= 500 ? "badge-error" : req.duration >= 100 ? "badge-warning" : "badge-success", children: [
|
|
3904
3869
|
req.duration.toFixed(2),
|
|
3905
3870
|
" ms"
|
|
@@ -22,6 +22,9 @@ module Profiler
|
|
|
22
22
|
|
|
23
23
|
url = build_url(host, port, req.path, use_ssl?)
|
|
24
24
|
req_body = req.body.to_s
|
|
25
|
+
# Fallback: body may be passed as the 2nd argument and only applied
|
|
26
|
+
# to req inside super via req.set_body_internal(body)
|
|
27
|
+
req_body = body.to_s if req_body.empty? && body
|
|
25
28
|
req_headers = req.to_hash.transform_values { |v| v.join(", ") }
|
|
26
29
|
request_id = SecureRandom.hex(8)
|
|
27
30
|
started_at = Time.now.iso8601(3)
|
data/lib/profiler/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-profiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sébastien Duplessy
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|