@@ -35,6 +35,7 @@ import { KubeObject } from '../../../lib/k8s/KubeObject';
3535import Pod from '../../../lib/k8s/pod' ;
3636import ReplicaSet from '../../../lib/k8s/replicaSet' ;
3737import { Activity } from '../../activity/Activity' ;
38+ import { colorizePrettifiedLog } from '../../pod/jsonHandling' ;
3839import ActionButton from '../ActionButton' ;
3940import { LogViewer } from '../LogViewer' ;
4041import { LightTooltip } from '../Tooltip' ;
@@ -67,6 +68,9 @@ function LogsButtonContent({ item }: LogsButtonProps) {
6768 const [ lines , setLines ] = useState < number > ( 100 ) ;
6869 const [ showPrevious , setShowPrevious ] = React . useState < boolean > ( false ) ;
6970 const [ showReconnectButton , setShowReconnectButton ] = useState ( false ) ;
71+ const [ prettifyLogs , setPrettifyLogs ] = useState < boolean > ( false ) ;
72+ const [ formatJsonValues , setFormatJsonValues ] = useState < boolean > ( false ) ;
73+ const [ hasJsonLogs , setHasJsonLogs ] = useState < boolean > ( false ) ;
7074
7175 const xtermRef = React . useRef < XTerminal | null > ( null ) ;
7276 const { t } = useTranslation ( [ 'glossary' , 'translation' ] ) ;
@@ -141,6 +145,14 @@ function LogsButtonContent({ item }: LogsButtonProps) {
141145 setShowPrevious ( previous => ! previous ) ;
142146 }
143147
148+ function handlePrettifyChange ( ) {
149+ setPrettifyLogs ( prev => ! prev ) ;
150+ }
151+
152+ function handleFormatJsonValuesChange ( ) {
153+ setFormatJsonValues ( prev => ! prev ) ;
154+ }
155+
144156 // Handler for initial logs button click
145157 async function onMount ( ) {
146158 if ( item instanceof Deployment || item instanceof ReplicaSet || item instanceof DaemonSet ) {
@@ -222,16 +234,19 @@ function LogsButtonContent({ item }: LogsButtonProps) {
222234 return timestampA . localeCompare ( timestampB ) ;
223235 } ) ;
224236
237+ const displayLogs =
238+ prettifyLogs && hasJsonLogs ? allLogs . map ( log => colorizePrettifiedLog ( log ) ) : allLogs ;
239+
225240 if ( xtermRef . current ) {
226241 xtermRef . current . clear ( ) ;
227- xtermRef . current . write ( allLogs . join ( '' ) . replaceAll ( '\n' , '\r\n' ) ) ;
242+ xtermRef . current . write ( displayLogs . join ( '' ) . replaceAll ( '\n' , '\r\n' ) ) ;
228243 }
229244
230245 setLogs ( {
231246 logs : allLogs ,
232247 lastLineShown : allLogs . length - 1 ,
233248 } ) ;
234- } , [ allPodLogs ] ) ;
249+ } , [ allPodLogs , prettifyLogs , hasJsonLogs ] ) ;
235250
236251 // Function to fetch and aggregate logs from all pods
237252 function fetchAllPodsLogs ( pods : Pod [ ] , container : string ) : ( ) => void {
@@ -243,7 +258,16 @@ function LogsButtonContent({ item }: LogsButtonProps) {
243258 pods . forEach ( pod => {
244259 const cleanup = pod . getLogs (
245260 container ,
246- ( { logs : newLogs } : { logs : string [ ] ; hasJsonLogs ?: boolean } ) => {
261+ ( {
262+ logs : newLogs ,
263+ hasJsonLogs : newHasJsonLogs ,
264+ } : {
265+ logs : string [ ] ;
266+ hasJsonLogs ?: boolean ;
267+ } ) => {
268+ if ( newHasJsonLogs ) {
269+ setHasJsonLogs ( true ) ;
270+ }
247271 const podName = pod . getName ( ) ;
248272 setAllPodLogs ( current => {
249273 const updated = {
@@ -258,6 +282,8 @@ function LogsButtonContent({ item }: LogsButtonProps) {
258282 showPrevious,
259283 showTimestamps,
260284 follow,
285+ prettifyLogs,
286+ formatJsonValues,
261287 onReconnectStop : ( ) => {
262288 setShowReconnectButton ( true ) ;
263289 } ,
@@ -277,6 +303,7 @@ function LogsButtonContent({ item }: LogsButtonProps) {
277303 if ( selectedContainer ) {
278304 clearLogs ( ) ;
279305 setAllPodLogs ( { } ) ; // Clear aggregated logs when switching pods
306+ setHasJsonLogs ( false ) ;
280307
281308 // Handle paused logs state
282309 if ( ! follow && logs . logs . length > 0 ) {
@@ -296,8 +323,17 @@ function LogsButtonContent({ item }: LogsButtonProps) {
296323 let lastLogLength = 0 ;
297324 cleanup = pod . getLogs (
298325 selectedContainer ,
299- ( { logs : newLogs } : { logs : string [ ] ; hasJsonLogs ?: boolean } ) => {
326+ ( {
327+ logs : newLogs ,
328+ hasJsonLogs : newHasJsonLogs ,
329+ } : {
330+ logs : string [ ] ;
331+ hasJsonLogs ?: boolean ;
332+ } ) => {
300333 if ( ! isSubscribed ) return ;
334+ if ( newHasJsonLogs ) {
335+ setHasJsonLogs ( true ) ;
336+ }
301337
302338 setLogs ( current => {
303339 const terminalRef = xtermRef . current ;
@@ -310,10 +346,12 @@ function LogsButtonContent({ item }: LogsButtonProps) {
310346 const endIdx = Math . min ( startIdx + CHUNK_SIZE , newLogs . length ) ;
311347
312348 // Process only the new chunk of logs
313- const newLogContent = newLogs
314- . slice ( startIdx , endIdx )
315- . join ( '' )
316- . replaceAll ( '\n' , '\r\n' ) ;
349+ const logSlice = newLogs . slice ( startIdx , endIdx ) ;
350+ const displaySlice =
351+ prettifyLogs && newHasJsonLogs
352+ ? logSlice . map ( log => colorizePrettifiedLog ( log ) )
353+ : logSlice ;
354+ const newLogContent = displaySlice . join ( '' ) . replaceAll ( '\n' , '\r\n' ) ;
317355
318356 terminalRef . write ( newLogContent ) ;
319357 lastLogLength = endIdx ;
@@ -342,6 +380,8 @@ function LogsButtonContent({ item }: LogsButtonProps) {
342380 showPrevious,
343381 showTimestamps,
344382 follow,
383+ prettifyLogs,
384+ formatJsonValues,
345385 onReconnectStop : ( ) => {
346386 if ( isSubscribed ) {
347387 setShowReconnectButton ( true ) ;
@@ -359,7 +399,18 @@ function LogsButtonContent({ item }: LogsButtonProps) {
359399 cleanup ( ) ;
360400 }
361401 } ;
362- } , [ selectedPodIndex , selectedContainer , lines , showTimestamps , follow , clearLogs , t , pods ] ) ;
402+ } , [
403+ selectedPodIndex ,
404+ selectedContainer ,
405+ lines ,
406+ showTimestamps ,
407+ follow ,
408+ clearLogs ,
409+ t ,
410+ pods ,
411+ prettifyLogs ,
412+ formatJsonValues ,
413+ ] ) ;
363414
364415 // Effect to process logs when allPodLogs changes - only for "All Pods" mode
365416 React . useEffect ( ( ) => {
@@ -496,6 +547,40 @@ function LogsButtonContent({ item }: LogsButtonProps) {
496547 disabled = { false }
497548 />
498549 </ LightTooltip >
550+
551+ { /* Prettify JSON logs switch */ }
552+ { hasJsonLogs && (
553+ < PaddedFormControlLabel
554+ label = { t ( 'translation|Prettify' ) }
555+ control = {
556+ < Switch
557+ checked = { prettifyLogs }
558+ onChange = { handlePrettifyChange }
559+ size = "small"
560+ sx = { { transform : 'scale(0.8)' } }
561+ />
562+ }
563+ />
564+ ) }
565+
566+ { /* Format JSON values switch */ }
567+ { hasJsonLogs && (
568+ < LightTooltip
569+ title = { t ( 'translation|Show JSON values in plain text by removing escape characters.' ) }
570+ >
571+ < PaddedFormControlLabel
572+ label = { t ( 'translation|Format' ) }
573+ control = {
574+ < Switch
575+ checked = { formatJsonValues }
576+ onChange = { handleFormatJsonValuesChange }
577+ size = "small"
578+ sx = { { transform : 'scale(0.8)' } }
579+ />
580+ }
581+ />
582+ </ LightTooltip >
583+ ) }
499584 </ Box > ,
500585 ] ;
501586
0 commit comments