Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Button to download the logs #41

Open
WillDaSilva opened this issue Aug 29, 2024 · 6 comments
Open

Button to download the logs #41

WillDaSilva opened this issue Aug 29, 2024 · 6 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@WillDaSilva
Copy link

It would be great if the LazyLog component could have an optional button to download the logs. This would be more efficient than adding a button outside the component, since the component has already made the request to get the logs, whereas a button outside of it would have to re-download them from the server.

@melloware melloware added enhancement New feature or request good first issue Good for newcomers labels Aug 29, 2024
@melloware
Copy link
Owner

I would assume this would only work in text mode as if its WebSocket you don't have the complete log or are you just saying dump to the download whatever the component has currently.

@WillDaSilva
Copy link
Author

I saw that the component keeps track of when it's finished streaming logs, so I figured that by default we could have the download button work for text and url mode. The button could be greyed out until the download/stream (for url mode) is done, and then become available.

Additional options could be added to enable downloading incomplete logs, which would let it support websockets too, or download mid-stream, and an option to control the name of the file that is downloaded.

@WillDaSilva
Copy link
Author

Maybe instead of a download button specifically, this could just be an option that takes a function that will be called with the contents of the logs. Or maybe there's some other way to access the content within the state of this component from outside of it, so that more features could be implemented that use the log data. I'm a beginner with React, so I'm not sure what's possible (or advisable) here.

@melloware
Copy link
Owner

Yeah I think exposing the data somehow in the component ref so you could do ref.current?.lines or something like that.

@WillDaSilva
Copy link
Author

Thank you for that pointer @melloware! I was able to implement a download button like so:

export default function StreamingLogs({ logId }: Props) {
  let url = '...';
  const [logComponent, setLogComponent] = useState<LazyLog | null>(null);

  const download = useCallback(() => {
    if (!logComponent) {
      console.error('No log component available to download from.');
      return;
    }
    const lines = logComponent.state.lines.toArray();
    if (lines.length < 1) {
      console.error('No bytes available to download.');
      return;
    }
    const link = document.createElement('a');
    link.href = URL.createObjectURL(new Blob(lines, { type: 'text/plain' }));
    link.download = `${logId}.log`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(link.href);
  }, [logComponent, logId]);

  return (
    <div className="flex flex-col items-start gap-2" >
      <Button className="mb-2 ml-auto pr-6" onClick={download}>
        <LuDownload className="mr-2" /> Download
      </Button>
      <div className="h-[80vh] w-full overflow-auto">
        <LazyLog
          ref={setLogComponent}
          caseInsensitive // Case insensitive search
          enableHotKeys // Use Ctrl-f or Cmd-f to search
          enableLineNumbers
          enableLinks
          enableSearch
          enableSearchNavigation
          extraLines={1}
          fetchOptions={{ credentials: 'include' }}
          selectableLines
          stream
          url={url}
        />
      </div>
    </div>
  );
}

I tried to use useRef initially, but I wasn't able to get a non-null log component within the download function without useCallback.

It's nice that this workaround exists, but having a built-in download button feature would be better, so I'd encourage keeping this issue open.

@melloware
Copy link
Owner

Thanks this looks pretty good. I feel like this should be able to be made into a download button on the LazyLog toolbar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants