What are hybrid applications? Google says: “Hybrid applications are web applications (or web pages) in the native browser, such as UIWebView in iOS and WebView in Android (not Safari or Chrome). Hybrid apps are developed using HTML, CSS and Javascript, and then wrapped in a native application using platforms like Cordova.

I don’t think I could say it any better myself!

The goal of this blog is to show a step-by-step approach of creating a mobile hybrid application and instrumenting it with Dynatrace. If you enjoy watching a video more than reading a blog check out our recorded Dynatrace Performance Clinic on our YouTube Channel.

Technology stack used in this tutorial: AngularJS, Ionic, Cordova, Spring Boot and Dynatrace
Technology stack used in this tutorial: AngularJS, Ionic, Cordova, Spring Boot and Dynatrace

Hybrid applications are very popular these days because one development team can build an application which can be used as “native” apps on Android and IOS devices, but also directly through the browser, all based on the same code. Although this seems easy, there are many technologies involved.

I was recently working with a customer who had a large development team working on a hybrid application. It was a major public-facing interface of the company and was very important for them. But like all mobile applications – and recent web applications based on these newer technologies – most of the action happens on the end users device. Even within the regular browser, these Single Page Apps (SPAs) execute a huge amount of JavaScript and only call the backend services to exchange JSONized information. We therefore typically see many very small and fast requests.

Although their end users complained about the performance of the application, they were completely blind on what was happening on the client, until Dynatrace UEM came along.

A sample hybrid application

Dynatrace supports the instrumentation of Hybrid applications, but make sure you do your homework. As our customer was doing things in a very specific way, we could not just follow the instructions in the Dynatrace documentation. Instrumenting a Hybrid application is in fact nothing more than combining the JavaScript UEM Agent with the Mobile ADK and, since we were struggling to get that working on the application of our customer, I thought “let’s try it myself, how hard can it be”. I have a lot of experience in creating Java backed web applications, but I am a total newbie in the Mobile and Hybrid area.

So I started on YouTube and found “Creating a simple hybrid app with AngularJS, Ionic and Cordova

The title says it all! I was indeed able to create a hybrid application with AngularJS and Cordova which were also the technologies used by our customer. Creating the application was rather easy once I managed to install the correct components via Node.js. Lessons learned: don’t install Node via some package manager in Linux. Just download the latest version and use that one. Once node is installed and available in the PATH, you download Cordova and Ionic with these commands:

sudo npm install -g cordova
sudo npm install -g ionic

Once that’s done, you can follow the tutorial or just use my sources on github. After executing “ionic serve” you should be able to see something like this:

Insert1

Insert2

If you got all the way to here, great. But we are not done yet. First of all, the back end of this small hybrid application is https://public-api.wordpress.com/rest/v1.1/freshly-pressed which is called via JSONP. I wanted a real back end which I could control so I would be able to add a Dynatrace agent on there as well. And secondly, this one-page application based on AngularJS is not yet running on a Mobile device or emulator.

1) Back-end project with Spring Boot

I am rather familiar with Spring Boot and it’s really easy to create a REST interface like my sample freshlypressed back end. Not only is Spring Boot great to avoid a lot of configuration overhead, but the fact that the output is a runnable jar makes it very useful for our demo case here. You find all sources on github, but I also uploaded the runnable jar. No need for you to build it. Running it with already an agent included is nothing more than:

java -agentpath:/opt/dynatrace-6.3/agent/lib64/libdtagent.so=name=Backend_HybridApp,server=localhost:9998 -jar ./freshlypressed-backend-0.0.1-SNAPSHOT.jar

Once it’s running (it starts very fast), a REST service is running on localhost:8080/stories which gives a minimum freshlypressed JSON response with two stories. To use this back end instead of the public jsonp api, simply make the following change in app.js:

InsertC

What? 192.168.56.1:81 instead of localhost:8080?

Yes, that’s a trick we need for the application to work both on a browser as on mobile device. Let me explain…

  • A browser cannot make cross domain calls unless you use jsonp or CORS, but I wanted to make a usable example with regular asynchronous web requests. A call to “/stories” without host and port would also work for a browser application if the html page is served via the same location. See my Apache configuration below to achieve this.
  • When a hybrid app is packaged into a mobile application, all resources like the html, css and javascript are locally packaged as well.  So then the full URL is required. Just pointing to “/stories” doesn’t work.

That’s why you need a single location for the browser, which I achieve via an Apache HTTPD server with following configuration. And since I will deploy on an emulator without internet connection, I now use the local IP address which is used as a bridge between the emulator and my OS.

The Apache configuration

Insert3

Notice that port 8080 is used by the Spring Boot backend and 8100 is used by “ionic serve” which is still running. Instead of a proxy pass to the running “ionic” demo, you could also just serve the html and other static resources directly via Apache as they are just static files.

The fact that I use port 81 here has no specific reason. I differentiate between virtual hosts based on port, so I can use the IP address. Port 80 would be nicer off course, but this is just a demo.

And since I am now using Apache, this can also be instrumented by Dynatrace.

2) Emulation via genymotion

The first step is to build the application for Android.

ionic platform add android

Adds Android as a target platforms

ionic build android

Produces the resulting apk with can be installed on a device or an emulator.

heydenb@WP1214 ~/workspace/hybridapp/freshlypressed $ ionic build android

BUILD SUCCESSFUL

Total time: 8.787 secs

Built the following apk(s):
/home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug.apk

Now that I have the APK I can run the app. For that I am using Genymotion which is a very good Android emulator. After downloading the free version of the emulator from I was able to install it and configure a device for my app.

Installing the apk to this device can be done via the adb tool which is included within the genymotion package.

heydenb@WP1214 /opt/genymobile/genymotion/tools $ ./adb install -r /home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug.apk

973 KB/s (3850447 bytes in 3.862s)

Insert4
The result on browser and android:

Insert5

Great! We have a running app on our mobile device which also works in a regular browser accessing a real backend application in Spring Boot. This was the hard part. Instrumenting this entire setup with Dynatrace was, in fact, much easier.

Instrumentation of our mobile app and back end

Let’s start with some prerequisites first:

The Java Backend

We already instrumented the backend earlier. My Dynatrace server contains the agent binaries which are located in /opt/dynatrace-6.3. So the following command is launching and instrumenting the Spring Boot app.

java -agentpath:/opt/dynatrace-6.3/agent/lib64/libdtagent.so=name=Backend_HybridApp,server=localhost:9998 -jar ./freshlypressed-backend-0.0.1-SNAPSHOT.jar

Further information on instrumenting Java-based apps can be found in the Dynatrace Doc or you can watch the Online Clinic on Dynatrace for Java Apps.

The Apache Webserver

Instrumenting the web service is straight forward:

#1: The dtwsagent.ini file needs to be configured with the agentname:

heydenb@WP1214 /opt/dynatrace-6.3/agent/conf $ head -12 dtwsagent.ini
# The UDP port on which the web server agent should listen for data packets. Should only be changed
# if the default port (UDP port 8001) is in use by a different application.
# This is NOT the port of the dynaTrace Collector this agent should connect to.
# Default: 8001
#Port 8001

# The name of the web server agent (used for agent mapping on the dynaTrace Server).
Name Apache_HybridApp

# The address of the dynaTrace Collector this agent should connect to.
# The address is of the form host:port, e.g. exampleserver:9998
Server localhost

#2: And the Dynatrace Apache module needs to be loaded through httpd.conf

heydenb@WP1214 /etc/apache2/mods-available $ cat dtagent.load
LoadModule dtagent_module /opt/dynatrace-6.3/agent/lib64/libdtagent.so

#3: The separate master agent process needs to be started:

heydenb@WP1214 /opt/dynatrace-6.3/init.d $ ./dynaTraceWebServerAgent start

#4: And Apache itself needs to be restarted

heydenb@WP1214 sudo service apache2 restart

Find more information on instrumenting an Apache Web Server in the Dynatrace Doc. If you use a different web server or no web server at all just check out the tutorials on our YouTube Channel.

The Hybrid Application

This part is all about User Experience Monitoring of the Hybrid application itself. This is well described in Instrumenting Hybrid Apps but I thought some practical information is missing.

I don’t want to repeat the documentation here, but the general rule about UEM on a hybrid app is that you need to do two things:

1) Use the JavaScript UEM agent without automatic injection. Since the html file(s) are packaged and not served.

2) Use the Mobile ADK with auto instrumentation.

Injecting JavaScript:

Just add following line inside index.html as the first script in the head tag. I even put it before the title element.

<script type=“text/javascript” src=“js/dtagent635_gjpqtx_1025.js” data-dtconfig=“tp=500,50,0|reportUrl=http://192.168.56.1:81/dynaTraceMonitor”></script>

Off course, you need to make sure this JavaScript is also placed within the js folder with exactly this name. The name of the file depends on the options which you have selected on the UEM configuration.

Retrieving this file is the easiest if you configure UEM for the browser application first with automatic injection.

Insert6

Insert7

Now, you can just download the script via http://192.168.56.1:81/dtagent635_gjpqtx_1025.js and save it in the correct location under www/js.

Once you have that line injected manually and the JavaScript file is at the right location, you can configure the UEM sensor pack on the Apache Agent Group to use manual injection. Manual injection makes updates of Dynatrace a bit more difficult, but you have to do this for your Mobile version anyway. So with manual injection, you keep both versions perfectly synchronized.

Insert8

With the setup until here, you should already be able to create a first visit from the browser.

Insert9

Mobile ADK part:

Once we have applied the changes from above, we need to rebuild “ionic build android”. The resulting APK can then be instrumented via the Dynatrace auto instrumentation.

You need to download the “UEM Mobile ADK” first from http://downloads.dynatracesaas.com/ and unzip it on your local machine. Within the Android/auto-instrumentor folder, you can edit the APK-Instr.properties and set the Application Id and the agentPath

cpwrUEM_startup.sApplId=FreshlyPressed Android
cpwrUEM_startup.agentPath=http://192.168.56.1:81

Next, you can just execute instrument.sh and pass the apk and this properties file.

heydenb@WP1214 ~/Downloads/dynatrace-adk-6.3/Android/auto-instrumentor $ ./instrument.sh apk=/home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug.apk prop=./APK-Instr.properties

Resulting APK files———————————————————————-
Original: /home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug.apk

Instrumented: /home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug/dist/android-debug.apk

Instrumented and signed: /home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug/dist/android-debug-signed.apk

Instrumented, signed and zipaligned: /home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug/dist/android-debug-final.apk

Finally deploy the update APK to the emulator and start playing with it. (Only one button to play with, but you get my point.)
heydenb@WP1214 /opt/genymobile/genymotion/tools $ ./adb install -r /home/heydenb/workspace/hybridapp/freshlypressed/platforms/android/build/outputs/apk/android-debug/dist/android-debug-final.apk

973 KB/s (3850447 bytes in 3.862s)
pkg: /data/local/tmp/android-debug-final.apk
Success

The final result: UEM for Mobile Hybrid

If you did everything correct we will see a Visit for every time somebody opens the mobile app. We will see each individual user action including full end-to-end traces to our backend service.

Insert10

If you want to see a demo, watch our recording of this blog on YouTube. If you want to try this yourself sign up for your own Dynatrace Personal License and get the sample app on our GitHub Project Page.