| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  | import { cx } from '@emotion/css'; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | import memoizeOne from 'memoize-one'; | 
					
						
							|  |  |  | import React, { PureComponent } from 'react'; | 
					
						
							|  |  |  | import Highlighter from 'react-highlight-words'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 02:24:41 +08:00
										 |  |  | import { CoreApp, findHighlightChunksInText, LogRowModel } from '@grafana/data'; | 
					
						
							|  |  |  | import { ClipboardButton, IconButton } from '@grafana/ui'; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { LogMessageAnsi } from './LogMessageAnsi'; | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  | import { LogRowStyles } from './getLogRowStyles'; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export const MAX_CHARACTERS = 100000; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  | interface Props { | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |   row: LogRowModel; | 
					
						
							|  |  |  |   wrapLogMessage: boolean; | 
					
						
							|  |  |  |   prettifyLogMessage: boolean; | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |   app?: CoreApp; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |   showContextToggle?: (row?: LogRowModel) => boolean; | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |   onOpenContext: (row: LogRowModel) => void; | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |   styles: LogRowStyles; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function renderLogMessage( | 
					
						
							|  |  |  |   hasAnsi: boolean, | 
					
						
							|  |  |  |   entry: string, | 
					
						
							|  |  |  |   highlights: string[] | undefined, | 
					
						
							|  |  |  |   highlightClassName: string | 
					
						
							|  |  |  | ) { | 
					
						
							|  |  |  |   const needsHighlighter = | 
					
						
							|  |  |  |     highlights && highlights.length > 0 && highlights[0] && highlights[0].length > 0 && entry.length < MAX_CHARACTERS; | 
					
						
							|  |  |  |   const searchWords = highlights ?? []; | 
					
						
							|  |  |  |   if (hasAnsi) { | 
					
						
							|  |  |  |     const highlight = needsHighlighter ? { searchWords, highlightClassName } : undefined; | 
					
						
							|  |  |  |     return <LogMessageAnsi value={entry} highlight={highlight} />; | 
					
						
							|  |  |  |   } else if (needsHighlighter) { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       <Highlighter | 
					
						
							|  |  |  |         textToHighlight={entry} | 
					
						
							|  |  |  |         searchWords={searchWords} | 
					
						
							|  |  |  |         findChunks={findHighlightChunksInText} | 
					
						
							|  |  |  |         highlightClassName={highlightClassName} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return entry; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const restructureLog = memoizeOne((line: string, prettifyLogMessage: boolean): string => { | 
					
						
							|  |  |  |   if (prettifyLogMessage) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       return JSON.stringify(JSON.parse(line), undefined, 2); | 
					
						
							|  |  |  |     } catch (error) { | 
					
						
							|  |  |  |       return line; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return line; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  | export class LogRowMessage extends PureComponent<Props> { | 
					
						
							| 
									
										
										
										
											2022-09-29 20:51:20 +08:00
										 |  |  |   onShowContextClick = (e: React.SyntheticEvent<HTMLElement, Event>) => { | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |     const { onOpenContext } = this.props; | 
					
						
							|  |  |  |     e.stopPropagation(); | 
					
						
							|  |  |  |     onOpenContext(this.props.row); | 
					
						
							| 
									
										
										
										
											2022-09-29 20:51:20 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-23 20:36:05 +08:00
										 |  |  |   onLogRowClick = (e: React.SyntheticEvent) => { | 
					
						
							|  |  |  |     e.stopPropagation(); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getLogText = () => { | 
					
						
							|  |  |  |     const { row, prettifyLogMessage } = this.props; | 
					
						
							|  |  |  |     const { raw } = row; | 
					
						
							|  |  |  |     return restructureLog(raw, prettifyLogMessage); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |   render() { | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |     const { row, wrapLogMessage, prettifyLogMessage, showContextToggle, styles } = this.props; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |     const { hasAnsi, raw } = row; | 
					
						
							|  |  |  |     const restructuredEntry = restructureLog(raw, prettifyLogMessage); | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |     const shouldShowContextToggle = showContextToggle ? showContextToggle(row) : false; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return ( | 
					
						
							| 
									
										
										
										
											2022-10-05 22:11:08 +08:00
										 |  |  |       <> | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           // When context is open, the position has to be NOT relative. // Setting the postion as inline-style to
 | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |           // overwrite the more sepecific style definition from `styles.logsRowMessage`.
 | 
					
						
							| 
									
										
										
										
											2022-10-05 22:11:08 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |         <td className={styles.logsRowMessage}> | 
					
						
							| 
									
										
										
										
											2022-10-05 22:11:08 +08:00
										 |  |  |           <div | 
					
						
							|  |  |  |             className={cx( | 
					
						
							|  |  |  |               { [styles.positionRelative]: wrapLogMessage }, | 
					
						
							|  |  |  |               { [styles.horizontalScroll]: !wrapLogMessage } | 
					
						
							|  |  |  |             )} | 
					
						
							|  |  |  |           > | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |             <button className={cx(styles.logLine, styles.positionRelative)}> | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |               {renderLogMessage(hasAnsi, restructuredEntry, row.searchWords, styles.logsRowMatchHighLight)} | 
					
						
							| 
									
										
										
										
											2022-12-21 21:45:47 +08:00
										 |  |  |             </button> | 
					
						
							| 
									
										
										
										
											2022-10-05 22:11:08 +08:00
										 |  |  |           </div> | 
					
						
							|  |  |  |         </td> | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |         <td className={cx('log-row-menu-cell', styles.logRowMenuCell)}> | 
					
						
							| 
									
										
										
										
											2023-06-06 02:24:41 +08:00
										 |  |  |           <span className={cx('log-row-menu', styles.rowMenu)} onClick={this.onLogRowClick}> | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |             {shouldShowContextToggle && ( | 
					
						
							| 
									
										
										
										
											2023-06-06 02:24:41 +08:00
										 |  |  |               <IconButton | 
					
						
							|  |  |  |                 size="md" | 
					
						
							|  |  |  |                 name="gf-show-context" | 
					
						
							|  |  |  |                 onClick={this.onShowContextClick} | 
					
						
							| 
									
										
										
										
											2023-06-08 16:23:28 +08:00
										 |  |  |                 tooltip="Show context" | 
					
						
							|  |  |  |                 tooltipPlacement="top" | 
					
						
							| 
									
										
										
										
											2023-06-06 02:24:41 +08:00
										 |  |  |               /> | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |             )} | 
					
						
							| 
									
										
										
										
											2023-05-23 20:36:05 +08:00
										 |  |  |             <ClipboardButton | 
					
						
							|  |  |  |               className={styles.copyLogButton} | 
					
						
							|  |  |  |               icon="copy" | 
					
						
							|  |  |  |               variant="secondary" | 
					
						
							|  |  |  |               fill="text" | 
					
						
							|  |  |  |               size="md" | 
					
						
							|  |  |  |               getText={this.getLogText} | 
					
						
							|  |  |  |               tooltip="Copy" | 
					
						
							|  |  |  |               tooltipPlacement="top" | 
					
						
							|  |  |  |             /> | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |           </span> | 
					
						
							|  |  |  |         </td> | 
					
						
							| 
									
										
										
										
											2022-10-05 22:11:08 +08:00
										 |  |  |       </> | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |