cryostatio / cryostat-web Goto Github PK
View Code? Open in Web Editor NEWWeb front-end for Cryostat: Secure JDK Flight Recorder management for containerized JVMs
Home Page: https://cryostat.io/
License: Other
Web front-end for Cryostat: Secure JDK Flight Recorder management for containerized JVMs
Home Page: https://cryostat.io/
License: Other
Since cryostatio/cryostat-legacy#86 , container-jfr optionally enables an authorization manager which requires auth tokens to be presented on certain requests. -web needs to ask the user to provide such a token and pass it along with each such request.
HTTP APIs should be used rather than WebSocket Command Channel APIs wherever applicable. There is currently a large amount of overlap in the APIs, but the HTTP (REST) APIs are preferred and the Command Channel equivalents will be deprecated down the line, once the web-client has switched.
Not all potential target JVMs will appear in the auto-discovery dropdown box populated by the container-jfr scan-targets command. In particular, accessible targets listening on a port other than 9091 will not be discovered. The UI needs some way to allow the user to connect to such targets regardless. In a Kubernetes-type scenario where service discovery can be performed by environment variables, perhaps the target list can include these targets but without a specified connection port, which the user then must supply when connecting to the target. In port-scan fallback scenarios there should be a way for the user to supply both the host/IP of the target as well as its port.
Due to cryostatio/cryostat-legacy#8 , report generation should require an explicit step from the user, rather than being automatically requested when exposing the start/stop/delete action buttons. Due to the aforementioned issue it can become impossible for a user to stop or delete a large recording without crashing the container-jfr backend, unless they resort to using a direct WebSocket connection via eg websocat
and manually sending the command to stop/delete the recording.
The CommandChannel/TargetSelect interaction in #82 is somewhat broken. The target connection port is not included in the connection identifier state set in the CommandChannel, so commands causing connections to targets using non-default ports will always fail.
Here's a recent screenshot from @Alexjsenn illustrating the problem:
The table headings of Name, Start Time, Duration, and State are not correctly aligned with the values in their columns (testing, timestamp, 30s, RUNNING). These should be correctly aligned in a vertical line so that ex. "testing" is directly below "Name", with both left-justified within the visual column whitespace.
When I start the web client with npm run dev:start
, I get a bunch of errors beginning with "Error from chokidar":
...
Error from chokidar (/home/vma/container-jfr-web/node_modules/@patternfly/react-tokens/dist/js): Error: ENOSPC: System limit for number of file watchers reached, watch '/home/vma/container-jfr-web/node_modules/@patternfly/react-tokens/dist/js/l_split.js'
Error from chokidar (/home/vma/container-jfr-web/node_modules/@patternfly/react-tokens/dist/js): Error: ENOSPC: System limit for number of file watchers reached, watch '/home/vma/container-jfr-web/node_modules/@patternfly/react-tokens/dist/js/l_split_m_gutter_MarginRight.d.ts'
Error from chokidar (/home/vma/container-jfr-web/node_modules/@patternfly/react-tokens/dist/js): Error: ENOSPC: System limit for number of file watchers reached, watch '/home/vma/container-jfr-web/node_modules/@patternfly/react-tokens/dist/js/l_split_m_gutter_MarginRight.js'
...
The web client works as expected though. Is this anything to worry about? @Alexjsenn told me he gets the same errors.
Users should be able to view an HTML Rules Report for a given recording in some in-line report view
There should be a way for users to customize the recording options (max age, max size, to disk, etc. - see RecordingOptionsCustomizer
in container-jfr). This is kept as internal state in container-jfr, but it may (or may not) make sense to implement this in a way that it appears to be associated with each individual new recording as it is created.
React client users should be able to upload recordings (active or achived) to jfr-datasource and see the associated Grafana dashboard in a new tab.
The UI allows selection from a list of times. Instead it should allow users to input a time; something like:
time := <number><unit> | 'unlimited'
number in set of Integers greater than 0
unit in {s, m, h, d}
e.g.
5s
30m
2h
1d
etc.
Ex.
The recording list should update with an empty list, but the content remains the same and displays data from the ContainerJFR instance.
The JVM ships default and profile jfc files (e.g. in Fedora openjdk11: lib/jfr/.jfc)
JMC UI supports selecting either of these. The UI should also allow users to select either of these when configuring a recording
Users should be able to input custom jfc files from their machine when configuring recordings
Api.service.ts
, and perhaps other sites as well, perform HTTP requests with unescaped components that are interpolated into path segments. This causes various breakages due to the invalid paths, ex. attempting to download a template results in an ".xml" file that really contains index.html
.
Missed this during review. The http.post performed by the archived recording component to (re-)upload recordings does not include the service auth token, so it will be rejected if the deployment includes an active auth manager.
Maybe the upload function should also be moved into the api service, mirroring the download function.
When the user attempts to download a recording and the download fails (ex. another client has deleted the recording but the first client's web-client data is out of date), the user receives a "foo.jfr" file with the contents "foo not found". This should instead cause an error notification to be displayed and no file to be downloaded.
The ContainerJFR backend has a new /health
endpoint, which can 1) provide information about the status of the ContainerJFR instance itself (ie response code 200
means it's alive, otherwise not) and 2) provide information about the Grafana/jfr-datasource configurations. ContainerJFR Web should use this endpoint to initialize its own Grafana/jfr-datasource configuration, rather than making separate requests to the current endpoints which respond 500
when no configuration exists.
This also raises the opportunity to remove the notifications that are displayed when Grafana/jfr-datasource configuration requests fail, or to at least consolidate them into a single notification.
Users should be able to create recordings with variable durations, user-provided names, and user-specified event types/templates. Snapshot recordings should also be supported.
Add-on following #28 and relating to cryostatio/cryostat-legacy#103 . Currently the auth token is sent via WebSocket SubProtocol as-is, ie what the user enters is what is appended to the subprotocol header. This should be first base64 encoded before being appended to the header string.
The current auth token dialog contains a message like "for example, if this is an OpenShift deployment", and a blurb about how to get an appropriate access token to paste in. This message should come from container-jfr and be tailored to the deployment platform.
Currently the API service and command channel service both only support token auth. That is, the API service only knows how to send Authorization: Bearer FOO
headers, and the command channel only knows the base64url.bearer.authorization.containerjfr.FOO
subprotocol. They should support Authorization: Basic
headers and basic.authorization.containerjfr
subprotocols, respectively. Related: #37 , since these two additions also require base64 encoding of the credentials. This is also related to #23 since there should be some tailored message instructing the user how to input their basic auth credentials.
Clicking the target selection dropdown and selecting a target, then repeating this for the same target, causes a refresh of the main view. This is noticeable when the main view is Recordings and a report frame is open. Re-selecting the same target should not cause views to be redrawn or network requests to be re-issued. If the main view needs a way to refresh its content then this should be implemented within the view itself.
As detailed in some recent PR comments:
We need to investigate client-side state management to simplify how different views can share the same application state, rather than needing to reinitialize their own local view of the state when mounted, and also to help prevent spurious data refreshes when things update that are not really local client state (ex. button clicks to expand/collapse menus etc.) but rather simple view state.
See #60
Supported event types should be viewable in a list or table view.
Some kind of UI should be implemented allowing for users to easily discover which templates are available and what those templates might be useful for, along with some way to easily select these templates when creating a new recording. This should still allow the user to input their own customized event specifier strings as well.
The command-channel.service
should expose the status of command channel and target JVM connections in a way that is easy for components, or other services, to consume. This should encode all of: (command channel | target JVM) x (not connected/unknown | connected | error)
.
The API responses from /api/v1/targets/:targetId/recordings
includes details on each recording about their maxAge/maxSize/toDisk option settings, but there is no UI element that exposes this information to the user. Since #103 adds a way for users to customize these settings and change their values from the defaults when a recording is created, there should also be a corresponding way for the user to see the values of these settings for each recording.
When in recording list view, if a target is selected and it fails to connect (for example a 404 error is thrown), the recording list maintains its previous state. If for example a list of recordings of a different target were being viewed, after clicking on the new unreachable target, the target selector shows the unreachable target is selected but the list continues to display the first target's recordings. There should be a loading state that clears the view in preparation for a new incoming list (and remains empty if the target fails to connect).
All templates currently have a "Download" action, allowing the user to download the template definition as XML to their local machine. The "ALL" template is not a real XML template however - its name is a special token used by ContainerJFR to signify a meta-template computed at runtime. When an attempt is made to download the ALL "template", the response body is simply "Not Found", which is then written into the "ALL.xml" saved to the user's machine. Instead, the ALL template simply should not be downloadable - the action button should be removed or disabled for this template entry.
This is really a bug against rh-jmc-team/container-jfr , but it's only really visible when using the web-client submodule.
When running ContainerJFR with a "full" image (including -web assets), it is not possible to directly visit web-client in-app routes such as /recordings
or /events
. ie visiting http://10.130.228.106:8181
works and brings the user to the home/dashboard page of the client. For the new React client, which has actual in-app routing, visiting http://10.130.228.106:8181/recordings
breaks and displays a Resource not found
page from the ContainerJFR embedded webserver. Clearly, the webserver is trying to serve a file named recordings
, which does not exist. Somehow, this needs to be translated into bootstrapping the web-client as if the user had visited /
, and then passing the /recordings
path on as a route to the bootstrapped client.
Users should be able to view a list of recordings including details such as name, start time, duration, and state. Users should also be able to archive active recordings. The list view should be able to display either active or archived recordings, or possibly both.
As in the pull request review above, the error messages sent from ContainerJFR could use some improvement. In some cases errors are only reflected in response status codes, with no meaningful payload text. In other cases there is payload text included, but this text may be simply raw, unformatted text (no JSON wrapping etc.), and with no particular well-established conventions. This makes it difficult for ContainerJFR Web or other clients to consume these messages and produce meaningful notifications for end users.
cryostatio/cryostat-legacy#166
When the backend command channel API for the upload-recording
command is updated to assume that the datasource URL should be the one configured on the ContainerJFR deployment, the -web client must also be updated to not include the datasource URL as an argument when sending this command message.
The Web client should have some kind of links to documentation (README, tutorials, wiki, etc.), discussion (mailing list, public IRC/Slack channel), and Issues (GitHub) so users are supported if they run into problems or have suggestions and don't need to go searching for where/how to make reports.
This feature was present in the old Angular client and has not yet been ported to the React client.
Supported event templates should be viewable in a list or table view.
In a CRC instance with the operator deployed, I can reproduce an internal server error when creating a recording for some application, clicking 'View in Grafana' and then clicking 'Download'.
After clicking the button to upload/view a recording in Grafana, two "Upload Success" notifications appear and two tabs for the Grafana Dashboard are opened.
For example, the Recordings view has a card with Active and Archived tabs. When visiting the route /recordings
, the general top-level card view is what is routed and this defaults to displaying the Active tab. Both the Active and Archived tabs should be reachable by in-app routing, so that users can bookmark or link to specific subviews, and to ensure that view state is preserved as much as possible should the user close/reopen or refresh the browser tab.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.