Showing posts with label JavaFX. Show all posts
Showing posts with label JavaFX. Show all posts

Tuesday, September 27, 2016

Computed metrics for HawkFX (updated)

Computed metrics are something I wanted to do for a very long time, already in RHQ, but never really got around it and sort of forgot about it again.

Lately I found a post that contained a DSL to do exactly this (actually you should read that post not because of the DSL, but because of the idea behind it).

After seeing this, I got the idea on what to do and to include this in HawkFX, my pet project, which is an explorer for Hawkular.

HawkFX screen shot
HawkFx with the input window for formulae, that shows a formula and also a parser error.
The orange chart shows Non-Heap used, the redish one the heap usage of a JVM.

Formulae

Formulas are in a DSL that looks a bit like UPN, e.g. as in the following (I've shortened the metric ID for readability, more on them below):

(+ metric( "MI~...Heap Used" , "max")
   metric( "MI~...NonHeap Used", "max"))

to sum up two metrics (see also screenshot below). The 'metric' element gets two parameters, the metric id and also which of the aggregates that the server sends should be taken (in this case the max value) - this comes from the fact that we request the values to be put into 120 buckets by the server.

Or if you have the total amount of memory you could also subtract the used memory to get a graph of the remaining:

(- 1000000 metric( "MI~...NonHeap Used", "max"))

You could also get the total wait time for responses at a point in time when you multiply the average wait time with the number of visitors:

(* metric("MI~..ResponseTime","avg")
   metric("MI~..NumberVisitors","sum"))

Computed total memory usage

Summing up the metrics for 'Heap Used' and 'NonHeap Used' as shown above would then give you a nice graph of the total memory consumption of a JVM:

Chart with computed metric
The green chart now shows to combined memory usage of Heap and Non-Heap, which is computed from the other two series. Orange and red are as above.

On metric IDs

Metric IDs are the IDs under which a metric is stored inside of Hawkular. The example here comes from an installation of Hawkular-services in Docker. If you just feed your metrics into Hawkular metrics, the IDs will looks like the ones you are using.

ID and path field
ID (upper) and path fields (lower) for a selected item in the tree

I have just pushed an update to HawkFX that provides the ID and path in their own fields at the bottom of the main window, so you can copy&paste them.

Future

I will talk more about the parser in an upcoming article. For now it is a personal playground to also better understand what is doable here. If this turns out to be successful I can imagine that the DSL could directly be incorporated into Hawkular-metrics so that the rules are available to all metrics clients.

It would of course be cool to have an editor for the formulas that allows to interactively pick metric IDs etc, but I doubt that I will get to this any time soon.

Monday, May 09, 2016

Introducing HawkFX

As I said before, I started playing with JRubyFX. And for me learning something new best works with a use case, so I started creating an inventory browser for Hawkular.

Why JRubyFX?

Let's first start with "What is JRubyFX" anyway? JRubyFX is JavaFX brought to the Ruby world by the means of JRuby. This means that you can implement UIs with the help of the JavaFX framework and use its components and tools to build the UI. The difference to plain JavaFX is though that all the implementation code is written in Ruby and run by JRuby on the JVM.

I was doing a bit of JavaFX in the past and I wanted to generate a standalone inventory browser for Hawkular. Now that I have been working with Ruby lately and we already have the Hawkular client gem, I thought I'd give JRubyFX a try.

And I have to say this is pretty cool.

Some screenshots

login screen
Login screen
Main screen with chart
Main screen with inventory browser (left) and metric chart

The main screen shows a tree view on the left that displays the feeds as top level elements. Opening a feed will show recursively the resources and metrics. Clicking on a metric gets it charted on the right side.

Alerts and Events
Alert and Event list

A menu item in the main screen opens the alerts browser that allows to peek at alerts and events in the system.

Like in the main screen, there is a context menu that will allow to view the raw object as shown below:

Raw event display
Raw display of an event

Custom components

The time range picker on the main screen and alert screen is a custom component, that was implemented once with a .fxml file and some Ruby code:

class TimePicker < Java::javafx::scene::layout::HBox
  include JRubyFX::Controller

  fxml 'TimePicker.fxml'

  def initialize(caller, callback)
[..]
end

Including it is pretty simple too:

    box = find '#alertEventTopBox'
    box.children.add time_picker(self, :set_time_range)

In the first line we find the HBox to add the picker and then just add it to the children of the box. Done.

Running and code

HawkFX is available on my GitHub account at https://github.com/pilhuhn/hawkfx. To run the tool you need JRuby 9

If you are using rvm you can select it via

rvm use jruby-9.0.5.0

install and use bundler to install the required gems

gem install bundler bundle install

then run

jruby hawkfx.rb

Enjoy! :-)

Sunday, March 20, 2016

Playing with JRubyFX

I started looking at JRubyFX as a combination of using a proven UI solution with Ruby as the programming language and I have to admit that I am impressed with how little it takes to get a UI done -- especially when it is driven by FXML.

Unfortunately the learning curve is steep, as one has to learn JavaFX and the special way JRubyFX calls the JavaFX classes and methods. And unfortunately, Google is not returning too much results here.

Anyway: this little code already creates GUI and populates a TreeView with elements it pulls from a remote server.

require 'jrubyfx'
require 'hawkular_all'

fxml_root File.dirname(__FILE__)

class HawkFx < JRubyFX::Application

  def start(stage)
    with(stage, title: 'Hello World!', width: 800, height: 600) do
      fxml HawkFxController
      show
    end

    stage.show()
  end
end

class HawkFxController
  include JRubyFX::Controller
  fxml 'fxmain.fxml'

  def login # callback from the login button
    creds = { :username => 'jdoe' ,
              :password => 'password' }
    url = 'http://localhost:8080/hawkular/inventory'
    @inventory_client = Hawkular::Inventory::InventoryClient.new(url, creds)
    @tenant = @inventory_client.get_tenant
    @FXMLtextArea.text = "Tenant: #{@tenant}"
    feeds = @inventory_client.list_feeds

    show_initial_tree(feeds)

  end

  def show_initial_tree(feeds)
    tree_root = tree_item('Feeds') do
      feeds.each do |feed|
        item = tree_item(feed) # this already adds the item to the root
      end
    end
    # bind to the view from fxml
    @FXMLtreeView.setRoot(tree_root)

    tree_root.setExpanded true
  end
end

HawkFx.launch

Monday, July 15, 2013

JavaFX UI for the RHQ plugin generator (updated)

In RHQ we have a tool to generate initial plugin skeletons, the plugin generator. This is a standalone tool, that you can use to get going with plugin development.
This is for example described in the "How to write a plugin" article.

Now my colleague Simeon always wanted a graphical frontend (he is very much in favor of graphical frontends, while I am one of those old Unix-neckbeards :). Inspired from this years Java Forum Stuttgart I sat down on the weekend and played a bit with JavaFX. The result is a first cut of UI frontend for the generator:

UI for the plugin generator

On top you see a message bar, that shows field validation issues, the middle is the part where you enter the settings and at the bottom you get a short description for each property.

I've pushed a first cut, that is not yet complete, but you will get the idea. Help is always appreciated.
Code is in RHQ git under modules/helpers/pluginGen.

[update]

I continued working a bit on the generator and have added a possibility to give a directory that contains classes that have been annotated with the annotations from the org.rhq.helpers:rhq-pluginAnnotations module.

Screenshot scan-for-annotations

A class could look like this


public class FooBean {

@Metric(description = "How often was this bean invoked",
displayType = DisplayType.SUMMARY,
measurementType = MeasurementType.DYNAMIC,
units = Units.SECONDS)
int invocationCount;

@Metric(description = "Just a foo", dataType = DataType.TRAIT)
String lastCommand;

@Operation(description = "Increase the invocation count")
public int increaseCounter() {
invocationCount++;
return invocationCount;
}

@Operation(description = "Decrease the counter")
public void decreaseCounter(@Parameter(description
= "How much to decrease?", name = "by") int by) {
invocationCount -= by;
}

And the generator would then create the respective <metric> and <operation> elements in the plugin descriptor - in this case you don't need to select the two "Has Metrics/Operations" flags above.

Now this work is still not finished. And in fact it would be good to find a common set of annotations for a more broader scope of projects.