fix: Application logs is not reversed and queried better
This commit is contained in:
@@ -88,7 +88,7 @@
|
|||||||
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
|
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
|
||||||
<div class="-mb-5 flex-col">
|
<div class="-mb-5 flex-col">
|
||||||
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
|
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
|
||||||
$t('application.build_logs')}
|
{$t('application.build_logs')}
|
||||||
</div>
|
</div>
|
||||||
<span class="text-xs">{application.name} </span>
|
<span class="text-xs">{application.name} </span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ export const get: RequestHandler = async (event) => {
|
|||||||
if (status === 401) return { status, body };
|
if (status === 401) return { status, body };
|
||||||
|
|
||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
let since = event.url.searchParams.get('since') || 0;
|
||||||
|
if (since !== 0) {
|
||||||
|
since = dayjs(since).unix();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const { destinationDockerId, destinationDocker } = await db.prisma.application.findUnique({
|
const { destinationDockerId, destinationDocker } = await db.prisma.application.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
@@ -20,16 +24,22 @@ export const get: RequestHandler = async (event) => {
|
|||||||
try {
|
try {
|
||||||
const container = await docker.engine.getContainer(id);
|
const container = await docker.engine.getContainer(id);
|
||||||
if (container) {
|
if (container) {
|
||||||
|
const logs = (
|
||||||
|
await container.logs({
|
||||||
|
stdout: true,
|
||||||
|
stderr: true,
|
||||||
|
timestamps: true,
|
||||||
|
since,
|
||||||
|
tail: 5000
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.toString()
|
||||||
|
.split('\n')
|
||||||
|
.map((l) => l.slice(8))
|
||||||
|
.filter((a) => a);
|
||||||
return {
|
return {
|
||||||
body: {
|
body: {
|
||||||
logs: (
|
logs
|
||||||
await container.logs({ stdout: true, stderr: true, timestamps: true, tail: 5000 })
|
|
||||||
)
|
|
||||||
.toString()
|
|
||||||
.split('\n')
|
|
||||||
.map((l) => l.slice(8))
|
|
||||||
.filter((a) => a)
|
|
||||||
.reverse()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,15 +29,12 @@
|
|||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
|
|
||||||
let loadLogsInterval = null;
|
let loadLogsInterval = null;
|
||||||
let allLogs = {
|
|
||||||
logs: []
|
|
||||||
};
|
|
||||||
let logs = [];
|
let logs = [];
|
||||||
let currentPage = 1;
|
let lastLog = null;
|
||||||
let endOfLogs = false;
|
|
||||||
let startOfLogs = true;
|
|
||||||
let followingInterval;
|
let followingInterval;
|
||||||
|
let followingLogs;
|
||||||
let logsEl;
|
let logsEl;
|
||||||
|
let position = 0;
|
||||||
|
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@@ -53,11 +50,8 @@
|
|||||||
async function loadAllLogs() {
|
async function loadAllLogs() {
|
||||||
try {
|
try {
|
||||||
const data: any = await get(`/applications/${id}/logs.json`);
|
const data: any = await get(`/applications/${id}/logs.json`);
|
||||||
allLogs = data.logs;
|
lastLog = data.logs[data.logs.length - 1];
|
||||||
logs = data.logs.slice(0, 100);
|
logs = data.logs;
|
||||||
if (logs.length < 100) {
|
|
||||||
endOfLogs = true;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
@@ -65,40 +59,40 @@
|
|||||||
}
|
}
|
||||||
async function loadLogs() {
|
async function loadLogs() {
|
||||||
try {
|
try {
|
||||||
const newLogs = await get(`/applications/${id}/logs.json`);
|
const newLogs: any = await get(
|
||||||
logs = newLogs.logs.slice(0, 100);
|
`/applications/${id}/logs.json?since=${lastLog.split(' ')[0]}`
|
||||||
|
);
|
||||||
|
if (newLogs.logs[newLogs.logs.length - 1] !== logs[logs.length - 1]) {
|
||||||
|
logs = logs.concat(newLogs.logs);
|
||||||
|
lastLog = newLogs.logs[newLogs.logs.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function loadOlderLogs() {
|
function detect() {
|
||||||
clearInterval(loadLogsInterval);
|
if (position < logsEl.scrollTop) {
|
||||||
loadLogsInterval = null;
|
position = logsEl.scrollTop;
|
||||||
logsEl.scrollTop = 0;
|
|
||||||
if (logs.length < 100) {
|
|
||||||
endOfLogs = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
startOfLogs = false;
|
|
||||||
endOfLogs = false;
|
|
||||||
currentPage += 1;
|
|
||||||
logs = allLogs.slice(currentPage * 100 - 100, currentPage * 100);
|
|
||||||
}
|
|
||||||
async function loadNewerLogs() {
|
|
||||||
currentPage -= 1;
|
|
||||||
logsEl.scrollTop = 0;
|
|
||||||
if (currentPage !== 1) {
|
|
||||||
clearInterval(loadLogsInterval);
|
|
||||||
endOfLogs = false;
|
|
||||||
loadLogsInterval = null;
|
|
||||||
logs = allLogs.slice(currentPage * 100 - 100, currentPage * 100);
|
|
||||||
} else {
|
} else {
|
||||||
startOfLogs = true;
|
if (followingLogs) {
|
||||||
loadLogs();
|
clearInterval(followingInterval);
|
||||||
loadLogsInterval = setInterval(() => {
|
followingLogs = false;
|
||||||
loadLogs();
|
}
|
||||||
|
position = logsEl.scrollTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function followBuild() {
|
||||||
|
followingLogs = !followingLogs;
|
||||||
|
if (followingLogs) {
|
||||||
|
followingInterval = setInterval(() => {
|
||||||
|
logsEl.scrollTop = logsEl.scrollHeight;
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
clearInterval(followingInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -186,12 +180,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<div class="flex justify-end sticky top-0 p-2 mx-1">
|
<div class="flex justify-end sticky top-0 p-2 mx-1">
|
||||||
<button
|
<button
|
||||||
on:click={loadOlderLogs}
|
on:click={followBuild}
|
||||||
class:text-coolgray-100={endOfLogs}
|
class="bg-transparent"
|
||||||
class:hover:bg-coolgray-400={!endOfLogs}
|
data-tooltip="Follow logs"
|
||||||
class="bg-transparent tooltip-bottom"
|
class:text-green-500={followingLogs}
|
||||||
data-tooltip="Older logs"
|
|
||||||
disabled={endOfLogs}
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -204,39 +196,17 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
<path
|
<circle cx="12" cy="12" r="9" />
|
||||||
d="M20 15h-8v3.586a1 1 0 0 1 -1.707 .707l-6.586 -6.586a1 1 0 0 1 0 -1.414l6.586 -6.586a1 1 0 0 1 1.707 .707v3.586h8a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1z"
|
<line x1="8" y1="12" x2="12" y2="16" />
|
||||||
/>
|
<line x1="12" y1="8" x2="12" y2="16" />
|
||||||
</svg>
|
<line x1="16" y1="12" x2="12" y2="16" />
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
on:click={loadNewerLogs}
|
|
||||||
class:text-coolgray-100={startOfLogs}
|
|
||||||
class:hover:bg-coolgray-400={!startOfLogs}
|
|
||||||
class="bg-transparent tooltip-bottom"
|
|
||||||
data-tooltip="Newer logs"
|
|
||||||
disabled={startOfLogs}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="w-6 h-6"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<path
|
|
||||||
d="M4 9h8v-3.586a1 1 0 0 1 1.707 -.707l6.586 6.586a1 1 0 0 1 0 1.414l-6.586 6.586a1 1 0 0 1 -1.707 -.707v-3.586h-8a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1z"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="font-mono w-full leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
|
class="font-mono w-full leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
|
||||||
bind:this={logsEl}
|
bind:this={logsEl}
|
||||||
|
on:scroll={detect}
|
||||||
>
|
>
|
||||||
<div class="px-2 pr-14">
|
<div class="px-2 pr-14">
|
||||||
{#each logs as log}
|
{#each logs as log}
|
||||||
|
|||||||
Reference in New Issue
Block a user