We would like to have grafana iFrames embedded in the host and service pages (==interactive graphs). This works great as long as autorefresh is disabled. As soon as you enable autorefresh the iframe has to continously reload which makes it impossible to keep use.
Thread on monitoring-portal:
https://monitoring-portal.org/index.php?thread/39830-grafana-module/&postID=245375#post245375
A possible solution would probably be to adapt the autorefresh feature to do a partial refresh of only the divs which a special attribute set (something like "refresh=true").
Anything planned or some pointers how to workaround this?
Thank!
Hi,
There is no way at the moment to refresh divs independently. Is this still relevant for the grafana module? I had a quick look at it and it seems that the module no longer uses iframes.
Best regards,
Eric
I think this is indeed still relevant for the grafana module, the iframe mode is still present according to the documentation (see: accessmode)
https://github.com/Mikesch-mp/icingaweb2-module-grafana/blob/master/doc/03-module-configuration.md#options
Regards,
Markus
Did some quick tests with detaching iframes and moving them around the DOM. Unfortunately you can't change the position without forcing a reload of the iframe. Sorry but I have to close this.
Would something like this be a solution? Moving the iframe using CSS works without reloading it seems..
https://stackoverflow.com/a/39997814
The adoptNode function also doesn't seem to Work without reloading iframes anymore :(
PS: thanks for trying and your time! :)
I made this little behavior and it is working well. I only use the Grafana plugin for iframes and have it set to only exempt the class module-grafana.
```iframe.js
/* Garrett Seward | @spectralsun | GPLv2 */
/**
function Iframe(icinga) {
Icinga.EventListener.call(this, icinga);
}
Iframe.prototype = new Icinga.EventListener();
/**
* Mutates the HTML before it is placed in the DOM after a reload
*
* @param content {string} The content to be rendered
* @param $container {jQuery} The target container
* @param action {string} The URL that caused the reload
* @param autorefresh {bool} Whether the rendering is due to an auto-refresh
*
* @return {string|null} The content to be rendered or null, when nothing should be changed
*/
Iframe.prototype.renderHook = function(content, $container, action, autorefresh) {
if (!autorefresh) {
return content;
} else {
var containerId = $container.attr('id');
if (containerId === 'menu' || containerId === 'application-state') {
return content;
}
}
if (!$container.find('iframe').length) {
return content;
}
var $children = $container.children();
var $contentChildren = $container.find('.content').children();
var $content = $('<div>').html(content);
$content.children().each(function(idx) {
var $child = $(this);
if (!$child.hasClass('content')) {
$($children[idx]).html($child.html());
} else {
$child.children().each(function(contentIdx) {
var $contentChild = $(this);
// All the iframes we use have this class, overwrite any others
if (!$contentChild.hasClass('module-grafana')) {
$($contentChildren[contentIdx]).html($contentChild.html());
}
});
}
});
$container.find('.controls .tabs').after('<div class="tabs-spacer">');
return null;
};
Icinga.Behaviors = Icinga.Behaviors || {};
Icinga.Behaviors.Iframe = Iframe;
}) (Icinga, jQuery);
@spectralsun where do I need to put this javascript snippet? I'm currently provisioning a icinga standalone vagrant box to test this.
@friesoft place this in a file and add an entry to JavaScript.php similar to this PR
You will probably want to add &refresh=5s as a custom var on your grafana graphs too (in the icingaweb2 grafana graph configuration entries).
@spectralsun works like a charm now :smile: very nice work! Could you maybe create a pullrequest for this?
For reference, I added the iframe.js here as last element to the jsFiles array: /usr/share/php/Icinga/Web/JavaScript.php
@friesoft awesome, thank you :smiley: sure, I could create a pull request for this.
@spectralsun Great! :smile: I noticed a small bug with the iframe.js included:
Before (initial load of the container):

After (after each refresh of the container):

The spacing on top seems to get lost.
@friesoft I updated the script I posted to fix this bug.
As for submitting this, I think this code makes sense either as its own module or as part of the grafana module.
@spectralsun: I guess it makes sense in the grafana Module in its current form. Without the check for the grafana module iframe it might even make sense in icingaweb2 directly?
@lippserd: what do you think?
I got inspiration for this script from how React works, by diffing the DOM. It would be great to see icingaweb2's frontend on a modern framework like React.
If this was going to go into the core icingaweb2 project, I think it should look for iframe elements to exempt, instead of the .module-grafana wrapper.
@spectralsun did you already open a pullrequest? I couldn't find it. Thanks :)
@friesoft no, haven't opened anything yet. Was going to wait for @lippserd to respond. If I were to open one today, I feel like it'd make most sense as being part of the existing grafana module.
I try to have a look here tomorrow guys.
We've just tested the iframe.js on Icingaweb2 2.6.0 and it works like a charm :)
@lippserd did you have time to look into this yet?
I've had a chance to look at this now. Sorry that it took me so long. I also think that it's best to get this into the grafana module. You may exit early if $container.hasClass('module-grafana') returns false. I think that's the only option to not refresh an iframe. Good job 馃憤
This works great and is a must-have for Grafana iframe graphs!
@friesoft @thox Did this make it into any PR or commit?
Most helpful comment
I made this little behavior and it is working well. I only use the Grafana plugin for iframes and have it set to only exempt the class
module-grafana.```iframe.js
/* Garrett Seward | @spectralsun | GPLv2 */
/**
*
*/
(function(Icinga, $) {
'use strict';
}) (Icinga, jQuery);