rails-profiler 0.12.0 → 0.13.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.css +46 -0
- data/app/assets/builds/profiler.js +316 -59
- data/lib/profiler/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e968972f60bc4764a4b61648179a5bf618f2d1f2a68b9d43f724c4e14f3c2794
|
|
4
|
+
data.tar.gz: 70536b9f1ed2c5d04b698657ae9f948abad17cbc9fa202125311092b77d94005
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e9bb63e8ac85773680d3f83daff09b18a8c440e5272bac926e10d1dd30142969b5442168965711e40eddd9882c05ac592323f0a46410fa6390a3f70064e8521
|
|
7
|
+
data.tar.gz: 16bc718c65e6fa50493e9cdc1cc87ae51264f1873cb68baac0db52915a22eb8c383c52523941ab7d2f7d14f86fad2cb6996b74e4e5c175fa7a4e5da3a75272cb
|
|
@@ -1957,6 +1957,52 @@ a.profiler-toolbar-item.profiler-text--warning::after {
|
|
|
1957
1957
|
opacity: 1;
|
|
1958
1958
|
}
|
|
1959
1959
|
|
|
1960
|
+
@keyframes profiler-shimmer {
|
|
1961
|
+
0% {
|
|
1962
|
+
background-position: 200% 0;
|
|
1963
|
+
}
|
|
1964
|
+
100% {
|
|
1965
|
+
background-position: -200% 0;
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
.profiler-skeleton__row {
|
|
1969
|
+
display: flex;
|
|
1970
|
+
align-items: center;
|
|
1971
|
+
gap: 20px;
|
|
1972
|
+
padding: 14px 20px;
|
|
1973
|
+
border-bottom: 1px solid var(--profiler-border);
|
|
1974
|
+
}
|
|
1975
|
+
.profiler-skeleton__row:last-child {
|
|
1976
|
+
border-bottom: none;
|
|
1977
|
+
}
|
|
1978
|
+
.profiler-skeleton__cell {
|
|
1979
|
+
height: 12px;
|
|
1980
|
+
border-radius: 3px;
|
|
1981
|
+
background: linear-gradient(90deg, var(--profiler-bg-lighter, #e5e7eb) 25%, var(--profiler-bg-light, #f3f4f6) 50%, var(--profiler-bg-lighter, #e5e7eb) 75%);
|
|
1982
|
+
background-size: 200% 100%;
|
|
1983
|
+
animation: profiler-shimmer 1.4s infinite linear;
|
|
1984
|
+
}
|
|
1985
|
+
.profiler-skeleton__cell--xs {
|
|
1986
|
+
width: 40px;
|
|
1987
|
+
flex-shrink: 0;
|
|
1988
|
+
}
|
|
1989
|
+
.profiler-skeleton__cell--sm {
|
|
1990
|
+
width: 72px;
|
|
1991
|
+
flex-shrink: 0;
|
|
1992
|
+
}
|
|
1993
|
+
.profiler-skeleton__cell--md {
|
|
1994
|
+
width: 120px;
|
|
1995
|
+
flex-shrink: 0;
|
|
1996
|
+
}
|
|
1997
|
+
.profiler-skeleton__cell--lg {
|
|
1998
|
+
width: 180px;
|
|
1999
|
+
flex-shrink: 0;
|
|
2000
|
+
}
|
|
2001
|
+
.profiler-skeleton__cell--flex {
|
|
2002
|
+
flex: 1;
|
|
2003
|
+
min-width: 60px;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
1960
2006
|
.profiler-timeline {
|
|
1961
2007
|
margin: 24px 0;
|
|
1962
2008
|
padding: 24px;
|
|
@@ -496,6 +496,63 @@
|
|
|
496
496
|
}
|
|
497
497
|
var PREVIEW_LIMIT = 500;
|
|
498
498
|
var CSV_ROW_LIMIT = 10;
|
|
499
|
+
function categoryMime(category) {
|
|
500
|
+
const map = {
|
|
501
|
+
json: "application/json",
|
|
502
|
+
xml: "application/xml",
|
|
503
|
+
csv: "text/csv",
|
|
504
|
+
html: "text/html",
|
|
505
|
+
svg: "image/svg+xml"
|
|
506
|
+
};
|
|
507
|
+
return map[category] || "text/plain";
|
|
508
|
+
}
|
|
509
|
+
function mimeToExt(mime) {
|
|
510
|
+
const m3 = mime.split(";")[0].trim().toLowerCase();
|
|
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
|
+
}
|
|
499
556
|
function SmartBodyPreview({ body, encoding, headers }) {
|
|
500
557
|
const [expanded, setExpanded] = d2(false);
|
|
501
558
|
const [objectUrl, setObjectUrl] = d2(null);
|
|
@@ -513,17 +570,21 @@
|
|
|
513
570
|
if (!body) return /* @__PURE__ */ u3("span", { class: "profiler-text--muted profiler-text--xs", children: "empty" });
|
|
514
571
|
if (encoding === "base64") {
|
|
515
572
|
const mime = Object.entries(headers).find(([k3]) => k3.toLowerCase() === "content-type")?.[1]?.split(";")[0].trim() || "application/octet-stream";
|
|
516
|
-
const filename = mime
|
|
573
|
+
const filename = `body${mimeToExt(mime)}`;
|
|
517
574
|
return /* @__PURE__ */ u3("div", { class: "profiler-body-binary", children: [
|
|
518
575
|
objectUrl && (category === "image" || category === "svg") && /* @__PURE__ */ u3("img", { src: objectUrl, alt: "response preview", style: "max-width:100%;max-height:300px;display:block;margin-bottom:8px;border-radius:4px;border:1px solid var(--profiler-border)" }),
|
|
519
576
|
objectUrl && category === "pdf" && /* @__PURE__ */ u3("iframe", { src: objectUrl, class: "profiler-body-preview-frame", title: "PDF preview" }),
|
|
520
|
-
|
|
521
|
-
"
|
|
522
|
-
|
|
577
|
+
/* @__PURE__ */ u3("div", { style: "display:flex;gap:8px;margin-top:4px", children: [
|
|
578
|
+
objectUrl && /* @__PURE__ */ u3("a", { href: objectUrl, download: filename, class: "profiler-body-download-btn profiler-text--xs", children: [
|
|
579
|
+
"Download ",
|
|
580
|
+
mime
|
|
581
|
+
] }),
|
|
582
|
+
/* @__PURE__ */ u3(CopyButton, { text: body })
|
|
523
583
|
] }),
|
|
524
584
|
!objectUrl && /* @__PURE__ */ u3("span", { class: "profiler-text--muted profiler-text--xs", children: "Loading preview\u2026" })
|
|
525
585
|
] });
|
|
526
586
|
}
|
|
587
|
+
const actualMime = Object.entries(headers).find(([k3]) => k3.toLowerCase() === "content-type")?.[1]?.split(";")[0].trim() || categoryMime(category);
|
|
527
588
|
if (category === "csv") {
|
|
528
589
|
const rows = parseCsv(body);
|
|
529
590
|
const header = rows[0] || [];
|
|
@@ -531,6 +592,10 @@
|
|
|
531
592
|
const visible = expanded ? dataRows : dataRows.slice(0, CSV_ROW_LIMIT);
|
|
532
593
|
const hasMore = dataRows.length > CSV_ROW_LIMIT;
|
|
533
594
|
return /* @__PURE__ */ u3("div", { children: [
|
|
595
|
+
/* @__PURE__ */ u3("div", { style: "display:flex;gap:8px;margin-bottom:6px", children: [
|
|
596
|
+
/* @__PURE__ */ u3(CopyButton, { text: body }),
|
|
597
|
+
/* @__PURE__ */ u3(DownloadTextButton, { text: body, mime: actualMime })
|
|
598
|
+
] }),
|
|
534
599
|
/* @__PURE__ */ u3("div", { style: "overflow-x:auto", children: /* @__PURE__ */ u3("table", { class: "profiler-body-csv", children: [
|
|
535
600
|
/* @__PURE__ */ u3("thead", { children: /* @__PURE__ */ u3("tr", { children: header.map((h3, i3) => /* @__PURE__ */ u3("th", { children: h3 }, i3)) }) }),
|
|
536
601
|
/* @__PURE__ */ u3("tbody", { children: visible.map((row, i3) => /* @__PURE__ */ u3("tr", { children: row.map((cell, j3) => /* @__PURE__ */ u3("td", { children: cell }, j3)) }, i3)) })
|
|
@@ -550,6 +615,10 @@
|
|
|
550
615
|
const preview = expanded ? formatted : formatted.slice(0, PREVIEW_LIMIT);
|
|
551
616
|
const truncated = formatted.length > PREVIEW_LIMIT && !expanded;
|
|
552
617
|
return /* @__PURE__ */ u3("div", { children: [
|
|
618
|
+
/* @__PURE__ */ u3("div", { style: "display:flex;gap:8px;margin-bottom:6px", children: [
|
|
619
|
+
/* @__PURE__ */ u3(CopyButton, { text: formatted }),
|
|
620
|
+
/* @__PURE__ */ u3(DownloadTextButton, { text: formatted, mime: actualMime })
|
|
621
|
+
] }),
|
|
553
622
|
/* @__PURE__ */ u3("pre", { class: "profiler-code profiler-text--xs", style: "white-space:pre-wrap;word-break:break-all;margin:0", children: [
|
|
554
623
|
preview,
|
|
555
624
|
truncated ? "\u2026" : ""
|
|
@@ -565,11 +634,101 @@
|
|
|
565
634
|
)
|
|
566
635
|
] });
|
|
567
636
|
}
|
|
637
|
+
function waterfallBarColor(status, duration) {
|
|
638
|
+
if (status === 0 || status >= 500) return "var(--profiler-error, #ef4444)";
|
|
639
|
+
if (status >= 400) return "var(--profiler-warning, #f59e0b)";
|
|
640
|
+
if (duration >= 500) return "var(--profiler-warning, #f59e0b)";
|
|
641
|
+
return "var(--profiler-success, #22c55e)";
|
|
642
|
+
}
|
|
643
|
+
function WaterfallView({ requests }) {
|
|
644
|
+
const timed = requests.filter((r3) => r3.started_at).map((r3) => ({ ...r3, startMs: new Date(r3.started_at).getTime() }));
|
|
645
|
+
if (!timed.length) {
|
|
646
|
+
return /* @__PURE__ */ u3("div", { class: "profiler-text--muted profiler-text--sm", children: "No timing data available (started_at missing)." });
|
|
647
|
+
}
|
|
648
|
+
const minStart = Math.min(...timed.map((r3) => r3.startMs));
|
|
649
|
+
const maxEnd = Math.max(...timed.map((r3) => r3.startMs + r3.duration));
|
|
650
|
+
const totalSpan = maxEnd - minStart || 1;
|
|
651
|
+
const ticks = [0, 0.25, 0.5, 0.75, 1].map((f4) => ({
|
|
652
|
+
pct: f4 * 100,
|
|
653
|
+
label: `${Math.round(f4 * totalSpan)}ms`
|
|
654
|
+
}));
|
|
655
|
+
return /* @__PURE__ */ u3("div", { children: [
|
|
656
|
+
/* @__PURE__ */ u3("div", { style: "display:flex;position:relative;margin-left:200px;margin-bottom:4px;height:16px", children: ticks.map((t3) => /* @__PURE__ */ u3("div", { style: `position:absolute;left:${t3.pct}%;font-size:10px;color:var(--profiler-text-muted);transform:translateX(-50%)`, children: t3.label }, t3.pct)) }),
|
|
657
|
+
/* @__PURE__ */ u3("div", { style: "position:relative", children: [
|
|
658
|
+
ticks.map((t3) => /* @__PURE__ */ u3("div", { style: `position:absolute;left:calc(200px + ${t3.pct}% * (100% - 200px) / 100);top:0;bottom:0;width:1px;background:var(--profiler-border);opacity:0.5;pointer-events:none` }, t3.pct)),
|
|
659
|
+
timed.map((req, i3) => {
|
|
660
|
+
const left = (req.startMs - minStart) / totalSpan * 100;
|
|
661
|
+
const width = Math.max(req.duration / totalSpan * 100, 0.5);
|
|
662
|
+
const path = req.url.replace(/^https?:\/\/[^/]+/, "") || req.url;
|
|
663
|
+
const color = waterfallBarColor(req.status, req.duration);
|
|
664
|
+
return /* @__PURE__ */ u3("div", { style: "display:flex;align-items:center;gap:0;margin-bottom:3px;height:22px", children: [
|
|
665
|
+
/* @__PURE__ */ u3(
|
|
666
|
+
"div",
|
|
667
|
+
{
|
|
668
|
+
title: req.url,
|
|
669
|
+
style: "width:200px;flex-shrink:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;color:var(--profiler-text-muted);padding-right:8px;text-align:right",
|
|
670
|
+
children: [
|
|
671
|
+
/* @__PURE__ */ u3("span", { style: `font-size:10px;font-weight:600;margin-right:4px;color:${color}`, children: req.method }),
|
|
672
|
+
path
|
|
673
|
+
]
|
|
674
|
+
}
|
|
675
|
+
),
|
|
676
|
+
/* @__PURE__ */ u3("div", { style: "flex:1;position:relative;height:14px;background:var(--profiler-bg-lighter);border-radius:2px", children: /* @__PURE__ */ u3(
|
|
677
|
+
"div",
|
|
678
|
+
{
|
|
679
|
+
style: `position:absolute;left:${left}%;width:${width}%;min-width:2px;height:100%;background:${color};border-radius:2px;opacity:0.85`,
|
|
680
|
+
title: `${req.duration.toFixed(2)}ms \xB7 ${req.status || "ERR"}`
|
|
681
|
+
}
|
|
682
|
+
) }),
|
|
683
|
+
/* @__PURE__ */ u3("div", { style: "width:52px;text-align:right;font-size:11px;color:var(--profiler-text-muted);padding-left:6px;flex-shrink:0", children: [
|
|
684
|
+
req.duration.toFixed(0),
|
|
685
|
+
"ms"
|
|
686
|
+
] })
|
|
687
|
+
] }, i3);
|
|
688
|
+
})
|
|
689
|
+
] }),
|
|
690
|
+
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-top:8px", children: [
|
|
691
|
+
"Total span: ",
|
|
692
|
+
totalSpan.toFixed(0),
|
|
693
|
+
"ms \xB7 ",
|
|
694
|
+
timed.length,
|
|
695
|
+
" request",
|
|
696
|
+
timed.length !== 1 ? "s" : ""
|
|
697
|
+
] })
|
|
698
|
+
] });
|
|
699
|
+
}
|
|
700
|
+
function buildCurl(req) {
|
|
701
|
+
const parts = [`curl -X ${req.method}`];
|
|
702
|
+
const headers = req.request_headers || {};
|
|
703
|
+
for (const [k3, v3] of Object.entries(headers)) {
|
|
704
|
+
parts.push(` -H ${JSON.stringify(`${k3}: ${v3}`)}`);
|
|
705
|
+
}
|
|
706
|
+
if (req.request_body && req.request_body_encoding !== "base64") {
|
|
707
|
+
parts.push(` -d ${JSON.stringify(req.request_body)}`);
|
|
708
|
+
}
|
|
709
|
+
parts.push(` ${JSON.stringify(req.url)}`);
|
|
710
|
+
return parts.join(" \\\n");
|
|
711
|
+
}
|
|
568
712
|
function HttpRequestDetail({ req, index, threshold }) {
|
|
569
713
|
const [open, setOpen] = d2(false);
|
|
714
|
+
const [copiedUrl, setCopiedUrl] = d2(false);
|
|
715
|
+
const [copiedCurl, setCopiedCurl] = d2(false);
|
|
570
716
|
const isError = req.status >= 400 || req.status === 0;
|
|
571
717
|
const isSlow = req.duration >= threshold;
|
|
572
718
|
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
|
+
}
|
|
573
732
|
return /* @__PURE__ */ u3("div", { class: `profiler-ajax-card ${cardCls}`, style: "margin-bottom:8px", children: [
|
|
574
733
|
/* @__PURE__ */ u3(
|
|
575
734
|
"div",
|
|
@@ -578,10 +737,20 @@
|
|
|
578
737
|
style: "cursor:pointer;user-select:none",
|
|
579
738
|
onClick: () => setOpen((o3) => !o3),
|
|
580
739
|
children: [
|
|
581
|
-
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-3", children: [
|
|
740
|
+
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-3", style: "min-width:0;flex:1", children: [
|
|
582
741
|
/* @__PURE__ */ u3("span", { style: "font-size:11px;color:var(--profiler-muted)", children: open ? "\u25BE" : "\u25B8" }),
|
|
583
742
|
/* @__PURE__ */ u3("span", { class: `profiler-ajax-card__method badge-${methodBadge(req.method)}`, children: req.method }),
|
|
584
|
-
/* @__PURE__ */ u3("strong", { class: "profiler-ajax-card__path", style: "word-break:break-all", children: req.url })
|
|
743
|
+
/* @__PURE__ */ u3("strong", { class: "profiler-ajax-card__path", style: "word-break:break-all", children: req.url }),
|
|
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
|
+
)
|
|
585
754
|
] }),
|
|
586
755
|
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-2", style: "flex-shrink:0", children: [
|
|
587
756
|
/* @__PURE__ */ u3("span", { class: `badge-${statusBadge(req.status)}`, children: req.status === 0 ? "ERR" : req.status }),
|
|
@@ -604,6 +773,7 @@
|
|
|
604
773
|
] }),
|
|
605
774
|
req.error && /* @__PURE__ */ u3("div", { class: "profiler-ajax-card__row", children: /* @__PURE__ */ u3("span", { class: "profiler-text--xs profiler-text--error", children: req.error }) }),
|
|
606
775
|
open && /* @__PURE__ */ u3("div", { style: "padding:12px 4px 4px;border-top:1px solid rgba(0,0,0,0.08);margin-top:8px", children: [
|
|
776
|
+
/* @__PURE__ */ u3("div", { style: "margin-bottom:12px", children: /* @__PURE__ */ u3("button", { onClick: copyCurl, class: "profiler-body-download-btn profiler-text--xs", style: "cursor:pointer", children: copiedCurl ? "Copied!" : "Copy as cURL" }) }),
|
|
607
777
|
/* @__PURE__ */ u3("div", { style: "margin-bottom:16px", children: [
|
|
608
778
|
/* @__PURE__ */ u3("div", { class: "profiler-text--sm", style: "font-weight:600;margin-bottom:8px;color:var(--profiler-muted)", children: "REQUEST" }),
|
|
609
779
|
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted", style: "margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px", children: "Headers" }),
|
|
@@ -688,13 +858,19 @@
|
|
|
688
858
|
] })
|
|
689
859
|
] }),
|
|
690
860
|
/* @__PURE__ */ u3("h3", { class: "profiler-text--lg profiler-mb-3", children: "Requests" }),
|
|
691
|
-
/* @__PURE__ */ u3(
|
|
692
|
-
|
|
861
|
+
/* @__PURE__ */ u3(WaterfallView, { requests: httpData.requests }),
|
|
862
|
+
/* @__PURE__ */ u3("div", { style: "margin-top:16px", children: [
|
|
863
|
+
/* @__PURE__ */ u3("p", { class: "profiler-text--xs profiler-text--muted profiler-mb-3", children: "Click a request to expand headers and body." }),
|
|
864
|
+
httpData.requests.map((req, index) => /* @__PURE__ */ u3(HttpRequestDetail, { req, index, threshold }, index))
|
|
865
|
+
] })
|
|
693
866
|
] });
|
|
694
867
|
}
|
|
695
868
|
|
|
696
869
|
// app/assets/typescript/profiler/components/ProfileList.tsx
|
|
697
870
|
var BASE = "/_profiler";
|
|
871
|
+
function TableSkeleton({ cols, rows = 6 }) {
|
|
872
|
+
return /* @__PURE__ */ u3("div", { children: Array.from({ length: rows }).map((_2, i3) => /* @__PURE__ */ u3("div", { class: "profiler-skeleton__row", children: cols.map((size, j3) => /* @__PURE__ */ u3("div", { class: `profiler-skeleton__cell profiler-skeleton__cell--${size}` }, j3)) }, i3)) });
|
|
873
|
+
}
|
|
698
874
|
function methodClass(method) {
|
|
699
875
|
const map = { GET: "badge-info", POST: "badge-success", PUT: "badge-warning", PATCH: "badge-warning", DELETE: "badge-error" };
|
|
700
876
|
return map[method] || "badge-default";
|
|
@@ -734,7 +910,7 @@
|
|
|
734
910
|
const col = params.get("sort");
|
|
735
911
|
const dir = params.get("dir");
|
|
736
912
|
return {
|
|
737
|
-
col: col === "duration" || col === "memory" || col === "status" || col === "queries" ? col : null,
|
|
913
|
+
col: col === "date" || col === "duration" || col === "memory" || col === "status" || col === "queries" ? col : null,
|
|
738
914
|
dir: dir === "desc" ? "desc" : "asc"
|
|
739
915
|
};
|
|
740
916
|
};
|
|
@@ -766,6 +942,7 @@
|
|
|
766
942
|
return PRESETS.some((pr) => pr.key === p3) ? p3 : "";
|
|
767
943
|
});
|
|
768
944
|
const [httpSort, setHttpSort] = d2(initialSort);
|
|
945
|
+
const [jobSort, setJobSort] = d2({ col: null, dir: "asc" });
|
|
769
946
|
const [jobSearch, setJobSearch] = d2("");
|
|
770
947
|
const [jobStatus, setJobStatus] = d2("");
|
|
771
948
|
const [jobDuration, setJobDuration] = d2("");
|
|
@@ -808,6 +985,11 @@
|
|
|
808
985
|
(prev) => prev.col === col ? { col, dir: prev.dir === "asc" ? "desc" : "asc" } : { col, dir: "asc" }
|
|
809
986
|
);
|
|
810
987
|
};
|
|
988
|
+
const toggleJobSort = (col) => {
|
|
989
|
+
setJobSort(
|
|
990
|
+
(prev) => prev.col === col ? { col, dir: prev.dir === "asc" ? "desc" : "asc" } : { col, dir: "asc" }
|
|
991
|
+
);
|
|
992
|
+
};
|
|
811
993
|
const togglePreset = (key) => {
|
|
812
994
|
setHttpPreset((prev) => prev === key ? "" : key);
|
|
813
995
|
};
|
|
@@ -873,6 +1055,7 @@
|
|
|
873
1055
|
setJobSearch("");
|
|
874
1056
|
setJobStatus("");
|
|
875
1057
|
setJobDuration("");
|
|
1058
|
+
setJobSort({ col: null, dir: "asc" });
|
|
876
1059
|
setOutboundSearch("");
|
|
877
1060
|
setOutboundMethod("");
|
|
878
1061
|
setOutboundStatus("");
|
|
@@ -955,6 +1138,10 @@
|
|
|
955
1138
|
return true;
|
|
956
1139
|
});
|
|
957
1140
|
const sortedProfiles = httpSort.col ? [...filteredProfiles].sort((a3, b) => {
|
|
1141
|
+
if (httpSort.col === "date") {
|
|
1142
|
+
const diff = new Date(a3.started_at).getTime() - new Date(b.started_at).getTime();
|
|
1143
|
+
return httpSort.dir === "asc" ? diff : -diff;
|
|
1144
|
+
}
|
|
958
1145
|
let av, bv;
|
|
959
1146
|
switch (httpSort.col) {
|
|
960
1147
|
case "duration":
|
|
@@ -987,6 +1174,26 @@
|
|
|
987
1174
|
}
|
|
988
1175
|
return true;
|
|
989
1176
|
});
|
|
1177
|
+
const sortedJobs = jobSort.col ? [...filteredJobs].sort((a3, b) => {
|
|
1178
|
+
if (jobSort.col === "date") {
|
|
1179
|
+
const diff = new Date(a3.started_at).getTime() - new Date(b.started_at).getTime();
|
|
1180
|
+
return jobSort.dir === "asc" ? diff : -diff;
|
|
1181
|
+
}
|
|
1182
|
+
let av, bv;
|
|
1183
|
+
switch (jobSort.col) {
|
|
1184
|
+
case "duration":
|
|
1185
|
+
av = a3.duration;
|
|
1186
|
+
bv = b.duration;
|
|
1187
|
+
break;
|
|
1188
|
+
case "status":
|
|
1189
|
+
av = a3.status;
|
|
1190
|
+
bv = b.status;
|
|
1191
|
+
break;
|
|
1192
|
+
default:
|
|
1193
|
+
return 0;
|
|
1194
|
+
}
|
|
1195
|
+
return jobSort.dir === "asc" ? av - bv : bv - av;
|
|
1196
|
+
}) : filteredJobs;
|
|
990
1197
|
const filteredOutbound = outboundRequests.filter((req) => {
|
|
991
1198
|
if (outboundSearch && !req.url.toLowerCase().includes(outboundSearch.toLowerCase())) return false;
|
|
992
1199
|
if (outboundMethod && req.method !== outboundMethod) return false;
|
|
@@ -1003,9 +1210,9 @@
|
|
|
1003
1210
|
const httpFiltersActive = !!(httpSearch || httpMethod || httpStatus || httpDuration || httpPreset);
|
|
1004
1211
|
const jobFiltersActive = !!(jobSearch || jobStatus || jobDuration);
|
|
1005
1212
|
const outboundFiltersActive = !!(outboundSearch || outboundMethod || outboundStatus);
|
|
1006
|
-
const sortIcon = (col) => {
|
|
1007
|
-
if (
|
|
1008
|
-
return /* @__PURE__ */ u3("span", { class: "sort-icon sort-icon--active", children:
|
|
1213
|
+
const sortIcon = (activeCol, dir, col) => {
|
|
1214
|
+
if (activeCol !== col) return /* @__PURE__ */ u3("span", { class: "sort-icon sort-icon--idle", children: "\u21C5" });
|
|
1215
|
+
return /* @__PURE__ */ u3("span", { class: "sort-icon sort-icon--active", children: dir === "asc" ? "\u25B2" : "\u25BC" });
|
|
1009
1216
|
};
|
|
1010
1217
|
return /* @__PURE__ */ u3("div", { class: "container", children: [
|
|
1011
1218
|
/* @__PURE__ */ u3("div", { class: "header", children: [
|
|
@@ -1031,7 +1238,7 @@
|
|
|
1031
1238
|
}, children: "Outbound HTTP" })
|
|
1032
1239
|
] }),
|
|
1033
1240
|
/* @__PURE__ */ u3("div", { class: "profiler-p-4 tab-content active", children: [
|
|
1034
|
-
section === "http" && (loadingHttp ? /* @__PURE__ */ u3(
|
|
1241
|
+
section === "http" && (loadingHttp ? /* @__PURE__ */ u3(TableSkeleton, { cols: ["sm", "xs", "flex", "sm", "sm", "sm", "xs", "sm"] }) : error ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: /* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: error }) }) : profiles.length === 0 ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: [
|
|
1035
1242
|
/* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: "No profiles found" }),
|
|
1036
1243
|
/* @__PURE__ */ u3("p", { class: "profiler-empty__description", children: "Make some requests to your application to see profiling data" })
|
|
1037
1244
|
] }) : /* @__PURE__ */ u3(k, { children: [
|
|
@@ -1090,24 +1297,27 @@
|
|
|
1090
1297
|
] }),
|
|
1091
1298
|
filteredProfiles.length === 0 ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: /* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: "No results match filters" }) }) : /* @__PURE__ */ u3("table", { children: [
|
|
1092
1299
|
/* @__PURE__ */ u3("thead", { children: /* @__PURE__ */ u3("tr", { children: [
|
|
1093
|
-
/* @__PURE__ */ u3("th", {
|
|
1300
|
+
/* @__PURE__ */ u3("th", { class: `sortable${httpSort.col === "date" ? " sortable--active" : ""}`, onClick: () => toggleHttpSort("date"), children: [
|
|
1301
|
+
"Time ",
|
|
1302
|
+
sortIcon(httpSort.col, httpSort.dir, "date")
|
|
1303
|
+
] }),
|
|
1094
1304
|
/* @__PURE__ */ u3("th", { children: "Method" }),
|
|
1095
1305
|
/* @__PURE__ */ u3("th", { children: "Path" }),
|
|
1096
1306
|
/* @__PURE__ */ u3("th", { class: `sortable${httpSort.col === "duration" ? " sortable--active" : ""}`, onClick: () => toggleHttpSort("duration"), children: [
|
|
1097
1307
|
"Duration ",
|
|
1098
|
-
sortIcon("duration")
|
|
1308
|
+
sortIcon(httpSort.col, httpSort.dir, "duration")
|
|
1099
1309
|
] }),
|
|
1100
1310
|
/* @__PURE__ */ u3("th", { class: `sortable${httpSort.col === "queries" ? " sortable--active" : ""}`, onClick: () => toggleHttpSort("queries"), children: [
|
|
1101
1311
|
"Queries ",
|
|
1102
|
-
sortIcon("queries")
|
|
1312
|
+
sortIcon(httpSort.col, httpSort.dir, "queries")
|
|
1103
1313
|
] }),
|
|
1104
1314
|
/* @__PURE__ */ u3("th", { class: `sortable${httpSort.col === "memory" ? " sortable--active" : ""}`, onClick: () => toggleHttpSort("memory"), children: [
|
|
1105
1315
|
"Memory ",
|
|
1106
|
-
sortIcon("memory")
|
|
1316
|
+
sortIcon(httpSort.col, httpSort.dir, "memory")
|
|
1107
1317
|
] }),
|
|
1108
1318
|
/* @__PURE__ */ u3("th", { class: `sortable${httpSort.col === "status" ? " sortable--active" : ""}`, onClick: () => toggleHttpSort("status"), children: [
|
|
1109
1319
|
"Status ",
|
|
1110
|
-
sortIcon("status")
|
|
1320
|
+
sortIcon(httpSort.col, httpSort.dir, "status")
|
|
1111
1321
|
] }),
|
|
1112
1322
|
/* @__PURE__ */ u3("th", { children: "Token" }),
|
|
1113
1323
|
/* @__PURE__ */ u3("th", {})
|
|
@@ -1129,7 +1339,7 @@
|
|
|
1129
1339
|
] }),
|
|
1130
1340
|
httpHasMore && !httpFiltersActive && /* @__PURE__ */ u3("div", { class: "profiler-load-more", children: /* @__PURE__ */ u3("button", { class: "btn btn-secondary", onClick: loadMoreHttp, disabled: httpLoadingMore, children: httpLoadingMore ? "Loading\u2026" : "Load more" }) })
|
|
1131
1341
|
] })),
|
|
1132
|
-
section === "jobs" && (loadingJobs ? /* @__PURE__ */ u3(
|
|
1342
|
+
section === "jobs" && (loadingJobs ? /* @__PURE__ */ u3(TableSkeleton, { cols: ["sm", "flex", "md", "sm", "xs", "xs", "sm"] }) : jobsError ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: /* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: jobsError }) }) : jobs.length === 0 ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: [
|
|
1133
1343
|
/* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: "No job profiles found" }),
|
|
1134
1344
|
/* @__PURE__ */ u3("p", { class: "profiler-empty__description", children: "Run background jobs in your application to see profiling data" })
|
|
1135
1345
|
] }) : /* @__PURE__ */ u3(k, { children: [
|
|
@@ -1169,16 +1379,25 @@
|
|
|
1169
1379
|
] }),
|
|
1170
1380
|
filteredJobs.length === 0 ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: /* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: "No results match filters" }) }) : /* @__PURE__ */ u3("table", { children: [
|
|
1171
1381
|
/* @__PURE__ */ u3("thead", { children: /* @__PURE__ */ u3("tr", { children: [
|
|
1172
|
-
/* @__PURE__ */ u3("th", {
|
|
1382
|
+
/* @__PURE__ */ u3("th", { class: `sortable${jobSort.col === "date" ? " sortable--active" : ""}`, onClick: () => toggleJobSort("date"), children: [
|
|
1383
|
+
"Time ",
|
|
1384
|
+
sortIcon(jobSort.col, jobSort.dir, "date")
|
|
1385
|
+
] }),
|
|
1173
1386
|
/* @__PURE__ */ u3("th", { children: "Job Class" }),
|
|
1174
1387
|
/* @__PURE__ */ u3("th", { children: "Queue" }),
|
|
1175
|
-
/* @__PURE__ */ u3("th", {
|
|
1176
|
-
|
|
1388
|
+
/* @__PURE__ */ u3("th", { class: `sortable${jobSort.col === "duration" ? " sortable--active" : ""}`, onClick: () => toggleJobSort("duration"), children: [
|
|
1389
|
+
"Duration ",
|
|
1390
|
+
sortIcon(jobSort.col, jobSort.dir, "duration")
|
|
1391
|
+
] }),
|
|
1392
|
+
/* @__PURE__ */ u3("th", { class: `sortable${jobSort.col === "status" ? " sortable--active" : ""}`, onClick: () => toggleJobSort("status"), children: [
|
|
1393
|
+
"Status ",
|
|
1394
|
+
sortIcon(jobSort.col, jobSort.dir, "status")
|
|
1395
|
+
] }),
|
|
1177
1396
|
/* @__PURE__ */ u3("th", { children: "Executions" }),
|
|
1178
1397
|
/* @__PURE__ */ u3("th", { children: "Token" }),
|
|
1179
1398
|
/* @__PURE__ */ u3("th", {})
|
|
1180
1399
|
] }) }),
|
|
1181
|
-
/* @__PURE__ */ u3("tbody", { children:
|
|
1400
|
+
/* @__PURE__ */ u3("tbody", { children: sortedJobs.map((p3) => {
|
|
1182
1401
|
const jobData = p3.collectors_data?.job;
|
|
1183
1402
|
const isFailed = p3.status === 500;
|
|
1184
1403
|
return /* @__PURE__ */ u3("tr", { children: [
|
|
@@ -1198,7 +1417,7 @@
|
|
|
1198
1417
|
] }),
|
|
1199
1418
|
jobHasMore && !jobFiltersActive && /* @__PURE__ */ u3("div", { class: "profiler-load-more", children: /* @__PURE__ */ u3("button", { class: "btn btn-secondary", onClick: loadMoreJobs, disabled: jobLoadingMore, children: jobLoadingMore ? "Loading\u2026" : "Load more" }) })
|
|
1200
1419
|
] })),
|
|
1201
|
-
section === "outbound" && (loadingOutbound ? /* @__PURE__ */ u3(
|
|
1420
|
+
section === "outbound" && (loadingOutbound ? /* @__PURE__ */ u3(TableSkeleton, { cols: ["sm", "xs", "flex", "sm", "xs"], rows: 4 }) : outboundError ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: /* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: outboundError }) }) : outboundRequests.length === 0 ? /* @__PURE__ */ u3("div", { class: "profiler-empty", children: [
|
|
1202
1421
|
/* @__PURE__ */ u3("div", { class: "profiler-empty__title", children: "No outbound HTTP requests found" }),
|
|
1203
1422
|
/* @__PURE__ */ u3("p", { class: "profiler-empty__description", children: "Make requests to external services to see outbound HTTP data" })
|
|
1204
1423
|
] }) : /* @__PURE__ */ u3(k, { children: [
|
|
@@ -1264,22 +1483,7 @@
|
|
|
1264
1483
|
}
|
|
1265
1484
|
|
|
1266
1485
|
// app/assets/typescript/profiler/components/dashboard/tabs/RequestTab.tsx
|
|
1267
|
-
function
|
|
1268
|
-
try {
|
|
1269
|
-
return JSON.stringify(JSON.parse(text), null, 2);
|
|
1270
|
-
} catch {
|
|
1271
|
-
return text;
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
function BodyBlock({ body, encoding }) {
|
|
1275
|
-
if (!body) return null;
|
|
1276
|
-
if (encoding === "base64") {
|
|
1277
|
-
return /* @__PURE__ */ u3("p", { class: "profiler-text--muted profiler-text--sm", children: "[binary content, base64-encoded]" });
|
|
1278
|
-
}
|
|
1279
|
-
const formatted = tryFormatJson(body);
|
|
1280
|
-
return /* @__PURE__ */ u3("pre", { class: "profiler-code profiler-text--xs", children: formatted });
|
|
1281
|
-
}
|
|
1282
|
-
function buildCurl(profile) {
|
|
1486
|
+
function buildCurl2(profile) {
|
|
1283
1487
|
const headers = profile.headers ?? {};
|
|
1284
1488
|
const params = profile.params ?? {};
|
|
1285
1489
|
const reqBody = profile.request_body;
|
|
@@ -1308,7 +1512,7 @@
|
|
|
1308
1512
|
}
|
|
1309
1513
|
function RequestTab({ profile }) {
|
|
1310
1514
|
const [copied, setCopied] = d2(false);
|
|
1311
|
-
const curl =
|
|
1515
|
+
const curl = buildCurl2(profile);
|
|
1312
1516
|
const routeData = profile.collectors_data?.request ?? {};
|
|
1313
1517
|
function copyToClipboard() {
|
|
1314
1518
|
navigator.clipboard.writeText(curl).then(() => {
|
|
@@ -1368,7 +1572,14 @@
|
|
|
1368
1572
|
] }),
|
|
1369
1573
|
profile.request_body && /* @__PURE__ */ u3(k, { children: [
|
|
1370
1574
|
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Request Body" }),
|
|
1371
|
-
/* @__PURE__ */ u3(
|
|
1575
|
+
/* @__PURE__ */ u3(
|
|
1576
|
+
SmartBodyPreview,
|
|
1577
|
+
{
|
|
1578
|
+
body: profile.request_body,
|
|
1579
|
+
encoding: profile.request_body_encoding,
|
|
1580
|
+
headers: profile.headers ?? {}
|
|
1581
|
+
}
|
|
1582
|
+
)
|
|
1372
1583
|
] }),
|
|
1373
1584
|
profile.response_headers && Object.keys(profile.response_headers).length > 0 && /* @__PURE__ */ u3(k, { children: [
|
|
1374
1585
|
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Response Headers" }),
|
|
@@ -1379,7 +1590,14 @@
|
|
|
1379
1590
|
] }),
|
|
1380
1591
|
profile.response_body && /* @__PURE__ */ u3(k, { children: [
|
|
1381
1592
|
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Response Body" }),
|
|
1382
|
-
/* @__PURE__ */ u3(
|
|
1593
|
+
/* @__PURE__ */ u3(
|
|
1594
|
+
SmartBodyPreview,
|
|
1595
|
+
{
|
|
1596
|
+
body: profile.response_body,
|
|
1597
|
+
encoding: profile.response_body_encoding,
|
|
1598
|
+
headers: profile.response_headers ?? {}
|
|
1599
|
+
}
|
|
1600
|
+
)
|
|
1383
1601
|
] }),
|
|
1384
1602
|
/* @__PURE__ */ u3("h2", { class: "profiler-section__header profiler-mt-6", children: "Curl Command" }),
|
|
1385
1603
|
/* @__PURE__ */ u3("div", { style: "position: relative;", children: [
|
|
@@ -1461,6 +1679,14 @@
|
|
|
1461
1679
|
] });
|
|
1462
1680
|
}
|
|
1463
1681
|
function ExplainModal({ state, onClose }) {
|
|
1682
|
+
y2(() => {
|
|
1683
|
+
if (!state.open) return;
|
|
1684
|
+
const handler = (e3) => {
|
|
1685
|
+
if (e3.key === "Escape") onClose();
|
|
1686
|
+
};
|
|
1687
|
+
document.addEventListener("keydown", handler);
|
|
1688
|
+
return () => document.removeEventListener("keydown", handler);
|
|
1689
|
+
}, [state.open]);
|
|
1464
1690
|
if (!state.open) return null;
|
|
1465
1691
|
const renderResult = () => {
|
|
1466
1692
|
if (state.loading) return /* @__PURE__ */ u3("div", { class: "profiler-text--muted", children: "Running EXPLAIN ANALYZE\u2026" });
|
|
@@ -1571,7 +1797,7 @@
|
|
|
1571
1797
|
] }),
|
|
1572
1798
|
n1Groups.length > 0 && /* @__PURE__ */ u3("div", { class: "profiler-alert-banner profiler-alert-banner--warning profiler-mb-4", children: [
|
|
1573
1799
|
/* @__PURE__ */ u3("span", { class: "profiler-alert-banner__icon", children: "\u26A0\uFE0F" }),
|
|
1574
|
-
/* @__PURE__ */ u3("div", { children: [
|
|
1800
|
+
/* @__PURE__ */ u3("div", { style: "flex:1", children: [
|
|
1575
1801
|
/* @__PURE__ */ u3("strong", { children: "Potential N+1 detected" }),
|
|
1576
1802
|
" \u2014 ",
|
|
1577
1803
|
n1Groups.length,
|
|
@@ -1581,7 +1807,19 @@
|
|
|
1581
1807
|
n1Groups.reduce((sum, g2) => sum + g2.indices.length, 0),
|
|
1582
1808
|
" times total",
|
|
1583
1809
|
/* @__PURE__ */ u3("div", { class: "profiler-text--xs profiler-text--muted profiler-mt-1", children: "Queries causing N+1 are highlighted below. Expand each group to see the call stack." })
|
|
1584
|
-
] })
|
|
1810
|
+
] }),
|
|
1811
|
+
n1Groups.length > 1 && /* @__PURE__ */ u3(
|
|
1812
|
+
"button",
|
|
1813
|
+
{
|
|
1814
|
+
class: "profiler-btn profiler-btn--sm",
|
|
1815
|
+
style: "flex-shrink:0;align-self:flex-start",
|
|
1816
|
+
onClick: () => {
|
|
1817
|
+
const allOpen = n1Groups.every((g2) => openBacktraces.has(g2.pattern));
|
|
1818
|
+
setOpenBacktraces(allOpen ? /* @__PURE__ */ new Set() : new Set(n1Groups.map((g2) => g2.pattern)));
|
|
1819
|
+
},
|
|
1820
|
+
children: n1Groups.every((g2) => openBacktraces.has(g2.pattern)) ? "Collapse all" : "Expand all"
|
|
1821
|
+
}
|
|
1822
|
+
)
|
|
1585
1823
|
] }),
|
|
1586
1824
|
n1Groups.map((group) => /* @__PURE__ */ u3("div", { class: "profiler-n1-group profiler-mb-4", children: [
|
|
1587
1825
|
/* @__PURE__ */ u3("div", { class: "profiler-n1-group__header", onClick: () => toggleBacktrace(group.pattern), children: [
|
|
@@ -3035,6 +3273,7 @@
|
|
|
3035
3273
|
}
|
|
3036
3274
|
function LogsTab({ logData }) {
|
|
3037
3275
|
const [filter, setFilter] = d2("ALL");
|
|
3276
|
+
const [search, setSearch] = d2("");
|
|
3038
3277
|
if (!logData?.logs?.length) {
|
|
3039
3278
|
return /* @__PURE__ */ u3("div", { class: "profiler-empty", children: [
|
|
3040
3279
|
/* @__PURE__ */ u3("div", { class: "profiler-empty__icon", children: "\u{1F4CB}" }),
|
|
@@ -3047,7 +3286,11 @@
|
|
|
3047
3286
|
] });
|
|
3048
3287
|
}
|
|
3049
3288
|
const levels = ["ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"];
|
|
3050
|
-
const filtered =
|
|
3289
|
+
const filtered = logData.logs.filter((l3) => {
|
|
3290
|
+
if (filter !== "ALL" && l3.level !== filter) return false;
|
|
3291
|
+
if (search && !l3.message.toLowerCase().includes(search.toLowerCase())) return false;
|
|
3292
|
+
return true;
|
|
3293
|
+
});
|
|
3051
3294
|
return /* @__PURE__ */ u3(k, { children: [
|
|
3052
3295
|
/* @__PURE__ */ u3("h2", { class: "profiler-section__header", children: [
|
|
3053
3296
|
"Log Messages (",
|
|
@@ -3064,19 +3307,32 @@
|
|
|
3064
3307
|
/* @__PURE__ */ u3("strong", { class: "profiler-text--warning", children: logData.warnings })
|
|
3065
3308
|
] })
|
|
3066
3309
|
] }),
|
|
3067
|
-
/* @__PURE__ */ u3("div", { class: "profiler-
|
|
3068
|
-
"
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3310
|
+
/* @__PURE__ */ u3("div", { class: "profiler-action-bar profiler-mb-4", children: [
|
|
3311
|
+
/* @__PURE__ */ u3("div", { class: "profiler-flex profiler-flex--gap-2", children: levels.map((level) => /* @__PURE__ */ u3(
|
|
3312
|
+
"button",
|
|
3313
|
+
{
|
|
3314
|
+
onClick: () => setFilter(level),
|
|
3315
|
+
class: `btn btn-sm ${filter === level ? "btn-primary" : "btn-secondary"}`,
|
|
3316
|
+
children: level
|
|
3317
|
+
},
|
|
3318
|
+
level
|
|
3319
|
+
)) }),
|
|
3320
|
+
/* @__PURE__ */ u3(
|
|
3321
|
+
"input",
|
|
3322
|
+
{
|
|
3323
|
+
type: "text",
|
|
3324
|
+
class: "profiler-filter-input",
|
|
3325
|
+
placeholder: "Search messages\u2026",
|
|
3326
|
+
value: search,
|
|
3327
|
+
onInput: (e3) => setSearch(e3.target.value),
|
|
3328
|
+
style: "width:200px"
|
|
3329
|
+
}
|
|
3330
|
+
)
|
|
3331
|
+
] }),
|
|
3076
3332
|
filtered.length === 0 ? /* @__PURE__ */ u3("div", { class: "profiler-text--muted profiler-text--sm", children: [
|
|
3077
|
-
"No ",
|
|
3078
|
-
|
|
3079
|
-
"
|
|
3333
|
+
"No messages match",
|
|
3334
|
+
search ? ` "${search}"` : "",
|
|
3335
|
+
"."
|
|
3080
3336
|
] }) : filtered.map((entry, index) => /* @__PURE__ */ u3("div", { class: "profiler-query-card profiler-mb-2", children: [
|
|
3081
3337
|
/* @__PURE__ */ u3("div", { class: "profiler-query-card__header", children: [
|
|
3082
3338
|
/* @__PURE__ */ u3(
|
|
@@ -3368,7 +3624,8 @@
|
|
|
3368
3624
|
(profile.memory / 1024 / 1024).toFixed(2),
|
|
3369
3625
|
" MB"
|
|
3370
3626
|
] })
|
|
3371
|
-
] })
|
|
3627
|
+
] }),
|
|
3628
|
+
/* @__PURE__ */ u3("span", { style: "color:var(--profiler-text-muted)", children: new Date(profile.started_at).toLocaleString("en", { hour12: false, month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit" }) })
|
|
3372
3629
|
] })
|
|
3373
3630
|
] }),
|
|
3374
3631
|
/* @__PURE__ */ u3("div", { class: "profiler-panel profiler-mb-6", children: [
|
data/lib/profiler/version.rb
CHANGED