Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import axios, {
registerErrorToastInterceptor,
} from '../utils/axios';
import waitForPolyfill from '../utils/eventsource-polyfill';
import logtail from '../utils/logtail';
import logtail, { getLogfileWindowMetadata } from '../utils/logtail';
import uri from '../utils/uri';

import { useSbaConfig } from '@/sba-config';
Expand Down Expand Up @@ -417,6 +417,25 @@ class Instance {
);
}

async fetchLogfileRange(start: number, end: number): Promise<LogfileRange> {
const response = await this.axios.get(uri`actuator/logfile`, {
responseType: 'text',
headers: {
Accept: 'text/plain',
Range: `bytes=${start}-${end}`,
},
});
const metadata = getLogfileWindowMetadata(response);

return {
data: response.data,
totalBytes: metadata.totalBytes,
windowStart: metadata.windowStart,
windowEnd: metadata.windowEnd,
status: response.status,
};
}

async listMBeans() {
return this.axios.get(uri`actuator/jolokia/list`, {
headers: { Accept: 'application/json' },
Expand Down Expand Up @@ -544,6 +563,14 @@ type Endpoint = {
url: string;
};

export type LogfileRange = {
data: string;
totalBytes: number;
windowStart: number;
windowEnd: number;
status: number;
};

export const DOWN_STATES = ['OUT_OF_SERVICE', 'DOWN', 'OFFLINE', 'RESTRICTED'];
export const UP_STATES = ['UP'];
export const UNKNOWN_STATES = ['UNKNOWN'];
47 changes: 43 additions & 4 deletions spring-boot-admin-server-ui/src/main/frontend/utils/logtail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,39 @@
*/
import { EMPTY, Observable, catchError, concatMap, of, timer } from './rxjs';

export default (getFn, interval, initialSize = 300 * 1024) => {
export const DEFAULT_LOGFILE_CHUNK_SIZE = 300 * 1024;

const parseInteger = (value, fallback) => {
const parsed = parseInt(value, 10);
return Number.isNaN(parsed) ? fallback : parsed;
};

export const getLogfileWindowMetadata = (response) => {
const contentLength = response.data.length;
const contentRange = response.headers.get('content-range');
const rangeMatch = contentRange?.match(/^bytes\s+(\d+)-(\d+)\/(\d+|\*)$/i);

if (rangeMatch) {
return {
windowStart: parseInteger(rangeMatch[1], 0),
windowEnd: parseInteger(rangeMatch[2], Math.max(contentLength - 1, 0)),
totalBytes: parseInteger(rangeMatch[3], contentLength),
};
}

const totalBytes = parseInteger(
response.headers.get('content-length'),
contentLength,
);

return {
windowStart: 0,
windowEnd: Math.max(contentLength - 1, 0),
totalBytes,
};
};

export default (getFn, interval, initialSize = DEFAULT_LOGFILE_CHUNK_SIZE) => {
let range = `bytes=-${initialSize}`;
let size = 0;

Expand All @@ -38,16 +70,21 @@ export default (getFn, interval, initialSize = 300 * 1024) => {
concatMap((response) => {
let initial = size === 0;
const contentLength = response.data.length;
let windowStart = 0;
let windowEnd = Math.max(contentLength - 1, 0);

if (response.status === 200) {
if (!initial) {
throw 'Expected 206 - Partial Content on subsequent requests.';
}
size = contentLength;
range = `bytes=${size - 1}-`;
range = `bytes=${Math.max(size - 1, 0)}-`;
} else if (response.status === 206) {
size = parseInt(response.headers['content-range'].split('/')[1]);
range = `bytes=${size - 1}-`;
const metadata = getLogfileWindowMetadata(response);
size = metadata.totalBytes;
windowStart = metadata.windowStart;
windowEnd = metadata.windowEnd;
range = `bytes=${Math.max(size - 1, 0)}-`;
} else if (response.status === 416) {
size = 0;
range = `bytes=-${initialSize}`;
Expand Down Expand Up @@ -77,6 +114,8 @@ export default (getFn, interval, initialSize = 300 * 1024) => {
totalBytes: size,
skipped,
addendum,
windowStart,
windowEnd,
})
: EMPTY;
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
"logfile": {
"label": "Log",
"download": "Herunterladen",
"wrap_lines": "Zeilen umbrechen"
"wrap_lines": "Zeilen umbrechen",
"page_up": "Seite nach oben",
"page_down": "Seite nach unten",
"previous_chunk": "Vorheriger Abschnitt",
"next_chunk": "Nächster Abschnitt",
"resume_follow": "Live-Ansicht fortsetzen"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
"logfile": {
"label": "Logfile",
"download": "Download",
"wrap_lines": "Wrap lines"
"wrap_lines": "Wrap lines",
"page_up": "Page up",
"page_down": "Page down",
"previous_chunk": "Previous chunk",
"next_chunk": "Next chunk",
"resume_follow": "Resume follow"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
"logfile": {
"label": "Archivo de log",
"download": "Descargar",

"wrap_lines": "Ajustar líneas"
"wrap_lines": "Ajustar líneas",
"page_up": "Subir página",
"page_down": "Bajar página",
"previous_chunk": "Fragmento anterior",
"next_chunk": "Fragmento siguiente",
"resume_follow": "Reanudar seguimiento"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"instances": {
"logfile": {
"label": "Fichier de log",
"download": "Téléchargement"
"download": "Téléchargement",
"wrap_lines": "Retour à la ligne",
"page_up": "Page vers le haut",
"page_down": "Page vers le bas",
"previous_chunk": "Segment précédent",
"next_chunk": "Segment suivant",
"resume_follow": "Reprendre le suivi"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"instances": {
"logfile": {
"label": "Annálaskrá",
"download": "Niðurhal"
"download": "Niðurhal",
"wrap_lines": "Línuskipting",
"page_up": "Síða upp",
"page_down": "Síða niður",
"previous_chunk": "Fyrri hluti",
"next_chunk": "Næsti hluti",
"resume_follow": "Fylgja aftur"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"instances": {
"logfile": {
"label": "로그파일",
"download": "다운로드"
"download": "다운로드",
"wrap_lines": "줄 바꿈",
"page_up": "페이지 위로",
"page_down": "페이지 아래로",
"previous_chunk": "이전 구간",
"next_chunk": "다음 구간",
"resume_follow": "실시간 추적 재개"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"instances": {
"logfile": {
"label": "Arquivo de Log",
"download": "Download"
"download": "Download",
"wrap_lines": "Quebrar linhas",
"page_up": "Subir página",
"page_down": "Descer página",
"previous_chunk": "Trecho anterior",
"next_chunk": "Próximo trecho",
"resume_follow": "Retomar acompanhamento"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"instances": {
"logfile": {
"label": "Лог-файл",
"download": "Загрузить"
"download": "Загрузить",
"wrap_lines": "Перенос строк",
"page_up": "Страница вверх",
"page_down": "Страница вниз",
"previous_chunk": "Предыдущий фрагмент",
"next_chunk": "Следующий фрагмент",
"resume_follow": "Возобновить слежение"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"instances": {
"logfile": {
"label": "日志文件",
"download": "下载"
"download": "下载",
"wrap_lines": "自动换行",
"page_up": "向上翻页",
"page_down": "向下翻页",
"previous_chunk": "上一段",
"next_chunk": "下一段",
"resume_follow": "恢复跟踪"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
"logfile": {
"label": "日誌檔案",
"download": "下載",
"wrap_lines": "自動換行"
"wrap_lines": "自動換行",
"page_up": "向上翻頁",
"page_down": "向下翻頁",
"previous_chunk": "上一段",
"next_chunk": "下一段",
"resume_follow": "恢復追蹤"
}
}
}
Loading