Statistics Library
The statistics library can be used to provide statistics services within App. The following
functionality is implemented:
-
Support of two types of datasets: StatisticsCumulative and StatisticsState. The
StatisticsCumulative provides values at timestamps, which can be added up over a
period of time to get a total in this timeframe. The StatisticsState provide a
state at a given timeframe. It can be used to find maximum values in a timeframe
of averages.
-
The Data is organized with Datasets, Charts and Categories. A dataset is a table
containing pairs of timestamp and value. These datasets can be combined with
to Charts. The data from multiple datasets of type StatisticsCumulative can be
added into a chart. The charts can be assigned to different categories.
-
Implement the App Websocker Api "com.innovaphone.statistics". For this the library
can register as JsonApi into the AppWebsocket framework so that it can be accessed
via AppWebsocket. If announced as a Service, the Api can be also found with the
Services Mechanism. The main Requests on this Api are:
- Categories
-
Read all available categories
- Charts
-
Read the available Charts
- Datasets
-
Read the available Datasets
- Data
-
Read the data in a dataset from a start to an end timestamp. This is
for testing only
- Current
-
Read the current value of a StatisticsState dataset.
- Read
-
Read data from a start to an end timestamp as yearly, monthly, weekly or
live data. It returns an array of long64 values. For live data the values
since the last Read are returned. By reading for example once a second a
live chart can be displayed
-
Provide internal Apis so that the App can define the available Categories, Charts and
Datasets and can provide data for the dataset. The App is responsible to provide
Updates whenever needed, the libray does not do any periodic polling.
The internal Api is split in statistics.h and statistics_dataset.h. statistics_dataset.h
is the Api to provide the data. It has no dependency on any other header file.
-
Keep a table for one hour of live data for each dataset. To limit the size of the table
the information of one second is combined. This means the table has a maximum of 3600
entries.
-
Store dataset data into a database table. A single entry in the table consists of a long64
timestamp (ms), a long64 value and a long64 reference to a dataset. So a total of 24
bytes are stored per value (plus any database overhead). Only one value per hour is stored
in case of StatisticsCumulative this is the sum of the values and in case of StatisticsState
it is the maximum. So during one year this can addup to 24*365.25=8766 values or 210KB
Interface
class IStatisticsProvider * CreateStatisticsProvider()
Global function to instaniate the library. Usually called from the App main module. To have
the library instantiated with this function, allows it to be replaced by a test library for
unit testing.
The function class IStatistics * IStatisticsProvider::CreateStatistics() can be used to create
the instance used within the AppInstance.
class IStatistics
Interface class to be used by the App Code
- void Init(class UStatistics * user, class IDatabase * database)
-
Has to be called for initialization. As long a no StatisticsInitComplete is called
all other calls to the interface are ignored
- void StartMonitor(const char * type, class json_io & send, word base, char *& tmp)
-
Starts monitoring of a given value with the "Monitor" functionality outside the scope
of the library
- void Close()
-
Close the library. Has to be done for graceful AppInstance shutdown. Is acknowledged with
StatisticsCloseComplete()
- void CreateCategory(const char * name)
-
Used to create a category
- void CreateChart(const char * category, const char * name, const char * condition)
-
Used to create a Chart. The condition identifies the datasets for the chart. Currently
only a single dataset identified with the name is supported.
- class IStatisticsDataset * CreateDataset(const char * name, enum StatisticsType type, class UStatisticsDataset * provider = 0)
-
Creates a dataset. If a provider pointer is given, no data is stored in the library, but the data
is retrieved from the App itself using the
void UStatisticsDataset::Get(class IStatisticsGet * user, long64 start, long64 end) function.
class IStatisticsDataset
Interface class to a dataset
- void Data(long64 value)
-
Provide a value. The timestamp of the value is the current system timestamp as read from
ITime::TimeStampMilliseconds()
- void BusyStart()/void BusyEnd()
-
With the call to BusyEnd the time since the call to BusyStart is stored as value.
Steps to include the libray into an App
-
Share sdk/common/service/statistics into App code and add
"include sdk/common/service/statistics/statistics.mak" to submodules.mak
-
Include the "com.innovaphone.statistis" as Client and as Service Api. Something like
word apis = msg.add_object(base, "apis");
msg.add_object(apis, "com.innovaphone.statistics");
In AppWebsocketAppInfo and AppWebsocketServiceInfo. At this point the App should show up
in Charts.
-
Include
IStatisticsProvider * statisticsProvider = CreateStatisticsProvider();
in <app>-main.cpp and include the statisticsProvider as argument in the AppService
constructor. The include file "common/interface/statistics.h" ís needed for this.
Add cleanup of the statistics provider before exiting main:
delete statisticsProvider;
-
Add
#include "common/interface/statistics.h"
#include "common/interface/statistics_dataset.h"
to the <App>.cpp module.
-
Add member
class IStatisticsProvider * statisticsProvider;
to the App Service class and
IStatistics * statistics;
to the App Instance class
-
Create the statistics instance with in the App instance constructor:
statistics = service->statisticsProvider->CreateStatistics();
-
Add a first category for the data. E.g.
this->statistics->CreateCategory("*");
-
Register the Json Api in the App Instance constructor with
RegisterJsonApi(statistics);
At this point the category should show up in charts when clicking on the App
-
Add CreateChart and CreateDataset to announce the data which shall be published.
For example
statisticsSessions = statistics->CreateDataset("sessions", StatisticsState);
statistics->CreateChart("*", "Sessions", "sessions");
-
App functions to provide data. For example in the session constructor to update the sessions
Count:
<AppService>->sessionCount++;
<AppService>->statisticsSessions->Data(<AppService>->sessionCount);
-
Add instance initialization and closing of the lib. For this use "public UStatistics"
as base class to the App Instance class. Add override functions
void StatisticsInitComplete() override;
void StatisticsCloseComplete() override;
Call statistics->Init(this, database) in the initialization chain after database
inititialization and statistics->Close() in the App Instance Close function. Continue
with closing only after the StatisticsCloseComplete() callback.