Counters¶
The counters
service allows managing Sum
or Count
queries that can be run on transactions, routing orders, logs or table data.
The results of these queries are called counter values.
Counters can be leveraged to display KPIs in home pages, or be queried from monitoring tools (Grafana, Nagios, Centreon …) and used to draw graphs or to trigger alerts.
The synchronization or refresh of counters can be performed from the Portal user interface or scheduled using cron expressions.
Read the page about the Counters user interface to learn more about how to handle counters via P6 Portal.
Counter’s parameters¶
A counter consists of several attributes.
Parameter | Description |
---|---|
name | The name of the counter |
description | The multi-language description of the counter |
target | Determines if the query is going to be run on transactions, logs, table data or routing orders |
type | Determines if the counter’s value is calculated by running a Sum or Count query |
query | An XPath (XML Path Language) expression |
XPath expressions¶
Validation¶
Valid XPath expressions are tightly coupled to the XML capabilities of the underlying database:
- PostgreSQL supports XPath 1.0 expressions
Root elements¶
Routing order XPaths should always start with /routingOrder
.
Transaction XPaths should start with a slash followed by the transaction type name, for example /TransactionInfo
Date & time variable expansions¶
To facilitate writing XPaths relative to time, two variable expansions are provided for date and time.
Date
The ${DATE}
variable will be expanded to a timestamp:
- The format of the timestamp is specified by the
p6.service.counters.date.format
configuration and defaults toyyyyMMdd'T'HH:mm:ss.S z
. - The timezone short form (CST, CDT, etc…) is specified by the
p6.service.counters.date.timezone
configuration and defaults to the server time zone.
Time
The ${TIME}
variable will be expanded to an epoch (the number of milliseconds since January 1st, 1970).
Calculations can be performed on DATE
and TIME
using the following syntax: ${[DATE|TIME]([+|-]\d+[s|m|h|d|M|y])*}
where:
s
: secondsm
: minutesh
: hoursd
: daysM
: monthsy
: years
Examples
Assuming the current date/time is May 13th, 2013 at 11:34:57.12 CEST which is an epoch of 1368437697012 ms.
XPath | Expanded |
---|---|
TransactionInfo[DateCreated<"${DATE-15d}"][Status="SENT"] |
TransactionInfo[DateCreated<"20130428T11:34:57.12 CEST"][Status="SENT"] |
TransactionInfo[DateSent>"${DATE-2d+1h}"][Status="SENT"] |
TransactionInfo[DateSent>"20130511T12:34:57.12 CEST"][Status="SENT"] |
TransactionInfo[DateCreated<"${DATE-15d}"][DateSent>"${TIME-2d+1h}"][Status="SENT"] |
TransactionInfo[DateCreated<"20130428T11:34:57.12 CEST"][DateSent>"1368268497012"][Status="SENT"] |
Counters synchronization¶
Once the counter is created, you will want to show its value - so you will need to ‘synchronize’ it (i.e. calculate or refresh its value).
Let’s take the example of a counter that counts the number of failed routing orders.
The counter‘s properties will look like:
{
"appKey": "",
"name": "Count_FailedRoutingOrders",
"description": { "EN": "Number Of Failed Routing Orders" },
"query": "/routingOrder",
"target": "FailedRoutingOrder",
"type": "COUNT"
}
{
"value": 24,
"lastSyncDate": 1534853700107
}
lastSyncDate
is the last calculation date).
Synch counters via the Portal¶
Counters can be synchronized via the Portal user interface, as explained on this section of the Counters UI page.
Synch counters via a route¶
You can automate the synchronization or refresh of counters leveraging the Routes service and cron expressions:
Go to the Routes service user interface and create a new route deployment script.
Choose a name (eg: Count_FailedRoutingOrders), a description, select the type Scheduler and the template BaseRoute.groovy.
In the script segment destroyRoutes, enter the following line:
p6.camel.destroyAllRoutes()
In the script segment addRoutes, you can define the route using the Camel component Quartz2.
The purpose of the route will be to ask the Counters service to calculate the counter which id is Count_FailedRoutingOrders at a period determined by a cron expression.
For any counter, the route will look like this:
from("quartz2://platform6/p6route_${COUNTER_ID}?cron=${CRON_EXPRESSION}")
.to('p6cmb://counters?platform6.request.action=synchronize&id=${COUNTER_ID}')
.routeId('${ROUTE_ID}')
The parameters are:
COUNTER_ID
: the counter‘s identifierCRON_EXPRESSION
: the cron expressionUSER_EMAIL_ADDRESS
: the email address of the user scheduling the counter (eg:admin@amalto.com
)ROUTE_ID
: it can be anything that you want, but it must be unique. We suggest you also use the counter‘s id
For some information about cron expressions, have a look at the Cron Scheduling section. It will explain the required format and show some examples.
Thus, if we decide to synchronize the Count_FailedRoutingOrders counter every 10 seconds, the route will look like as follow:
from("quartz2://platform6/p6route_Count_FailedRoutingOrders?cron=0/10+*+*+*+*+?")
.to('p6cmb://counters?platform6.request.action=synchronize&id=Count_FailedRoutingOrders')
.routeId('Count_FailedRoutingOrders')
Enable the route deployment script and save it.
Finally, start the route deployment script. As long as the job is running, the counter will be automatically calculated every 10 seconds.
Remote access to counters¶
Remote access to counters require the creation of specific scripts and routes.
Authentication¶
All Platform 6 RESTful services are guarded with basic authentication. The username/passwords used are those defined using the Platform 6 user administration.
List counters¶
In order to list all the counters available on your instance, you first need to define a script (say ‘CounterList’):
p6.pipeline.put("body", p6.counter.list())
And then define the corresponding route:
rest("/public/counters")
.get("/list")
.to("p6cmb://scripts?platform6.request.action=execute&id=CounterList")
.id("CounterList")
Once done, you will have access your route via the following URL:
http://<hostname>:8080/p6/public/counters/list
Where:
<hostname>
: the host running the Platform 6 instance.
The response is text/plain
and contains a list of all deployed counters in a JSON text format.
Retrieve a counter’s value¶
In order to remotely retrieve a counter‘s value, you first need to define a script (say ‘CounterDetail’):
p6.pipeline.put("body", p6.counter.get(p6.pipeline.get("counter")))
And then define the corresponding route:
rest("/public/counters")
.get("/detail/?counter={counter}")
.to("p6cmb://scripts?platform6.request.action=execute&id=CounterDetail&counter={counter}")
.id("CounterDetail")
Once done, you will have access to your route via the following URL:
http://<hostname>:8080/p6/public/counters/detail?counter=<countername>
Where:
<hostname>
: the host running the Platform 6 instance<countername>
: the name of the counter to query
Warning
If a counter’s name contains spaces then the URL will require this name to be escaped.
The response is text/plain
and contains the detail of the counter in a JSON text format.
Synchronize a counter and retrieve its value¶
In order to remotely synchronize a counter and retrieve its value, you will first need to define a script (say ‘CounterSync’):
p6.pipeline.put("body", p6.counter.synchronize(p6.pipeline.get("counter")))
And then define the corresponding route:
rest("/public/counters")
.get("/sync/?counter={counter}")
.to("p6cmb://scripts?platform6.request.action=execute&id=CounterSync&counter={counter}")
.id("CounterSync")
Once done, you will have access to your route via the following URL:
http://<hostname>:8080/p6/public/counters/sync?counter=<countername>
Where:
<hostname>
: the host running the Platform 6 instance<countername>
: the name of the counter to query
Warning
If a counter’s name contains spaces then the URL will require this name to be escaped.
The response is text/plain
and contains the counter‘s value.