Logs.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import React, { Fragment, PureComponent } from 'react';
  2. import { LogsModel, LogRow } from 'app/core/logs_model';
  3. interface LogsProps {
  4. className?: string;
  5. data: LogsModel;
  6. }
  7. const EXAMPLE_QUERY = '{job="default/prometheus"}';
  8. const Entry: React.SFC<LogRow> = props => {
  9. const { entry, searchMatches } = props;
  10. if (searchMatches && searchMatches.length > 0) {
  11. let lastMatchEnd = 0;
  12. const spans = searchMatches.reduce((acc, match, i) => {
  13. // Insert non-match
  14. if (match.start !== lastMatchEnd) {
  15. acc.push(<>{entry.slice(lastMatchEnd, match.start)}</>);
  16. }
  17. // Match
  18. acc.push(
  19. <span className="logs-row-match-highlight" title={`Matching expression: ${match.text}`}>
  20. {entry.substr(match.start, match.length)}
  21. </span>
  22. );
  23. lastMatchEnd = match.start + match.length;
  24. // Non-matching end
  25. if (i === searchMatches.length - 1) {
  26. acc.push(<>{entry.slice(lastMatchEnd)}</>);
  27. }
  28. return acc;
  29. }, []);
  30. return <>{spans}</>;
  31. }
  32. return <>{props.entry}</>;
  33. };
  34. export default class Logs extends PureComponent<LogsProps, any> {
  35. render() {
  36. const { className = '', data } = this.props;
  37. const hasData = data && data.rows && data.rows.length > 0;
  38. return (
  39. <div className={`${className} logs`}>
  40. {hasData ? (
  41. <div className="logs-entries panel-container">
  42. {data.rows.map(row => (
  43. <Fragment key={row.key}>
  44. <div className={row.logLevel ? `logs-row-level logs-row-level-${row.logLevel}` : ''} />
  45. <div title={`${row.timestamp} (${row.timeFromNow})`}>{row.timeLocal}</div>
  46. <div>
  47. <Entry {...row} />
  48. </div>
  49. </Fragment>
  50. ))}
  51. </div>
  52. ) : null}
  53. {!hasData ? (
  54. <div className="panel-container">
  55. Enter a query like <code>{EXAMPLE_QUERY}</code>
  56. </div>
  57. ) : null}
  58. </div>
  59. );
  60. }
  61. }