Skip to content

Commit 4a6dd43

Browse files
committed
fix(#5370): fix logfile view styling issues and make sure that links are rendered with an underline similarly to what already happens in other views
1 parent b3662bd commit 4a6dd43

3 files changed

Lines changed: 49 additions & 13 deletions

File tree

spring-boot-admin-samples/spring-boot-admin-sample-servlet/src/main/java/de/codecentric/boot/admin/sample/QuartzJobsConfiguration.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.quartz.SimpleScheduleBuilder;
2525
import org.quartz.Trigger;
2626
import org.quartz.TriggerBuilder;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
2729
import org.springframework.context.annotation.Bean;
2830
import org.springframework.context.annotation.Configuration;
2931
import org.springframework.scheduling.quartz.QuartzJobBean;
@@ -108,9 +110,11 @@ public Trigger hourlyTestTrigger() {
108110
*/
109111
public static class SampleJob extends QuartzJobBean {
110112

113+
private static final Logger logger = LoggerFactory.getLogger(SampleJob.class);
114+
111115
@Override
112116
protected void executeInternal(org.quartz.JobExecutionContext context) {
113-
System.out.println("Sample Quartz Job executed at " + new java.util.Date());
117+
logger.info("Sample Quartz Job executed at {}", new java.util.Date());
114118
}
115119

116120
}
@@ -120,9 +124,11 @@ protected void executeInternal(org.quartz.JobExecutionContext context) {
120124
*/
121125
public static class AnotherSampleJob extends QuartzJobBean {
122126

127+
private static final Logger logger = LoggerFactory.getLogger(AnotherSampleJob.class);
128+
123129
@Override
124130
protected void executeInternal(org.quartz.JobExecutionContext context) {
125-
System.out.println("Another Quartz Job executed at " + new java.util.Date());
131+
logger.info("Another Quartz Job executed at {}", new java.util.Date());
126132
}
127133

128134
}

spring-boot-admin-server-ui/src/main/frontend/utils/logtail.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { EMPTY, Observable, catchError, concatMap, of, timer } from './rxjs';
1818
export default (getFn, interval, initialSize = 300 * 1024) => {
1919
let range = `bytes=-${initialSize}`;
2020
let size = 0;
21+
let atTheEnd = false;
2122

2223
return timer(0, interval).pipe(
2324
concatMap(() => {
@@ -46,7 +47,10 @@ export default (getFn, interval, initialSize = 300 * 1024) => {
4647
size = contentLength;
4748
range = `bytes=${size - 1}-`;
4849
} else if (response.status === 206) {
49-
size = parseInt(response.headers['content-range'].split('/')[1]);
50+
const contentRangeParts = response.headers['content-range'].split('/');
51+
size = parseInt(contentRangeParts[1]);
52+
// The end value of the range is always one byte less than the size when at the end
53+
atTheEnd = parseInt(contentRangeParts[0].split('-')[1]) == size - 1;
5054
range = `bytes=${size - 1}-`;
5155
} else if (response.status === 416) {
5256
size = 0;
@@ -68,13 +72,14 @@ export default (getFn, interval, initialSize = 300 * 1024) => {
6872
skipped = size - addendum.length;
6973
}
7074
} else if (response.data.length > 1) {
71-
// Remove the first byte which has been part of the previos response.
75+
// Remove the first byte which has been part of the previous response.
7276
addendum = response.data.substring(1);
7377
}
7478

7579
return addendum
7680
? of({
7781
totalBytes: size,
82+
atTheEnd,
7883
skipped,
7984
addendum,
8085
})

spring-boot-admin-server-ui/src/main/frontend/views/instances/logfile/index.vue

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
:class="{ 'wrap-lines': wrapLines }"
9696
class="log-viewer overflow-x-auto text-sm -mx-6 -my-20 pt-14"
9797
>
98-
<table class="table-striped" />
98+
<table ref="logContainer" class="table-striped min-w-full" />
9999
</div>
100100
</sba-instance-section>
101101
</template>
@@ -136,6 +136,7 @@ export default {
136136
atBottom: false,
137137
atTop: true,
138138
skippedBytes: null,
139+
logEnded: false,
139140
wrapLines: false,
140141
scrollSubscription: null,
141142
}),
@@ -184,21 +185,35 @@ export default {
184185
tap(
185186
(part) => (this.skippedBytes = this.skippedBytes || part.skipped),
186187
),
188+
tap((part) => (this.logEnded = part.atTheEnd)),
187189
concatMap((part) => chunk(part.addendum.split(/\r?\n/), 250)),
188190
map((lines) => of(lines, animationFrameScheduler)),
189191
concatAll(),
190192
)
191193
.subscribe({
192194
next: (lines) => {
193195
this.hasLoaded = true;
194-
lines.forEach((line) => {
195-
const row = document.createElement('tr');
196-
const col = document.createElement('td');
197-
const pre = document.createElement('pre');
198-
pre.innerHTML = autolink(this.ansiUp.ansi_to_html(line));
199-
col.appendChild(pre);
200-
row.appendChild(col);
201-
document.querySelector('.log-viewer > table')?.appendChild(row);
196+
const logContainer = this.$refs.logContainer;
197+
lines.forEach((line, index) => {
198+
let content;
199+
if (line) {
200+
content = document.createElement('pre');
201+
content.innerHTML = autolink(this.ansiUp.ansi_to_html(line));
202+
} else if (!this.logEnded || index < lines.length - 1) {
203+
/*
204+
If we're not at the end of the log file, probably this new line is indeed valid.
205+
If we're at the end of the log file, then it may a temporary one since the log file always ends with a new line until the next one gets written.
206+
In such a case, we ignore it if it's the last entry of the batch of lines.
207+
*/
208+
content = document.createElement('br');
209+
}
210+
if (content) {
211+
const row = document.createElement('tr');
212+
const col = document.createElement('td');
213+
col.appendChild(content);
214+
row.appendChild(col);
215+
logContainer.appendChild(row);
216+
}
202217
});
203218
204219
if (this.atBottom) {
@@ -269,15 +284,25 @@ export default {
269284
max-height: 100%;
270285
}
271286
287+
.log-viewer tr,
288+
.log-viewer td {
289+
@apply w-full;
290+
}
291+
272292
.log-viewer pre {
273293
padding: 0 0.75em;
274294
margin-bottom: 1px;
295+
@apply w-full;
275296
}
276297
277298
.log-viewer pre:hover {
278299
background: #dbdbdb;
279300
}
280301
302+
.log-viewer a[href] {
303+
@apply underline;
304+
}
305+
281306
.log-viewer.wrap-lines pre {
282307
@apply whitespace-pre-wrap;
283308
word-break: break-all;

0 commit comments

Comments
 (0)