Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Clear all filters
code share

APM - Track clicks on webtop resources

Problem this snippet solves:

This configuration sample provide to the administrator a way to log all APM webtop resources clicked by a logged-in user. Those logs can be exported to external systems like Splunk to do some Analytics.

Those configuration objects are currently for experimentation only. It is not recommended for production yet.

How to use this snippet:

Insert this javascript snippet to the end of the hometab.inc file that you can find and modify in Advanced Customization >> Your Webtop Name.

window.onclick = function(e) { 
    if (e.target.parentNode.className == "favorite") {
        var xhttp = new XMLHttpRequest();
        console.log(e.target.parentNode.id);
        var uri = "/analytics?t=" + Math.random() + "&r=" + encodeURIComponent(window.btoa(e.target.parentNode.id)) + "&d=" + Date.now();
        xhttp.open("GET", uri, true);
        xhttp.send();
    }
    if (e.target.parentNode.className == "image" && e.target.parentNode.parentNode.className == "favorite") {
        var xhttp = new XMLHttpRequest();
        console.log(e.target.parentNode.id);
        var uri = "/analytics?t=" + Math.random() + "&r=" + encodeURIComponent(window.btoa(e.target.parentNode.parentNode.id)) + "&d=" + Date.now();
        xhttp.open("GET", uri, true);
        xhttp.send();
    }
};

Then, add the irule provided in the attachment of this article to the Virtual Server with the access profile.

Here is an example of logged accesses :

time=08/14/17 20:19:24, clientip=10.20.30.5, user=test, session=a7585749, res=/Common/fullvpn-test
time=08/14/17 20:19:22, clientip=10.20.30.5, user=test, session=a7585749, res=/Common/debian-test
Tested on Version:
11.5
Comments on this Snippet
Comment made 15-Aug-2017 by Stanislas Piron 10106

Hi Yann,

you can use ACCESS_ACL_ALLOWED instead of HTTP_REQUEST. it prevent session lookup and limit irule suspend in high load architectures.

when ACCESS_ACL_ALLOWED {
    if { [HTTP::path] eq "/analytics" } {
        set time [clock format [expr { [URI::query [HTTP::uri] "d"]/1000 }] -format "%D %T"]
        set res [b64decode [URI::decode [URI::query [HTTP::uri] "r"]]]
        set user [ACCESS::session data get session.logon.last.username]
        set session [HTTP::cookie value LastMRH_Session]
        set clientip [ACCESS::session data get session.user.clientip]
        log local0. "time=$time, clientip=$clientip, user=$user, session=$session, res=$res"
        ACCESS::respond 200 noserver
    }
}
0
Comment made 15-Aug-2017 by Yann Desmarest 4479

Hi Stanislas,

Thank you for your suggestion. I modified the original code with your update.

Thank you for your help

BR

Yann

0
Comment made 06-Mar-2018 by brad 375

Anything different using this on v12.1? i put the javascript code in the hometab.inc file but it doesn't seem to show up or function. I found the hometab.inc in the webtop as it wasn't in the access profiles.

This should do what the customer is requesting.. to obtain analytics on what items are being used on the access portal.. and by whom.

Thanks for any pointers here.. Much appreciated..

0
Comment made 06-Mar-2018 by Yann Desmarest 4479

Hi Brad,

Do you have some logs or error displayed in the console of your browser ?

Which browser do you use for testing ?

Are you using the same hostname for the webtop and analytics URI ? Otherwise, you may face a CORS issue.

Will run the script in my labs for testing

Hope it helps

Yann

0
Comment made 08-Mar-2018 by brad 375

I moved it up a bit in the hometab.inc. It seems that putting it at the bottom was not bringing it in. I then added the iRule to the virtual server and now it is logging just fine.

Placed it before var HangupErrorUserInitiated = 1; it probably could go after that, too. but it works..

Some testing.. it isn't logging 100% of selections. Not sure why and will have to add a data capture. Usually it will log when used with IE but sometimes it misses one. Chrome is showing more misses on the logging. around 30-40% it seems.

thanks.

0
Comment made 4 months ago by brad 375

after lots of trying it seems it isn't working with any reliability. the onclick event does not trigger most of the time.. it doesn't make a difference if it is chrome or IE browser both seem to 'miss' the event.

if anyone has worked on this more and it is reliable we would really like to hear from you!!! it is something that has been desired. These analytics would be so helpful to know what items are being used.

Thank you!

0
Comment made 4 months ago by Yann Desmarest 4479

Hi Brad,

I have done several tests using all kind of available resources on the webtop and I'm able to log everything. I found that when someone click on the icon of the resource and not the text, the script fails. So I added a piece of code to handle this case :

if (e.target.parentNode.className == "image" && e.target.parentNode.parentNode.className == "favorite") {
    var xhttp = new XMLHttpRequest();
    console.log(e.target.parentNode.id);
    var uri = "/analytics?t=" + Math.random() + "&r=" + encodeURIComponent(window.btoa(e.target.parentNode.parentNode.id)) + "&d=" + Date.now();
    xhttp.open("GET", uri, true);
    xhttp.send();
}

In fact, the class of all icons is image, not favorite. So I check the parent element of the parent of the icon.

I tested again and now it looks like it matches 100% of clicks. Let me know if it works fine for you.

Have a nice day

Yann

0
Comment made 4 months ago by brad 375

Well close.. Still didn't seem to be hitting 100%. But the following modification seems to be working much better..

window.onclick = function (e) {
    if (e.target.parentNode.className == "favorite" || e.target.parentNode.className == "image" || e.target.parentNode.className == "caption") {
        var xhttp = new XMLHttpRequest();
        console.log(e.target.parentNode.id);
        var parentNodeId = "";

        //populate parent's parent
        if (e.target.parentNode.parentNode.id) {
            parentNodeId = e.target.parentNode.parentNode.id;
        }
        //overwrite parent's parent if parent not null
        if (e.target.parentNode.id) {
            parentNodeId = e.target.parentNode.id;
        }

        //open link
        if (parentNodeId) {
            var uri = "/analytics?t=" + Math.random() + "&r=" + encodeURIComponent(window.btoa(parentNodeId)) + "&d=" + Date.now();
            xhttp.open("GET", uri, true);
            xhttp.send();
        }
        //log failed result
        else {
            console.log("Parent ID is NULL");
        }
    }
};


0
Comment made 4 months ago by Yann Desmarest 4479

Hi Brad,

My Bad, I forgot to include caption too. I never use them by the way.

Thank you for your great work, I will update my code with your script.

Have a nice day

Yann

0