Skip to content

Hints on how to update XSLT

Jim Caffrey edited this page Mar 22, 2016 · 1 revision

Example of how to update style sheets to improve the visualization of ADE output

The Anomaly Detection Engine for  Linux Logs (ADE) generates xml which can be viewed using simple xml style sheets which have been provided. The style sheets provided can be edited to highlight the information which will help the users of ADE answer their questions.

Here are some examples of changes to the style sheets you might want to make:

  • Changing the style sheets so that when you click on a column header the table is sorted by the values in that column

  • Reorder the information about messages within an interval ( interval details) so that only the important information is provided like

    • the contribution of the message to the interval contribution score

    • information about the context of the message - cluster status - issued at a periodic interval

    • number of times it occurred during the hour

    • in how many intervals within a day does it occurs

    • when it occurred within the interval

    • example of the message text

You might want to include other information in the details depending on what questions ADE is being used to answer.

How to change the style sheet used by Anomaly Detection Engine for Linux

Where to find the style sheets

The style sheets used by ADE are found in the directory pointed to by ade.xml.xsltDir. The default location is conf/xml.

They are copied into the output directories by

  • AnalyzedIntervalXmlStorer.java(ade/ade-core/src/main/java/org/openmainframe/ade/output/)
  • ExtJaxbAnalyzedPeriodV2XmlStorer.java (ade/ade-ext/src/main/java/org/openmainframe/ade/ext/output/) and
  • ExtJaxbAnalyzedIntervalV2XmlStorer.java ade/ade-ext/src/main/java/org/openmainframe/ade/ext/output/).

The default is for ADE will write the style sheets as part of the ADE output.If you are not getting xslt directories in your ADE output directories check the value of the property createXSLDirectory for the outputers in the flowlayout.xml LINUXx24,LINUXx32, and LINUXx35. The value for this property should be True.

How to update the xsl to sort rows based on values in a columns

  • down load sorttable.js from GitHub
  • add the sorttable .js file to the list of resources "s_xslResources" copied into each xslt directory by
    • ExtJaxbAnalyzedPeriodV2XmlStorer.java for period
    • ExtJaxbAnalyzedIntervalV2XmlStorer.java for interval within period
   private static final String[] s_xslResources = {
                                                    "AnalyzedInterval.xsl",
													"AdeCorePlex.xsl",
													"global.css",
													"sorttable.js"
													}

Note:ExtJaxbAnalyzedPeriodV2XmlStorer.java or ExtJaxbAnalyzedIntervalV2XmlStorer.java are the java parts to be updated to copy javascript parts or cascaded style sheets into ADE output.

  • add the following to AdeCorePlexV2.xsl
    • add the following lines within the header
<head>

                <link href='./xslt/global.css' rel='stylesheet' type='text/css' />
				<!-- Adding sortable column support to standard xsl stylesheets /> -->
				<script src="./xslt/sorttable.js"></script>

            </head>
  • add the class sortable to table
						<table class="sortable">

                            <tr>
                                <th width="125" >
                                Interval Index
                                </th>
  • add the following to AdeCorePlexV2.xsl
    • add the following lines within the header
<head>
                <link href='./xslt/global.css' rel='stylesheet' type='text/css'>
                </link>
				<!-- Adding sortable column support to standard stylesheets /> -->
				<script src="./xslt/sorttable.js"></script>

            </head>
  • add the following lines to the table class
                <div class="scrollTableContainer">
                    <table class="sortable" border="1" cellpadding="3">
                        <tr>
  • rebuild ADE

How to reorder columns so the most important information is first and remove less important information

Suppose for the systems you are monitoring critical problems occur when messages which are routine appear when they are not expected or a message that normally occurs in a cluster appears without the messages that are normally associated with it. You can modify the style sheets to highlight the information about in what context messages within an interval occur.  Here is a screen shot using a modified style sheet that highlights the information about the context of the message.

To make these changes

  • modify AdeCoreIntervalV2.xsl to your liking; There is an example at the end of this section
  • rebuild ADE

Picture of results after removing and reordering columns

Picture of results of removing and reordering columns

Here is the stylesheet that displays only the "interesting" portion of the information which ADE has about each message within each interval.

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:i="http://www.openmainframe.org/ade/AdeCoreIntervalV2">
    <xsl:template match="/">
        <html>
            <title>Anomaly Detection Engine Interval View</title>
            <head>
                <link href='./xslt/global.css' rel='stylesheet' type='text/css'>
                </link>
                <!-- Adding sortable column support to standard stylesheets /> -->
                <script src="./xslt/sorttable.js"></script>

            </head>
            <body>
                <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
                <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
                <xsl:variable name="number_of_intervals_in_a_day" select="(24 * 60 * 60) div (i:interval/i:model_info/@interval_size_in_sec)" />
                <h1>Anomaly Detection Engine Interval View</h1>
                <p>
                    System identifier:
                    <xsl:value-of select="i:interval/i:sys_id" />
                    <br></br>
                    Dates:
                    <xsl:value-of select="i:interval/i:start_time" />
                    --
                    <xsl:value-of select="i:interval/i:end_time" />
                    <br></br>
                    Number of intervals in a day:
                    <xsl:value-of select="$number_of_intervals_in_a_day" />
                    <br></br>
                    Intervals size in seconds:
                    <xsl:value-of select="i:interval/i:model_info/@interval_size_in_sec" />
                    <br></br>
                    <br></br>
                    Interval anomaly score:
                    <xsl:variable name="display_anomaly_score" select="i:interval/i:anomaly_score" />
                    <xsl:value-of select="$display_anomaly_score" />
                    <br></br>

                </p>

                <div class="scrollTableContainer">
                    <table class="sortable" border="1" cellpadding="3">
                        <tr>

                            <th width='7%'>Interval Contribution</th>
                            <th width='7%'>cluster_context</th>
                            <th width='7%'>Periodicity status</th>
                            <th width='7%'>Num of instance</th>
                            <th width='7%'>Frequency</th>
                            <th width='140px'>Time Line</th>
                            <th>Message</th>
                        </tr>
                        <xsl:for-each select="i:interval/i:interval_message">
                            <tr>
                                <td>
                                    <xsl:variable name="display_intCont" select="format-number(i:intCont, '0.000;#')" />
                                    <xsl:value-of select="$display_intCont" />
                                </td>
                                <td>
                                  <xsl:choose>
                                    <xsl:when test="i:cluster_status='IN_CONTEXT'">
                                        in context (<xsl:value-of select="i:cluster_id" />)
                                    </xsl:when>
                                    <xsl:when test="i:cluster_status='OUT_CONTEXT'">
                                        out of context (
                                        <xsl:value-of select="i:cluster_id"/> )
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <xsl:value-of select="translate(i:cluster_status,$uppercase, $smallcase)" />
                                    </xsl:otherwise>
                                  </xsl:choose>
                                </td>
                                <td>
                                    <xsl:value-of select="i:periodicity/@status" />
                                </td>
                                <td>
                                    <xsl:value-of select="i:num_instances" />
                                </td>
                                <td>
                                    <xsl:variable name="display_frequency_int_per_occ"
                                              select="format-number($number_of_intervals_in_a_day div i:bernoulli/@frequency, '0.000;#')" />
                                    <xsl:variable name="frequency_occ_per_day" select="format-number(i:bernoulli/@frequency, '0.000;#')" />
                                    <!--xsl:variable name="frequency_occ_per_day" select="$number_of_intervals_in_a_day div i:bernoulli/@frequency" /-->
                                    <!-- Convert frequency to: X number of occurrence every N days.  X must be at least 1 -->

                                    <xsl:variable name="display_frequency_occ_per_day" select="format-number($frequency_occ_per_day, '0.000;#')" />
                                    <xsl:value-of select="$display_frequency_occ_per_day" />_occ/day

                                    <xsl:choose>
                                      <xsl:when test="1 > $frequency_occ_per_day">
                                        <!-- if the number of occ per day is less than 1, then find out number of days for it to occur once -->
                                        <xsl:variable name="frequency_baseline_number_of_days" select="format-number(1 div $frequency_occ_per_day, '0;#')" />
                                        <xsl:variable name="occ_per_baseline_number_of_days" select="$frequency_occ_per_day * $frequency_baseline_number_of_days" />

                                        <xsl:variable name="display_occ_per_baseline_number_of_days" select="format-number($occ_per_baseline_number_of_days, '0.000;#')" />
                                        <xsl:value-of select="$display_occ_per_baseline_number_of_days" />_occ/<xsl:value-of select="$frequency_baseline_number_of_days" />days
                                      </xsl:when>
                                    </xsl:choose>
                                    <br></br>
                                    <xsl:value-of select="$display_frequency_int_per_occ" />_interval/occ
                                </td>
                                <td>
                                    <div id="{@msg_id}" style='position:relative;height:32px;width:140px'>
                                        <div
                                            style="left: 0px; top: 0px; width: 120px; height: 32px; clip: rect(0pt, 120px, 32px, 0pt); background-color: rgb(0, 0, 0); position: absolute;"></div>
                                        <xsl:for-each select="i:time_vec/i:occ">
                                            <div
                                                style="left: {.}px; top: 26px; width: 2px; height: 5px; clip: rect(0pt, 2px, 5px, 0pt); background-color:rgb(0,255,0); position: absolute;"></div>
                                        </xsl:for-each>
                                    </div>
                                </td>
                                <td title="{i:text_smp}">
                                    <xsl:value-of select="i:text_sum" />
                                </td>
                            </tr>
                        </xsl:for-each>
                    </table>
                </div>
                <br />
                <br />
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>