blob: 693f7d4ba8dfa1c2b4a2219abda560b0a13101d1 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_CLL_StatCapture_Functions
//
// Purpose:
// This module contains the implementation of Statistics Capture Control functions.
//
// Module Parameters:
// tsp_EPTF_StatCapture_def_capture_file - *charstring* := "Default_Capture_File";
// set it to a filename string to define a default capture file
// tsp_EPTF_StatCapture_max_file_size - *integer* := 1000000000;
// set it to define a maximum file size for logfiles (in bytes)
// tsp_EPTF_StatCapture_max_nrof_files - *integer* := 100;
// set it to define the maximum number of files opened for one logfile stream
// tsp_EPTF_StatCapture_FileFormat - <EPTF_StatCapture_FileFormat> := readable;
// set it to readable/gnuplot for defining output file format
// tsp_debug_EPTF_StatCapture_Functions - boolean
// tsp_EPTF_StatCapture_headerSeparator - *charstring* := " ";
// the separator string that will be printed between each statistics name
// tsp_EPTF_StatCapture_statNameSeparatorSubstitute - *charstring* := "_";
// if a statistics name contains a header separator, it will be replaced with this string
//
// Module depends on:
// <EPTF_CLL_StatCapture_Definitions>
// <EPTF_CLL_Base_Functions>
// <EPTF_CLL_Variable_Functions>
// <EPTF_CLL_StatMeasure_Functions>
// <EPTF_CLL_Scheduler_Definitions>
// <EPTF_CLL_RBTScheduler_Functions>
// <TCCFileIO_Functions>
// <EPTF_CLL_Common_Definitions>
// <EPTF_CLL_HashMapInt2Int_Functions>
// <EPTF_CLL_Logging_Definitions>
// <EPTF_CLL_Logging_Functions>
// <EPTF_CLL_HashMap_Functions>
//
// Public functions:
// <f_EPTF_StatCapture_init>
// <f_EPTF_StatCapture_setGroupStatDirectory>
// <f_EPTF_StatCapture_getGroupStatDirectory>
// <f_EPTF_StatCapture_openNewStatLogFile>
// <f_EPTF_StatCapture_createStatforCapture>
// <f_EPTF_StatCapture_addNewGroup>
// <f_EPTF_StatCapture_parseConfigGroup>
// <f_EPTF_StatCapture_addStatistics>
// <f_EPTF_StatCapture_addListOfStatistics>
// <f_EPTF_StatCapture_setTimerPeriod>
// <f_EPTF_StatCapture_InactivateStatistics>
// <f_EPTF_StatCapture_ActivateStatistics>
// <f_EPTF_StatCapture_getStatisticsID>
// <f_EPTF_StatCapture_startGroupCapture>
// <f_EPTF_StatCapture_startCaptureAll>
// <f_EPTF_StatCapture_stopGroupCapture>
// <f_EPTF_StatCapture_stopCaptureAll>
// <f_EPTF_StatCapture_deleteGroup>
// <f_EPTF_StatCapture_getFileName>
//
// Current Owner:
// Andrea Darabos (EANDDAR)
//
// Last Review Date:
// 2007-11-16
//
// Detailed Comments:
// This module contains the interface functions for the EPTF Statistics Capture Control.
//
///////////////////////////////////////////////////////////////
module EPTF_CLL_StatCapture_Functions {
import from EPTF_CLL_StatCapture_Definitions all;
import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_Variable_Definitions all;
import from EPTF_CLL_Variable_Functions all;
import from EPTF_CLL_StatMeasure_Functions all;
import from EPTF_CLL_Scheduler_Definitions all;
import from EPTF_CLL_RBTScheduler_Functions all;
import from TCCFileIO_Functions all;
import from EPTF_CLL_Common_Definitions all;
import from EPTF_CLL_HashMapInt2Int_Functions all;
import from EPTF_CLL_Logging_Definitions all;
import from EPTF_CLL_Logging_Functions all;
import from EPTF_CLL_HashMap_Functions all;
modulepar charstring tsp_EPTF_StatCapture_def_capture_file := "Default_Capture_File";
modulepar integer tsp_EPTF_StatCapture_max_file_size := 1000000000; //1GByte, 10^9 bytes
modulepar integer tsp_EPTF_StatCapture_max_nrof_files := 100; //max nr of files opened for one data stream
modulepar EPTF_StatCapture_FileFormat tsp_EPTF_StatCapture_fileFormat := readable;
modulepar EPTF_StatCapture_CaptureGroupsConfig tsp_EPTF_StatCapture_captureGroups := {}; //by default, capture groups are not created from the config file
modulepar boolean tsp_debug_EPTF_StatCapture_Functions := false;
modulepar charstring tsp_EPTF_StatCapture_headerSeparator := " ";
modulepar charstring tsp_EPTF_StatCapture_statNameSeparatorSubstitute := "_";
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_init
//
// Purpose:
// Initializes the StatCapture component and depending components.
//
// Parameters:
// selfName - *in* *charstring* - name of the component
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function initializes used components and defines the handleEvent behaviour (Scheduler).
// In case a module parameter is given, the function creates a default log file for capture groups.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_init(in charstring pl_selfName) runs on EPTF_StatCapture_CT {
if (v_StatCapture_initialized) {
return; // component is already initialized
}
f_EPTF_Base_init_CT(pl_selfName);
f_EPTF_Scheduler_init_CT(pl_selfName);
f_EPTF_StatMeasure_init_CT(pl_selfName);
f_EPTF_HashMap_init_CT (pl_selfName);
f_EPTF_Logging_init_CT(pl_selfName);
v_StatCapture_loggingMaskId := f_EPTF_Logging_registerComponentMasks(tsp_EPTF_StatCapture_loggingComponentMask, c_EPTF_StatCapture_loggingEventClasses, EPTF_Logging_CLL);
if(tsp_debug_EPTF_StatCapture_Functions) {
f_EPTF_Logging_enableLocalMask(v_StatCapture_loggingMaskId, c_EPTF_StatCapture_loggingClassIdx_Debug);
} else {
f_EPTF_Logging_disableLocalMask(v_StatCapture_loggingMaskId, c_EPTF_StatCapture_loggingClassIdx_Debug);
}
v_StatCapture_initialized := true;
v_StatCapture_captureGroups := {};
v_StatCapture_eventHandler := refers(f_EPTF_StatCapture_handleEvent);
v_StatCapture_inthashmap_id := f_EPTF_int2int_HashMap_New("fd2nameHashmap");
v_StatCapture_logfilenames := {};
v_StatCapture_resetStatList := {};
v_StatCapture_subscribeVarReqParamList := {};
if (tsp_EPTF_StatCapture_def_capture_file == "") {
v_StatCapture_deffd := -1;
}
else {
v_StatCapture_deffd := f_EPTF_StatCapture_openNewStatLogFile(tsp_EPTF_StatCapture_def_capture_file);
if (v_StatCapture_deffd < 0)
{
f_EPTF_StatCapture_debug(f_FIO_get_error_string());
}
}
v_StatCapture_serverAlt := activate(as_EPTF_StatCapture_serverAlt());
f_EPTF_Base_registerCleanup(refers(f_EPTF_StatCapture_cleanup));
v_EPTF_StatCapture_GroupStat_directory := "";
f_EPTF_StatCapture_debug("----StatCapture INIT DONE----");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_setGroupStatDirectory
//
// Purpose:
// This function sets the group statistics directory,
// where the groupstat files placed
// in f_EPTF_StatCapture_handleSubscribeAndAddToGroup.
// [artf367628 AFS debug timebox: set directory]
//
// Parameters:
// pl_directory - *in* <charstring> - the directory
//
// Return Value:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_setGroupStatDirectory(in charstring pl_directory) runs on EPTF_StatCapture_CT{
v_EPTF_StatCapture_GroupStat_directory := pl_directory;
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_getGroupStatDirectory
//
// Purpose:
// This function returns with the group statistics directory.
// [artf367628 AFS debug timebox: get directory]
//
// Parameters:
// -
//
// Return Value:
// *charstring* - the directory
//
/////////////////////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_getGroupStatDirectory() runs on EPTF_StatCapture_CT return charstring{
return v_EPTF_StatCapture_GroupStat_directory;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_behavior
//
// Purpose:
// Behavior function of the StatCapture server component.
//
// Parameters:
// selfName - *in* *charstring* - name of the component
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function initializes used components and waits for components to be done.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_behavior(in charstring pl_selfName) runs on EPTF_StatCapture_CT{
f_EPTF_StatCapture_init(pl_selfName);
f_EPTF_Base_wait4Shutdown();
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_addNewGroup
//
// Purpose:
// Creates a new variable group, returns groupID (index of group in the captureGroups record)
//
// Parameters:
// groupname - *in* *charstring* - name of the group (must be unique)
// timerperiod - *in* *float* - the timeout period belonging to the group
// pl_logfiles - *in* <EPTF_IntegerList> - the file descriptors, where we want to print our group, empty list by default
// pl_statList - *in* <EPTF_StatCapture_GroupStatistics> - list of statistics to add to the group, empty list by default
// groupID - *out* *integer* - the index of the group in the captureGroups record
// pl_groupstatidxList - *out* <EPTF_IntegerList> - index of inserted statistics inside the group
//
// Return Value:
// -
//
// Errors:
// 1, The group name must be unique, error is returned if the groupname already exists.
// 2, Either a default log file or log files for the group itself must be specified.
//
// Detailed Comments:
// This function creates a new group with the given name, sets timout period and log files belonging to the group, adds
// the statistics defined by the input statistics list and also sets internal parameters (eventID, deleted flag).
// Logging is carried out to the specified pl_logfiles list of files. In case this parameter is {},
// the group is logged to the default log file (specified in the config file).
// The index of the group in the captureGroups record and the index of statistics inserted is returned.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_addNewGroup(
in charstring pl_groupname,
in float pl_timerperiod,
in EPTF_IntegerList pl_logfilesfd := {},
in EPTF_StatCapture_GroupStatistics pl_statList := {},
out integer pl_groupidx,
out EPTF_IntegerList pl_groupstatidxList )
runs on EPTF_StatCapture_CT
{ //pl_idx is returned as groupID
var integer vl_idx;
var EPTF_IntegerList vl_logfilesfd := pl_logfilesfd;
if (f_EPTF_StatCapture_checkGroupName(pl_groupname,vl_idx) == false){
f_EPTF_StatCapture_error("New StatCapture Group name is not unique.");
//f_EPTF_Base_stop();
}
if ((vl_logfilesfd=={}) and (v_StatCapture_deffd == -1)){
f_EPTF_StatCapture_error("No output file defined for Capture Group " & pl_groupname);
//f_EPTF_Base_stop();
}
//f_EPTF_Base_assert("ERROR: New StatCapture Group name is not unique.", f_EPTF_StatCapture_checkGroupName(pl_groupname,vl_idx) == true);
//f_EPTF_Base_assert("ERROR: No output file defined for Capture Group " & pl_groupname, (vl_logfilesfd!={}) or (v_StatCapture_deffd != -1) );
if (vl_logfilesfd=={}) {
vl_logfilesfd := {v_StatCapture_deffd}; //set default logfile for capture group
}
pl_groupidx := sizeof(v_StatCapture_captureGroups);
v_StatCapture_captureGroups[pl_groupidx].groupName := pl_groupname;
v_StatCapture_captureGroups[pl_groupidx].timerPeriod:= pl_timerperiod;
v_StatCapture_captureGroups[pl_groupidx].groupStatistics := {};
f_EPTF_StatCapture_addListOfStatistics(pl_groupidx, pl_statList, pl_groupstatidxList);
for (var integer i:=0; i<sizeof(vl_logfilesfd); i:=i+1) {
v_StatCapture_captureGroups[pl_groupidx].logFiles[i].fd := vl_logfilesfd[i];
v_StatCapture_captureGroups[pl_groupidx].logFiles[i].idx := f_EPTF_StatCapture_addNewFileData(vl_logfilesfd[i]);
}
v_StatCapture_captureGroups[pl_groupidx].deleted := false;
v_StatCapture_captureGroups[pl_groupidx].eventID:= -1;
v_StatCapture_captureGroups[pl_groupidx].measurementID := -1;
v_StatCapture_captureGroups[pl_groupidx].statAdded := false;
f_EPTF_StatCapture_debug(log2str("New group ", pl_groupidx, "successfully added"));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_openNewStatLogFile
//
// Purpose:
// Function for creating a new statistics log file with capture settings
//
// Parameters:
// pl_userfilename - *in* *charstring* - the filename defined by the user
//
// Return Value:
// true if file open was successful, false otherwise
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_openNewStatLogFile(in charstring pl_userfilename) runs on EPTF_StatCapture_CT return integer{
var integer vl_fd;
var charstring vl_acttime := f_EPTF_StatCapture_get_time();
var charstring vl_filename := pl_userfilename & "_" & f_EPTF_Base_selfName() & "_" & log2str(self) & "_" & vl_acttime;
var integer vl_filenameidx := sizeof(v_StatCapture_logfilenames);
v_StatCapture_logfilenames[vl_filenameidx] := vl_filename;
if (tsp_EPTF_StatCapture_fileFormat == readable){
vl_filename := vl_filename & ".txt";
}
if (tsp_EPTF_StatCapture_fileFormat == gnuplot){
vl_filename := vl_filename & ".gpl";
}
vl_fd := f_FIO_open_append_wronly_excl(vl_filename);
if (vl_fd != -1){
f_EPTF_int2int_HashMap_Insert ( v_StatCapture_inthashmap_id, vl_fd , vl_filenameidx );
var charstring logstring :="";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
f_EPTF_SchedulerComp_refreshSnapshotTime();
logstring := logstring & "TimeStampBase: " & f_EPTF_StatCapture_get_time("%Y-%m-%d-%H:%M:%S", true) & " " & float2str(f_EPTF_SchedulerComp_snapshotTime());
logstring := logstring & "\n";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "CaptureFileVersion: " & "2.2"; //REL 2, Version 2.
logstring := logstring & "\n";
f_EPTF_StatCapture_dumpStringtoFile(vl_fd, logstring);
} else {
f_EPTF_StatCapture_error(log2str("Cannot open new statistics log file[" & vl_filename & "] " & f_FIO_get_error_string() & "!"));
}
return vl_fd;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_getFileName
//
// Purpose: To get the name of a capture file based on component variable v_StatCapture_logfilenames
//
// Parameters:
// - pl_fileIdx - *in* *integer* - the index in the filenamelist v_StatCapture_logfilenames
// - pl_fNameSuffix - *in* *charstring* - the string to be appended after the filename,
// when more files are used for the same log beacause of long logs.
// - pl_fileName - *out* *charstring* - the output filename
//
// Return Value:
// *boolean* - true if pl_fileIdx an therfore the filename is valid, otherwise false
//
// Detailed Comments: -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_getFileName(in integer pl_fileIdx, in charstring pl_fNameSuffix,out charstring pl_fileName)
runs on EPTF_StatCapture_CT
return boolean
{
if( sizeof(v_StatCapture_logfilenames) < pl_fileIdx or pl_fileIdx<0) {
pl_fileName:=""
return false;
}
pl_fileName:=v_StatCapture_logfilenames[pl_fileIdx];
if(tsp_EPTF_StatCapture_fileFormat == readable){
pl_fileName := pl_fileName & pl_fNameSuffix & ".txt";
} else if(tsp_EPTF_StatCapture_fileFormat == gnuplot){
pl_fileName := pl_fileName & pl_fNameSuffix & ".gpl";
} else {
//do nothing, imposssible brench
}
return true;
}//f_
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_deleteGroup
//
// Purpose:
// Marks a capture group as deleted
//
// Parameters:
// groupID - *in* *integer* - the index of the group in the captureGroups record
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// The deleted flag of the indexed group is set to true. Field contents of the group are deleted.
// This capture group cannot be used for capturing any more.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_deleteGroup(in integer pl_groupidx) runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_warning("Group to be deleted does not exist.");
return;
}
v_StatCapture_captureGroups[pl_groupidx].deleted := true;
var integer v_eventID := v_StatCapture_captureGroups[pl_groupidx].eventID;
if (v_eventID != -1) {
if(not f_EPTF_SchedulerComp_CancelEvent(v_eventID)) { //timer cancel (if running timer then stop)
f_EPTF_StatCapture_warning(log2str(%definitionId, ": could not cancel event ", v_eventID));
}
}
v_StatCapture_captureGroups[pl_groupidx].timerPeriod := -1.0;
v_StatCapture_captureGroups[pl_groupidx].eventID := -1;
v_StatCapture_captureGroups[pl_groupidx].groupStatistics := {};
v_StatCapture_captureGroups[pl_groupidx].logFiles := {};
v_StatCapture_captureGroups[pl_groupidx].measurementID := -1;
f_EPTF_StatCapture_debug(log2str("Group ", pl_groupidx, " successfully deleted"));
}
/////////////////////////////////////////////////////////////////////////
// Function: f_StatCapture_GroupStat_directory
//
// Purpose:
// Create valid directory charstring from v_EPTF_StatCapture_GroupStat_directory.
// [artf367628 AFS debug timebox: get valid directory]
//
// Parameters:
// -
//
// Return Value:
// charstring - the directory name
/////////////////////////////////////////////////////////////////////////
private function f_StatCapture_GroupStat_directory( )
runs on EPTF_StatCapture_CT return charstring {
if(lengthof(v_EPTF_StatCapture_GroupStat_directory) > 0){
if(substr(v_EPTF_StatCapture_GroupStat_directory, lengthof(v_EPTF_StatCapture_GroupStat_directory)-1 ,1) != "/"){
if( not f_FIO_fileOrDirExists(v_EPTF_StatCapture_GroupStat_directory & "/") ) {
f_EPTF_StatCapture_warning(%definitionId&": Directory does not exist: "&v_EPTF_StatCapture_GroupStat_directory & "/. Trying working directory.");
return "";
}
return v_EPTF_StatCapture_GroupStat_directory & "/";
} else {
if( not f_FIO_fileOrDirExists(v_EPTF_StatCapture_GroupStat_directory) ) {
f_EPTF_StatCapture_warning(%definitionId&": Directory does not exist: "&v_EPTF_StatCapture_GroupStat_directory&". Trying working directory.");
return "";
}
return v_EPTF_StatCapture_GroupStat_directory;
}
}
return "";
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_getGroupByName
//
// Purpose:
// Function for retreiving the group by its groupname
//
// Parameters:
// groupname - *in* *charstring* - name of the group (unique)
// groupID - *out* *integer* - the index of the group in the captureGroups record
//
// Return Value:
// true if the group is found, false else
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_getGroupByName(in charstring pl_groupname, out integer pl_groupidx) runs on EPTF_StatCapture_CT return boolean{
for(var integer i:=0; i<sizeof(v_StatCapture_captureGroups); i:=i+1) {
if (v_StatCapture_captureGroups[i].groupName == pl_groupname) {
pl_groupidx := i;
return true;
}
}
f_EPTF_StatCapture_warning(log2str("Group is not found for name :", pl_groupname));
return false;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_createStatforCapture
//
// Purpose:
// Function for creating a new statistics data record
//
// Parameters:
//
// statID - *in* *integer* - the statistics identifier
// statname - *in* *charstring* - the name of the statistics
// periodicreset - *in* *boolean* - whether the statistics should be reset on capture time intervals (default value is false)
// activestat - *in* *boolean* - the statistics state (default value is active == true)
//
// Return Value:
// EPTF_StatCapture_Statistics
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_createStatforCapture(
in integer pl_statID,
in charstring pl_statname,
in boolean pl_periodicreset := false,
in boolean pl_activestat:= true)
runs on EPTF_StatCapture_CT
return EPTF_StatCapture_Statistics
{
for(var integer i:=0; i<sizeof(v_StatCapture_captureGroups); i:=i+1) {
for(var integer j:=0; j<sizeof(v_StatCapture_captureGroups[i].groupStatistics); j:=j+1) {
if (v_StatCapture_captureGroups[i].groupStatistics[j].statID == pl_statID){
f_EPTF_StatCapture_error("Cannot create Statistics, StatID already exists!");
//f_EPTF_Base_stop();
}
}
}
var EPTF_StatCapture_Statistics stat := {
statID := pl_statID,
statname := pl_statname,
activestat := pl_activestat,
periodicreset := pl_periodicreset
}
f_EPTF_StatCapture_debug("New statistics created successfully.");
return stat;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_addStatistics
//
// Purpose:
// Function for adding a new statistics data to a capture group
//
// Parameters:
// groupID - *in* *integer* - index of the group
// stat - *in* <EPTF_StatCapture_Statistics> - the statistics data record to be added
// groupstatID - *out* *integer* - the index of the new statistics data in the group
//
// Return Value:
// -
//
// Errors:
// If the group does not exist.
// If the periodic resettable statistics is already in an other capture group.
// If the same periodic resettable statistics is already added to the capture group.
//
// Detailed Comments:
// If a statistics is added with periodic reset==true, it must be ensured, that the
// statistics is assigned only to 1 capture group. Therefore, these kind of statistics
// are stored in a database enabling faster search on the structure when adding a new statistics.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_addStatistics(in integer pl_groupidx, in EPTF_StatCapture_Statistics pl_stat, out integer pl_groupstatidx) runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_error("Group does not exist.");
//f_EPTF_Base_stop();
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
if (pl_stat.periodicreset == true){
for (var integer i:= 0; i< sizeof(v_StatCapture_resetStatList); i:= i+1){
if (v_StatCapture_resetStatList[i].statID == pl_stat.statID){ //then the statID is already in a Capture group, we are not allowed to add it in a different group
if (v_StatCapture_resetStatList[i].groupID == pl_groupidx){
f_EPTF_StatCapture_error("The same statistics already added to the group!");
//f_EPTF_Base_stop();
}
f_EPTF_StatCapture_error("Statistics with periodic reset cannot be added to more capture groups");
//f_EPTF_Base_stop();
}
}
var integer nextElem:= sizeof(v_StatCapture_resetStatList);
v_StatCapture_resetStatList[nextElem].statID := pl_stat.statID;
v_StatCapture_resetStatList[nextElem].groupID := pl_groupidx;
}
pl_groupstatidx := sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics);
v_StatCapture_captureGroups[pl_groupidx].groupStatistics[pl_groupstatidx].statID := pl_stat.statID; //same statIDs within one group are allowed
v_StatCapture_captureGroups[pl_groupidx].groupStatistics[pl_groupstatidx].statname := f_EPTF_StatCapture_substituteSeparatorInStatName(pl_stat.statname); //stores statistics name
v_StatCapture_captureGroups[pl_groupidx].groupStatistics[pl_groupstatidx].activestat := pl_stat.activestat; //default value is true for activestat
v_StatCapture_captureGroups[pl_groupidx].groupStatistics[pl_groupstatidx].periodicreset := pl_stat.periodicreset; //default value is false for periodicreset
v_StatCapture_captureGroups[pl_groupidx].statAdded := true;
f_EPTF_StatCapture_debug(log2str("New statistics ", pl_groupstatidx, "successfully added to group ", pl_groupidx));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_addListOfStatistics
//
// Purpose:
// Function for adding a list of new statistics to a given capture group
//
// Parameters:
// groupID - *in* *integer* - index of the group
// statlist - *in* <EPTF_StatCapture_GroupStatistics> - List of statistics data record to be added
// groupstatIDlist - *out* <EPTF_IntegerList> - List of indexes of the new statistics data in the group
//
// Return Value:
// -
//
// Errors:
// If the group does not exist.
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_addListOfStatistics(in integer pl_groupidx, in EPTF_StatCapture_GroupStatistics pl_statList, out EPTF_IntegerList pl_groupstatidxList) runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_error("Group does not exist.");
//f_EPTF_Base_stop();
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
if(sizeof(pl_statList) == 0) {
pl_groupstatidxList := {};
return;
}
for (var integer i:=0; i<sizeof(pl_statList); i:=i+1) {
f_EPTF_StatCapture_addStatistics(pl_groupidx,pl_statList[i], pl_groupstatidxList[i]);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_InactivateStatistics
//
// Purpose:
// Function for setting statistics state to inactive inside a capture group
//
// Parameters:
// groupID - *in* *integer* - index of the group
// groupstatID - *in* *integer* - the index of the statistics in the group
//
// Return Value:
// -
//
// Errors:
// Error is returned either if the capture group or the statistics index in it does not exist.
//
// Detailed Comments:
// If the statistics is set to inactive, it is not captured for that capture group, that means,
// in the log file, only "-" is printed out instead of its actual value.
// If this statistics is included in other capture groups, then its state
// can be set independently for each capture group.
// The state of the statistics can be modified during run-time.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_InactivateStatistics(in integer pl_groupidx, in integer pl_groupstatidx) runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_error("Group does not exist.");
//f_EPTF_Base_stop();
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
if((pl_groupstatidx >= sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics)) or (pl_groupstatidx < 0)) {
f_EPTF_StatCapture_error("Statistics index inside the group does not exist.");
//f_EPTF_Base_stop();
}
//f_EPTF_Base_assert("ERROR: Statistics index inside the group does not exist.", (pl_groupstatidx < sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics)) and
//(pl_groupstatidx >= 0));
v_StatCapture_captureGroups[pl_groupidx].groupStatistics[pl_groupstatidx].activestat := false;
f_EPTF_StatCapture_debug(log2str("Statistics ", pl_groupstatidx, " state set to inactive in group ", pl_groupidx));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_ActivateStatistics
//
// Purpose:
// Function for setting statistics state to active
//
// Parameters:
// groupID - *in* *integer* - index of the group
// groupstatID - *in* *integer* - the index of the statistics in the group
//
// Return Value:
// -
//
// Errors:
// Error is returned either if the capture group or the statistics index in it does not exist.
//
// Detailed Comments:
// If the statistics is set to active, it is captured, that means,
// in the log file, its value is printed out at sampling intervals of the group.
// The state of the statistics can be modified during run-time.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_ActivateStatistics(in integer pl_groupidx, in integer pl_groupstatidx) runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_warning("Group does not exist.");
return;
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
if((pl_groupstatidx >= sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics)) or (pl_groupstatidx < 0)) {
f_EPTF_StatCapture_warning("Statistics index inside the group does not exist.");
return;
}
//f_EPTF_Base_assert("ERROR: Statistics index inside the group does not exist.", (pl_groupstatidx < sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics)) and
//(pl_groupstatidx >= 0));
v_StatCapture_captureGroups[pl_groupidx].groupStatistics[pl_groupstatidx].activestat := true;
f_EPTF_StatCapture_debug(log2str("Statistics ", pl_groupstatidx, " state set to active in group ", pl_groupidx));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_getStatisticsID
//
// Purpose:
// Function for finding the statistics ID from a capture group
//
// Parameters:
// stat - *in* <EPTF_StatCapture_Statistics> - the statistics data record looked for
// groupID - *in* *integer* - the group index in the captureGroups record
// groupstatID - *out* *integer* - the index of requested statistics in the group
//
// Return Value:
// true if the statistics is found, false else
//
// Errors:
// If the requested group does not exist.
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_getStatisticsID(in EPTF_StatCapture_Statistics pl_stat, in integer pl_groupidx, out integer pl_groupstatidx) runs on EPTF_StatCapture_CT return boolean {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_error("Group does not exist.");
//f_EPTF_Base_stop();
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
for(var integer i:=0; i<sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics); i:=i+1) {
if (v_StatCapture_captureGroups[pl_groupidx].groupStatistics[i] == pl_stat) {
pl_groupstatidx := i;
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_setTimerPeriod
//
// Purpose:
// Function for setting the timer period (sampling time) of a variable group
//
// Parameters:
// groupID - *in* *integer* - the group index in the captureGroups record
// timerperiod - *in* *float* - the timer period to be set
//
// Return Value:
// -
//
// Errors:
// If the group does not exist.
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_setTimerPeriod(in integer pl_groupidx, in float pl_timerperiod) runs on EPTF_StatCapture_CT {
var charstring logstring :="";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := "#";
}
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_warning("Group does not exist.");
return;
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
v_StatCapture_captureGroups[pl_groupidx].timerPeriod := pl_timerperiod;
logstring := logstring & "SampleTime[\"" & v_StatCapture_captureGroups[pl_groupidx].groupName & "]: " & float2str(v_StatCapture_captureGroups[pl_groupidx].timerPeriod) & " sec" ;
f_EPTF_StatCapture_debug(log2str("Timer period of group ", pl_groupidx, "successfully set to ", v_StatCapture_captureGroups[pl_groupidx].timerPeriod, "sec"));
logstring := logstring & "\n";
f_EPTF_StatCapture_debug(log2str("logstring", logstring));
f_EPTF_StatCapture_dumpStringforGroup(pl_groupidx, logstring);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_startCaptureAll
//
// Purpose:
// Function for starting the capture of all capture groups
//
// Parameters:
// -
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function starts capturing (collecting statistics) for each capture group.
// At this time, the current contents of the not deleted capture groups is printed out to the log.
// The sampling time can be set per capture group. The timeout event is registered into the
// Scheduler.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_startCaptureAll(in charstring pl_capturemode := "programmed") runs on EPTF_StatCapture_CT {
var charstring vl_capturemode := pl_capturemode;
for(var integer i:=0; i<sizeof(v_StatCapture_captureGroups); i:=i+1){ //for all groups
f_EPTF_StatCapture_startGroupCapture(i, vl_capturemode);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_startGroupCapture
//
// Purpose:
// Function for starting the capture of all capture groups
//
// Parameters:
// groupID - *in* *integer* - the group index in the captureGroups record
// capturemode - *in* *charstring* - the capture control mode, default value is programmed (API function calls)
//
// Return Value:
// -
//
// Errors:
// If the group does not exist.
//
// Detailed Comments:
// This function starts capturing (collecting statistics) for a given capture group.
// At this time, the current contents of the variable group (if not deleted) is printed out to the log.
// The sampling time can be set per capture group. The timeout event is registered into the
// Scheduler.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_startGroupCapture(in integer pl_groupidx, in charstring pl_capturemode := "programmed") runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx < 0) {
f_EPTF_StatCapture_warning("Group does not exist.");
return;
}
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
if (sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics) == 0) {
f_EPTF_StatCapture_warning("No capture data defined for this capture group");
return;
}
if (v_StatCapture_captureGroups[pl_groupidx].eventID != -1) {return;} //i.e. the capture has already been started
if (v_StatCapture_captureGroups[pl_groupidx].deleted != true) {
f_EPTF_StatCapture_debug(log2str("Capture of capturegroup ", pl_groupidx, " started"));
var charstring logstring :="";
/* if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
f_EPTF_SchedulerComp_refreshSnapshotTime();
logstring := logstring & "TimeStampBase: " & f_EPTF_StatCapture_get_time("%Y-%m-%d-%H:%M:%S", true) & " " & float2str(f_EPTF_Base_snapshotTime());
logstring := logstring & "\n";
*/
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "CaptureGroup[\""&
v_StatCapture_captureGroups[pl_groupidx].groupName &"\"]";
logstring := logstring & "\n";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
v_StatCapture_captureGroups[pl_groupidx].measurementID := v_StatCapture_captureGroups[pl_groupidx].measurementID + 1;
logstring := logstring & "Capture_Started[\""& v_StatCapture_captureGroups[pl_groupidx].groupName & "\", " & int2str(pl_groupidx) & "_" &
int2str(v_StatCapture_captureGroups[pl_groupidx].measurementID) & ", " & pl_capturemode & "]";
logstring := logstring & "\n";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "SampleTime[\""& v_StatCapture_captureGroups[pl_groupidx].groupName &"\"]: " & float2str(v_StatCapture_captureGroups[pl_groupidx].timerPeriod) &" sec";
logstring := logstring & "\n";
f_EPTF_StatCapture_dumpStringforGroup(pl_groupidx, logstring);
// logstring := f_EPTF_StatCapture_getValueHeaderString(pl_groupidx);
// v_StatCapture_captureGroups[pl_groupidx].statAdded := false;
// f_EPTF_StatCapture_dumpStringforGroup(pl_groupidx, logstring);
v_StatCapture_captureGroups[pl_groupidx].statAdded := true; // this way the value header will be added by f_EPTF_StatCapture_handleEvent
f_EPTF_SchedulerComp_refreshSnapshotTime();
if(not f_EPTF_StatCapture_handleEvent({f_EPTF_SchedulerComp_snapshotTime(),v_StatCapture_eventHandler,{pl_groupidx},null}, -1)) {
f_EPTF_StatCapture_warning(log2str(%definitionId, " handling event failed."));
}
}
}
private function f_EPTF_StatCapture_substituteSeparatorInStatName(in charstring pl_name)
return charstring
{
var charstring vl_newName := "";
for(var integer i:=0; i<lengthof(pl_name); i:=i+1) {
if( i + lengthof(tsp_EPTF_StatCapture_headerSeparator) <= lengthof(pl_name) and
substr(pl_name, i, lengthof(tsp_EPTF_StatCapture_headerSeparator)) == tsp_EPTF_StatCapture_headerSeparator) {
vl_newName := vl_newName & tsp_EPTF_StatCapture_statNameSeparatorSubstitute;
i := i+lengthof(tsp_EPTF_StatCapture_headerSeparator) - 1;
} else {
vl_newName := vl_newName & pl_name[i];
}
}
return vl_newName;
}
private function f_EPTF_StatCapture_getValueHeaderString(in integer pl_groupidx)
runs on EPTF_StatCapture_CT
return charstring
{
var charstring logstring := "";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a comment into the gnuplot file
logstring := "#";
}
logstring := logstring & "ValueHeader[\""& v_StatCapture_captureGroups[pl_groupidx].groupName & "\"]:" & tsp_EPTF_StatCapture_headerSeparator;
for(var integer j:=0; j<sizeof(v_StatCapture_captureGroups[pl_groupidx].groupStatistics); j:=j+1) {
logstring := logstring & v_StatCapture_captureGroups[pl_groupidx].groupStatistics[j].statname & tsp_EPTF_StatCapture_headerSeparator;
}
return logstring & "\n";
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_stopGroupCapture
//
// Purpose:
// Function for stopping the capture of a given capture group
//
// Parameters:
// groupID - *in* *integer* - the group index in the captureGroups record
// pl_valid - *in* *boolean* - the validity of the capture of the group, optional parameter, def true
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function stops capturing for a given capture group.
// The capture group's timeout event is removed from the
// Scheduler's event queue.
// The capturing of the group can be restarted any time later
// with <f_StatCapture_startGroupCapture>.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_stopGroupCapture(in integer pl_groupidx, in boolean pl_valid := true) runs on EPTF_StatCapture_CT {
if(pl_groupidx >= sizeof(v_StatCapture_captureGroups) or pl_groupidx<0) {
f_EPTF_StatCapture_warning("Group does not exist");
return;
}
var integer v_eventID := v_StatCapture_captureGroups[pl_groupidx].eventID; //lookup belonging eventidx
if (v_eventID != -1) {
if(not f_EPTF_SchedulerComp_CancelEvent(v_eventID)) { //stop eventidx event, remove it from eventqueue
f_EPTF_StatCapture_warning(log2str(%definitionId, ": could not cancel event ", v_eventID));
}
v_StatCapture_captureGroups[pl_groupidx].eventID := -1; //delete eventID of the group
if (pl_valid == false){
var charstring logstring :="";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "Capture_Aborted[\""& v_StatCapture_captureGroups[pl_groupidx].groupName & "\", " & int2str(pl_groupidx) & "_" &
int2str(v_StatCapture_captureGroups[pl_groupidx].measurementID) & "]";
logstring := logstring & "\n";
f_EPTF_StatCapture_dumpStringforGroup(pl_groupidx, logstring);
}
else {
var charstring logstring :="";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "Capture_Finished[\""& v_StatCapture_captureGroups[pl_groupidx].groupName & "\", " & int2str(pl_groupidx) & "_" &
int2str(v_StatCapture_captureGroups[pl_groupidx].measurementID) & "]";
logstring := logstring & "\n";
f_EPTF_StatCapture_dumpStringforGroup(pl_groupidx, logstring);
}
f_EPTF_StatCapture_debug(log2str("Capture of capture group", pl_groupidx," stopped"));
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_stopCaptureAll
//
// Purpose:
// Function for stopping the capture of all capture groups
//
// Parameters:
// pl_valid - *in* *boolean* - the validity of the capture of the group, optional parameter, def true
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function stops capturing for all capture groups.
// The capture group's timeout event is removed from the
// Scheduler's event queue.
// The capturing of groups can be restarted any time later
// with <f_StatCapture_startGroupCapture> or with
// <f_StatCapture_startCaptureAll> .
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_stopCaptureAll(in boolean pl_valid := true) runs on EPTF_StatCapture_CT {
var integer v_eventID;
for(var integer i:=0; i<sizeof(v_StatCapture_captureGroups); i:=i+1) {
if (v_StatCapture_captureGroups[i].eventID != -1) {
v_eventID := v_StatCapture_captureGroups[i].eventID;
if(not f_EPTF_SchedulerComp_CancelEvent(v_eventID)) { //stop eventidx event, remove it from eventqueue
f_EPTF_StatCapture_warning(log2str(%definitionId, ": could not cancel event ", v_eventID));
}
v_StatCapture_captureGroups[i].eventID := -1;
if (pl_valid == false){
var charstring logstring :="";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "Capture_Aborted[\""& v_StatCapture_captureGroups[i].groupName & "\", " & int2str(i) & "_" & int2str(v_StatCapture_captureGroups[i].measurementID) & "]";
logstring := logstring & "\n";
f_EPTF_StatCapture_dumpStringforGroup(i, logstring);
}
else {
var charstring logstring :="";
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){ //setting a commment into the gnuplot file
logstring := logstring & "#";
}
logstring := logstring & "Capture_Finished[\""& v_StatCapture_captureGroups[i].groupName & "\", " & int2str(i) & "_" & int2str(v_StatCapture_captureGroups[i].measurementID) & "]";
logstring := logstring & "\n";
f_EPTF_StatCapture_dumpStringforGroup(i, logstring);
}
f_EPTF_StatCapture_debug(log2str("Capture Group (groupid) stopped", i));
}
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_handleEvent
//
// Purpose:
// Function for handling timeout event for a capture group
//
// Parameters:
// pl_action - *in* <EPTF_ScheduledAction> - the action returned by the Scheduler
// eventIndex - *in* *integer* - the index of the event
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// The Scheduler notifies, that a registered event with a given actionID = capture group ID
// has timeout. The event is handled by printing out statistics data to log from the
// capture group and reregistering a new event for the variable group for the
// 'action.when + timerperiod' timepoint.
// Those statistics, for which periodic reset is set, are reset after they are captured and printed
// to the logfiles.
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_handleEvent(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex) runs on EPTF_StatCapture_CT return boolean{
var integer v_groupID := pl_action.actionId[0]; //the event belongs to which group
var charstring logstring := "";
if(v_StatCapture_captureGroups[v_groupID].statAdded) {
logstring := f_EPTF_StatCapture_getValueHeaderString(v_groupID);
v_StatCapture_captureGroups[v_groupID].statAdded := false;
f_EPTF_StatCapture_dumpStringforGroup(v_groupID, logstring);
}
if(tsp_EPTF_StatCapture_fileFormat == readable){
logstring := "[\"";
logstring := logstring & v_StatCapture_captureGroups[v_groupID].groupName;
logstring := logstring & "\",";
logstring := logstring & float2str(pl_action.when);
logstring := logstring & "]: ";
}
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){
logstring := "\"" & v_StatCapture_captureGroups[v_groupID].groupName & "\"";
logstring := logstring & " ";
logstring := logstring & float2str(pl_action.when);
logstring := logstring & " ";
}
var integer vl_statID;
var charstring vl_value;
for(var integer j:=0; j<sizeof(v_StatCapture_captureGroups[v_groupID].groupStatistics); j:=j+1) { //print variable content
if (v_StatCapture_captureGroups[v_groupID].groupStatistics[j].activestat == true){
vl_statID := v_StatCapture_captureGroups[v_groupID].groupStatistics[j].statID;
vl_value := "N/A";
if (f_EPTF_StatMeasure_getStatType(vl_statID) == EPS){
f_EPTF_StatMeasure_update_EPS(vl_statID, v_StatCapture_captureGroups[v_groupID].timerPeriod);
}
vl_value := f_EPTF_StatMeasure_value2str(vl_statID);
if (tsp_EPTF_StatCapture_fileFormat == gnuplot){
var charstring vl_tmpValue := vl_value;
vl_value := "";
for (var integer i := 0; i < lengthof(vl_tmpValue); i := i + 1) {
if (vl_tmpValue[i] != " ") {
vl_value := vl_value & vl_tmpValue[i];
}
}
}
logstring := logstring & vl_value & " ";
}
else {
vl_value := "-";
logstring := logstring & vl_value & " ";
}
}
logstring := logstring & "\n";
f_EPTF_StatCapture_debug(log2str("logstring", logstring));
f_EPTF_StatCapture_dumpStringforGroup(v_groupID, logstring);
var integer v_eventidx;
if(not f_EPTF_SchedulerComp_scheduleAction(pl_action.when +
v_StatCapture_captureGroups[v_groupID].timerPeriod,
v_StatCapture_eventHandler,{v_groupID}, v_eventidx, false)) {
f_EPTF_StatCapture_warning(log2str(%definitionId, ": could not schedule timer for capture group ", v_groupID));
}
v_StatCapture_captureGroups[v_groupID].eventID := v_eventidx;
for(var integer j:=0; j<sizeof(v_StatCapture_captureGroups[v_groupID].groupStatistics); j:=j+1) { //resets statistics with periodic reset == true
if (v_StatCapture_captureGroups[v_groupID].groupStatistics[j].periodicreset == true){
vl_statID := v_StatCapture_captureGroups[v_groupID].groupStatistics[j].statID;
f_EPTF_StatMeasure_resetStat(vl_statID);
}
}
return true;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_parseConfigGroup
//
// Purpose:
// This function automatically processes the config file parameter
// tsp_EPTF_StatCapture_captureGroups and if it is filled in,
// creates Statistics and capture groups according to the module parameter.
//
// Parameters:
// -
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function should be called in the user application after
// the Variables - for which statistics should be captured -
// are created on the user component.
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_parseConfigGroup() runs on EPTF_StatCapture_CT {
if (tsp_EPTF_StatCapture_captureGroups == {}) {
return;
}
var EPTF_StatCapture_CaptureGroupsConfig vl_configGroup := tsp_EPTF_StatCapture_captureGroups;
var charstring vl_groupName := "";
var float vl_timerPeriod := 0.0;
var integer vl_fd := -1;
var EPTF_IntegerList vl_fileList := {}; // for storing log file descriptors
var integer vl_fileListidx := 0;
var integer vl_varID := -1;
var integer vl_statID := -1;
var EPTF_StatCapture_Statistics vl_stat;
var integer vl_statListidx := 0;
var EPTF_StatCapture_GroupStatistics vl_statList := {}; //for storing created EPTF Statistics
var integer vl_groupidx := -1;
var EPTF_IntegerList vl_groupstatidxList := {};
for (var integer i := 0; i < sizeof(vl_configGroup); i:= i+1){ //for the number of capture groups defined in the config group
vl_groupName := vl_configGroup[i].groupName;
vl_timerPeriod := vl_configGroup[i].timerPeriod;
vl_fd := -1;
vl_fileList := {}; // for storing log file descriptors
vl_fileListidx := 0;
for (var integer j:= 0; j< sizeof(vl_configGroup[i].logFileNames); j := j+1){
vl_fd := f_EPTF_StatCapture_openNewStatLogFile(vl_configGroup[i].logFileNames[j]);
vl_fileListidx := sizeof(vl_fileList);
vl_fileList[vl_fileListidx] := vl_fd;
}
vl_varID := -1;
vl_statID := -1;
vl_statList := {}; //for storing created statistics belonging to the capture group
vl_statListidx := 0;
for (var integer k:= 0; k< sizeof(vl_configGroup[i].statistics); k := k+1) { //for all Statistics defined to the group
vl_varID := f_EPTF_Var_getId(vl_configGroup[i].statistics[k].varName);
vl_statID := f_EPTF_StatMeasure_newStat(vl_varID, vl_configGroup[i].statistics[k].statType);
vl_stat := f_EPTF_StatCapture_createStatforCapture(vl_statID, vl_configGroup[i].statistics[k].statName,vl_configGroup[i].statistics[k].periodicReset,vl_configGroup[i].statistics[k].activeStat);
vl_statListidx := sizeof(vl_statList);
vl_statList[vl_statListidx] := vl_stat;
}
vl_groupidx := -1;
vl_groupstatidxList := {};
f_EPTF_StatCapture_addNewGroup(vl_groupName, vl_timerPeriod, vl_fileList, vl_statList, vl_groupidx, vl_groupstatidxList);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_getGroupId
//
// Purpose:
// Returns the groupId for a given group name.
//
// Parameters:
// pl_name - *charstring* - name of the group
//
// Return Value:
// *integer* - groupId of the group
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCapture_getGroupId(in charstring pl_name)
runs on EPTF_StatCapture_CT return integer{
var integer vl_idx := -1;
f_EPTF_StatCapture_checkGroupName(pl_name,vl_idx);
return vl_idx;
}
group ClientSide{
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_init
//
// Purpose:
// Initializes the StatCapture Client component and depending components.
//
// Parameters:
// pl_selfname - *charstring* - name of the component
// pl_server - <EPTF_StatCapture_CT> - the server component to connect to.
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_init(in charstring pl_selfname, in EPTF_StatCapture_CT pl_server)
runs on EPTF_StatCaptureClient_CT{
if(v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_server := pl_server;
f_EPTF_Var_init_CT(pl_selfname);
connect(self:v_StatCaptureClient_PCO, v_StatCaptureClient_server:v_StatCapture_PCO);
f_EPTF_Base_registerCleanup(refers(f_EPTF_StatCaptureClient_cleanup));
v_StatCaptureClient_initialized := true;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_addStatsToGroup
//
// Purpose:
// Subscription for a list of statistics in a given group
//
// Parameters:
// pl_groupName - *charstring* - name of the group
// pl_stats - <EPTF_CharstringList> - list of statistics to be created - this list contains variable names on the client side.
// pl_subscriptionMode - <EPTF_Var_SubscriptionMode> - subscription mode of the variable that will be created on the server side.
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_addStatsToGroup(in charstring pl_groupName, in EPTF_CharstringList pl_stats, in EPTF_Var_SubscriptionMode pl_subscriptionMode)
runs on EPTF_StatCaptureClient_CT{
if(not v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_PCO.send(EPTF_StatCapture_OpMsg:
{subsAndCreateGroup := {
groupName := pl_groupName,
statNames := pl_stats,
subscriptionMode := pl_subscriptionMode}});
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_startGroup
//
// Purpose:
// Starts the specific statistics capture group on the server.
//
// Parameters:
// pl_groupName - *charstring* - name of the group
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_startGroup(in charstring pl_groupName)
runs on EPTF_StatCaptureClient_CT{
if(not v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_PCO.send(EPTF_StatCapture_OpMsg:t_StatCaptureClient_startGroup(pl_groupName, false));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_startGroupAll
//
// Purpose:
// Starts all the statistics groups on server.
//
// Parameters:
// -
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_startGroupAll()
runs on EPTF_StatCaptureClient_CT{
if(not v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_PCO.send(EPTF_StatCapture_OpMsg:t_StatCaptureClient_startGroup("", true));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_stopGroup
//
// Purpose:
// Stops the specific statistics capture group on the server.
//
// Parameters:
// pl_groupName - *charstring* - name of the group
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_stopGroup(in charstring pl_groupName)
runs on EPTF_StatCaptureClient_CT{
if(not v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_PCO.send(EPTF_StatCapture_OpMsg:t_StatCaptureClient_stopGroup(pl_groupName, false));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_stopGroupAll
//
// Purpose:
// Stops all the statistics groups on server.
//
// Parameters:
// -
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_stopGroupAll()
runs on EPTF_StatCaptureClient_CT{
if(not v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_PCO.send(EPTF_StatCapture_OpMsg:t_StatCaptureClient_stopGroup("", true));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_deleteGroup
//
// Purpose:
// Deletes the specific statistics capture group on the server.
//
// Parameters:
// pl_groupName - *charstring* - name of the group
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
public function f_EPTF_StatCaptureClient_deleteGroup(in charstring pl_groupName)
runs on EPTF_StatCaptureClient_CT{
if(not v_StatCaptureClient_initialized){return;}
v_StatCaptureClient_PCO.send(EPTF_StatCapture_OpMsg:t_StatCaptureClient_deleteGroup(pl_groupName, false));
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCaptureClient_cleanup
//
// Purpose:
// Cleanup function for the StatCaptureClient component
//
// Parameters:
// -
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// Closes connection to the server component.
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCaptureClient_cleanup()
runs on EPTF_StatCaptureClient_CT{
if (not v_StatCaptureClient_initialized) { return; }
disconnect(self:v_StatCaptureClient_PCO, v_StatCaptureClient_server:v_StatCapture_PCO);
v_StatCaptureClient_initialized := false;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Private Functions
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
group Private {
///////////////////////////////////////////////////////////
// Function: as_EPTF_StatCapture_serverAlt
//
// Purpose:
// Handler for message from the clients
///////////////////////////////////////////////////////////
private altstep as_EPTF_StatCapture_serverAlt() runs on EPTF_StatCapture_CT{
var EPTF_StatCapture_OpMsg vl_msg;
var EPTF_StatCaptureClient_CT vl_client;
[] v_StatCapture_PCO.receive(EPTF_StatCapture_OpMsg:?) -> value vl_msg sender vl_client{
f_EPTF_StatCapture_handleClientRequest(vl_client, vl_msg);
repeat;
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_handleClientRequest
//
// Purpose:
// Handles client requests - decides what request has arrived and what to do with it.
//
// Parameters:
// pl_client - <EPTF_StatCaptureClient_CT> - client who have sent the message
// pl_msg - <EPTF_StatCapture_OpMsg> - message itself
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
//
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_handleClientRequest(in EPTF_StatCaptureClient_CT pl_client, in EPTF_StatCapture_OpMsg pl_msg)
runs on EPTF_StatCapture_CT{
if(ischosen(pl_msg.subsAndCreateGroup)){
f_EPTF_StatCapture_handleSubscribeAndAddToGroup(pl_client, pl_msg.subsAndCreateGroup);
} else if (ischosen(pl_msg.startGroup)){
f_EPTF_StatCapture_handleStartGroup(pl_msg.startGroup)
} else if (ischosen(pl_msg.stopGroup)){
f_EPTF_StatCapture_handleStopGroup(pl_msg.stopGroup)
} else if (ischosen(pl_msg.deleteGroup)){
f_EPTF_StatCapture_handleDeleteGroup(pl_msg.deleteGroup)
} else {
f_EPTF_StatCapture_warning(%definitionId&" Unhandled Request received!");
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_handleStartGroup
//
// Purpose:
// Handles startGroup client request - start the requested capture group or all of them
//
// Parameters:
// pl_groupOp - <EPTF_StatCapture_GroupOP> - requested operation
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
//
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_handleStartGroup(in EPTF_StatCapture_GroupOP pl_groupOp)
runs on EPTF_StatCapture_CT{
if(pl_groupOp.forall){
f_EPTF_StatCapture_startCaptureAll();
} else {
f_EPTF_StatCapture_startGroupCapture(f_EPTF_StatCapture_getGroupId(pl_groupOp.groupName));
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_handleStopGroup
//
// Purpose:
// Handles stopGroup client request - stop the requested capture group or all of them
//
// Parameters:
// pl_groupOp - <EPTF_StatCapture_GroupOP> - requested operation
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
//
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_handleStopGroup(in EPTF_StatCapture_GroupOP pl_groupOp)
runs on EPTF_StatCapture_CT{
if(pl_groupOp.forall){
f_EPTF_StatCapture_stopCaptureAll();
} else {
f_EPTF_StatCapture_stopGroupCapture(f_EPTF_StatCapture_getGroupId(pl_groupOp.groupName));
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_handleDeleteGroup
//
// Purpose:
// Handles deleteGroup client request - delete the requested capture group or all of them
//
// Parameters:
// pl_groupOp - <EPTF_StatCapture_GroupOP> - requested operation
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
//
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_handleDeleteGroup(in EPTF_StatCapture_GroupOP pl_groupOp)
runs on EPTF_StatCapture_CT{
if(pl_groupOp.forall){
// FIXME : only if needed.
//f_EPTF_StatCapture_deleteCaptureAll();
} else {
f_EPTF_StatCapture_deleteGroup(f_EPTF_StatCapture_getGroupId(pl_groupOp.groupName));
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_handleSubscribeAndAddToGroup
//
// Purpose:
// Handles subscribeAndAddToGroup client request
//
// Parameters:
// pl_client - <EPTF_StatCaptureClient_CT> - client who have sent the message
// pl_msg - <EPTF_StatCapture_SubscribeAndCreateGroupOP> - message itself
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
//
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_handleSubscribeAndAddToGroup(in EPTF_StatCaptureClient_CT pl_client, in EPTF_StatCapture_SubscribeAndCreateGroupOP pl_msg)
runs on EPTF_StatCapture_CT{
var integer vl_clientId := f_EPTF_Base_upcast(pl_client);
for (var integer i:=0; i<sizeof(pl_msg.statNames); i:=i+1){
var integer vl_reqListIdx := sizeof(v_StatCapture_subscribeVarReqParamList);
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].remoteCompRef := pl_client;
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].remoteProviderVarName := pl_msg.statNames[i];
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].subscriptionMode := pl_msg.subscriptionMode;
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].localName := c_EPTF_StatCapture_remoteVarPrefix & int2str(vl_clientId) &"."& pl_msg.statNames[i];
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].groupName := pl_msg.groupName;
f_EPTF_Var_subscribeRemote_nonBlocking(
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].remoteCompRef,
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].remoteProviderVarName,
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].subscriptionMode,
v_StatCapture_subscribeVarReqParamList[vl_reqListIdx].localName,
pl_respHandler := {refers(f_EPTF_StatCapture_resubscribeRemoteResp_handler), {vl_reqListIdx}});
}
}
private function f_EPTF_StatCapture_resubscribeRemoteResp_handler(in integer pl_idx, in boolean pl_result, in EPTF_IntegerList pl_argList)
runs on EPTF_StatCapture_CT {
if (not pl_result) {
return;
}
if (sizeof(pl_argList) == 0) {
return;
}
var EPTF_StatCapture_SubscribeVar_Req_Param vl_req := v_StatCapture_subscribeVarReqParamList[pl_argList[0]];
var integer vl_statistic := f_EPTF_StatMeasure_newStat(pl_idx, content);
var integer vl_groupIdx:=0;
var EPTF_StatCapture_GroupStatistics vl_groupStat := {f_EPTF_StatCapture_createStatforCapture(vl_statistic, vl_req.remoteProviderVarName)};
var EPTF_IntegerList vl_groupStatIdx := {};
if (f_EPTF_StatCapture_checkGroupName(vl_req.groupName,vl_groupIdx)) {
f_EPTF_StatCapture_addNewGroup(
vl_req.groupName,
f_EPTF_Var_getRefreshPeriod(0), // basicly tsp_EPTF_Var_SyncInterval
{f_EPTF_StatCapture_openNewStatLogFile(f_StatCapture_GroupStat_directory() & vl_req.groupName)}, // [artf367628 AFS debug timebox: get valid directory]
vl_groupStat,
vl_groupIdx,
vl_groupStatIdx);
} else {
f_EPTF_StatCapture_addListOfStatistics(vl_groupIdx, vl_groupStat, vl_groupStatIdx);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_cleanup
//
// Purpose:
// Cleanup function for the StatCapture component
//
// Parameters:
// -
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// Closes all opened file descriptors for the component.
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_cleanup() runs on EPTF_StatCapture_CT {
if (v_StatCapture_initialized == false) {
return;
}
f_EPTF_StatCapture_stopCaptureAll();
for(var integer j:=0; j<sizeof(v_StatCapture_FileDataList); j:=j+1) {
if(0 != f_FIO_close(v_StatCapture_FileDataList[j].actfd)) {
f_EPTF_StatCapture_warning(log2str(%definitionId, ": close failed (", f_FIO_get_error_string(), ")."));
}
}
f_EPTF_int2int_HashMap_Delete("fd2nameHashmap");
deactivate(v_StatCapture_serverAlt);
if(v_StatCapture_deffd != -1){ // artf367628 AFS debug timebox: not closed before
if(0 != f_FIO_close(v_StatCapture_deffd)) {
f_EPTF_StatCapture_warning(log2str(%definitionId, ": close failed (", f_FIO_get_error_string(), ")."));
}
v_StatCapture_deffd := -1;
}
v_StatCapture_initialized := false;
f_EPTF_StatCapture_debug("----- STATCAPTURE CLEANUP DONE -------");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_addNewFileData
//
// Purpose:
// Creates a new variable group, returns groupID (index of group in the captureGroups record)
//
// Parameters:
// pl_startfd - *in* *integer* - name of the group (must be unique)
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// This function adds a new element to the FileDataList database. The elements are identified by their
// startfd, which is the file descriptor defined by the user of a log file to write data of a capture group.
// To a given startfd, additional data is stored, such as actual file descriptor actfd, where we dump data
// actually, nrofBytes written to actfd, nrofFiles opened since startfd was opened, and the startDate, when
// the startfd was opened.
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_addNewFileData(in integer pl_startfd ) runs on EPTF_StatCapture_CT return integer { //pl_idx is returned as groupID
var integer vl_filedataidx;
if (f_EPTF_StatCapture_checkFileDataUnique(pl_startfd) == -1) {
vl_filedataidx := sizeof(v_StatCapture_FileDataList);
v_StatCapture_FileDataList[vl_filedataidx].startfd := pl_startfd;
v_StatCapture_FileDataList[vl_filedataidx].actfd := pl_startfd;
v_StatCapture_FileDataList[vl_filedataidx].nrofBytes := 0;
v_StatCapture_FileDataList[vl_filedataidx].nrofFiles := 1;
v_StatCapture_FileDataList[vl_filedataidx].startDate := f_EPTF_StatCapture_get_time();
f_EPTF_StatCapture_debug(log2str("File Data saved for file ", pl_startfd, "to index", vl_filedataidx));
}
else { vl_filedataidx := f_EPTF_StatCapture_checkFileDataUnique(pl_startfd);} //startfd is already in our database, save its index
return vl_filedataidx;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_checkFileDataUnique
//
// Purpose:
// Function for checking the uniqueness of file data in our database (1 file descriptor (startfd) should be present only once)
//
// Parameters:
// pl_startfd - *in* *integer* - the startfd descriptor should be unique
//
// Return Value:
//
//
// Errors:
// -
//
// Detailed Comments:
// The function returns the index of the startfd in the FileDataList or -1 otherwise (i.e. it is unique)
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_checkFileDataUnique(in integer pl_startfd) runs on EPTF_StatCapture_CT return integer {
for(var integer i:=0; i<sizeof(v_StatCapture_FileDataList); i:=i+1) {
if (v_StatCapture_FileDataList[i].startfd == pl_startfd) {
return i; // startfd is not unique, return its index in the FileDataList
}
}
return -1;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_checkGroupName
//
// Purpose:
// Function for checking the uniqueness of group names
//
// Parameters:
// groupname - *in* *charstring* - name of the group (must be unique)
// groupID - *out* *integer* - the index of the group in the captureGroups record
//
// Return Value:
// true if the group name is unique, false otherwise
//
// Errors:
// The group name must be unique, error is returned if the groupname already exists.
//
// Detailed Comments:
// The function returns true (pl_idx = -1) if groupname is unique, returns false (pl_idx = index of the group) if the name exists
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_checkGroupName(in charstring pl_name, out integer pl_idx) runs on EPTF_StatCapture_CT return boolean {
pl_idx := -1;
if (pl_name=="") {
return true;
}
for(var integer i:=0; i<sizeof(v_StatCapture_captureGroups); i:=i+1) {
if (v_StatCapture_captureGroups[i].groupName == pl_name) {
pl_idx := i;
return false; // group name is not unique
}
}
return true;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_dumpStringforGroup
//
// Purpose:
// Dumping the logstring to the logfiles belonging to the capture group
//
// Parameters:
// groupID - *in* *integer* - the group, for which logfiles the string has to be dumped
// logstring - *in* *charstring* - the string, which has to be dumped
//
// Return Value:
// -
//
// Errors:
// If the logfile cannot be opened for dumping or cannot be written. Also if the group does not exist.
//
// Detailed Comments:
// This function accounts file handling data (eg. file nr of bytes written to file, actual fd, start fd, etc.)
// for being able to handle very big log files. It opens new file if the previous one is full and writes
// logstring to the actual file. If the maximum number of files (reopened for one initial startfd) is reached,
// no more data is dumped. It is the user's responsibility to change default values
// (tsp_EPTF_StatCapture_max_file_size,tsp_EPTF_StatCapture_max_nrof_files) if required in the config file.
// This is a private function.
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_dumpStringforGroup(in integer pl_groupidx, in charstring pl_logstring) runs on EPTF_StatCapture_CT {
var integer vl_fileidx;
var integer vl_sizeoflogstring := 0;
var integer vl_nrofBytes := 0;
var integer vl_actfd;
var integer vl_nrofFiles;
var charstring vl_filename := "";
var integer vl_filenameidx;
vl_sizeoflogstring := lengthof(pl_logstring);
//f_EPTF_Base_assert("ERROR: Group does not exist.", (pl_groupidx < sizeof(v_StatCapture_captureGroups)) and (pl_groupidx >= 0));
if ((pl_groupidx >= sizeof(v_StatCapture_captureGroups)) or (pl_groupidx < 0)){
f_EPTF_StatCapture_error("Group does not exist.");
//f_EPTF_Base_stop();
}
for (var integer i :=0; i<sizeof(v_StatCapture_captureGroups[pl_groupidx].logFiles); i:= i+1){
vl_fileidx := v_StatCapture_captureGroups[pl_groupidx].logFiles[i].idx; //index of the record with id startfd, containing actual statistics to actfd
vl_nrofBytes := v_StatCapture_FileDataList[vl_fileidx].nrofBytes; //nr of bytes written so far to actfd
vl_actfd := v_StatCapture_FileDataList[vl_fileidx].actfd;
if ((vl_sizeoflogstring + vl_nrofBytes <= tsp_EPTF_StatCapture_max_file_size) and (v_StatCapture_FileDataList[vl_fileidx].nrofFiles < tsp_EPTF_StatCapture_max_nrof_files)){
if (f_FIO_write_text(vl_actfd, pl_logstring) == -1){
f_EPTF_StatCapture_error(log2str("ERROR: Cannot dump to logfile. " & f_FIO_get_error_string()));
//f_EPTF_Base_stop();
}
v_StatCapture_FileDataList[vl_fileidx].nrofBytes := v_StatCapture_FileDataList[vl_fileidx].nrofBytes + vl_sizeoflogstring;
}
else { //previous file is full
f_EPTF_StatCapture_debug("Actual file is full, closed.");
if(0 != f_FIO_close(vl_actfd)) {
f_EPTF_StatCapture_warning(log2str(%definitionId, ": close failed (", f_FIO_get_error_string(), ")."));
}
v_StatCapture_FileDataList[vl_fileidx].nrofBytes := 0;
if (v_StatCapture_FileDataList[vl_fileidx].nrofFiles + 1 <= tsp_EPTF_StatCapture_max_nrof_files){ //open next file
f_EPTF_StatCapture_debug("Opening new file.");
v_StatCapture_FileDataList[vl_fileidx].nrofFiles := v_StatCapture_FileDataList[vl_fileidx].nrofFiles + 1;
vl_nrofFiles := v_StatCapture_FileDataList[vl_fileidx].nrofFiles;
var charstring vl_starttime := v_StatCapture_FileDataList[vl_fileidx].startDate;
var charstring vl_userfilename:="";
if (f_EPTF_int2int_HashMap_Find (v_StatCapture_inthashmap_id, v_StatCapture_FileDataList[vl_fileidx].startfd, vl_filenameidx) == true )
{
vl_userfilename := v_StatCapture_logfilenames[vl_filenameidx];
}
else { vl_userfilename := "notfound";}
if(tsp_EPTF_StatCapture_fileFormat == readable){
vl_filename := vl_userfilename & "-" & int2str(vl_nrofFiles) & ".txt";
}
if(tsp_EPTF_StatCapture_fileFormat == gnuplot){
vl_filename := vl_userfilename & "-" & int2str(vl_nrofFiles) & ".gpl";
}
v_StatCapture_FileDataList[vl_fileidx].actfd := f_FIO_open_append_wronly_excl(vl_filename);
if (v_StatCapture_FileDataList[vl_fileidx].actfd == -1){
f_EPTF_StatCapture_error(log2str("Cannot open logfile." & f_FIO_get_error_string()));
//f_EPTF_Base_stop();
}
vl_actfd := v_StatCapture_FileDataList[vl_fileidx].actfd ;
vl_nrofBytes := v_StatCapture_FileDataList[vl_fileidx].nrofBytes;
if (vl_sizeoflogstring <= tsp_EPTF_StatCapture_max_file_size){
if (f_FIO_write_text(vl_actfd, pl_logstring) == -1){
f_EPTF_StatCapture_error(log2str("Cannot dump to logfile." & f_FIO_get_error_string()));
//f_EPTF_Base_stop();
}
v_StatCapture_FileDataList[vl_fileidx].nrofBytes := v_StatCapture_FileDataList[vl_fileidx].nrofBytes + vl_sizeoflogstring;
}
else {
f_EPTF_StatCapture_warning("File size too low. Logstring cannot be dumped.");
}
}//if the max nr of files is exceeded, we do not dump
else{
f_EPTF_StatCapture_warning(log2str("The last file ", vl_actfd, "is full, capture finished. Data is not logged to file."));
}
}
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_dumpStringtoFile
//
// Purpose:
// Dumping the TimeStampBase string to the logfile
//
// Parameters:
// fd - *in* *integer* - the file descriptor of the logfile
// logstring - *in* *charstring* - the string, which has to be dumped (Timestamp)
//
// Return Value:
// -
//
// Errors:
// If the logfile cannot be opened for dumping or cannot be written. Also if the group does not exist.
//
// Detailed Comments:
// This is a private function.
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_dumpStringtoFile(in integer pl_fd, in charstring pl_logstring) runs on EPTF_StatCapture_CT {
if (f_FIO_write_text(pl_fd, pl_logstring) == -1){
f_EPTF_StatCapture_error(log2str("Cannot dump to logfile." & f_FIO_get_error_string()));
//f_EPTF_Base_stop();
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_get_time
//
// Purpose: A wrapper function for getting the actual time and date.
//
// Parameters:
// -
//
// Return Value:
// The actual time and date as a string.
//
// Detailed Comments:
// This is a private function.
//
///////////////////////////////////////////////////////////
external function f_EPTF_StatCapture_get_time(in charstring formatstring := "%Y-%m-%d_%H.%M.%S", in boolean milisec := false) return charstring;
group Logging {
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_error
//
// Purpose:
// Function to log an error from StatCapture feature.
//
// Parameters:
// - pl_message - *in* *charstring* - the message to log
//
// Return Value:
// -
//
// Errors & assertions:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_error(in charstring pl_message)
runs on EPTF_StatCapture_CT
{
f_EPTF_Logging_error(true, tsp_EPTF_StatCapture_loggingComponentMask&": "&pl_message);
f_EPTF_Base_stopAll();
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_warning
//
// Purpose:
// Function to log a warning from StatCapture feature.
//
// Parameters:
// - pl_message - *in* *charstring* - the message to log
//
// Return Value:
// -
//
// Errors & assertions:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_warning(in @lazy charstring pl_message)
runs on EPTF_StatCapture_CT
{
f_EPTF_Logging_warningV2(pl_message, v_StatCapture_loggingMaskId, {c_EPTF_StatCapture_loggingClassIdx_Warning});
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_debug
//
// Purpose:
// Function to log a debug message from StatCapture feature.
//
// Parameters:
// - pl_message - *in* *charstring* - the message to log
//
// Return Value:
// -
//
// Errors & assertions:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_debug(in @lazy charstring pl_message)
runs on EPTF_StatCapture_CT
{
f_EPTF_Logging_debugV2(pl_message, v_StatCapture_loggingMaskId, {c_EPTF_StatCapture_loggingClassIdx_Debug});
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_StatCapture_debugEnabled
//
// Purpose:
// Function to check if debug is enabled for StatCapture
//
// Parameters:
// -
//
// Return Value:
// *boolean* - true if debug enalbed
//
// Errors & assertions:
// -
//
// Detailed Comments:
// -
//
///////////////////////////////////////////////////////////
private function f_EPTF_StatCapture_debugEnabled()
runs on EPTF_StatCapture_CT
return boolean
{
return f_EPTF_Logging_isEnabled(v_StatCapture_loggingMaskId, c_EPTF_StatCapture_loggingClassIdx_Debug);
}
} // group Logging
} //private functions
} // end of module