Counters Guide
Counters are sum or count queries that can be run on transactions and routing orders.
These queries can be scheduled using CRON expressions.
They can also be manually triggered from the user interface. Read the Counters user interface to learn how to synchronize a counter from the Platform 6 Portal.
The results of the queries, called counter’s value can be queried from monitoring tools (Grafana, Nagios, Centreon …) and used to draw graphs or to trigger alerts.
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 or routing orders |
data partition | When queries are run on Item , the Data partition to the user; usually TRANSACTION for documents like TransactionInfo |
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 as in /TransactionInfo[FinalRecipient="BankOfAmerica"]
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
counters.date.format
configuration and defaults toyyyyMMdd'T'HH:mm:ss.S z
. - The timezone short form (CST, CDT, etc…) is specified by the
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 scheduling¶
Counters’s queries can be scheduled using CRON expressions.
Let’s take the example of a counter which 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" }
With the user interface¶
Once the counter is created, you can manually recalculate it through the user interface.
If there are 24 failed routing orders, the counter’s value will be:
{ "value": 24, "lastSyncDate": 1534853700107 }
(where lastSyncDate
is the last calculation date).
You can try to recreate a failing routing order and check after calculation that the counter’s new value is 25
.
However, you can’t spend your time clicking on the calculation button, especially if you have hundreds of counters.
With the Routes service¶
You can automate the calculation task thanks to the Routes service.
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, we’ll 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 identifier.CRON_EXPRESSION
: the CRON expression.USER_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 our CRON scheduling section. It will explain the required format and show some examples.
Thus, if we decide to synchronise our 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 automatically be calculated every 10 seconds.
Remote access to counters values¶
For a remote access you must declare specific 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.
Enumerate all deployed counters¶
You need to define a script (ie. named 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")
You can now access to your route via the 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.
Access a counter’s value¶
You need to define a script (ie. named 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")
You can now access to your route via the 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.
Access a synchronized counter’s value¶
You need to define a script (ie. named 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")
You can now access to your route via the 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 the counter’s value.