Display a MAML string in a textbox?

I have a dashboard running queries against SQL Server, and one of my new requirements is to read back a text field - a MAML string - and render it, preferably, in a Text panel. Well, I don’t actually have a preference, as long as it renders in dashboard.

I know the built-in Text panel can render plain text, markup or HTML. But, it’s really not well adapted for MAML - or to put it bluntly, it doesn’t know anything about MAML. For those unfamiliar, Wikipedia has an article here on MAML itself.

It is essentially a set of proprietary XML tags that shouldn’t look all that alien to anyone who’s ever written any basic HTML. My best hope is perhaps to rework the string and substitute those MAML tags with HTML tags, but the definition for MAML suggests it’s probably too complex to try to manipulate in that way, especially since (unless there’s a better solution) I’d be trying to perform substitutions with nothing more than SQL’s string manipulation functions. Unless there’s a better Transform option, I haven’t yet looked into that.

I can probably make some headway for very simple cases, but there’s always going to be “something else” I haven’t planned for, thus me asking if anyone’s ever tried to display a block of MAML text in a Grafana dashboard. If you’ve done that, what did you end up using?

SQL server should have some functions for XML transformations (not just string transformations). Random search result:

So check doc for your SQL server.

1 Like

Interesting thought. I knew SQL can convert strings to XML, but I had forgotten about XSL in this context. This might be the ticket. Thanks for the suggestion, I’ll follow up if I can put together a clean, “not too hack-y” solution…

Please provide a sample maml text and what it should look like once rendered and also what it would should look like if converted to html

Two things:

a) XML-XSL Transformations, even though it’s been available for SQL Server for a long time, is still not enabled by default in recent versions. My users are in locked down environments, and reconfiguring SQL Server to enable this functionality is a non-starter in a lot of cases. I don’t have the luxury of asking them to have their SQL admins to allow add-ons.

b) The Text panel, it seems, can’t have its own query. As soon as I change my visualization from Table to Text, the Queries/Transformations tabs both go away. I suppose I could have the query return its raw data in a Table panel (like any other), and then have a Text panel refer to the data shown by that panel, through some variable, I’m presuming. I haven’t yet tried that, but I suspect that’s the mechanism. I’ll investigate further and report back…

Here’s a sample MAML text string, saved as XML and then loaded with a browser, just so the indented nodes make it easier to follow:

Here’s what an application making use of that same string renders it:

So, my hope is that I can get away with, essentially, substituting tags with basic HTML equivalents. It doesn’t have to look exactly as it does in that screenshot, but that’s the sort of thing I’m hoping I can achieve.

1 Like

I guess you have to write own Grafana text panel, which will have XSLT support.

So, I tweaked my SQL query to replace MAML tags with standard HTML tags. If I take that and load it with a browser, it renders correctly.

Because a text panel does not have a data source, I’ve defined a variable that uses a URL param to run a SQL query and return the data. That works fine - with a caveat.

My Text panel has been switched to HTML mode, and the content is:

<div>
  <h1>Product Knowledge</h1>
  <p>$ProductKnowledge</p>
</div>

I realize that you’re not supposed to have [html], [head], [body], [style] (etc) tags, so I made sure I’m not using any of those.

I can see the value of the $ProductKnowledge variable.

The problem is, the HTML tags are shown literally.

If, in the above, I replace $ProductKnowledge with, say, this hardcoded value:

Hello, <b>World</b>

…then “World” is bolded, as expected.

ChatGPT tells me there’s 2 options - both presenting the same security risks:

a) Add this to a grafana.ini:

[panels]
disable_sanitize_html = true

b) Define an environment variable (which I’ve done as a system variable, not a user variable):

GF_PANELS_DISABLE_SANITIZE_HTML=true

…then restart Grafana.

Neither work. I’m still seeing my HTML tags:

And yes, I did restart the Grafana service as pointed out.

Should this work? If so, what might I be doing wrong?

1 Like

Try business text plugin,bit can handle proper html

If you post you data as text you will get more traction with someone helping you

Try business text plugin,bit can handle proper html

I can try that, but given that the built-in text panel has an HTML mode, I’d much rather try to get it to work with that first and foremost. Any additional plugin beyond what’s built-in is an impediment for adoption, and I don’t have the final say.

If you post you data as text you will get more traction with someone helping you

This is the text output by SQL, after it performs string substitution. Note how it doesn’t have any or tag - although that doesn’t prevent a browser from rendering it as HTML.

<div><div><div style="font-weight: bold; font-size: 1.2em;">Summary</div><p style="margin-bottom: 20px;">This alert indicates that an Operations Manager agent attempted to discover or generate data about an object that resides on another computer. This is not allowed by default, but is sometimes required for proper monitoring. For example, the agent might be running as part of a cluster, and trying to discover the virtual cluster node.</p><p style="margin-bottom: 20px;">The agent will not be able to do this until agent proxy is enabled.</p></maml:section><div><div style="font-weight: bold; font-size: 1.2em;">Causes</div><p style="margin-bottom: 20px;">It may be completely valid for the agent to discover objects residing on another computer. You must review the details of the alert description to determine if the agent should be configured with proxying.</p></maml:section><div><div style="font-weight: bold; font-size: 1.2em;">Resolutions</div><p style="margin-bottom: 20px;">If you have reviewed that the agent should be able to discover and send data on behalf of another computer, you should enable proxying for that agent:</p><br /><ul><li><p style="margin-bottom: 20px;">Go to the Administration space in the Operations Manager Console</p></li><li><p style="margin-bottom: 20px;"> Find the agent in the <b>Agent Managed</b> view </p></li><li><p style="margin-bottom: 20px;"> Open <b>Properties</b> for that agent </p></li><li><p style="margin-bottom: 20px;"> In the <b>Security </b>tab, check the <b>Allow this agent to act as a proxy</b> option </p></li><li><p style="margin-bottom: 20px;">Click OK</p></li></ul><br /></maml:section></div>
1 Like

Please Post the unadulterated maml sample you posted earlier

Please Post the unadulterated maml sample you posted earlier

I realized there’s a closing tag I had not replaced, but ultimately it should not affect how it was rendered. Regardless, here’s the MAML as it’s extracted directly from the database:

<MamlContent>
	<maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
		<maml:title>Summary</maml:title>
		<maml:para>This alert indicates that an Operations Manager agent attempted to discover or generate data about an object that resides on another computer. This is not allowed by default, but is sometimes required for proper monitoring. For example, the agent might be running as part of a cluster, and trying to discover the virtual cluster node.</maml:para>
		<maml:para>The agent will not be able to do this until agent proxy is enabled.</maml:para>
	</maml:section>
	<maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
		<maml:title>Causes</maml:title>
		<maml:para>It may be completely valid for the agent to discover objects residing on another computer. You must review the details of the alert description to determine if the agent should be configured with proxying.</maml:para>
	</maml:section>
	<maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
		<maml:title>Resolutions</maml:title>
		<maml:para>If you have reviewed that the agent should be able to discover and send data on behalf of another computer, you should enable proxying for that agent:</maml:para>
		<maml:para/>
		<maml:list>
			<maml:listItem>
				<maml:para>Go to the Administration space in the Operations Manager Console</maml:para>
			</maml:listItem>
			<maml:listItem>
				<maml:para>                      Find the agent in the <maml:ui>Agent Managed</maml:ui> view                    </maml:para>
			</maml:listItem>
			<maml:listItem>
				<maml:para>                      Open <maml:ui>Properties</maml:ui> for that agent                    </maml:para>
			</maml:listItem>
			<maml:listItem>
				<maml:para>                      In the <maml:ui>Security </maml:ui>tab, check the <maml:ui>Allow this agent to act as a proxy</maml:ui> option                    </maml:para>
			</maml:listItem>
			<maml:listItem>
				<maml:para>Click OK</maml:para>
			</maml:listItem>
		</maml:list>
		<maml:para/>
	</maml:section>
</MamlContent>

…and the editor here seems to mess up some tags. Here it is again, using the “preformatted text” option:

<MamlContent><maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10"><maml:title>Summary</maml:title><maml:para>This alert indicates that an Operations Manager agent attempted to discover or generate data about an object that resides on another computer. This is not allowed by default, but is sometimes required for proper monitoring. For example, the agent might be running as part of a cluster, and trying to discover the virtual cluster node.</maml:para><maml:para>The agent will not be able to do this until agent proxy is enabled.</maml:para></maml:section><maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10"><maml:title>Causes</maml:title><maml:para>It may be completely valid for the agent to discover objects residing on another computer. You must review the details of the alert description to determine if the agent should be configured with proxying.</maml:para></maml:section><maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10"><maml:title>Resolutions</maml:title><maml:para>If you have reviewed that the agent should be able to discover and send data on behalf of another computer, you should enable proxying for that agent:</maml:para><maml:para/><maml:list><maml:listItem><maml:para>Go to the Administration space in the Operations Manager Console</maml:para></maml:listItem><maml:listItem><maml:para>                      Find the agent in the <maml:ui>Agent Managed</maml:ui> view                    </maml:para></maml:listItem><maml:listItem><maml:para>                      Open <maml:ui>Properties</maml:ui> for that agent                    </maml:para></maml:listItem><maml:listItem><maml:para>                      In the <maml:ui>Security </maml:ui>tab, check the <maml:ui>Allow this agent to act as a proxy</maml:ui> option                    </maml:para></maml:listItem><maml:listItem><maml:para>Click OK</maml:para></maml:listItem></maml:list><maml:para/></maml:section></MamlContent>
1 Like

use <em> instead, more robust than the lonely <b>

<div><div>Hello <em  style="font-weight: bold;">World</em></div>

Until I get it to display as HTML, instead of showing tags as literal strings, I’m not gonna worry about that too much.

1 Like

I got it working with the Business Text panel.

As a bonus, it has its own data source, like most other panels, which eliminates the need to create a variable just to run the query.

I should also mention I have to refer to the data as {{{MyColumn}}}, as opposed to {{MyColumn}} (three curly braces instead of two). But if that means I also don’t have to rely on the disable_sanitize_html flag, that’s also a win.

But, I remain curious - since the Text panel supports HTML, I have to think I should have been able to get it to work. Again, the problem is, the value of a variable is shown as a literal string, whereas hardcoded tags work fine. Maybe that’s by design, but if it is, I must be misreading the documentation.

Unless I hear back with other suggestions, I’ll probably mark this as the solution. I’m leaving this opened for now.