React LogViewer
React component that loads and views remote text in the browser lazily and efficiently. Logs can be loaded from static text, a URL, a WebSocket, or an EventSource and including ANSI highlighting.
Forked from mozilla-frontend-infra/react-lazylog.
If you like this project, please consider supporting me ❤️
Features
- Efficient scrolling performance thanks to react-window
- Able to load large files upwards of 100MB without crashing the browser
- Parses, colorizes, and styles ANSI escapes within content
- Supports remote text files as well as chunked/streamed responses
- Line highlighting
- Customizable styling
- Searching through log
- Works in latest browser versions, including iOS Safari and Android Chrome
- TypeScript support
Demo
You can see a running demonstration at https://melloware.github.io/react-logviewer/ which is built from StoryBook.
Installation
Install the plugin with npm or yarn:
$ npm i --save @melloware/react-logviewer
Getting started
The core component from react-logviewer is LazyLog
. There is also a higher-order component (HOC) for
following logs until scroll. This module can be required via ES imports, CommonJS require, or UMD.
import { LazyLog } from "@melloware/react-logviewer";
const { LazyLog } = require("@melloware/react-logviewer");
<LazyLog />
Usage
After importing a component, it can be rendered with the required url
prop:
import React from "react";
import { render } from "react-dom";
import { LazyLog } from "@melloware/react-logviewer";
render(<LazyLog url="http://example.log" />, document.getElementById("root"));
By default the LazyLog
will expand to fill its container, so ensure this container has valid dimensions and layout.
If you wish to have fixed dimensions, change the height
and width
props.
If you are going to be rendering a complete file, or an endpoint which can be downloaded all at once, use the
<LazyLog />
component as-is for better overall performance at the expense of slightly longer upfront load time.
If you are going to be requesting a streaming or chunked response, use the <LazyLog stream />
component with the
stream
prop of true
for quicker upfront rendering as content can be decoded as it arrives. |
<ScrollFollow />
ScrollFollow
is a higher-order component (HOC) that aims to simplify toggling a LazyLog
's
"follow" functionality based on user scrolling.
Usage
The ScrollFollow
component accepts a render prop function which should return a component to render based on the
function's arguments.
[!NOTE]
ScrollFollow must be wrapped in an element that contains a fixed height such as a <div>
import React from "react";
import { render } from "react-dom";
import { LazyLog, ScrollFollow } from "@melloware/react-logviewer";
render(
<div style={{ height: 500, width: 902 }}>
<ScrollFollow
startFollowing={true}
render={({ follow, onScroll }) => (
<LazyLog url="http://example.log" stream follow={follow} onScroll={onScroll} />
)}
/>
</div>,
document.getElementById("root"),
);
Styling
All of the components exposed from react-lazylog use CSS modules to contain its styles to each individual component. If
you wish to override these styles, there are a few techniques you can use.
style
and containerStyle
For the core container of <LazyLog />
, you can pass a style
object prop to affect many styles.
For affecting the look or behavior of the scrollable region of these components, use the containerStyle
prop with a
styling object.
defaultProps.style
For many react-logviewer components, continually passing varied styling objects is tedious. To make this simpler, you can
override the defaultProps.style
of any desired component to override styles of that component. For example:
import Line from "@melloware/react-logviewer/build/Line";
Line.defaultProps.style = {
color: "green",
};
Note: overriding the ANSI colors and styles is currently undocumented, and will probably need some source-diving to
figure out. I would gladly accept a pull request that could improve the styling API.
CSS stylesheets
If you are using CSS stylesheets, you can target the main virtual LazyList
component with the react-lazylog
class name. From there you can target the individual div
lines, a
line numbers, or span
line content.
Sub-components
react-lazylog uses a number of sub-components internally to render individual parts of the log-viewing component:
<Line />
A single row of content, containing both the line number and any text content within the line.
<LineNumber />
The line number of a single line. The anchor contained within is interactive, and will highlight the entire line upon
selection.
<LineContent />
The container of all the individual pieces of content that is on a single line. May contain one or more LinePart
s
depending on ANSI parsing.
<LinePart />
An individual segment of text within a line. When the text content is ANSI-parsed, each boundary is placed within its
own LinePart
and styled separately (colors, text formatting, etc.) from the rest of the line's content.
Technology
- React Window for efficiently rendering large lines of data
fetch
API for efficiently requesting data with array buffers and binary streams- ansiparse for nice log styling, like Travis
- mitt for dead-simple events to manage streaming lifecycle
- Immutable for efficiently storing and managing very large collections of lines and highlight ranges
Uint8Array
for dealing with text content as binary, allows for conditionally rendering partial data and decoding everything without crashing your browser
Development and Contributing
- Fork and clone this repo.
- Install the dependencies with
npm
. - Start the development server with
npm run dev
. This will launch a StoryBook instance.
Open a browser to http://localhost:6006 to preview the React components. - Use CTRL-C to exit the StoryBook.
- Use
npm run build
to generate the compiled component for publishing to npm.
Publishing
Adjust the version in the package.json
if necessary, then
npm login
npm publish --access public
Then upload code to github, create tag & release.
License
Licensed under the Mozilla Public License 2.0 license.
SPDX-License-Identifier: Mozilla Public License 2.0