StatsLibrary - Mini-IT/SnipeWiki GitHub Wiki
This article describes the system for collecting and viewing statistics outside of running Snipe server. The collection is based on compiling the tool and running it once per day at the start. The tool goes through modules each containing SQL queries that result in key-value pairs of statistics information. These pairs are then inserted into database table for later viewing through the editor.
The core statistics modules include user registrations count and user retention. User retention module uses "TempUserLogins" table and deletes all old records from it. This table has one record per user for each day that user logged in to server. If you do not use this module or do not collect statistics at all using this method, you will need to clear this table periodically.
Once the tool is compiled and ready to run, you can add it to server cron table like this ("run.sh" script calls Neko interpreter):
0 0 * * * $HOME/scripts/stats/run.sh
Note that statistics collection tool will insert new rows into "Stats" database table using yesterday as a date at the beginning of the day. If you intend to add records to this database table through some other means (for example, shop item stats are saved directly from the cache server), do not forget to use the correct date.
The stats collector configuration file is called "stats.cfg" and should be located in the same directory with the application.
Configuration variable | Description |
---|---|
database.host | Database connection host address string. |
database.name | Database name. |
database.password | Database password. |
database.port | Database port. |
database.user | Database user. |
server.logQuery | If enabled, logs all SQL queries. |
server.printLog | Enables printing log to stdout. |
server.writeLog | Enables writing log to log files. |
Main stats collection application class needs to extend snipe.stats.StatsServer
class. Here's the example:
import snipe.stats.StatsServer;
import snipe.stats.modules.*;
class StatsServerTest extends StatsServer
{
public function new()
{
super();
moduleClasses = [
UserRegsCore,
UserRetentionCore,
];
}
static var inst: StatsServerTest;
static function main()
{
inst = new StatsServerTest();
inst.init();
inst.run();
}
}
Everything is straightforward here. moduleClasses
array needs to hold module classes that are used. Here's the example of a module class:
import snipe.stats.StatsServer;
import snipe.stats.ModuleStats;
class UserAccounts extends ModuleStats
{
public function new()
{
super();
name = 'user accounts';
}
public override function run(server: StatsServer): _ModuleReturn
{
var cnt = server.getCount(
"SELECT count(*) AS cnt FROM Users");
return { single: { key: 'user.accounts', value: cnt } };
}
}
The stats collector module needs to override the run()
method to calculate some value (or multiple values) and return it. The module needs to be added to moduleClasses
.
After the stats collector is ready and running, you can use the editor to view the results (the first item in the top menu). However, if you've added some new modules to the stats collection, you also need to register them in the editor with StatsEditCore.registerType()
method call.
Usage example (basic):
public function new(s: ServerTest)
{
// ...
server.coreStatsModule.registerType({
id: 'user.accounts',
name: 'User Accounts' });
}
This adds the link to the editor stats list page that will display the basic table.
If you need more advanced stats display, you can add function link to the parameters that will output the webpage. For example:
public function new(s: ServerTest)
{
// ...
server.coreStatsModule.registerType({
id: 'user.accounts',
name: 'User Accounts',
func: userAccounts });
}
function userAccounts(vars: Vars)
{
manager.addList({
type: BLOCK_LIST,
query: "SELECT * FROM Stats " +
"WHERE Key = 'user.accounts' " +
"ORDER BY ID DESC LIMIT 50",
fields: [ 'date', 'value' ]
}, vars);
}
In this example the function draws a list of statistics values.
There can be a need to limit editor user access to some of the statistics pages available in the editor. This can be done through the use of user sub-permissions. Give the permission to look at the stats list and stats page themselves with "core/stats.list,core/stats.page" string. After that you can specify the stats pages the user has access to using "core/stats.page/" strings. For example, if you want to give the user access to the stats defined in the previous section of this article, use the following permissions string in the user record:
core/stats.list,core/stats.page,core/stats.page/user.accounts
Note that if the permissions string contains any stats sub-permissions, then all the stats pages that are not in the string will be disabled for this user.
Statistics list editor page displays a list of dashboard blocks on top of the full stats list. This dashboard is completely customizable with the use of the following snipe.edit.StatsEditCore
API:
-
registerDashboardChartBasic(id, title)
- basic single-line dashboard chart. -
registerDashboardChart(title, chart)
- customizable dashboard chart with chart options as an argument. -
registerDashboardFunc(id, title, func)
- dashboard block that is rendered with a given function.
All given dashboard block IDs (and in the case of registerDashboardChart()
chart ID) are also checked through the permission system as described in the previous section before display.
This is the Stats
database table definition used for storing stats records.
create table Stats
(
ID serial PRIMARY KEY, -- ID
Key text DEFAULT '' NOT NULL, -- stats type
Date timestamp with time zone DEFAULT now() NOT NULL, -- date of collection
Value real DEFAULT 0 NOT NULL -- stats value
);
create index Stats_Key_Date ON Stats(Key, Date);