FusionReactor Blog - News and expert analysis for Java APM users.

Screencast – Using the FusionReactor Profiler to find slow code

In this awesome video by CF and Coldbox developer advocate Brad Wood – we see how to use FusionReactor features such as the request Profiler to identify several bottlenecks of slow code in a ColdFusion

Remember though that the overhead is actually really small in comparison to the benefit you get. In this video, the profile probably took under 45ms in total. So for a 9-second request that’s not bad!

How I improved Angular performance and page responsiveness

For a little while now I’ve had issues with DOM rendering performance within an enterprise scale product, built using Angular. I’ve always tried to follow some common approaches1 to improving and maintaining high performance within an Angular application.

The main approaches I’ve taken to combat performance degradation over time within this application are as follows;

Working outside the Angular zone

	/**
	 * Loop outside of the Angular zone
	 * so the UI does not refresh after each setTimeout cycle
	 */
	logOutsideOfAngularZone() {
		this.ngZone.runOutsideAngular(() => {
			setTimeout(() => {
				// reenter the Angular zone and display a console log
				this.ngZone.run(() => { console.log('Outside Done!'); });
			});
		});
	}

Adjusting ChangeDetection Strategies

@Component({
	selector       : 'app-my-component',
	template       : `
		<h1>Title</h1>
	`,
	changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MyComponent implements OnInit, OnDestroy
{
	constructor(private cdRef: ChangeDetectorRef) {}
	public ngOnInit(): void {}
}

Using trackBy Functions with *ngFor

@Component({
	selector       : 'app-my-component',
	template       : `
		<h1>Title</h1>

		<li *ngFor="let person of people; trackBy:trackByFunction">{{person.name}}</li>
	`,
})
export class MyComponent implements OnInit, OnDestroy
{
	public people: any[] = [
		{ id: 123, name: 'John' },
		{ id: 456, name: 'Doe' },
	];

	constructor() {}
	public ngOnInit(): void {}

	public trackByFunction = (index: number, person: any): number => person.id;
}

While using all these techniques listed above, did result in isolated and localized increases in page performance, I still suffered from an overall application-wide DOM rendering performance problem. This was perceivable to me as what I consider to be page rendering lag where by elements of the page are visible at given dimensions and positioned a given way, then ping to their correct position and dimensions. Another visible indicator of this issue was noticeable delays in mouse hover queues, such as subtle underlines, css animations and tooltip display.

The Culprit! my position-to-bottom directive

After further investigation I discovered that one thing this product made use of that my other products did not, was a directive, the position-to-bottom directive.

export class PositionToBottomDirective implements OnDestroy, AfterViewInit
{
	private readonly ngUnsubscribe: Subject<any> = new Subject();

	constructor(private readonly el: ElementRef, private readonly zone: NgZone) {
		this.el.nativeElement.style.height = 'auto';
	}

	public ngOnDestroy(): void {
		this.ngUnsubscribe.next();
		this.ngUnsubscribe.complete();
	}

	public ngAfterViewInit(): void {
		setTimeout(() => this.calcSize());

		this.zone.runOutsideAngular(() => {
			fromEvent(window, 'resize')
				.pipe(debounceTime(500), takeUntil(this.ngUnsubscribe))
				.subscribe((res: any) => this.calcSize());
		});
	}

	public calcSize(): void {
		let viewport: { top: string };

		this.zone.runOutsideAngular(() => {
			viewport = this.el.nativeElement.getBoundingClientRect()
		});

		const offset: number = parseInt(viewport.top, 10) + 10;
		const height: string = `calc(100vh - ${ offset }px)`;

		this.el.nativeElement.style.overflowY = 'auto';
		this.el.nativeElement.style.height = height;
	}

From the code snippet above, you can see that this directive was relatively simple. Upon initialization and after every browser resize event, each component this directive was attached to would have it’s height set to the available space within the window.

Use of the RxJS debounceTime2 and Angular’s runOutsideAngular3 functionality I had hoped to mitigate the impact this directive would have on the performance of the product, as I knew Angular’s change detection will be called for every asynchronous browser event4.

Unfortunately this was not enough so I removed the the use of this directive in favor of CSS Flexbox (probably should have used this to begin with :D). After removing the use of this directive I saw a 61% increase in page responsiveness. This was calculate using the top 10 Total time consuming activities.

Top 10 time consuming activities before removal of this directive
Top 10 time consuming activities after removal of this directive

Black Friday Sale 2019

Voucher Code FR-DEV-SAVER-19

Half Price FusionReactor Developer Edition annual license

To get a year’s license for FusionReactor Developer Edition at half price use coupon code FR-DEV-SAVER-19 at checkout. Hurry offer ends 30 November 2019.

What is FusionReactor Developer Edition?

The FusionReactor Developer Edition can be used in development and test environments (*) to help you to pinpoint issues and performance bottlenecks before applications are deployed to production.

It has all the same features and functionality of the FusionReactor Ultimate Edition which is used all over the world by Java and CFML developers who are looking for deep insight into their code.

What does FusionReactor Developer Edition do?

High level features

FusionReactor Developer has all of the features that you would expect to find in a APM

  • Application monitoring
    • Transactions, web requests, JSON, JMX, Kafka, Java & CF
  • Database monitoring – JDBC requests 
    • Slowest requests, numbers of requests and any errors
  • End User monitoring 
    • Sessions, DB time, request time – live and aggregated 
  • System monitoring for your instance and your system & server
    • CPU, heap and non-heap, garbage collection information, thread state 

Low level deep insight

If you are looking for deep insight then FusionReactor delivers

  • Automated root cause analysis – automated delivery of code, scope variables and stack when an issue arises 
  • Production safe debugging with a user friendly IDE style debugger 
  • Advanced profiling
    • Code profiler insight into code performance issues 
    • The memory profiler enables you to isolate memory leaks and excessive object creation 
    • The thread profiler will detect thread contention, deadlocks and show thread state 
    • The CPU profiler analyses the CPU usage per running thread and will enable you to find performance bottlenecks

Who would use FusionReactor Developer Edition

FusionReactor Developer Edition is used by Java and CFML developers around the globe who need deep insight into their applications during development and testing stages.

How do I buy FusionReactor Developer Edition

The easiest way to buy FR Developer is directly from us; don’t forget to use this coupon code FR-DEV-SAVER-19 at checkout and get the annual license for half price saving $100.

FusionReactor Developer Edition Usage Policy (EULA)

FusionReactor Developer Edition enables you to develop, test, evaluate and analyze applications which are running in a non-production environment. The Developer Edition may not be used to monitor an application which is running in a live or stand-by production environment or staging environment, in each case, including, without limitation, in any environment accessed by application end- users, including, but not limited to, servers, workstations, kiosks, and mobile computers.

FusionReactor ends support for Java 1.6

FusionReactor will be dropping support for Java 1.6 with FusionReactor 8.3.0. This release is currently scheduled for the end of this year / early 2020.

Fusionreactor 8.2.x releases will be the last micro releases to support Java 1.6.

FusionReactor customers have been moving off Java 1.6 for some time and only 0.3% of FusionReactor 8 users are still using Java 1.6.

Oracle ended its “Extended Support” on December 2018.

IBM ended its support of Java 1.6 with its “End of Service” on September 2018.

Configuring and Disabling log tracking in FusionReactor

Introduction

FusionReactor tracks calls to any logging implementation made within your application. These logs are captured within the request object and can be configured based on their log severity.

We capture log statements for both Java frameworks and CF log statements;

Java Frameworks

  • SLF4J
  • Log4J
  • Logback
  • Apache Commons Logging

CFML log tags

  • ColdFusion log tags
  • Lucee log tags

In this blog we will cover how to configure framework log capture and how to disable log capture all together if you believe FusionReactor log tracking is causing issues in your application.

Configuring Java Framework log tracking in FusionReactor

It is possible to configure the logging severity for captured requests by going to FusionReactor (Top Left) > Plugins > Active Bundles, then modifying the configuration of the  FusionReactor Log Tracker Plugin.

In the configuration, you can capture log statements for error and above, warning and above, fatal only or no log statements at all.

Disabling log tracking in FusionReactor

If you have sensitive information in log statements, or believe that FusionReactor is causing an issue with log capture, you can disable log tracking.

To do this you will need to deploy a properties file, as well as add a system property to your application server.

Creating the fusionreactoragent.properties file

In order to disable pointcuts into the logging Frameworks that FusionReactor makes using ASM, you will need to create a properties file in the same directory as your fusionreactor.jar file.

By default this will be {FusionReactor Directory}/instance/{instance name}, so on your server you may see;

  • /opt/fusionreactor/tomcat/fusionreactor.jar
  • C:\\FusionReactor\instance\CF2018\fusionreactor.jar

In this directory you should create a file with the name ‘fusionreactoragent.properties’

In this file should contain;

com.intergral.fusionreactor.agent.pointcuts.logtracker.SLF4JPointCut=false

com.intergral.fusionreactor.agent.pointcuts.logtracker.Log4J2PointCut=false

com.intergral.fusionreactor.agent.pointcuts.logtracker.ColdFusionCFLOGPointCut=false

com.intergral.fusionreactor.agent.pointcuts.logtracker.LuceeCFLOGPointCut=false

Adding system properties

FusionReactor uses mixins as well as cuts into the application code to track certain frameworks. In order to disable these mixins you will need to add the following system property to your jvm arguments file;

  • -Dfr.mixin.apache.commons.logging=false

In ColdFusion, your jvm arguments are typically set in the jvm.config file, which is located in the {ColdFusion Directory}/cfusion/bin directory.

In tomcat / lucee, your jvm arguments are typically located in the setenv.sh file for unix, or through running the TomcatW.exe process in Windows. These files are located under the {Tomcat Directory}/bin directory.

For a full list of configuration files for the supported application server types see Application Server Examples 

Restarting the Application server

In order to apply these changes, you will need to restart the application server.

  • On windows this would typically involve restarting the Tomcat / ColdFusion service. 
  • On Linux this will normally involve running the restart command on the Tomcat / ColdFusion executable file.

You should now no longer see log statements on any transactions as FusionReactor is no longer interacting with the logging frameworks.

The Top Application Performance Monitoring (APM) Software for Small-Business

We have been on the G2 Review site for a little under a year; we have encouraged our customers to leave reviews on G2 and have made it to the top of the Best APM for Small business category by customer satisfaction. This makes us very proud as it is our customers who have placed us here and we thank them for their kind words and continued commitment to FusionReactor.

G2.com is a real-time and unbiased user review website that specializes in business software. It uses algorithms to calculate scores based on detailed reviews that real (and verified) customers leave.

The team at FusionReactor has always been proud of our software and our service and historically we have always had extremely good reviews from the FeeFo service.

We are competing with some very big players and indeed very big budgets so you can imagine our delight to be ranked #1 APM for Small business. Winning an overall satisfaction score of 91 out of 100

number 1 APM for Small business
The Top Application Performance Monitoring (APM) Software for Small-Business

Some of the competitors in the Small Business category of APM

Invaluable Insights with FusionReactor

Our reviews are from customers who use our APM with Java and ColdFusion applications. Looking through our reviews you will quickly see that customers particularly like the depth of insight that FusionReactor gives its users.

I love the ability to immediately gain insight into actual, real world production issues and the system factors behind them. From system resources to network or database congestion and conflicts, it’s all right there at your fingertips

Easily the best tool I’ve used for root causes analysis on the JVM – and one of the cheapest too

FusionReactor provides amazing insight into the server health, specifically in regards to the way ColdFusion is operating. The reporting and visualization into the server are fantastic!

See all of our G2 reviews

See our FeeFo reviews

Start a free trial

The Runtime service is not available – ColdFusion 2018

A few days ago I got an error with my ColdFusion 2018 server which I had not seen in many years.

coldfusion.server.ServiceFactory$ServiceNotAvailableException: The Runtime service is not available.
	at coldfusion.server.ServiceFactory.getRuntimeService(ServiceFactory.java:121)
	at coldfusion.graph.InteractiveGraphingServiceImpl.load(InteractiveGraphingServiceImpl.java:445)
	at coldfusion.graph.InteractiveGraphingServiceImpl.start(InteractiveGraphingServiceImpl.java:425)
	at coldfusion.server.CFService.setupGraphing(CFService.java:402)
	at coldfusion.server.CFService.start(CFService.java:688)
	at coldfusion.server.j2ee.CFStartUpServlet.startCFService(CFStartUpServlet.java:567)
	at coldfusion.server.j2ee.CFStartUpServlet.init(CFStartUpServlet.java:510)
	at javax.servlet.GenericServlet.init(GenericServlet.java:158)
	at coldfusion.bootstrap.ClassloaderHelper.initServletClass(ClassloaderHelper.java:121)
	at coldfusion.bootstrap.BootstrapServlet.init(BootstrapServlet.java:111)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1124)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1079)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:971)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4886)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1425)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1415)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1425)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1415)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:258)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at com.adobe.coldfusion.launcher.Launcher.run(Launcher.java:957)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at com.adobe.coldfusion.bootstrap.Bootstrap.init(Bootstrap.java:100)
	at com.adobe.coldfusion.bootstrap.Bootstrap.main(Bootstrap.java:185)

I had seen this error when running ColdFusion 9 many years ago but not for some time. I could not figure out what I had broken.

After some googling it seemed to be that I could have done something when I had installed ColdFusion 2018 Update 4. I could only find old articles on the web like https://community.adobe.com/t5/ColdFusion/Why-is-ColdFusion-throwing-a-500-Internal-Server-error-after/td-p/6626931 but nothing specific, so I tried the following

cd /opt/coldfusion2018/cfusion/hf-updates/
../../jre/bin/java -jar hotfix-004-314546.jar

After following the updater I checked the update.log which lives in the logs directory. There didn’t seem to be any issues with the update so I tried to start the CF servers again.

It didn’t work. I was presented with lots the exceptions like above and the server didn’t function. I was unable to access the CF admin UI but the logs didn’t tell me what could be wrong. I was very close to reinstalling CF 2018.

After some investigation and lots of frustration I remembered what I had been investigating when I last ran my CF 2018 server.

It was the Redis session storage with CF 2018. Specifically related to FRS-465. I had configured the session manager as shown below :

I no longer had the local redis server running (and had uninstalled it), but this was not just affecting sessions, it was completely breaking the CF admin UI preventing me from disabling the redis session storage.

After some help I found that I could remove the redis session manager by editing the libs/neo-runtime.xml file.

I change the var from

<var name='sessionStorage'><string>redis</string></var>

to

<var name='sessionStorage'><string>memory</string></var>

Now the ColdFusion 2018 server starts 🙂

FusionReactor delivers Fantastic insight

“Fantastic insight!”

What do you like best?

FusionReactor provides amazing insight into the server health, specifically in regards to the way ColdFusion is operating. The reporting and visualization into the server are fantastic!

What do you dislike?

Really not much I can say here. We rarely have issues with FR as an application, but if we do the support group helps resolve it quickly.

Recommendations to others considering the product:

Where you’re finding issues with code and resources that aren’t easily identifiable or prompt resolution is critical, FusionReactor can really make a significant difference in you debugging and daily operations for overall application management!

What problems are you solving with the product? What benefits have you realized?

We can zero in on issues MUCH faster with FR and solve problems in a fraction of the time. When we have a lot of programmers providing code sometimes the most expensive part in debugging is finding the issue – with FR we can really hone in on the issue MUCH FASTER. The reporting and tools are second to none.

See review on G2

Start free trial

Configuring Ephemeral instances in the Enterprise Dashboard

In FusionReactor 8.1 we introduced the Ephemeral Data Service (EDS). This service allows you to register your transient / short-lived instances to the Enterprise Dashboard so they can all be monitored from a single location.

FusionReactor Enterprise Dashboard

Using EDS, you see each instance in your dashboard and have the ability to group these instances together to quickly see the health of either single instance or group of instances.

Specifically, with EDS you also gain access to secure tunnelling, this means when your instance spins up and registered with your Enterprise dashboard, a secured tunnel is created between the dashboard.

This allows data to flow between the instance and the dashboard to power metrics, but more importantly, it allows the Dashboard to view the user interface of the connected instance via a proxy.

Using the proxy means you can access the user interface of the running instance without having to expose a port to access FusionReactor, meaning your application can be locked down and secure without limiting access to your APM data.

Before we begin!

It is important to note that EDS ephemeral instances will only function if the instance is not already registered within the Enterprise Dashboard.

If you are converting to using EDS and have previously added instances to your Enterprise Dashboard manually or using the Dynamic Configuration using the -Dfrregisterwith JVM arguments, the servers must be removed from the Enterprise dashboard.

To do this you can go to the Manage Servers page and delete the instances.

To confirm if you have non ephemeral instances registered you can look for the entry for the instance in the Manage Servers page of FusionReactor. Ephemeral instances will not display here.

How to Configure the EDS?

Below is a full guide for running a dashboard and application instances via Docker.

Configuring the EDS requires you to set a few java arguments on both the instance running the Enterprise dashboard and the application instances.

We will be using Docker and Docker-compose to create our ephemeral instances to run the EDS setup.

Java Arguments

Passing Java arguments into your JVM can be done in a number of different ways and changes depending on the application server you are running. For a list of all the common locations see this doc.

The full list of available arguments for the EDS can be found here.

For our example we will be using only the required arguments:

  • -Dfr.ed.ds.enable=true – This argument allows the dashboard to use EDS connections
  • -Xmx512m – This argument increases the memory of the dashboard instance, as the secured tunnels and metrics are held in memory
  • -Dfr.ed.ds.target=fram:2106 – This argument tells the application instance which dashboard to register to

We will also be using the following arguments listed here to configure our instance settings automatically. These arguments are optional:

  • -Dfrlicense=X – This argument sets the license key used by the instance
  • -Dfradminpassword – This argument sets the administrator password for the instance

Docker Images

In our example, we created 2 simple docker images and a docker-compose file to run our EDS setup. All the files used in our example is available in our GitHub repository

Our FRAM instance uses an OpenJDK base image and the FusionReactor NoJRE installer. We are using a FRAM instance as it does not use an additional server seat so we do not need to pay for an extra license to run it.

Our Dockerfile contains the following:

FROM openjdk:12

ADD https://intergral-dl.s3.amazonaws.com/FR/Latest/FusionReactor_unix_nojre.tar.gz /opt

RUN tar -xvf /opt/FusionReactor_unix_nojre.tar.gz -C /opt

ADD start.sh /opt/fusionreactor/start.sh

EXPOSE 8087

WORKDIR /opt/fusionreactor/

CMD /opt/fusionreactor/start.sh

This docker image downloads the latest NoJRE installer, adds our custom start script with the required Java arguments and exposes the FRAM port 8087.

In the injected start.sh file we have:

#!/bin/bash

dir=`pwd`
LICENSE=${LICENSE:='XXXX-XXXX-XXXX-XXXX-XXXX'}
PASS=${PASS:='admin'}
java -javaagent:"$dir/instance/FRAM/fusionreactor.jar"=name=FRAM,address=:8087 -Dfrnopointcuts -Dfrstartupdelay=0 -Djava.awt.headless=true -Xmx512m -Dfr.ed.ds.enable=true -Dfrlicense=${LICENSE} -Dfradminpassword=${PASS} -cp "$dir/instance/FRAM/fusionreactor.jar" com.intergral.fusionreactor.agent.service.Service

In this bash file, we set the instance password and license key based on the environment variables LICENSE and PASS, and have our EDS server arguments in place.

Our Tomcat instance uses the tomcat base image. The Dockerfile contains:

FROM tomcat

RUN mkdir -p /opt/fusionreactor/instance/tomcat

ADD https://intergral-dl.s3.amazonaws.com/FR/Latest/fusionreactor.jar /opt/fusionreactor/instance/tomcat

ADD https://s3-us-west-1.amazonaws.com/intergral-dl/FR/Latest/libfrjvmti_x64.so /opt/fusionreactor/instance/tomcat

ADD runTomcat.sh /opt

RUN chmod =x /opt/runTomcat.sh

CMD /opt/runTomcat.sh

This file takes the base tomcat image, downloads the 2 FusionReactor files and adds a custom tomcat start script that allows us to set dynamic java arguments. The installation of FusionReactor is based off a manual instllation.

The tomcat start script looks like:

#!/bin/bash

LICENSE=${LICENSE:='XXXX-XXXX-XXXX-XXXX-XXXX'}
PASS=${PASS:='admin'}
TARGET=${TARGET:='fram'}
GROUPS=${GROUPS:='group1'}
export JAVA_OPTS="$JAVA_OPTS -javaagent:/opt/fusionreactor/instance/tomcat/fusionreactor.jar=address=8088,name=tomcat -agentpath:/opt/fusionreactor/instance/tomcat/libfrjvmti_x64.so -Dfrlicense=${LICENSE} -Dfr.ed.ds.target=${TARGET}:2106 -Dfradminpassword=${PASS} -Dfr.ed.ds.groups=${GROUPS}"
/usr/local/tomcat/bin/catalina.sh run

This file passes in the FusionReactor start arguments, the license key, admin password and the EDS target and groups are based off the environment variables LICENSE, PASS, TARGET and GROUPS.

Running the EDS setup

To run the EDS setup, we are using docker-compose. This allows us to configure services with environment variables and exposed ports, without needing to add them to our docker run commands each time.

Our docker-compose yml file is:

version: '3'
services:
    fram:
      image: fram
      container_name: fram
      ports:
        - "8187:8087"
      environment:
        - LICENSE=YOUR_LICENSE_HERE
        - PASS=admin1
    tomcat:
      image: edtomcat
      depends_on:
        - fram
      environment:
        - LICENSE=YOUR_LICENSE_HERE
        - PASS=admin2
        - TARGET=fram
        - GROUPS=production,tomcats

In this file we have our license key, passwords, target and groups specified and a dependency ensuring the FRAM dashboard is running before the tomcat instances deploy.

To run our EDS setup we can run docker-compose up –scale tomcat=X to run as many copies of the application as we require. Provided the memory option of -Xmx=512M has been set in the FRAM instance, it is possible for the dashboard to monitor around 10,000 instances.

Features of the EDS Enterprise Dashboard

With the EDS dashboard running, as instances start, stop or restart they will be removed and re-added to the dashboard as soon as they are running. This means as your instances scale up and down you can always get an accurate picture of the health of your infrastructure.

Group and Instance Health

The grouped cubes colour will change as your group health transitions from Error > Warning > OK.

The colour of the instance cube will indicate the health of the instance, you see the used heap memory, used CPU, number of active requests and number of active database calls with a quick glance.

The cubes will transition between OK, warning and error states based on configurable limits.

For the instance you can see an overview of the web metrics, without having to navigate to the instance to view the data.

Instance User Interface with Proxy

For each instance there is a link that will use the tunnel proxy to give you access to the instances user interface, without any ports of the application being exposed to the internet.

To access the instance through the tunnel, you can click the Arrow icon on the instance.

Using the tunnel applications could be completely locked down behind a firewall, load balancer or AWS security group and you can still access the FusionReactor data to diagnose any issues you are facing.

Using Active Directory to Log In to FusionReactor

Since FusionReactor 8.2, users with Enterprise licenses (or better) can use Microsoft Active Directory to log in to FusionReactor. In this blog post, we’ll covere how to set this up.

Introduction

In FusionReactor 8.2, we changed the way we handle logging you in and out behind the scenes. We still have the Role/Password system, and it’s still the basis of the authentication system, but we’re now able to provide other ways to authenticate you.

The first new authentication scheme we added in 8.2 is the Lightweight Directory Access Protocol, or LDAP. LDAP is used by large organizations to enable their users to log in to different systems, without having to set these users up on each and every system. There are several Directory Service products that are LDAP-enabled – and can therefore be used by FusionReactor – and Microsoft’s Active Directory system is an important and popular one.

Setting up Active Directory itself is a long and quite complicated process, and isn’t covered by this post. We’ll assume you have a working Active Directory environment already.

Prerequisites and Required Information

Here’s what you’ll need to have before you start configuration FusionReactor. Your Active Directory administrator will be able to supply this information.

Prerequisites

  • Your Active Directory server must have the features Lightweight Directory Services, AD DS Tools and AD DS and LDS Tools installed.
  • If your Active Directory server is firewalled, the LDAP port (usually 389) must be accessible to your FusionReactor instance.

Required Information

You’ll need to find out:

  • Whether your server uses/requires TLS encryption.
  • The IP address and port of your Active Directory server.
  • The X.500 Search Base – this what LDAP uses to limit queries against Active Directory.
    You can find this by running the following command in Command Prompt on your Active Directory server:
    dsquery * -scope base
  • The X.500 Distinguished Name (DN) address of a user able to read the directory. FusionReactor will connect as this user to use the directory.
    You can use the following command in Command Prompt to list all users:
    dsquery user
  • … and you’ll need the password of this user.

You’ll additionally need to have a strategy for mapping your Active Directory users to FusionReactor roles: Administrator, Manager, and Observer. Any roles you don’t have mappings for will be simply disabled – users won’t be able to log in to these roles.

One common strategy is to set up a new Active Directory User Group for each of the FusionReactor roles. You’ll need the Distinguished Name (DN) of the groups you’re going to use for these users. You can get this information in Command Prompt using the command dsquery group.

There are some additional prerequisites and rules for mapping users, and these are detailed in our User Manual.

Here are the details we’re using for our example:

  • No TLS encryption.
  • IP: 1.2.3.4 / 389
  • Search base: DC=testdomain,DC=com
  • User: CN=FusionReactor LDAP Reader,CN=Users,DC=testdomain,DC=com
  • Password: fusion4u
  • Active Directory group for FusionReactor Administrators: fradmins.

Now we can go ahead and configure FusionReactor.

Configuration FusionReactor

Navigate to FusionReactor > Manage Logins > FusionReactor X.500/LDAP Login to access the LDAP configuration section.

UI Elements

Many user interface elements can be configured for this login mechanism. We’ve set up some example data so you can see how it maps to the actual login screen. Here’s the configuration:

… and here’s the rendered login screen:

Active Directory Server Details

Here’s the configuration for the remaining details:

The Test Login button can be used to check these details are right. FusionReactor will try to log in to Active Directory using these details.

Now we’ll enter the filter for the Administrator user. Don’t worry about the syntax yet, we’ll cover that next. Any users matched by this filter in Active Directory will be able to log in as FusionReactor Administrator.

The Validate Filters button checks the syntax of the filters.

Finally we hit Save Login Settings to save this form.

To make LDAP the preferred login provider, go to FusionReactor > Manage Logins > Global Settings and set FusionReactor X.500/LDAP Login as the Preferred Identity Provider.

Now let’s have a look at the filter.

Crafting LDAP Filters

The filter we used to identify Administrators is as follows (we’ve formatted it so it’s easier to read).

(&
   (objectClass=user)
   (sAMAccountName={{USERID}})
   (memberof=CN=fradmins,CN=Users,DC=testdomain,DC=com)
)

LDAP filters are very powerful (more information). Here’s a breakdown of this one:

  • The ampersand means that all the conditions in this block must be true to match a record in the directory.
  • objectClass=user ensures that the filter only matches users. Active Directory can also store information about computers, printers and other resources. We are only interested in users.
  • sAMAccountName={{USERID}} means that whatever the user provides in the upper login input box (which we labelled Active Directory Username earlier) will be used to select an Active Directory record with that value as the Windows Logon ID (what Active Directory calls the SAM Account Name).
  • memberof=CN=fradmins,CN=Users,DC=testdomain,DC=com means that the user must be part of an Active Directory group called fradmins.

Conclusion

The ability to log in to any LDAP-enabled service opens up FusionReactor authentication to a whole new realm of Enterprise possibility. Active Directory is perhaps the most popular service for handling thousands of users, and FusionReactor’s LDAP interface allows these users to access FusionReactor without having to share a role password.