Skip to content
This repository has been archived by the owner on Jan 21, 2022. It is now read-only.

Create a Plan

Hristo Iliev edited this page Mar 15, 2018 · 26 revisions

Measures and metrics are grouped into a single entity called a plan. Plans provide Resource providers with a way to express the relationship between the measures and metrics. For example, if one needs two measures in order to be able to calculate the value of a metric, it is possible to group the two measures and the metric into a metering plan.

Based on what the plan is responsible for, there are three plan categories: metering, rating, and pricing.

Metering Plan

The metering plan defines the metering part of the calculations that Abacus will execute. meter, accumulate, and aggregate functions can be used with a metering plan. For example, consider the object storage metering plan.

Rating Plan

The rating plan defines the rating calculations. The charge and rate functions can be used with a metering plan. For example, see object storage rating plan.

Pricing Plan

The pricing plan defines the pricing on per-measure basis. For example, check the object storage pricing plan.

Sample Plans

There are a few predefined plans available in Abacus. You can find the examples with the metrics contained for each plan below:

Note: The basic analytics metrics use deprecated formulas and you can use them as a reference on how to migrate from the formulas to the new functions format.

Default Plan Functions

By default Abacus defines default functions. You can choose to override them by defining your own function with the same name or to work with the default one.

Metering

const meter = (metricName) => (measures) => measures[metricName];
const accumulate = (a, qty, start, end, from, to, twCell) =>
  end < from || end >= to ? null : new BigNumber(a || 0).add(qty || 0).toNumber();
const aggregate = (a, prev, curr, aggTwCell, accTwCell) =>
  new BigNumber(a || 0)
    .add(curr)
    .sub(prev || 0)
    .toNumber();
const summarize = (t, qty) => qty ? qty : 0;

By default the metric function uses measure with the same name. The accumulate and aggregate functions do simple sum. summarize returns the sum.

Rating

const rate = (p, qty) => new BigNumber(p || 0).mul(qty).toNumber();
const charge = (t, cost) => cost ? cost : 0;

Plan Snippets

Calculate the average sum of all measures

Abacus does not support average out of the box, but this is easily implemented by keeping the sum and the count of elements in compound object. This also increases the accuracy of the result.

Average sum plan

{
  "plan_id": "average_value",
  "measures": [
    {
      "name": "store",
      "unit": "BYTE"
    }
  ],
  "metrics": [
    {
      "name": "store",
      "unit": "GIGABYTE",
      "type": "discrete",
      "meter": "(m) => new BigNumber(m.store).div(1073741824).toNumber()",
      "accumulate": "(a, current) => a ? { sum: a.sum + current, count: a.count + 1 } : { sum: current, count: 1 }",
      "aggregate": "(a, p, current) => a ? { sum: a.sum + current.sum, count: a.count + current.count } : { sum: current.sum, count: current.count }",
      "summarize": "(t, qty) => new BigNumber(qty.sum).div(qty.count).toNumber()"
    }
  ]
}

Count of several metrics

Here we are summing several kinds of transactions (charges, refunds, others) into individual metrics. Then we have a global sum transactions that count the number of all operations. We want to keep a breakdown of the individual components, plus the total count of operations.

Sum of all transactions

{
  plan_id: 'transactions-plan',
  measures: [
    {
      name: 'charges',
      unit: 'NUMBER'
    },
    {
      name: 'refunds',
      unit: 'NUMBER'
    },
    {
      name: 'others',
      unit: 'NUMBER'
    }
  ],
  metrics: [{
    name: 'transactions',
    unit: 'NUMBER',
    type: 'discrete',
    meter: (m) => ({
      charges: new BigNumber(m.charges || 0).toNumber(),
      refunds: new BigNumber(m.refunds || 0).toNumber(),
      others: new BigNumber(m.others || 0).toNumber()
    }),
    accumulate: (a, c) => {
      const charges = a ? new BigNumber(a.charges).add(c.charges) : c.charges
      const refunds = a ? new BigNumber(a.refunds).add(c.refunds) : c.refunds;
      const others = a ? new BigNumber(a.others).add(c.others) : c.others;
      
      const transactions = a ?
        a.transactions.add(charges).add(refunds).add(others) :
        new BigNumber(0).add(charges).add(refunds).add(others);

      return {
        charges: charges.toNumber(),
        refunds: refunds.toNumber(),
        others: others.toNumber(),
        transactions: transactions.toNumber()
      };
    }
  }]
}
<< Create a Resource Provider Upload Plan >>

Related Links:

Clone this wiki locally