CFML Archives - FusionReactor Observability & APM https://fusion-reactor.com/tag/cfml/ Wed, 21 Aug 2024 19:57:40 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://fusion-reactor.com/wp-content/uploads/2024/03/cropped-icon-32x32.png CFML Archives - FusionReactor Observability & APM https://fusion-reactor.com/tag/cfml/ 32 32 VueJS 101 for CFML Devs https://fusion-reactor.com/blog/technical-blogs/vuejs-101-for-cfml-devs/ Tue, 07 Dec 2021 13:51:00 +0000 https://fusionreactor.dev.onpressidium.com/?p=66719 VueJS 101 for CFML Devs I’ve been stumbling across a fair few developers recently who like the idea of using VueJS, but are not sure how to get started. VueJS can be used to build whole applications, but sometimes the … Read More

The post VueJS 101 for CFML Devs appeared first on FusionReactor Observability & APM.

]]>

VueJS 101 for CFML Devs

I’ve been stumbling across a fair few developers recently who like the idea of using VueJS, but are not sure how to get started. VueJS can be used to build whole applications, but sometimes the requirement is to just build something within an existing CFML page to make the UI more dynamic and user-friendly. This set of examples is aimed at those of you who want to dip your toes into VueJS and might have an existing CFML application that you want to enhance.

We’re mainly going to focus on the question I get the most, which is “how to do I get my data from CFML to VueJS?”.

All the code is available on Github, but we’ll go through some of the key concepts each example brings. The setup is simple, one index file, and one “remote” cfm/cfc file which we’ll call via VueJS.

VueJS 101 example 1 – Simple Message

Our aim here is simple – pressing the button should do a request to our CFML page, and return a message.

Let’s look at the index.cfm first.

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

The first thing to note is we’re just going to use regular old script tags to import Vue. We’ll also import Axios, which is a library we’ll use to make our AJAX requests.

<div id="app">
{{ message }}
<br />
<button @click="getData">Get Message</button>
</div>

Then, we’ve got a div with an id of “app”: this is our Vue instance will operate within. Our JS markup uses `{{}}` to denote the value of a variable, and our button has an `@click` handler which calls the corresponding method in the methods block.

<script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' }, methods: { getData: function() { axios.get('remote.cfm') .then(function(response) { app.message = response.data.message; }) .catch(function(error) { console.log(error); }); } } }); </script>

Our main script block initializes the Vue instance and uses `el` to bind it to the div.

The data object is where you can define variable defaults; we’ll use a simple message variable to store the message we get back from our request.

Our methods block contains a single method, `getData()`, which is called when the button is clicked. It uses the Axios library to make a request to our CFML page and then sets the `message` variable to the response. If anything goes wrong, then the catch block will output the error to the console.

Our remote.cfm couldn’t be simpler;

header name="Content-Type" value="application/json"; data = { "message" = "Hi from CFML! The time is #now()#" }; writeOutput(serializeJSON(data));

We set the return type as JSON, create a new struct with a single field called “message”, and then return that via serializeJSON();

We can monitor the response in chrome dev tools.

Obviously, this is a very simple example: most of the time you’ll have a backend framework that will handle the incoming requests and allow you to pass back JSON easily.

VueJS 101 example 2 – Basic Array

The second example is equally simple, but this time we’ll output an array.

data: {
messages: []
},

The key difference is that in our data block, our messages js variable now defaults to an empty array.

<ul v-if="messages.length">
<li v-for="msg in messages">
{{ msg }}
</li>
</ul>

In our HTML output, the unordered list will only display when we have something via the “v-if” directive. Lastly, we’ll use a “v-for” directive to loop over the array and output the messages.

VueJS 101 example 3 – Simple Query

Next, we can try a CFML query. The Vue side is basically the same as the previous example, except we’re now renamed the array to `users`, and are outputting id, name and role within the loop.

<ul v-if="users.length">
<li v-for="user in users">
{{ user.id }} {{ user.name }} {{ user.role }}
</li>
</ul>

Our remote.cfm will now return a query result as an array.

header name="Content-Type" value="application/json";
data = queryNew(
"id,name,role",
"integer,varchar,varchar",
[
{"id"=1, name="Joe", role="admin"},
{"id"=2, name="Jane", role="user"},
{"id"=3, name="John", role="user"}
]
);
writeOutput(serializeJSON(data, "struct"));

If you return a query object via serializeJSON(), it will default to a different format, separating the columns and data; personally, I prefer the array of structs format, so in Lucee we can pass in the “struct” return type and it will do it all for us.

Example 4 – To-Do List

This last example is a bit more fleshed out – and we’ve included Bootstrap for some simple styling. It’s the ubiquitous “To-Do List” example.

Let’s look at the “backend” first; A simple CFC with some remote methods. We’re using an array in the session scope to store our to-do items.

private function setup(){
if(!structKeyExists(session, "items"))
session.items = [];
if (cgi.content_type EQ "application/json")
request.data = deserializeJSON(ToString(getHTTPRequestData().content));
}

Before each request, we check there’s an array in the session scope called “items”, and if not we’ll create it.

private function respond(){
header name="Content-Type" value="application/json";
return structKeyExists(session, "items") && isArray(session.items) ? session.items : [];
}

We’ll also set the request’s response type to be JSON.

remote function get() {
return this.respond();
}
remote function add() {
this.setup();
session.items.push({
"name": request.data.item,
"created": DateTimeFormat(now())
});
return this.respond();
}
remote function remove() {
this.setup();
ArrayDeleteAt(session.items, url.position);
return this.respond();
}
remote function clear(){
this.setup();
session.items = [];
return this.respond();
}

The `get()` function will simply return our array; `add()` will push an item to the array, and `remove()` will remove an item. `clear()` will remove all items.

There’s a bit more code in the index.cfm, so let’s go through some of the more notable changes.

The Axios configuration has changed slightly. There’s an instance of Axios which we’ve set to the `api` constant, set a timeout default of 5 seconds for any remote request, and used an interceptor to handle any errors.

const api = axios.create({
timeout: 5000
});
api.interceptors.response.use((response) => response, (error) => {
app.errors.push(error.message);
});

There’s now an error array in the Vue data object, which we’ll use to display any errors. The interceptor simply pushes any errors to this array, which are then looped over, alongside a simple dismiss button which resets the error array back to zero.

mounted: function() {
this.getItems();
},

The `mounted` function is triggered when the Vue component is initially loaded on the page – so within that, we’ll call our `getItems()` method to get the items from our remote `get` function in the CFC.

addItem: function() {
api.post('remote.cfc?method=add', {
item: this.newItem
})
.then(function(response) {
app.items = response.data;
app.newItem = null;
})
},

Inputting a new item uses one of the key concepts in Vue, that of the `v-model`, which binds a variable to the input value automatically. The `addItem()` method simply POSTs the new item to our remote `add` function. Since all the remote functions return the array back, we can just update the local array with the response.

One of the nice things about Vue is how it can easily enable and disable (or hide) elements. When Vue checks the validity of a variable, it will assume it’s invalid if it’s null, undefined of zero length. So you can see that the Add Button can be easily disabled when the input is empty.

<button class="btn btn-primary" :disabled="!newItem" @click="addItem">Add Item</button>

To remove an item, we’ll send the position of the clicked item in the javascript array (plus one, of course, remembering that JS arrays start at zero) to the remote `remove` function.

removeItem: function(position) {
api.delete('remote.cfc?method=remove&position=' + position)
.then(function(response) {
app.items = response.data;
})
}

Hopefully, this might have whetted your appetite a bit, and given you a few pointers to how you might start using VueJS in your existing CFML application.

The post VueJS 101 for CFML Devs appeared first on FusionReactor Observability & APM.

]]>
Why Load Test ColdFusion Apps (4 Reasons) https://fusion-reactor.com/blog/evangelism/why-load-test-coldfusion-apps-4-reasons/ Mon, 18 Jan 2021 11:58:18 +0000 http://fusionreactor.dev.onpressidium.com/?p=61659 By Michaela Light, CEO of TeraTech Let’s make sure that your new ColdFusion app doesn’t crash immediately after launch – by effective load testing. In this article, we will look at 4 reasons why load test ColdFusion Apps. You will … Read More

The post Why Load Test ColdFusion Apps (4 Reasons) appeared first on FusionReactor Observability & APM.

]]>

By Michaela Light, CEO of TeraTech

Let’s make sure that your new ColdFusion app doesn’t crash immediately after launch – by effective load testing.

In this article, we will look at 4 reasons why load test ColdFusion Apps. You will learn:

Why do you need to load test?

How to Easily Load Test and Make it a Routine

  1. Pick a load testing tool
  2. Write testing scripts that simulate real life
  3. Assess the results of the test
  4. Rinse and repeat your tests and fixes

The Long-term Benefits of Load Testing

About the Author

If you don’t plan ahead with load testing when too many users hit your newborn app at the same time, then it can become very slow or even crash your CF server. Leading to upset users, lost revenue for your company, and serious egg on the faces of everyone in your IT department.

In performance tuning circles, we call it “The Wall”. It’s hard to see it coming. But you’ll know when you’ve hit it.

“The Wall, in web applications, is that perfect storm of occurrences that suddenly, and within seconds, brings a web application to its knees. It is almost always caused by one thing: a stacking up of all available ColdFusion application threads. Which to be fair, is preceded, rather quickly, with a slow down in performance. 

There can be many reasons, a successful marketing campaign, a major event, an unexpectedly successful launch. Whatever the cause, it is possible to architect and build infrastructure that can cope with any load” – my colleague Mike Brunt (CF performance expert) says.

It’s a wall similar to the one faced by marathon runners. It’s when your body decides to call it quits and all systems fall apart.

Fortunately, you can avoid The Wall with load testing. Done properly, it can save you and your company a lot of time, money, and frazzled nerves. Let’s look in more detail at why you should load test.

Why Do You Need To Load Test ColdFusion Apps?

No ColdFusion team wants their new app to crash after launch. But sometimes under pressure, or due to lack of knowledge, you launch it too soon. Before it has been stress-tested under real load conditions. 

There are a few nasty side-effects of poorly-planned app launches that lead to crashes. This is typically caused by a sudden influx of traffic or users, spiking demand at times when resources are limited. It can bring your web app crashing down. It happens when you are stacking up all available application threads that collapse under their own weight.

  • Crashes can spook users, leading them to jump to your competitors. 
  • It will slow down your company’s critical operations that are dependent upon the app. This all leads to added costs.
  • Inevitably, you will have to call in the fire brigade to squeeze out new load capacity.
  • Perhaps worst of all: Bugs and server crashes will chase away customers and kill productivity. This, in tandem, hurts your company’s image. 

With proper load testing, you can discover your app’s weak points before the curtain opens on your launch to a live audience. With the right set up, you can enjoy pushing your app and server architecture to the limit, breaking them, and then fixing the resulting mess. All in a consequence-free setting. Makes me feel like a kid again!

Load testing your code and app is the most effective, least costly way to expose any weaknesses or mistakes in your work.

How To Easily Load Test ColdFusion Apps and Make It A Routine

1. Pick a load testing tool

Start with a load testing tool such as the free open-source Apache JMeter. It lets you write and playback user scripts that simulate real users running your app. You can include userIDs/passwords or other user data from data files to make the simulated users more realistic. And include random “thinking time”, just as humans delay between clicks or form submits. 

As you progress in load testing, you can consider the many paid load testing tools which add more features, with prices ranging from $100 to $100,000.

2. Write Testing Scripts That Simulate Real Life

Write a testing script that mimics real users interacting with your web app.
Make sure the “users” are as active and numerous as real-world users would be. They should be clicking, updating, refreshing, downloading, and generally frantically chewing over every inch of your app.

Turn up the load of simulated users through 3 levels:

  • Ramp up the number of users until your app slows down. 
  • Take it to the normal expected number of users and see how it performs.
  • Then get “a little bit naughty” – keep ramping up users until it finally breaks the server with a total crash. This is called a stress test and lets you find the ultimate limits to your code, architecture, and hardware setup. 

Note you should have fixed all regular bugs before you start load testing. I wrote about Testing and automated testing to help with that.

3. Assess The Results Of The Test

Now that your digital army of simulated users has done a great job of slowing down or crashing your app, you can get to work in analyzing why it happened. 

Load issues are usually caused by a combination of factors:

  • Software configuration issues, either for CF, IIS, JVM, databases
  • Poorly optimized software code that cannot handle an influx of activity
  • Badly designed database tables, indices, or queries
  • Speed issues with external services called by CFHTTP or REST API calls
  • Poor network configurations which get bogged down by increased demand
  • Incorrectly configured clustering and load balancing
  • Insufficient hardware (CPU, RAM, and disk space), which cannot meet the overall demands of running the app at peak load

You can learn more about fixing issues in this podcast interview I did with CF scaling expert Mike Collins.

I use a performance monitoring tool such as FusionReactor during load tests to make tracking down the cause of problems easier.

4. Rinse and Repeat Your Tests and Fixes

Keep load testing your app until:

  • You’re sure the expected number of users won’t slow down your app.
  • You can handle reasonable surges in users, of say 100% above the expected load. 
  • You are comfortable that the point that your server crashes under load is a high number of users. And given user growth predictions, that it is far enough into the future that you could buy extra hardware to prevent problems before they happen.

The Long-term Benefits of Load Test ColdFusion Apps

Load testing remains one of the more overlooked aspects of CF development. Many treat it as an afterthought. But it’s an early decision that could have long-term ramifications for the success of your web app, as well as the financial health of your company. Load test properly, or it could cost you big time. In the worst case, it can cause a company to go out of business.

Run tests that push the limits of your web apps and servers. This stress test will show your app’s breaking point, which will help you spot trouble ahead of time.

Be optimistic! Load testing is a part of coding where not planning for failure leads to ultimate failure after launch.

About the Author

Michaela Light Image

Michaela Light is the host of the CF Alive Podcast and has interviewed more than 100 ColdFusion experts. In each interview, she asks “What Would It Take to make CF more alive this year?” The answers still inspire her to continue to write and interview new speakers. Michaela has been programming in ColdFusion for more than 25 years. She founded TeraTech in 1989. The company specializes in ColdFusion maintenance, application development, security, and optimization. She has also founded the CFUnited Conference and runs the annual State of the CF Union Survey. 

The post Why Load Test ColdFusion Apps (4 Reasons) appeared first on FusionReactor Observability & APM.

]]>
Using The FusionReactor API (FRAPI) To Add Custom Instrumentation In Lucee CFML 5.2.9.40 https://fusion-reactor.com/blog/evangelism/using-the-fusionreactor-api-frapi-to-add-custom-instrumentation-in-lucee-cfml-5-2-9-40/ Mon, 27 Jan 2020 16:15:41 +0000 https://fronprem.dev.onpressidium.com/2020/01/27/using-the-fusionreactor-api-frapi-to-add-custom-instrumentation-in-lucee-cfml-5-2-9-40/ [vc_row][vc_column][vc_column_text] Written By Ben Nadel on January 25, 2020, original article reproduced with kind permission. Now that InVision is migrating from the New Relic APM to the FusionReactor APM (Application Performance Management) for our Lucee CFML servers, I wanted to take some time to familiarize myself with the API … Read More

The post Using The FusionReactor API (FRAPI) To Add Custom Instrumentation In Lucee CFML 5.2.9.40 appeared first on FusionReactor Observability & APM.

]]>
[vc_row][vc_column][vc_column_text]

Written By Ben Nadel on January 25, 2020, original article reproduced with kind permission.

Now that InVision is migrating from the New Relic APM to the FusionReactor APM (Application Performance Management) for our Lucee CFML servers, I wanted to take some time to familiarize myself with the API exposed by the FusionReactor Java Agent. On its own, the FusionReactor core functionality is already quite insightful. However, I am constantly using feature flags to experiment with code optimization; so, it would be even more helpful if I could graph the impact of my experimentation alongside the performance of our Lucee CFML 5.2.9.40 servers.

[/vc_column_text][us_separator][vc_column_text]

[/vc_column_text][us_separator][vc_column_text]

Much like the New Relic Java Agent, once you have the FusionReactor Java Agent installed, you can access its API directly from within your ColdFusion CFML code. I couldn’t find many examples of this online. So, much of what follows is based on an old article from the FusionReactor blog, dumping out the FRAPI Java Objects, and several bouts of trial-and-error.

To figure out how everything works, I created a small ColdFusion script that exercises several of the FRAPI methods in the context of a simulated feature flag. The idea below is to branch some CPU-intensive processing, and then use the FusionReactor API to help see which version of the code is more performant.

 

NOTE: The following CFML code has a lot of comments. Those represents all of the confusion that I had about how things worked, especially with regard to the differences between the Standalone dashboard and the Cloud dashboard.

[/vc_column_text][us_separator][vc_column_text]

<cfscript>
    
    // Get the running FusionReactor API (FRAPI) instance from the FRAPI factory class.
    // --
    // Java Docs: http://fusionreactor.dev.onpressidium.com/frapi/7_0_0/com/intergral/fusionreactor/api/FRAPI.html
    frapi = createObject( "java", "com.intergral.fusionreactor.api.FRAPI" )
        .getInstance()
    ;
    // ------------------------------------------------------------------------------- //
    // ------------------------------------------------------------------------------- //
    // By default, FusionReactor will use the name of the application as defined in the
    // Application.cfc ColdFusion framework component. However, we can set the name
    // programmatically.
    frapi.setTransactionApplicationName( "FRAPI-Testing" );
    // By default, FusionReactor will calculate the transaction name based on the request
    // context. It actually seems to "understand" the fact that we're using Framework One
    // (FW/1) in production and uses the "action" value as the transaction name. That's
    // the beauty of using an APM product that is embedded within the ColdFusion and CFML
    // community. That said, we can set the transaction name programmatically.
    // --
    // See Framework Support: http://fusionreactor.dev.onpressidium.com/support/kb/frs-431/
    frapi.setTransactionName( "GET/feature-flag-test" );
    // ------------------------------------------------------------------------------- //
    // ------------------------------------------------------------------------------- //
    // SIMULATE FEATURE FLAG setting.
    shouldUseExperiment = randRange( 0, 1 );
    // We can use the trace() method to aggregate arbitrary time-stamped data along with
    // the request. This data gets placed in a "Traces" tab in the Request detail.
    // --
    // CAUTION: At the time of this writing, this data is not accessible on the Cloud
    // dashboard, only on the STANDALONE dashboard. And, this data SHOULD NOT be
    // confused with the "Tracing" tab on the CLOUD dashboard, which is concerned with
    // nested Transactions only.
    frapi.trace( "Starting Experiment." );
    // Try tracing a Struct.
    frapi.trace({
        usingExpeirment: yesNoFormat( shouldUseExperiment )
    });
    // Try tracing an Array.
    frapi.trace([
        "DATE",
        dateFormat( now() ),
        "TIME (EST)",
        timeFormat( now() )
    ]);
    // Let's imagine that this page is going to represent two different algorithms: the
    // base one and an experimental one that we are testing with a feature flag. In
    // order to see if our experiment is worthwhile, we're going to track the relative
    // execution time of each approach.
    startedAt = getTickCount();
    // CASE: Experiment.
    if ( shouldUseExperiment ) {
        frapi.trace( "Starting experimental case." );
        // We can associate arbitrary key-value pairs with the request. These will show
        // up in the "Properties" tab of the request detail.
        // --
        // NOTE: At the time of this writing, these properties are not accessible on the
        // Cloud dashboard, only on the Standalone dashboard.
        frapi.getActiveTransaction()
            .setProperty( "Features - Optimizations - Test", "True" )
        ;
        // In addition to the timing metrics which we are going to record, we can also
        // create segments, aka "sub transactions", that help us map the relative
        // execution time for parts of the request.
        // --
        // NOTE: In the CLOUD dashboard, these show up in the "Traces" tab of a
        // Transaction detail. In the STANDALONE dashboard, these who up in the
        // "Relations" tab of a Transaction detail.
        // --
        // NOTE: In the CLOUD dashboard, these can also be found in the "Flavor" dropdown
        // of the Transactions tab. In the STANDALONE dashboard, these can also be
        // graphed under the Transactions section.
        // --
        // NOTE: When naming a transaction, I was running into issues in the STANDALONE
        // dashboard if I used any kind of path-style notation (either "/" or "."): only
        // the last segment of the "path" would show up, but would have no values.
        try {
            subtransaction = frapi.createTrackedTransaction( "HeavyProcessing-Exp-Start" );
            // SIMULTATE algorithm time.
            sleep( randRange( 25, 50 ) );
        } finally {
            subtransaction.close();
        }
        try {
            subtransaction = frapi.createTrackedTransaction( "HeavyProcessing-Exp-End" );
            // SIMULTATE algorithm time.
            sleep( randRange( 25, 50 ) );
        } finally {
            subtransaction.close();
        }
    // CASE: Default.
    } else {
        frapi.trace( "Starting default case." );
        // We can associate arbitrary key-value pairs with the request. These will show
        // up in the "Properties" tab of the request detail.
        // --
        // NOTE: At the time of this writing, these properties are not accessible on the
        // Cloud dashboard, only on the Standalone dashboard.
        frapi.getActiveTransaction()
            .setProperty( "Features - Optimizations - Test", "False" )
        ;
        // In addition to the timing metrics which we are going to record, we can also
        // create segments, aka "sub transactions", that help us map the relative
        // execution time for parts of the request.
        // --
        // NOTE: In the CLOUD dashboard, these show up in the "Traces" tab of a
        // Transaction detail. In the STANDALONE dashboard, these who up in the
        // "Relations" tab of a Transaction detail.
        // --
        // NOTE: In the CLOUD dashboard, these can also be found in the "Flavor" dropdown
        // of the Transactions tab. In the STANDALONE dashboard, these can also be
        // graphed under the Transactions section.
        // --
        // NOTE: When naming a transaction, I was running into issues in the STANDALONE
        // dashboard if I used any kind of path-style notation (either "/" or "."): only
        // the last segment of the "path" would show up, but would have no values.
        try {
            subtransaction = frapi.createTrackedTransaction( "HeavyProcessing-Base-Start" );
            // SIMULTATE algorithm time.
            sleep( randRange( 1000, 2500 ) );
        } finally {
            subtransaction.close();
        }
        try {
            subtransaction = frapi.createTrackedTransaction( "HeavyProcessing-Base-End" );
            // SIMULTATE algorithm time.
            sleep( randRange( 1000, 2500 ) );
        } finally {
            subtransaction.close();
        }
    } // END: Processing experiment.
    duration = ( getTickCount() - startedAt );
    // In addition to the Transaction-based recording we're doing above, we can also
    // record custom metrics which we can then graph in the FusionReactor dashboard.
    // --
    // NOTE: FusionReactor's documentation seems to use a path-style notation when naming
    // custom metrics. As such, I am just following the same pattern in the following
    // metric examples.
    // --
    // NOTE: The metrics are always available in the STANDALONE version of the
    // FusionReactor dashboard; but, to stream them to the CLOUD dashboard as well, the
    // metric has to be explicitly enabled with .enableCloudMetric(), and only works for
    // NUMERIC AGGREGATE metrics.
    if ( shouldUseExperiment ) {
        
        frapi.postNumericAggregateMetric( "/optimizations/exp/duration", duration );
        frapi.enableCloudMetric( "/optimizations/exp/duration" );
    } else {
        frapi.enableCloudMetric( "/optimizations/base/duration" );
        frapi.postNumericAggregateMetric( "/optimizations/base/duration", duration );
    }
    frapi.trace( "Ending Experiment." );
</cfscript>

<!--- ------------------------------------------------------------------------------ --->
<!--- ------------------------------------------------------------------------------ --->

<script>
    // Simulate regular throughput / traffic to this endpoint by refreshing.
    setTimeout(
        function() {
            window.location.reload();
        },
        1000
    );
</script>

view rawtest.cfm hosted with ❤ by GitHub

[/vc_column_text][us_separator][vc_column_text]

As you can see, this ColdFusion code runs, sits there for 1-second, and then refreshes itself using JavaScript. Within the code, I’m using the following FRAPI methods:

 

  • setTransactionApplicationName()
  • setTransactionName()
  • trace()
  • getActiveTransaction()
  • setProperty()
  • createTrackedTransaction()
  • postNumericAggregateMetric()
  • enableCloudMetric()

Let’s look at these methods individually to see what they do and how they show up in the various FusionReactor dashboards.

[/vc_column_text][us_separator][vc_column_text]

FRAPI.setTransactionApplicationName() Method

The Transaction Application Name is the name of the ColdFusion application framework instance that is processing the current request. By default, FusionReactor will use the name that you provide inside the Application.cfc component (using this.name). However, you can override it programmatically as I am doing above.

Since you can have N-number of ColdFusion applications running within a single ColdFusion instance, your FusionReactor dashboard may pickup Transactions from several concurrently-running applications. Having a sensible, human-readable name for your “Transaction Application” name will help differentiate the various recordings within the dashboard.

[/vc_column_text][us_separator][vc_column_text]

FRAPI.setTransactionName() Method

Just as with the Transaction Application Name, FusionReactor will automatically get the Transaction Name from current request. And, as an added bonus, FusionReactor is built to understand several of the popular ColdFusion Application frameworks (like ColdBox, Framework/One, and Fusebox). This means that FusionReactor will automatically use the framework action variable to help identify the Transaction.

So, for example, if you were to make a Framework/One (FW/1) request to:

GET /subsystem:section/item/foo/bar/meep/moop/

… FusionReactor would automatically give the Transaction the following name:

subsystem:section/item

Of course, if you are using an unsupported ColdFusion framework, or want to override the Transaction name, you can use the .setTransactionName() method.

 

ASIDE: It’s this kind of tight integration that sets FusionReactor apart from other Java APMs. Yes, it can monitor any type of JVM-based application; but, it clearly goes above and beyond to make ColdFusion developers happy! You gotta love that mindset.

[/vc_column_text][us_separator][vc_column_text]

FRAPI.trace() Method

The .trace() method allows you to log arbitrary time-stamped values along with the request. As you can see from my example, I’m logging a String, a Struct, and an Array. Each of these values is handled properly by the FusionReactor API and is rendered within the “Traces” tab of a Transaction detail:

[/vc_column_text][us_separator][us_image image=”57954″][us_separator][vc_column_text]

As you can see, the trace output is associated with the Transaction; but, it’s not intermingled with the rest of the request metadata – it stands on its own. To get more intermingled timing data, we can use sub-transactions, which we’ll look at shortly.

As far as I can tell, the Traces tab is only available in the Standalone dashboard – I could not find this data in the Cloud dashboard. The Cloud dashboard does have a “Tracing” tab; but, that tab deals with sub-transactions, not with the .trace() output.

[/vc_column_text][us_separator][vc_column_text]

FRAPI.getActiveTransaction() Method

The .getActiveTransaction() method gives you access to the Transaction associated with the current thread. If you are in the parent request, this gives you the same result as calling .getActiveMasterTransaction() (not demonstrated in my example). However, if you are in a sub-transaction, calling .getActiveTransaction() will give you the sub-transaction, not the master transaction.

NOTE: The BaseTransaction and TrackedTransction classes have a load of methods on them which don’t seem to be documented anywhere – not even in the FRAPI Java Docs. To see what is available, you have to grab the Java object and dump() it out to the screen. Among the potentially interesting methods that I saw, there are:

 

  • setProperty()
  • setSubFlavour()
  • setExplanation()
  • setDescription()

… and many more which may prove interesting for really low-level debugging.

[/vc_column_text][us_separator][vc_column_text]

Transaction.setProperty() Method

Once I have the currently-executing Transaction, I call .setProperty() to store arbitrary key-value pairs. The values must be Strings; and are rendered in the “Properties” tab of the Transaction detail:

[/vc_column_text][us_separator][us_image image=”57956″][us_separator][vc_column_text]

I usually use this type of functionality to store the associated User ID with the request.

I have confirmed with the FusionReactor Support team that the Properties values are only accessible in the Standalone dashboard – these values are not streamed to the Cloud dashboard.

[/vc_column_text][us_separator][vc_column_text]

FRAPI.createTrackedTransaction() Method

Creating nested transactions allows us to segment our code in such a way that makes the execution time of the code much more visible within the FusionReactor dashboard. There are two ways to create nested transactions:

 

  • .createTrackedTransaction()
  • .createTransaction()

 

CAUTION: Each transaction has to be explicitly closed via .close(). While I didn’t test this, I assume that if you don’t call .close(), the timing of the sub-transaction will be corrupted and will likely time-out at some point, making it appear as if the transaction took substantially longer than it really did.

Both of these create a nested transaction that is visible within the breakdown of a parent transaction / request. But, only the “tracked” transaction can be seen in an “activity” graph within the dashboard.

In my demo, each branch of the simulated feature flag is further segmented into two sub-transactions. In the Standalone dashboard, these sub-transactions are visible in the “Relations” tab of a given Transaction:

[/vc_column_text][us_separator][us_image image=”57957″][us_separator][vc_column_text]

As you can see, the relative execution times of each sub-transaction is visible under the overall execution time of the parent transaction / request.

Sub-transaction can also be viewed on their own, independently of any parent transaction, in the Transactions section of the Standalone dashboard via the “Transactions” dropdown:

[/vc_column_text][us_separator][us_image image=”57960″][us_separator][vc_column_text]

In the Cloud dashboard, this same data is available in the “Tracing” tab of a given Transaction:

[/vc_column_text][us_separator][us_image image=”57962″][us_separator][vc_column_text]

Or, to view them on their own, independent of any parent request, you can select them in the “Flavor” dropdown on the Transactions tab:

[/vc_column_text][us_separator][us_image image=”57963″][us_separator][vc_column_text]

I ran into a lot of trouble when naming my sub-transactions. It looks as if including any kind of “path style” notation in the transaction name creates some unexpected behaviors in the dashboard. For example:

 

  • /my/transaction/name
  • my.transaction.name

Using either a / or a . in the name seemed to cause unexpected rendering in the dashboard that I couldn’t understand. Maybe this has something to do with the “flavors” that can be associated with the Transactions? I’m not sure. Furthermore, the behavior seemed to be a bit different in the Standalone dashboard vs. the Cloud dashboard.

For now, I’m just going to stick with non-pathed Transaction names.

One of the really cool features of the Standalone dashboard is that these sub-transactions can be easily graphed right alongside the JVM’s Heap and CPU graphs.

[/vc_column_text][us_separator][us_image image=”57966″][us_separator][vc_column_text]

I could not figure out how to create the same side-by-side comparison in the Cloud dashboard. I suspect that it would require creating a Custom graph; but, I couldn’t figure out how to find those transactions in the graph queries.

[/vc_column_text][us_separator][vc_column_text]

FRAPI.postNumericAggregateMetric() Method

In addition to segmenting my code with nested Transactions, I can also use various “metric” methods on the FRAPI to track arbitrary timing data. In this case, I’m using the generic “numeric” method; but, there are several methods that help ensure the appropriate data-type is stored:

 

  • postMetric()
  • postNumericAggregateMetric()
  • postNumericAggregateMetricFloat()
  • postNumericAggregateMetricLong()
  • postNumericAggregateMetrics()
  • postNumericMetric()
  • postNumericMetricFloat()
  • postNumericMetricLong()

The difference between the “vanilla” metric and the “aggregate” metric is that the aggregate metric will give you a roll-up graph (hour, day, week) in addition to the “live” graph. The vanilla metrics, on the other hand, will only give you the “live” graph.

In the Standalone dashboard, these metrics can be seen in the “Custom Series” of the Metrics graphs:

[/vc_column_text][us_separator][us_image image=”57968″][us_separator][vc_column_text]

In the Cloud dashboard, it’s a bit tricker to get at this data – you have to create a custom graph in the Metrics section:

[/vc_column_text][us_separator][us_image image=”57969″][us_separator][vc_column_text]

Note that the name of the metric has been automatically prefixed with /custom to differentiate it from other metrics that are implicitly provided by FusionReactor.

Only “aggregate numeric” metrics can be streamed to the Cloud dashboard. And, to do so, you have to explicitly call .enableCloudMetric() to target a specific metric name for Cloud consumption.

[/vc_column_text][us_separator][vc_column_text]

Using The FusionReactor API (FRAPI)

Hopefully I didn’t get any of this wildly wrong. I am still trying to get a grip on FusionReactor’s Cloud dashboard – it’s got a lot of the same functionality, but feels very different than the older Standalone dashboard. And, the whole “custom graph” thing is a bit confusing as well, especially when it comes to adding those graphs to the Graphs tab. In fact, it looks as if the custom graphs can’t keep up with the “Live” view of the Cloud dashboard.

But, this little exploration should get be far enough into the custom instrumentation that I can do with FusionReactor’s FRAPI object in Lucee CFML 5.2.9.40. If anyone else has any tips on what they can do, I’d love to hear it.

[/vc_column_text][/vc_column][/vc_row]

The post Using The FusionReactor API (FRAPI) To Add Custom Instrumentation In Lucee CFML 5.2.9.40 appeared first on FusionReactor Observability & APM.

]]>
The De Facto Standard for ColdFusion / Java Application Monitoring https://fusion-reactor.com/blog/evangelism/the-de-facto-standard-for-coldfusion-java-application-monitoring-2/ Wed, 12 Jun 2019 10:45:54 +0000 http://f_reactor.dev.onpressidium.com/?p=40095 The De Facto Standard for ColdFusion / Java Application Monitoring What do you like best? FusionReactor is a necessary tool if you’re running a ColdFusion application of any appreciable size. Not helpful, not convenient. Necessary. It provides insights and alerts … Read More

The post The De Facto Standard for ColdFusion / Java Application Monitoring appeared first on FusionReactor Observability & APM.

]]>

The De Facto Standard for ColdFusion / Java Application Monitoring

What do you like best?

FusionReactor is a necessary tool if you’re running a ColdFusion application of any appreciable size. Not helpful, not convenient. Necessary.

It provides insights and alerts that you’re not going to get anywhere else, and in many cases it’s the only tool that’s going to be able to help you track down obscure bugs, memory leaks, or other issues that make you want to pull your hair out. And on top of that, the team behind it is incredibly responsive and always pushing the product forward.

What do you dislike?

The price of the Ultimate Edition is the biggest pain point. Configuration and use within a containerized environment continues to improve, but still isn’t as strong/easy/helpful and the on-premise FR offering.

Recommendations to others considering the product:

If you’re considering FusionReactor, talk to the team there and evaluate the product (it’s free to trial). They can answer your questions and help you get started. There’s no-risk, and the benefits are obvious from the moment you start using it.

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

The benefit is twofold. 1) FusionReactor provides alerting when there are issues with our applications. We set thresholds for memory usage, request quantity, or request length, and we get alerts when they’re exceeded. This is helpful in proactively addressing potential issues. 2) FusionReactor also provides detailed insight into what is going on within applications, which we’ll use when we need to track down the cause of a problem or an area that we’d like to optimize.

See full review

Start free trial

The post The De Facto Standard for ColdFusion / Java Application Monitoring appeared first on FusionReactor Observability & APM.

]]>
The De Facto Standard for ColdFusion / Java Application Monitoring https://fusion-reactor.com/blog/the-de-facto-standard-for-coldfusion-java-application-monitoring/ Wed, 12 Jun 2019 10:45:54 +0000 https://fronprem.dev.onpressidium.com/2019/06/12/the-de-facto-standard-for-coldfusion-java-application-monitoring/ The De Facto Standard for ColdFusion / Java Application Monitoring What do you like best? FusionReactor is a necessary tool if you’re running a ColdFusion application of any appreciable size. Not helpful, not convenient. Necessary. It provides insights and alerts … Read More

The post The De Facto Standard for ColdFusion / Java Application Monitoring appeared first on FusionReactor Observability & APM.

]]>

The De Facto Standard for ColdFusion / Java Application Monitoring

What do you like best?

FusionReactor is a necessary tool if you’re running a ColdFusion application of any appreciable size. Not helpful, not convenient. Necessary.

It provides insights and alerts that you’re not going to get anywhere else, and in many cases it’s the only tool that’s going to be able to help you track down obscure bugs, memory leaks, or other issues that make you want to pull your hair out. And on top of that, the team behind it is incredibly responsive and always pushing the product forward.

What do you dislike?

The price of the Ultimate Edition is the biggest pain point. Configuration and use within a containerized environment continues to improve, but still isn’t as strong/easy/helpful and the on-premise FR offering.

Recommendations to others considering the product:

If you’re considering FusionReactor, talk to the team there and evaluate the product (it’s free to trial). They can answer your questions and help you get started. There’s no-risk, and the benefits are obvious from the moment you start using it.

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

The benefit is twofold. 1) FusionReactor provides alerting when there are issues with our applications. We set thresholds for memory usage, request quantity, or request length, and we get alerts when they’re exceeded. This is helpful in proactively addressing potential issues. 2) FusionReactor also provides detailed insight into what is going on within applications, which we’ll use when we need to track down the cause of a problem or an area that we’d like to optimize.

See full review

Start free trial

The post The De Facto Standard for ColdFusion / Java Application Monitoring appeared first on FusionReactor Observability & APM.

]]>
A must have tool for monitoring CF apps https://fusion-reactor.com/blog/evangelism/a-must-have-tool-for-monitoring-cf-apps-2/ Wed, 05 Jun 2019 10:16:37 +0000 http://f_reactor.dev.onpressidium.com/?p=40083 Latest review on G2 What do you like best? The most helpful feature of FusionReactor is the fact that you can introspect all the requests running in production. You can easily see how much time it takes to run a … Read More

The post A must have tool for monitoring CF apps appeared first on FusionReactor Observability & APM.

]]>
APM 5 star review

Latest review on G2

What do you like best?

The most helpful feature of FusionReactor is the fact that you can introspect all the requests running in production. You can easily see how much time it takes to run a specific process, identify its pain points and optimise them. What is highly appreciated is also the profiling functionality! You can even profile your app and dig into very low level optimisations which otherwise would be not easily pinpointed!

What do you dislike?

What probably needs more rework is the documentation when you are exporting the java cache files from the FR JVM. I spent quite some time looking into what each value ment, which could have been better documented.

Recommendations to others considering the product:

Since there is a lack of actual debugging tools for ColdFusion, I consider FusionReactor to be the only tool that actually gives you an insight within your application!

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

Real time monitoring of processes is a huge benefit. Optimising slow processes is a huge plus.

See full review

Start a free trial

The post A must have tool for monitoring CF apps appeared first on FusionReactor Observability & APM.

]]>
A must have tool for monitoring CF apps https://fusion-reactor.com/blog/a-must-have-tool-for-monitoring-cf-apps/ Wed, 05 Jun 2019 10:16:37 +0000 https://fronprem.dev.onpressidium.com/2019/06/05/a-must-have-tool-for-monitoring-cf-apps/ Latest review on G2 What do you like best? The most helpful feature of FusionReactor is the fact that you can introspect all the requests running in production. You can easily see how much time it takes to run a … Read More

The post A must have tool for monitoring CF apps appeared first on FusionReactor Observability & APM.

]]>
APM 5 star review

Latest review on G2

What do you like best?

The most helpful feature of FusionReactor is the fact that you can introspect all the requests running in production. You can easily see how much time it takes to run a specific process, identify its pain points and optimise them. What is highly appreciated is also the profiling functionality! You can even profile your app and dig into very low level optimisations which otherwise would be not easily pinpointed!

What do you dislike?

What probably needs more rework is the documentation when you are exporting the java cache files from the FR JVM. I spent quite some time looking into what each value ment, which could have been better documented.

Recommendations to others considering the product:

Since there is a lack of actual debugging tools for ColdFusion, I consider FusionReactor to be the only tool that actually gives you an insight within your application!

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

Real time monitoring of processes is a huge benefit. Optimising slow processes is a huge plus.

See full review

Start a free trial

The post A must have tool for monitoring CF apps appeared first on FusionReactor Observability & APM.

]]>
FusionReactor and Your ColdFusion Queries https://fusion-reactor.com/blog/evangelism/fusionreactor-and-your-coldfusion-queries-2/ Tue, 28 May 2019 13:21:57 +0000 http://f_reactor.dev.onpressidium.com/?p=40062 FusionReactor and Your ColdFusion Queries In my last article on FusionReactor, I talked about slow pages and how the tool helps you find them. In that article, I specifically avoided talking about one of the biggest culprits of slow pages – … Read More

The post FusionReactor and Your ColdFusion Queries appeared first on FusionReactor Observability & APM.

]]>

FusionReactor and Your ColdFusion Queries

In my last article on FusionReactor, I talked about slow pages and how the tool helps you find them. In that article, I specifically avoided talking about one of the biggest culprits of slow pages – database queries. My history with ColdFusion goes back to about version 2 and even back then database queries were the primary culprit in poorly performing applications.

There are multiple reasons why database queries can be a chokepoint for your application:

 

  • A poor connection to the database.
  • A poorly configurated database.
  • A poorly configurated table.
  • A poorly written ColdFusion query.
  • And so forth.

In an ideal world, your organization has a DBA (database administrator) who tunes the database and tables and then crafts a beautiful SQL (or stored procedure) you can simply drop into your application. Unfortunately very few of us live in that ideal world. It’s also very easy to simply ignore the problem. SQL, like any language, lets you get stuff done quickly and it can be easy to not consider the performance aspects of your query. Like any poorly written piece of code, a “slightly bad” query in a request can then be joined by another slightly bad one and slowly compound into a poorly performing page.

Being that database activity is such an important part of the performance, it’s no surprise FusionReactor has specific reporting tools focused on just that area. In this post, I’m going to share what that looks like and share some examples of the kind of reports you can find.

JDBC Reports

In my last post, I explained that JDBC stands for Java Database Connectivity. Any time you use a cfquery tag (or queryExecute function), you’re making use of JDBC to allow your ColdFusion templates to speak to a database. Within FusionReactor, you’ll want to start with the JDBC icon on the left:

Under here you’ve got a variety of options:

  • JDBC Activity – i.e. what’s going on right now.
  • JDBC History – historical activity.
  • JDBC Error History – past query errors.
  • Activity Graph and Time Graph – a “live” graphical report of JDBC activity.
  • Longest Transactions and Slowest Transaction – to be honest, this was a bit confusing. Wouldn’t the longest transaction also be the slowest transaction? The “Longest” report will show the transactions that have taken the longest to execute, no matter how long. The “Slowest” report is a report of all transactions over a particular threshold. So it may be possible that you have nothing there as your ColdFusion queries are performant, but the “Longest” report will still rank them for you.
  • Trans. By Mem – reports on queries with high memory usage.
  • Stack Trace Filter – it’s possible that multiple different things are making use of your database. The stack trace filter lets you reduce the amount of “noise” you may get from other applications. By default, there’s filters set up for .cfm.cfc, and .jsp.
  • Databases – this gives a really cool report on how you’re using your databases. I’ll be sharing an example of this later.
  • Settings – this is where you can configure how FusionReactor logs and monitors your database transactions

As with the previous examples I’ve shown from FusionReactor, take note of the controls on the top right to allow for filtering, reloading, and so forth. What isn’t obvious from the screenshot is that the “All SubFlavors” button actually lets you filter by the type of query, select, insert, and so forth. That’s pretty neat.

The main table of data reports on the app that was being used (I’m just working in my default Lucee home directory) and the SQL that was used. You can see the file name as well as timing information. Note the Time column which shows you how long the particular query took.

Notice how the SQL is reported as well. One of the features of FusionReactor is to automatically replace queryparam values with their ‘real’ values when reporting on the query. You can enable or disable this feature under the “JDBC/Settings” page. While this is a cool feature, it means it’s difficult to see where you’ve forgotten to use queryparams. I’ve reported to the FusionReactor folks that it would be nice if it was obvious when such a replacement has happened, maybe by using bold tags or some such. That way if you a query is not using queryparams it will be easier to find and correct.

The detail view is very deep. Here’s the main tab of information:

There is almost an overwhelming amount of information here, but I’d probably focus mostly on the execution time values under JDBC and the memory section. Here’s the JDBC tab:

ColdFusion Queries

As before, there’s a lot of information, but I’d focus on the row count. If you’ve ever seen someone select everything from a table and then use ColdFusion conditionals to restrict what is shown, then you know why this is a problem. The query is returning a mind-boggling twenty-seven thousand rows. There’s no way that was intentional. (Ok, for my test it was, but you get my point.)

The final tab, Relations, gives you a good look at the query within the page it was working. For example, this page had multiple coldFusion queries and you can see how they impacted the overall total page performance.

Finding Query Errors

Let’s now take a look at how FusionReactor reports errors. To test, I ran two requests with simple SQL errors, one trying to get a field that didn’t exist and one against a table that didn’t exist. Here’s how the main error history page shows the results.

For the most part, this is fairly similar to the history report, except now you can get a short report of the error. As a test, I shut down my MySQL server and ran my request again. As expected, I got an error. However, that error does not show up in this report. It does show up under “Request/Error History” though. My guess is that since Lucee couldn’t ever speak to MySQL, a JDBC transaction was not made. That makes sense to me, but just keep in mind that you may want to check both error reports when hunting down issues.

The detail view is the same as before but with a new tab called “Error Details”:

As always, I find the stack trace a bit hard to parse, but the error details on top seem nice and clear to me. Notice the debug button on the right. This allows you to add a breakpoint for future errors like this. I’m going to talk about FusionReactor’s debugging features later.

JDBC Graphs

FusionReactor offers two reports of JDBC activities. The first is just raw activity (Activity Graph) while the second (Time Graph) reports on how long queries are taken. Both default to a “live” view but also let you look at specific time ranges. Here’s an example of both, but note the graphs are a bit boring for me as this is just my local laptop.

ColdFusion Queries

Finding Those Bad ColdFusion Queries

As I explained above, FusionReactor provides two reports to help you find slow queries. “Longest Transactions” will simply list out all your recorded transactions sorted by time. “Slowest Transactions” focuses on queries that are slower than a defined threshold. You can set that threshold in the settings panel, under “History”. The default value is 3 seconds. There are quite a few interesting things you can tweak in the settings panel so I recommend taking a look at it. For my laptop, with again a simple test and not “real” data, here’s the “Longest Transactions” view:

coldfusion queries

Your Database Use

The final thing I want to show is probably the coolest. The “Databases” report gives you a report on how you are using each of the datasources on your server. It breaks it down by type of operations as well as table usage. It also reports on the queries sent to the datasource.

ColdFusion Queries

This is just freaking cool as heck to me. While I think most of us will deal with one database per server, larger more complex applications could be dealing with numerous databases. A report like this could help you figure out if one, or more, are perhaps being used rarely enough to be decommissioned or transitioned to one main database. The table report could be really useful too. I’ve dealt with projects hitting a database with a huge amount of tables. This can give you an idea of what’s actually being used.

Summary

As I said in the beginning, database issues tend to be the number one culprit when it comes to poorly performing ColdFusion queries on sites. I think the JDBC set of features in FusionReactor will probably be your top tool for helping improve your applications. I know this is where I’d start looking!

Thanks to our special guest author Raymond Camdem for writing this article for us.

Blog : www.raymondcamden.com
Twitter: raymondcamden

The post FusionReactor and Your ColdFusion Queries appeared first on FusionReactor Observability & APM.

]]>
FusionReactor and Your ColdFusion Queries https://fusion-reactor.com/blog/fusionreactor-and-your-coldfusion-queries/ Tue, 28 May 2019 13:21:57 +0000 https://fronprem.dev.onpressidium.com/2019/05/28/fusionreactor-and-your-coldfusion-queries/ [vc_row][vc_column][vc_column_text] FusionReactor and Your ColdFusion Queries In my last article on FusionReactor, I talked about slow pages and how the tool helps you find them. In that article, I specifically avoided talking about one of the biggest culprits of slow pages … Read More

The post FusionReactor and Your ColdFusion Queries appeared first on FusionReactor Observability & APM.

]]>
[vc_row][vc_column][vc_column_text]

FusionReactor and Your ColdFusion Queries

In my last article on FusionReactor, I talked about slow pages and how the tool helps you find them. In that article, I specifically avoided talking about one of the biggest culprits of slow pages – database queries. My history with ColdFusion goes back to about version 2 and even back then database queries were the primary culprit in poorly performing applications.

There are multiple reasons why database queries can be a chokepoint for your application:

 

  • A poor connection to the database.
  • A poorly configurated database.
  • A poorly configurated table.
  • A poorly written ColdFusion query.
  • And so forth.

In an ideal world, your organization has a DBA (database administrator) who tunes the database and tables and then crafts a beautiful SQL (or stored procedure) you can simply drop into your application. Unfortunately very few of us live in that ideal world. It’s also very easy to simply ignore the problem. SQL, like any language, lets you get stuff done quickly and it can be easy to not consider the performance aspects of your query. Like any poorly written piece of code, a “slightly bad” query in a request can then be joined by another slightly bad one and slowly compound into a poorly performing page.

Being that database activity is such an important part of the performance, it’s no surprise FusionReactor has specific reporting tools focused on just that area. In this post, I’m going to share what that looks like and share some examples of the kind of reports you can find.

[/vc_column_text][us_separator size=”small”][vc_column_text]

JDBC Reports

In my last post, I explained that JDBC stands for Java Database Connectivity. Any time you use a cfquery tag (or queryExecute function), you’re making use of JDBC to allow your ColdFusion templates to speak to a database. Within FusionReactor, you’ll want to start with the JDBC icon on the left:

[/vc_column_text][us_separator size=”small”][us_image image=”57374″][us_separator size=”small”][vc_column_text]

Under here you’ve got a variety of options:

  • JDBC Activity – i.e. what’s going on right now.
  • JDBC History – historical activity.
  • JDBC Error History – past query errors.
  • Activity Graph and Time Graph – a “live” graphical report of JDBC activity.
  • Longest Transactions and Slowest Transaction – to be honest, this was a bit confusing. Wouldn’t the longest transaction also be the slowest transaction? The “Longest” report will show the transactions that have taken the longest to execute, no matter how long. The “Slowest” report is a report of all transactions over a particular threshold. So it may be possible that you have nothing there as your ColdFusion queries are performant, but the “Longest” report will still rank them for you.
  • Trans. By Mem – reports on queries with high memory usage.
  • Stack Trace Filter – it’s possible that multiple different things are making use of your database. The stack trace filter lets you reduce the amount of “noise” you may get from other applications. By default, there’s filters set up for .cfm.cfc, and .jsp.
  • Databases – this gives a really cool report on how you’re using your databases. I’ll be sharing an example of this later.
  • Settings – this is where you can configure how FusionReactor logs and monitors your database transactions

[/vc_column_text][us_separator size=”small”][us_image image=”57375″][us_separator size=”small”][vc_column_text]

As with the previous examples I’ve shown from FusionReactor, take note of the controls on the top right to allow for filtering, reloading, and so forth. What isn’t obvious from the screenshot is that the “All SubFlavors” button actually lets you filter by the type of query, select, insert, and so forth. That’s pretty neat.

The main table of data reports on the app that was being used (I’m just working in my default Lucee home directory) and the SQL that was used. You can see the file name as well as timing information. Note the Time column which shows you how long the particular query took.

Notice how the SQL is reported as well. One of the features of FusionReactor is to automatically replace queryparam values with their ‘real’ values when reporting on the query. You can enable or disable this feature under the “JDBC/Settings” page. While this is a cool feature, it means it’s difficult to see where you’ve forgotten to use queryparams. I’ve reported to the FusionReactor folks that it would be nice if it was obvious when such a replacement has happened, maybe by using bold tags or some such. That way if you a query is not using queryparams it will be easier to find and correct.

The detail view is very deep. Here’s the main tab of information:

[/vc_column_text][us_separator size=”small”][us_image image=”57378″][us_separator size=”small”][vc_column_text]

There is almost an overwhelming amount of information here, but I’d probably focus mostly on the execution time values under JDBC and the memory section. Here’s the JDBC tab:

[/vc_column_text][us_separator size=”small”][us_image image=”57380″][us_separator size=”small”][vc_column_text]

As before, there’s a lot of information, but I’d focus on the row count. If you’ve ever seen someone select everything from a table and then use ColdFusion conditionals to restrict what is shown, then you know why this is a problem. The query is returning a mind-boggling twenty-seven thousand rows. There’s no way that was intentional. (Ok, for my test it was, but you get my point.)

The final tab, Relations, gives you a good look at the query within the page it was working. For example, this page had multiple coldFusion queries and you can see how they impacted the overall total page performance.

[/vc_column_text][us_separator size=”small”][us_image image=”57384″][us_separator][vc_column_text]

Finding Query Errors

Let’s now take a look at how FusionReactor reports errors. To test, I ran two requests with simple SQL errors, one trying to get a field that didn’t exist and one against a table that didn’t exist. Here’s how the main error history page shows the results.

[/vc_column_text][us_separator size=”small”][us_image image=”57387″][us_separator size=”small”][vc_column_text]

For the most part, this is fairly similar to the history report, except now you can get a short report of the error. As a test, I shut down my MySQL server and ran my request again. As expected, I got an error. However, that error does not show up in this report. It does show up under “Request/Error History” though. My guess is that since Lucee couldn’t ever speak to MySQL, a JDBC transaction was not made. That makes sense to me, but just keep in mind that you may want to check both error reports when hunting down issues.

The detail view is the same as before but with a new tab called “Error Details”:

[/vc_column_text][us_separator size=”small”][us_image image=”57390″][us_separator size=”small”][vc_column_text]

As always, I find the stack trace a bit hard to parse, but the error details on top seem nice and clear to me. Notice the debug button on the right. This allows you to add a breakpoint for future errors like this. I’m going to talk about FusionReactor’s debugging features later.

[/vc_column_text][us_separator size=”small”][vc_column_text]

JDBC Graphs

FusionReactor offers two reports of JDBC activities. The first is just raw activity (Activity Graph) while the second (Time Graph) reports on how long queries are taken. Both default to a “live” view but also let you look at specific time ranges. Here’s an example of both, but note the graphs are a bit boring for me as this is just my local laptop.

[/vc_column_text][us_separator size=”small”][us_image image=”57392″][us_separator size=”small”][us_image image=”57395″][us_separator][vc_column_text]

Finding Those Bad ColdFusion Queries

As I explained above, FusionReactor provides two reports to help you find slow queries. “Longest Transactions” will simply list out all your recorded transactions sorted by time. “Slowest Transactions” focuses on queries that are slower than a defined threshold. You can set that threshold in the settings panel, under “History”. The default value is 3 seconds. There are quite a few interesting things you can tweak in the settings panel so I recommend taking a look at it. For my laptop, with again a simple test and not “real” data, here’s the “Longest Transactions” view:

[/vc_column_text][us_separator size=”small”][us_image image=”57398″][us_separator size=”small”][vc_column_text]

Your Database Use

The final thing I want to show is probably the coolest. The “Databases” report gives you a report on how you are using each of the datasources on your server. It breaks it down by type of operations as well as table usage. It also reports on the queries sent to the datasource.

[/vc_column_text][us_separator size=”small”][us_image image=”57401″][us_separator size=”small”][vc_column_text]

This is just freaking cool as heck to me. While I think most of us will deal with one database per server, larger more complex applications could be dealing with numerous databases. A report like this could help you figure out if one, or more, are perhaps being used rarely enough to be decommissioned or transitioned to one main database. The table report could be really useful too. I’ve dealt with projects hitting a database with a huge amount of tables. This can give you an idea of what’s actually being used.

[/vc_column_text][us_separator size=”small”][vc_column_text]

Summary

As I said in the beginning, database issues tend to be the number one culprit when it comes to poorly performing ColdFusion queries on sites. I think the JDBC set of features in FusionReactor will probably be your top tool for helping improve your applications. I know this is where I’d start looking!

Thanks to our special guest author Raymond Camdem for writing this article for us.

Blog : www.raymondcamden.com
Twitter: raymondcamden

[/vc_column_text][/vc_column][/vc_row]

The post FusionReactor and Your ColdFusion Queries appeared first on FusionReactor Observability & APM.

]]>
Changing your FusionReactor instance name, easily https://fusion-reactor.com/blog/evangelism/changing-your-fusionreactor-instance-name-easily-2/ Sat, 06 Apr 2019 00:32:58 +0000 http://f_reactor.dev.onpressidium.com/?p=39823 Have you wished you could change the name given to your monitored instance in FusionReactor (the name that appears in the UI and various reports/emails)? Did you know you could change it easily, on the fly, from within the instance … Read MoreRead More

The post Changing your FusionReactor instance name, easily appeared first on FusionReactor Observability & APM.

]]>

Have you wished you could change the name given to your monitored instance in FusionReactor (the name that appears in the UI and various reports/emails)? Did you know you could change it easily, on the fly, from within the instance and without need of restarting your instance?

How to change the instance name

Just use the menu labelled “FusionReactor” (on the top left), and from there choose “Settings”, then the tab for “Instance Name”. See below. After changing it, click the “Save FusionReactor Settings” button in the bottom right corner of the screen (not visible below).

If you don’t see an Instance Name option on that Settings page, then you are looking at the FRAM instance, typically running on the 8087 port. Change to port 8088 or whatever port should be used for the instance in question.

Why you may want to change the name

Why might someone want to rename their instance? As you may know, when you implement FR using the FRAM (Admin Mgr) tool and its Instance Manager, that picks a name for your instance. While you can change it at that time, you (or the person installing FR) may not have bothered to change the name it picked.

But as this name appears in the FR reports, CP alerts, and on the FR Enterprise Dashboard (as well as in the top right of your instance itself), you may decide later that you wish you had given it a more helpful name. With the above, you can do just that!

Some other considerations

Note that the instance name also is stored within the java configuration of your instance, in terms of the javaagent and (optional) agentpath java args for FR. It’s also used for the name of the folder for the instance, as found within your “instances” folder of the FusionReactor directory created during installation.

(Note that if you choose to do manual installation of FR, where you download the fusionreactor.jar, and manually configure your jvm args, then you will have picked the name in doing that, and would have created the folder for the instance. More important, you won’t have run the FR installer I refer to, nor will you have the FRAM instance I refer to. But you can still rename the instance the way I describe.)

Anyway, these values (the name in the java args, and the folder name for your instance) are NOT changed when you change the instance name as described above. There’s no problem. They just won’t be in sync with the other elements that show the new name.

If you DO for some reason want to change those, you can, manually. Just stop the instance that FR is monitoring, then rename those values, and restart it. Do note that in the case of the javaagent arg, the name appears twice:  once to represent the folder in which the instance’s fusionreactor.jar is located, and once to represent the instance name.

 


For more blog posts from Charlie Arehart, see his posts here as well as his posts at carehart.org. And follow him on Twitter and other social media as carehart.

The post Changing your FusionReactor instance name, easily appeared first on FusionReactor Observability & APM.

]]>