| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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 |
| |
| |