You are on page 1of 33

Create Custom Metrics for HANA Monitoring

With SAP Solution Manager 7.1

Introduction: When monitoring SAP HANA, most metrics are metrics stored in SAP HANA alert tables.
However these tables do not include all the metrics you might be interested in. Some information is
never written to these alert tables, because the SAP HANA administrator could use SAP HANA Studio
to manually monitor these metrics, e.g. landscape information. To automate the monitoring for this
kind of metrics we developed a data collector that pulls this information directly from the corresponding
table in HANA. This guide describes how customers can create an own data collector implementation
based on the SAP delivered data collector to collect own metrics from the SAP HANA database.

Contents
..................................................................................................................................................................................1
Prerequistes ............................................................................................................................................................2
Connect SAP HANA to SAP Solution Manager .......................................................................................................2
Create Custom Data Provider Implementation ....................................................................................................2
Security Considerations ............................................................................................................................................2
Copy SAP Data Provider Implementation ................................................................................................................3
Adjust Custom Data Provider Implementation..........................................................................................................5
Declare Result Table ................................................................................................................................................5
Retrieve and filter result from HANA DB ..................................................................................................................7
Handle Result .........................................................................................................................................................10
Create Custom Data Collector for Monitoring and Alerting .............................................................................13
Copy SAP standard Data Collector Template ........................................................................................................13
Create Custom Metric and Alert ..........................................................................................................................18
Create a Custom Metric ..........................................................................................................................................18
Create a Custom Alert ............................................................................................................................................22
Result .....................................................................................................................................................................24
Appendix ...............................................................................................................................................................26
Coding for Z_HANA_METRIC_EXTRACTOR ........................................................................................................26
PREREQUISTES
Connect SAP HANA to SAP Solution Manager
To enable technical monitoring with SAP Solution Manager for SAP HANA the first step is to connect the SAP
HANA database to SAP Solution Manager via the managed system configuration.
For a detailed description how to connect SAP HANA database to SAP Solution Manager please follow the
guide in the SMSETUP wiki:
http://wiki.scn.sap.com/wiki/display/SMSETUP/Managed+System+Setup+of+HANA+in+Solution+Manager+7.1

CREATE CUSTOM DATA PROVIDER IMPLEMENTATION


The newest data provider to collect HANA metrics is shipped with ST-PI SP10. This data collector collects
metrics via SELECT statements that are sent into the HANA database.
Security Considerations
For security reasons we couldnt create a completely generic data collector, which accepts SQL statements as
input. We rather have to hard-code the SELECT statement in the data provider implementation. For your own
SELECT statements you will copy the SAP delivered data collector and adjust it to your needs.
The user used to run the SELECT statement against the HANA database is the user maintained in the DBA
Cockpit connection for SAP HANA created during the managed systems configuration.
This user should have been created in SAP HANA as part of the managed system setup as described in the
SMSETUP wiki page. The recommended granted roles for this user are the roles MONITORING and PUBLIC.
With this roles the user has read-only access only to the schemas SYS and _SYS_STATISTICS.

By using this user to establish the connection to SAP HANA you can make sure that no business data can be
pulled out of HANA during the monitoring.

Copyright/Trademark
Copy SAP Data Provider Implementation
To create and send you own SELECT statement you first have to copy the function module
/SDF/HANA_METRIC_EXTRACTOR in customer namespace.
At first you have to create a function group for your function module. The easiest way to do this is in transaction
SE80. Select Function Group from the drop-down box and enter a name for your function group. When you
click the display button it will guide you thru the creation of the function group if it doesnt exist yet.

If you want to transport the function module later on, please make sure to select a Z-package for you code.
Call transaction SE37 and enter /SDF/HANA_METRIC_EXTRACTOR in the input field. Click the Copy button
to copy the function module.

Copyright/Trademark
Enter a name for your function module and the function group you created before.

Done! You now have a custom data provider implementation to work with.

Copyright/Trademark
Adjust Custom Data Provider Implementation
You can reuse most of the data provide implementation, like e.g. the establishment of the DB connection, the
import and export parameter and most of the error handling. But some parts are specific to the key figures you
plan to collect and hence have to be adjusted.
In this guide we will implement two additional key figures.
HANA Services Status the key figure lists the status of all HANA services. The result is already rated
by the data collector.
Number of Trace Files the key figure returns the number of trace files by host.
Examples for HANA SQL statements that could build the basis for your custom metrics can be found attached
the SAP note 1969700 - SQL statement collection for SAP HANA and SAP knowledge base article 1999993 -
SAP HANA Mini Checks.
You find a complete listing of the coding in the appendix of this document.
Declare Result Table
The result table is the table in which the result of the SELECT statement is written. Hence this data structure
depends on your SELECT statement. You have to declare the columns exactly as you specify them in the
SELECT statement.
Example 1: HANA Services Status
The data declaration area begins roundabout in code line 60+. Everything before doesnt have to be changed.
For the first example I use this select statement:
SELECT
HOST,
SERVICE_NAME,
COORDINATOR_TYPE TYPE,
ACTIVE_STATUS
FROM
M_SERVICES S
ORDER BY
S.HOST,
S.SERVICE_NAME
The result is this table:

Copyright/Trademark
The result structure I declare contains the fields host, service_name, type and active_status:
" data declarations for metric Service Status
types: begin of st_services,
host(64) type c,
service_name(128) type c,
type(128) type c,
active_status(64) type c,
end of st_services.
data: services_iterator type st_services.
data: services_list type table of st_services.

Example 2: Number of Trace Files


The second example is an example for a metric with returns a numeric value.
I use the following SELECT statement retrieve this metric:
SELECT
HOST,
COUNT(*) No_of_tracefiles
FROM
M_TRACEFILES T
GROUP BY
T.HOST
The result is this table. In my case only one host is ONLINE. Hence I only have one entry. If you have a multi-
node HANA DB, you would find one entry per host.

The result structure contains the two columns host and no_of_tracefiles.
" data declarations for metric id 1501
types: begin of st_tracefiles,
host(64) type c,
no_of_tracefiles TYPE string,
end of st_tracefiles.
data: tracefiles_iterator type st_tracefiles.
data: tracefiles_list type table of st_tracefiles.

Copyright/Trademark
Retrieve and filter result from HANA DB
Now you have to create the SELECT statement and handle the result set. Depending on the type of your key
figure you can return a value or a rating. Technically you could return both, but this doesnt necessarily make
sense.
The coding for the key figure starts around code line 210+ in the original coding. You can also filter for the string
here plays the music this will take you directly to the first key figure
Each key figure is identified by a number; this is just for the coding, as you can have more than one key figure in
your HANA data provider implementation. In order to avoid confusion with the HANA alert IDs you should not
use 000 to 999. We suggest using 1000 to 2000 for this extractor.
The easiest way is to copy the coding from the original key figures and adjust it to your needs.
Example 1: HANA Services Status
For this key figure I want to return a rating. As also the key figure 1000 is an already rated key figure, I copied
this piece of code.
Now you have to adjust the coding. I will go thru the coding step by step and highlight the areas that have to be
adjusted.
1. Replace the name of the result table with the name from your own data declaration:
when '1500'. "Service Status List - available filter parameters: HOST and SERVICE
if connection is bound.
clear dref.
clear cols.
refresh services_list.
get reference of services_list into dref.
adbc_sql = connection->create_statement( ).
2. Enter your own SELECT statement:
try.
concatenate
'SELECT host,service_name,COORDINATOR_TYPE type,active_status ' "#EC NOTEXT
' FROM M_SERVICES S ORDER BY S.HOST, S.SERVICE_NAME'
into statement.
adbc_result = adbc_sql->execute_query( statement ).
adbc_result->set_param_table( itab_ref = dref
corresponding_fields = cols ).
As I mentioned before make sure that your result data structure and the column names match the returned
fields.
You can test your select statement in HANA Studio using the SQL Console. This way you see if your SELECT
statement is syntactically correct, but also how the result looks like. Knowing what the result looks like helps with
the next step.
3. Filter the result set
The standard data provider has 3 parameters. DBCNAME is the DB connection name and will be prefilled by the
monitoring infrastructure. KEY_FIGURE is the ID for the key figure you want to select. ALERT_TEXT is used if
you want to filter your result set.
The parameters DBCNAME and KEY_FIGURE are set should not be changed in the coding. But if you want, you
can do something about ALERT_TEXT. I rather wanted to have the parameters HOST and SERVICE as filter
parameters for my key figure. This way I can filter for the hosts Im interested in, as well as put an additional filter
on the service name.

Copyright/Trademark
" prepare the select options table
refresh sel_opt_table.
loop at e_selopt_para-selection_parameter assigning <selection_parameter>
where param = 'HOST'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.

delete services_list where host not in sel_opt_table.

loop at e_selopt_para-selection_parameter assigning <selection_parameter>


where param = 'SERVICE'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.

delete services_list where service_name not in sel_opt_table.

Example 2: Number of Trace Files


For this key figure I want to return the number of trace files per host. I copied key figure 1001 as template, as this
key figure also returns a numeric value. The steps here are the same as for example 1.
1. Replace the name of the result table with the name from your own data declaration:
when '1501'. "Number of trace files per host - available filter parameters: HOST
if connection is bound.
clear dref.
clear cols.
refresh tracefiles_list.
get reference of tracefiles_list into dref.
adbc_sql = connection->create_statement( ).
2. Enter your own SELECT statement:
try.
concatenate
'SELECT host, COUNT(*) no_of_tracefiles '
' FROM M_TRACEFILES T'
' GROUP BY T.HOST'
into statement.

adbc_result = adbc_sql->execute_query( statement ).


adbc_result->set_param_table( itab_ref = dref corresponding_fields = cols ).

Copyright/Trademark
3. Filter the result set
In this case we only have one parameter, the hostname.
if adbc_result->next_package( ) > 0.
" prepare the select options table
refresh sel_opt_table.
loop at e_selopt_para-selection_parameter assigning <selection_parameter>
where param = 'HOST'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.

delete tracefiles_list where host not in sel_opt_table.

Copyright/Trademark
Handle Result
Now you have to fill the export parameter RESULT. You dont have to worry about RETURN_STATUS, this is
already done in the original implementation.
You result table will consist of a text and also a rating or a value. Based on the returned values you will then
create thresholds for your metrics.
Example 1: HANA Services Status
For this metric we will use an already rated value. So we basically check the result table and return a rating
(green, red, yellow or grey) and a text for the metric. In the monitoring we set up this metric with the threshold
type already rated.
The code below will produce the following result:

At first we create the right side of the picture above. To make sure we can use the metric in a metric group later
on, we have to create one entry for each parameter in the parameter table.
refresh t_parameter.
" produce result table (one metric per host:service in services_list)
l_parameter-param = 'HOST'.
l_parameter-value = services_iterator-host.
append l_parameter to t_parameter.

l_parameter-param = 'SERVICE'.
l_parameter-value = services_iterator-service_name.
append l_parameter to t_parameter.

l_result-result-t_parameter = t_parameter.
Now we concatenate the values to have a useful text in the result text.
concatenate 'Type:' services_iterator-type 'Active:' services_iterator-
active_status into l_result-result-text separated by space.

condense l_result-result-text.
l_result-result-count = 1.
l_result-result-average = l_result-result-sum = l_result-result-min =
l_result-result-max = 0.
The last 2 lines of code fill the numeric return table fields with the value 0. As we will create an already rated
metric, we will not use these fields.

Copyright/Trademark
Now we have to rate the return value. The rating values are:

Value Rating
0 Grey
1 Green
2 Yellow
3 Red

" evaluate rating 0 = gray, 1 = green, 2 = yellow, 3 = red


case services_iterator-active_status.
when 'YES'.
l_result-result-rating = 1.
when 'NO'.
if services_iterator-type = 'MASTER'.
l_result-result-rating = 3.
else.
l_result-result-rating = 2.
endif.
when others.
l_result-result-rating = 0.
endcase.
You can leave the rest of the code as it is.
The next step for this metric is to create a data collector template and a custom metric. This is described in the
subsequent sections.

Example 2: Number of Trace Files


For the second metric, we will not rate the result, but we will only return an alert text and an alert value.
At first we create the parameter identification in the System Monitoring application.
loop at tracefiles_list into tracefiles_iterator.
refresh t_parameter.
" produce result table (one metric per host in tracefiles_list)
l_parameter-param = 'HOST'.
l_parameter-value = tracefiles_iterator-host.
append l_parameter to t_parameter.
l_result-result-t_parameter = t_parameter.
Then we create a result text.
l_result-result-text = tracefiles_iterator-no_of_tracefiles.
condense l_result-result-text.

Copyright/Trademark
In the last step we have to assign the numeric value to the respective field in the result array. In this case I
assign the same value to min, max and average. This way I make sure, that the implementation is a bit more
error tolerant when it comes to the selection of the value that is compared in the threshold (youll see this later).
l_result-result-count = 1.
l_result-result-average =
l_result-result-min =
l_result-result-max =
l_result-result-sum = tracefiles_iterator-no_of_tracefiles.
" no rating evaluation - no pre-rated metric
l_result-call_id = e_selopt_para-call_id.
append l_result to t_result.
Thats it.
Dont forget to generate and activate your code. After this we can move on to the creation of data collector
templates.

Copyright/Trademark
CREATE CUSTOM DATA COLLECTOR FOR MONITORING AND ALERTING
To use your custom data provider implementation you have to create data collector template to be able to use it
in the monitoring and alerting templates. The data collector template serves as the interface between your
implementation and the template maintenance. It provides the possible input fields for the parameters in the
template maintenance and hands the input values over to the data provider implementation it uses.
As the basis for the data collector template we use the data collector template Hana Database Metrics, which
uses the original SAP delivered data provider implementation.
Copy SAP standard Data Collector Template
Example 1: HANA Services Status
Open the Data Collector Maintenance via the URL
http://<SolMan Host>:<SolMan Port>/sap/bc/webdynpro/sap/wd_mai_dpc_main
Then find the data collector Hana Database Metrics under the RFC (Pull) collector types.

Adjust the name of the data collector. Make sure the name starts with ZZ, as this is going to be a table entry, you
have to use double-Z to protect it against overwrite during a content update.

Copyright/Trademark
Save you data collector template. It will ask for a transport request at this point.
Now we have to change the parameters.
As mentioned before the parameters DBCNAME and KEY_FIGURE are set. But as I changed the parameters in
my data provider implementation I have to adjust them here too. I also want to hardcode the key figure to make
sure the user uses the correct key figure for my parameters. So in a first step I change the parameter usage to
HIDDEN, to avoid that users can change it and also enter 1500 as value. I also remove the flag for Ext.
Context.

Now I add two new parameters HOST and SERVICE.

Now I delete ALERT_TEXT, as I dont want to use it anymore.

Done, now I can use this data collector template in a custom metric.

Copyright/Trademark
Example 2: Number of Trace Files
Open the Data Collector Maintenance via the URL
http://<SolMan Host>:<SolMan Port>/sap/bc/webdynpro/sap/wd_mai_dpc_main
Create a copy of the same data collector template as in example 1.

I again hardcode the key figure and leave the DBCNAME as it is.

Then I just rename the parameter ALERT_TEXT with HOST.

Save the data collector template.

Copyright/Trademark
Remark:
Right now we are creating one data collector template per metric. This is the most user-friendly way but also the
one with the most effort. If you want to cut down the number of created data collector templates you could also
create e.g. one template for all metrics with just one filter value, one for all metrics with two filter values, and so
on.
You would have to address this already in the coding. So instead of using specific parameter names like HOST
and SERVICE, you would use your generic parameter names, e.g. FILTER1, FILTER2 etc. in your code, when
you filter the result:
refresh sel_opt_table.
loop at e_selopt_para-selection_parameter assigning <selection_parameter>
where param = 'FILTER1'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.

delete tracefiles_list where <host> not in sel_opt_table.


In this example FILTER1 = host.
But be careful. You have to document very well, which filter parameter filter on which field in your result (e.g. for
HANA Services Status FILTER1 = host, FILTER2 = service). Only this way you can make sure that later on
during the setup of the metric in the template management the right parameter value are set.
If the same data collector template is used for several key figures, it is also recommendable to add an input help
for the KEY_FIGURE field. And certainly this field cannot be HIDDEN

Copyright/Trademark
This is how it will look later on in the metric creation in the template maintenance.

Copyright/Trademark
CREATE CUSTOM METRIC AND ALERT
The last step in this guide is to create a custom metric and alert that uses our new data provider implementation.
I already created a custom template. The template should be created as custom template from the SAP HANA
DB (NEW) template.
Create a Custom Metric
Example 1: HANA Services Status
Switch to expert mode and click the Edit button to be able to add you custom metric. Click Create Metric to
create the metric.

Enter the name and the category for your metric. Make sure to create it as a Metric Group if you plan to use no
filter or a filter that returns more than one line.

Copyright/Trademark
Select you data collector from the list. As we create a metric group, you have to create a variant. In this case I do
not restrict by hostname or service name. To enter the values for host name and service name, click on the
green in the columns. Its OK that it changes to a when you add a pattern

On the next tab you can decide if you want to use the metric only for alerting or also for reporting. I didnt change
anything here. On the Threshold tab you have to select Already Rated as threshold type to make sure your
rating value that you return is taken into account.

Copyright/Trademark
Click Next. You could assign the metric to an already existing alert. But I want to create an own alert for this.
Click Finish and save your work.
Example 2: Number of Trace Files
Create a custom metric and enter name, category and a technical name.

Select the data collector template and enter a variant for the host filter.

In the tab Threshold you have to choose a numeric threshold. As we fill the result value in the min, max and the
average value, it luckily doesnt matter which one you choose as Monitored Value.

Copyright/Trademark
Click Next and then Finish. Then save you template.
The last step is to create a custom alert for the metric.

Copyright/Trademark
Create a Custom Alert
Example 1: HANA Services Status
Click Create Alert.
Enter an alert name, the category (make sure its the same one as your metric) and a technical name.

You can disregard the other tabs for now, this can be maintained later. Click Next.
Select your new metric from the list and click Finish. Save your work.

Copyright/Trademark
Example 2: Number of Tracefiles

Assign your custom metric to the alert.

Copyright/Trademark
RESULT
After you applied and activated the template on a HANA DB, you should see this result.
Example 1: HANA Services Status

Copyright/Trademark
Example 2: Number of Trace Files

Copyright/Trademark
APPENDIX
Coding for Z_HANA_METRIC_EXTRACTOR
Find the complete code for the custom data provider implementation attached.
function z_hana_metric_extractor.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(SELOPT_PARA) TYPE /SDF/E2E_SELECTION_PARAMETER_T
*" EXPORTING
*" REFERENCE(RESULT) TYPE /SDF/E2E_RESULT_TT
*" REFERENCE(RETURN_STATUS) TYPE /SDF/E2E_EFWKE_RETURN_STATUS_T
*"----------------------------------------------------------------------
* reports HANA metrics for use in E2E monitoring for HANA
*---------------------
* mandatory parameters
*---------------------
* KEY_FIGURE a unique identifier to select the requested metric
* in order to avoid confusion with the HANA alert IDs y
ou should not use 000 to 999
* we suggest to use 1000 to 2000 for this extractor

* DBCNAME Name of the DBCON connection to be used to connect to


the HANA DB
*
* ALERT_TEXT Can be used to define the filter value for metric gro
up variants
*

types: begin of t_db_system,


dbcname type dbcon_name,
t_selopt_para type /sdf/e2e_selection_parameter_t,
end of t_db_system.

data: ls_db_system type t_db_system.


data: lt_db_systems type standard table of t_db_system.

data: sys_ref type ref to cl_db6_sys.

data: ex_db6_sys type ref to cx_db6_sys. "#EC NEEDED

data: wa_return_status like line of return_status.


data: t_return_status like return_status.
data: l_return_status like line of t_return_status.

data: e_selopt_para type /sdf/e2e_selection_para.


data: t_result type /sdf/e2e_result_tt.
data: l_result like line of t_result.
data: l_parameter type /sdf/e2e_para.
data: t_parameter type /sdf/e2e_para_tt.

data: message type string.


data: connection type ref to cl_sql_connection.
data: cols type adbc_column_tab.
data: dref type ref to data.
data: adbc_sql type ref to cl_sql_statement,

Copyright/Trademark
adbc_result type ref to cl_sql_result_set,
adbc_err type ref to cx_sql_exception,
adbc_cols type adbc_column_tab,
adbc_dref type ref to data.
data: statement type string.
data: sqlerr_ref type ref to cx_sql_exception.
data: con_check_ok type c.
data: error type c.
data: found type c.
data: internal_error_num(11) type n.

" data declarations for metric id 1500


types: begin of st_services,
host(64) type c,
service_name(128) type c,
type(128) type c,
active_status(64) type c,
end of st_services.
data: services_iterator type st_services.
data: services_list type table of st_services.

" data declarations for metric id 1501


types: begin of st_tracefiles,
host(64) type c,
no_of_tracefiles TYPE string,
end of st_tracefiles.
data: tracefiles_iterator type st_tracefiles.
data: tracefiles_list type table of st_tracefiles.

" --------------

data: sel_opt_table type /sdf/e2e_selop_tt.

field-symbols: <selection_parameter> type /sdf/e2e_selection_params.


field-symbols: <param_range> type /sdf/ranges.
field-symbols: <db_system> type t_db_system.

* extract DBCNAME from SELOPT_PARA


loop at selopt_para into e_selopt_para.
clear ls_db_system.
read table e_selopt_para-selection_parameter
assigning <selection_parameter>
with key param = 'DBCNAME'. "#EC NOTEXT
if sy-subrc <> 0.
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-status = 2.
wa_return_status-msgtext = 'No database connection specified!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.

read table <selection_parameter>-t_ranges


assigning <param_range>
index 1.
if sy-subrc <> 0.

Copyright/Trademark
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-status = 2.
wa_return_status-msgtext = 'No database connection specified!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.

ls_db_system-dbcname = <param_range>-low.
" if this DBCNAME is already in our list (lt_db_systems) we need to append it
to the existing entry, otherwise we have to create a new one
found = space.
loop at lt_db_systems assigning <db_system> where dbcname = ls_db_system-
dbcname.
append e_selopt_para to <db_system>-t_selopt_para.
found = 'X'.
endloop.
if found <> 'X'.
append e_selopt_para to ls_db_system-t_selopt_para.
append ls_db_system to lt_db_systems.
endif.
endloop.

loop at lt_db_systems
assigning <db_system>.
read table <db_system>-t_selopt_para into e_selopt_para index 1.
if sy-subrc = 0.
wa_return_status-call_id = e_selopt_para-call_id.
endif.

wa_return_status-status = 0. " think positive


error = space.

" handle connection checks


try.
sys_ref = cl_db6_sys=>get_sys_ref_by_connection( <db_system>-dbcname ).
catch cx_db6_sys into ex_db6_sys. "#EC NO_HANDLER
wa_return_status-status = 2.
concatenate 'No system reference found for DBCNAME:' <db_system>-dbcname
into wa_return_status-msgtext separated by space.
append wa_return_status to t_return_status.
error = 'X'.
endtry.

if error <> 'X'.


try. " connection test
con_check_ok = 'X'.
connection = cl_sql_connection=>get_connection( con_name = <db_system>-
dbcname ).
catch cx_sql_exception into sqlerr_ref.
con_check_ok = space.
wa_return_status-status = 2.
if sqlerr_ref->sql_code <> 0 or sqlerr_ref->sql_message is not initial.
wa_return_status-msgtext = sqlerr_ref->sql_message.
else.
if sqlerr_ref->unknown_connection = 'X'.
wa_return_status-msgtext = 'Unknown Connection Name'. "#EC NOTEXT

Copyright/Trademark
elseif sqlerr_ref->connection_closed = 'X'.
wa_return_status-msgtext = 'Connection closed'. "#EC NOTEXT
elseif sqlerr_ref->internal_error <> 0.
write sqlerr_ref->internal_error to internal_error_num no-zero.
wa_return_status-msgtext =
'Internal error &1 has occured'. "#EC NOTEXT
replace '&1' with internal_error_num into wa_return_status-msgtext.
else.
wa_return_status-msgtext = 'ADBC Error'. "#EC NOTEXT
endif.
endif.
concatenate 'DBCNAME: ' <db_system>-dbcname ': ' wa_return_status-msgtext
into wa_return_status-msgtext.
append wa_return_status to t_return_status.
endtry.
endif.

if error <> 'X' and con_check_ok = 'X'.


" now loop through call_ids for this db connection
loop at <db_system>-t_selopt_para into e_selopt_para.

wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-status = 0.
clear l_result.
clear wa_return_status.

read table e_selopt_para-selection_parameter


assigning <selection_parameter>
with key param = 'KEY_FIGURE'.
if sy-subrc <> 0.
wa_return_status-status = 2.
wa_return_status-msgtext = 'No KEY_FIGURE specified!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.
if error = space.
read table <selection_parameter>-t_ranges
assigning <param_range>
index 1.
if sy-subrc <> 0.
wa_return_status-status = 2.
wa_return_status-msgtext =
'No KEY_FIGURE value specified!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.
endif.
case <param_range>-low.
** here plays the music
when '1500'. "Service Status List available filter parameters:
HOST and SERVICE
if connection is bound.
clear dref.
clear cols.
refresh services_list.
get reference of services_list into dref.

Copyright/Trademark
adbc_sql = connection->create_statement( ).
try.
concatenate
'SELECT host,service_name,COORDINATOR_TYPE type,active_status '
"#EC NOTEXT
' FROM M_SERVICES S ORDER BY S.HOST, S.SERVICE_NAME'
into statement.
adbc_result = adbc_sql->execute_query( statement ).
adbc_result->set_param_table( itab_ref = dref
corresponding_fields = cols ).
if adbc_result->next_package( ) > 0.
" prepare the select options table
refresh sel_opt_table.
loop at e_selopt_para-selection_parameter assigning
<selection_parameter> where param = 'HOST'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.

delete services_list where host not in sel_opt_table.

loop at e_selopt_para-selection_parameter assigning


<selection_parameter> where param = 'SERVICE'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.

delete services_list where service_name not in sel_opt_table.

loop at services_list into services_iterator.


refresh t_parameter.
" produce result table (one metric per host:service in services_list)
l_parameter-param = 'HOST'.
l_parameter-value = services_iterator-host.
append l_parameter to t_parameter.

l_parameter-param = 'SERVICE'.
l_parameter-value = services_iterator-service_name.
append l_parameter to t_parameter.

l_result-result-t_parameter = t_parameter.

concatenate 'Type:' services_iterator-type 'Active:'


services_iterator-active_status
into l_result-result-text separated by space.

condense l_result-result-text.
l_result-result-count = 1.
l_result-result-average = l_result-result-sum =
l_result-result-min =
l_result-result-max = 0.

" evaluate rating 0 = gray, 1 = green, 2 = yellow, 3 = red


case services_iterator-active_status.
when 'YES'.
l_result-result-rating = 1.

Copyright/Trademark
when 'NO'.
if services_iterator-type = 'MASTER'.
l_result-result-rating = 3.
else.
l_result-result-rating = 2.
endif.
when others.
l_result-result-rating = 0.
endcase.
l_result-call_id = e_selopt_para-call_id.
append l_result to t_result.
wa_return_status-status = 0.
wa_return_status-call_id = e_selopt_para-call_id.
append wa_return_status to t_return_status.
endloop.
else.
wa_return_status-status = 2.
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-msgtext = 'No data returned!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.
catch cx_sql_exception into adbc_err.
wa_return_status-status = 2.
concatenate 'SQL error: ' "#EC NOTEXT
adbc_err->sql_message into wa_return_status-msgtext.
append wa_return_status to t_return_status.
continue.
endtry.
else.
wa_return_status-status = 2.
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-msgtext = 'Connection to DB lost!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.
when '1501'. "Number of trace files per host available filter
parameters: HOST
if connection is bound.
clear dref.
clear cols.
refresh tracefiles_list.
get reference of tracefiles_list into dref.
adbc_sql = connection->create_statement( ).
try.
concatenate
'SELECT host, COUNT(*) no_of_tracefiles '
' FROM M_TRACEFILES T'
' GROUP BY T.HOST'
into statement.

adbc_result = adbc_sql->execute_query( statement ).


adbc_result->set_param_table( itab_ref = dref
corresponding_fields = cols ).
if adbc_result->next_package( ) > 0.
" prepare the select options table

Copyright/Trademark
refresh sel_opt_table.
loop at e_selopt_para-selection_parameter assigning
<selection_parameter> where param = 'HOST'.
sel_opt_table = <selection_parameter>-t_ranges.
exit.
endloop.
delete tracefiles_list where host not in sel_opt_table.

loop at tracefiles_list into tracefiles_iterator.


refresh t_parameter.
" produce result table (one metric per host in tracefiles_list)
l_parameter-param = 'HOST'.
l_parameter-value = tracefiles_iterator-host.
append l_parameter to t_parameter.
l_result-result-t_parameter = t_parameter.

l_result-result-text = tracefiles_iterator-no_of_tracefiles.
condense l_result-result-text.

l_result-result-count = 1.
l_result-result-average =
l_result-result-min =
l_result-result-max =
l_result-result-sum = tracefiles_iterator-no_of_tracefiles.
" no rating evaluation - no pre-rated metric
l_result-call_id = e_selopt_para-call_id.
append l_result to t_result.
wa_return_status-status = 0.
wa_return_status-call_id = e_selopt_para-call_id.
append wa_return_status to t_return_status.
endloop.
else.
wa_return_status-status = 2.
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-msgtext = 'No data returned!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.
catch cx_sql_exception into adbc_err.
wa_return_status-status = 2.
concatenate 'SQL error: ' "#EC NOTEXT
adbc_err->sql_message into wa_return_status-msgtext.
append wa_return_status to t_return_status.
continue.
endtry.
else.
wa_return_status-status = 2.
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-msgtext = 'Connection to DB lost!'. "#EC NOTEXT
append wa_return_status to t_return_status.
continue.
endif.
when others.
wa_return_status-status = 2.
wa_return_status-call_id = e_selopt_para-call_id.
wa_return_status-msgtext =

Copyright/Trademark
'KEY_FIGURE ''&1'' not yet implemented!'. "#EC NOTEXT
replace '&1' with <param_range>-low into wa_return_status-msgtext.
append wa_return_status to t_return_status.
continue.
endcase.
endloop. " through call_ids of this db connection
endif.

endloop.

append lines of t_result to result.


append lines of t_return_status to return_status.

endfunction.

Copyright/Trademark

You might also like