Coder Social home page Coder Social logo

cryostatio / cryostat-web Goto Github PK

View Code? Open in Web Editor NEW
10.0 6.0 20.0 13.03 MB

Web front-end for Cryostat: Secure JDK Flight Recorder management for containerized JVMs

Home Page: https://cryostat.io/

License: Other

JavaScript 1.09% TypeScript 97.49% HTML 0.05% CSS 1.37%
react patternfly openshift kubernetes hacktoberfest cryostat hacktoberfest2021

cryostat-web's Introduction

cryostat-web

CI Google Group : Cryostat Development

Web front-end for Cryostat, providing a graphical user interface for managing JFR on remote JVMs.

Based on Patternfly React Seed.

SEE ALSO

  • cryostat-core for the core library providing a convenience wrapper and headless stubs for use of JFR using JDK Mission Control internals.

  • cryostat-operator for an OpenShift Operator facilitating easy setup of Cryostat in your OpenShift cluster as well as exposing the Cryostat API as Kubernetes Custom Resources.

  • cryostat for the JFR management service.

REQUIREMENTS

  • Node v16+
  • Yarn v3.3.0+

BUILD

Setup dependencies

$ yarn install --immutable

Run a production build

$ yarn build
# or without tests
$ yarn build:notests

DEVELOPMENT SERVER

Development environment supports hot reload with Webpack's Hot Module Replacement.

With Cryostat

First, launch a Cryostat instance with CORS enabled by setting CRYOSTAT_CORS_ORIGIN to http://localhost:9000. For example:

$ cd /path/to/cryostat
$ CRYOSTAT_DISABLE_SSL=true CRYOSTAT_CORS_ORIGIN=http://localhost:9000 sh run.sh

Then, run:

$ yarn start:dev

Without Cryostat

To quickly preview changes without launching a Cryostat instance, run:

$ yarn start:dev:preview

In this case, API requests are intercepted and handled by Mirage JS.

TEST

Run the unit tests

$ yarn test

Run the integration tests

$ yarn itest:preview

Refer to TESTING.md for more details about tests.

Run the linter

ESLint is a linter that checks for code quality and style. Configuration can be found in .eslintrc.

The ESLint job runs on every pull request, and will fail if there are any ESLint errors. Warnings will not fail the job.

To fix this, run:

$ yarn eslint:apply

You can also run yarn eslint:check to see if there are any ESLint issues without applying the fixes.

To run a development server with ESLint enabled in hot-reload mode, run:

$ yarn start:dev:lint

With this command, ESLint will run on every file change, and will show ESLint errors/warnings in the terminal.

Run the code formatter

Prettier is a code formatter that makes sure that all code is formatted the same way. Configuration can be found in .prettierrc. There is a prettierignore file that tells Prettier to ignore certain files.

The license header checking job makes sure that all files have the correct license header. The npm package can be found here. The license header can be found in LICENSE. The license-check-and-add configuration can be found in license-config.json.

The Format job runs on every pull request, and will fail if the code is not formatted correctly, or if some licenses have not been added to some files.

To fix this, format the code:

$ yarn format:apply

You can also run yarn format:check to see if there are any formatting issues without applying the formatting.

Inspect the bundle size

$ yarn bundle-profile:analyze

LOCALIZATION

To generate translation entries for texts in the app, run:

$ yarn localize

The extraction tool is i18next-parser, which statically finds and exports translation entries, meaning i18next-parser does not run code and requires explicit values. See more details.

To workaround this, specify static values in i18n.ts file under any top-level directory below src/app. For example, src/app/Settings/i18n.ts.

Refer to LOCALIZATION.md for more details about our localization framework.

CONTRIBUTING

Code consistency

  • [*].types.ts(x): Define type definitions, including types and enums.
  • [*].utils.ts(x): Define utility functions. These might contain constants (usually tightly coupled with the utility functions).
  • [*].const.ts: Define constants. These constants are purely for UI rendering.
  • [*].context.tsx: Define React contexts. These can be defined in util files.

Code contribution

See CONTRIBUTING.md.

cryostat-web's People

Contributors

aali309 avatar alexjsenn avatar andrewazores avatar aptmac avatar dependabot-preview[bot] avatar dependabot[bot] avatar ebaron avatar gunnarmorling avatar hareetd avatar jiekang avatar jobayer12 avatar josh-matsuoka avatar maxcao13 avatar mwangggg avatar tabjy avatar tthvo avatar vic-ma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cryostat-web's Issues

HTTP Basic auth should be supported

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.

[Task] "Sub"views should be routable

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.

View in Grafana

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.

Refactor connection states

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).

Reports should not be automatically requested upon list item expansion

Due to cryostatio/cryostat#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.

UI for event templates

Related to #34 and #36

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.

Auth token dialog should be customizable for deployment types

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.

UI should expose some way to manually connect to target JVMs

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.

View for customizing recording options

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.

Recording re-upload does not include auth token

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.

[react] Tab sets should have consistent widths

Tabsets are used in various pieces of the React rewrite of the Web client. We need to decide if these should span the width of the container (card) in all cases, or if they should only be as wide as needed for each tab title. Then all tabsets should be made consistent in their widths.

image
image
image

List recordings

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.

https://invis.io/3MWWKS9DYAP

Support user-inputted times

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.

Use new backend /health endpoint

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.

Improve error messages/notifications

#59 (comment)

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.

"ALL" meta-template should not be downloadable

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.

Re-selecting a target causes view refresh

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.

[react] State management

As detailed in some recent PR comments:

#73 (comment)

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.

Recording table headings and columns are misaligned

Here's a recent screenshot from @Alexjsenn illustrating the problem:
image

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.

[design] Recording's options (max age, max size, toDisk) should be discoverable

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.

Selecting a target that fails to connect leaves previous content in recording list view

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).

View recording reports

Users should be able to view an HTML Rules Report for a given recording in some in-line report view

Recording download failure should not save "not found" file

#118 (comment)

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.

Switching target selection does not cause view update

Ex.

  1. Set up a sample app other than ContainerJFR itself
  2. Go to Recordings view
  3. Select the ContainerJFR target
  4. Create a recording
  5. Select the other target

The recording list should update with an empty list, but the content remains the same and displays data from the ContainerJFR instance.

Use HTTP APIs wherever applicable

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.

Routing to in-application paths is broken when served via ContainerJFR webserver

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.

[react] Documentation, Discussion, and Issues links

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.

Path segments are not escaped

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.

"Error from chokidar" when Starting Web Client

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.

Authorization headers are unset

Since cryostatio/cryostat#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.

Support using jfc profiles from the JDK

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.