-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #258 from site24x7/mani
sap_business_object monitoring plugin
- Loading branch information
Showing
3 changed files
with
239 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# SAP Business Object Monitoring | ||
## Prerequisites | ||
|
||
- Download and install the latest version of the [Site24x7 Linux agent/Site24x7 Windows agent](https://www.site24x7.com/app/client#/admin/inventory/add-monitor) in the server where you plan to run the plugin. | ||
|
||
### Plugin Installation | ||
|
||
- Create a directory named `sap_business_object`. | ||
|
||
```bash | ||
mkdir sap_business_object | ||
cd sap_business_object/ | ||
``` | ||
- Download below files and place it under the "sap_business_object" directory. | ||
|
||
```bash | ||
wget https://raw.githubusercontent.com/site24x7/plugins/master/sap_business_object/sap_business_object.py && sed -i "1s|^.*|#! $(which python3)|" sap_business_object.py | ||
wget https://raw.githubusercontent.com/site24x7/plugins/master/sap_business_object/sap_business_object.cfg | ||
``` | ||
|
||
- Execute the below command with appropriate arguments to check for the valid json output: | ||
|
||
```bash | ||
python3 sap_business_object.py --host localhost --port 6405 --username Administrator --password Admin123 | ||
``` | ||
|
||
- Provide your sap_business_object configurations in sap_business_object.cfg file. | ||
|
||
```bash | ||
[SAPBO] | ||
host = "localhost" | ||
port = "6405" | ||
username = "Administrator" | ||
password = "Admin123" | ||
``` | ||
|
||
- Since it's a Python plugin, to run the plugin in a Windows server please follow the steps in [this link](https://support.site24x7.com/portal/en/kb/articles/run-python-plugin-scripts-in-windows-servers). The remaining configuration steps are the same. | ||
|
||
### Move the plugin under the Site24x7 agent directory | ||
|
||
#### Linux | ||
|
||
- Move the "sap_business_object" directory under the Site24x7 Linux Agent plugin directory: | ||
|
||
```bash | ||
mv sap_business_object /opt/site24x7/monagent/plugins/ | ||
``` | ||
#### Windows | ||
|
||
- Move the "sap_business_object" directory under the Site24x7 Windows Agent plugin directory: | ||
|
||
``` | ||
C:\Program Files (x86)\Site24x7\WinAgent\monitoring\Plugins\ | ||
``` | ||
The agent will automatically execute the plugin within five minutes and user can see the plugin monitor under Site24x7 > Plugins > Plugin Integrations. | ||
|
||
## SAP Business Object Server Monitoring Plugin Metrics | ||
|
||
| **Metrics** | **Description** | | ||
|--------------------------------------|---------------------------------------------------------------------------------------------------| | ||
| `TotalNoOfServers` | Total number of servers being monitored. | | ||
| `TotalNoOfRunningServers` | Total number of servers currently running. | | ||
| `TotalNoOfStoppedServers` | Total number of servers currently stopped. | | ||
| `TotalNoOfEnabledServers` | Total number of servers that are enabled. | | ||
| `TotalNoOfDisabledServers` | Total number of servers that are disabled. | | ||
| `TotalNoOfUsers` | Total number of users in the system. | | ||
| `TotalNoOfFolders` | Total number of folders in the system. | | ||
| `users` | List of users with their respective `name`, `ownerid`, and `parentid`. | | ||
| `folders` | List of folders with their respective `name`, `folder_id`, and `owner_id`. | | ||
| `servers` | List of servers with their respective `name`, `status`, `server_process_id`, `enabled`, and IDs. | | ||
|
||
|
||
## Sample ScreenShot | ||
|
||
![image](https://github.com/user-attachments/assets/c03a8281-f9ee-4c9b-8b87-2255b6690b4a) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[SAPBO] | ||
host = "localhost" | ||
port = "6405" | ||
username = "Administrator" | ||
password = "Admin123" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import requests | ||
import xml.etree.ElementTree as ET | ||
import json | ||
import argparse | ||
|
||
DEFAULT_PARAMS = { | ||
"plugin_version": 1, | ||
"heartbeat_required": True | ||
} | ||
|
||
def fetch_logon_token(host, port, username, password): | ||
logon_url = f"http://{host}:{port}/biprws/logon/long" | ||
headers = { | ||
"Accept": "application/xml", | ||
"Content-Type": "application/xml" | ||
} | ||
data = f'''<attrs xmlns="http://www.sap.com/rws/bip"> | ||
<attr name="userName" type="string">{username}</attr> | ||
<attr name="password" type="string">{password}</attr> | ||
<attr name="auth" type="string" possibilities="secEnterprise,secLDAP,secWinAD,secSAPR3">secEnterprise</attr> | ||
</attrs>''' | ||
|
||
try: | ||
response = requests.post(logon_url, headers=headers, data=data) | ||
if response.status_code == 200: | ||
root = ET.fromstring(response.text) | ||
logon_token = root.find('.//{http://www.sap.com/rws/bip}attr[@name="logonToken"]') | ||
if logon_token is not None: | ||
return logon_token.text | ||
else: | ||
raise Exception("Logon Token not found in the response.") | ||
else: | ||
raise Exception(f"Failed to log in: {response.status_code}") | ||
except requests.exceptions.RequestException as e: | ||
raise Exception(f"Connection Error: {str(e)}") | ||
|
||
def safe_int(value): | ||
try: | ||
return int(value) | ||
except (ValueError, TypeError): | ||
return None | ||
|
||
def fetch_data(host, port, url_path, logon_token, data_type): | ||
url = f"http://{host}:{port}/{url_path}" | ||
headers = { | ||
"Content-Type": "application/xml", | ||
"Accept": "application/xml", | ||
"X-SAP-LogonToken": logon_token | ||
} | ||
try: | ||
response = requests.get(url, headers=headers) | ||
if response.status_code == 200: | ||
root = ET.fromstring(response.text) | ||
data = [] | ||
namespaces = { | ||
'atom': 'http://www.w3.org/2005/Atom', | ||
'bip': 'http://www.sap.com/rws/bip' | ||
} | ||
for entry in root.findall('.//atom:entry', namespaces): | ||
item_data = {} | ||
attrs = entry.find('.//atom:content/bip:attrs', namespaces) | ||
if attrs is not None: | ||
for attr in attrs.findall('.//bip:attr', namespaces): | ||
name = attr.get("name") | ||
value = attr.text | ||
if data_type == 'users': | ||
if name == "name": | ||
item_data["name"] = value | ||
elif name == "ownerid": | ||
item_data["ownerid"] = value | ||
elif name == "parentid": | ||
item_data["parentid"] = value | ||
elif data_type == 'folders': | ||
if name == "name": | ||
item_data["name"] = value | ||
elif name == "id": | ||
item_data["folder_id"] = safe_int(value) | ||
elif name == "ownerid": | ||
item_data["owner_id"] = value | ||
elif data_type == 'servers': | ||
if name == "kind": | ||
item_data["name"] = value | ||
elif name == "status_type": | ||
item_data["status"] = 1 if value == "Running" else 0 | ||
elif name == "disabled": | ||
item_data["enabled"] = 1 if value == "Enabled" else 0 | ||
elif name == "server_process_id": | ||
item_data["server_process_id"] = safe_int(value) | ||
elif name == "id": | ||
item_data["server_id"] = safe_int(value) | ||
elif name == "parent_id": | ||
item_data["parent_id"] = safe_int(value) | ||
data.append(item_data) | ||
return data | ||
else: | ||
raise Exception(f"Failed to fetch {data_type}: {response.status_code}") | ||
except requests.exceptions.RequestException as e: | ||
raise Exception(f"Connection Error: {str(e)}") | ||
|
||
def fetch_users(host, port, logon_token): | ||
return fetch_data(host, port, "biprws/v1/users", logon_token, 'users') | ||
|
||
def fetch_folders(host, port, logon_token): | ||
return fetch_data(host, port, "biprws/v1/folders", logon_token, 'folders') | ||
|
||
def fetch_servers(host, port, logon_token): | ||
return fetch_data(host, port, "biprws/bionbi/server/list/", logon_token, 'servers') | ||
|
||
def calculate_server_metrics(servers): | ||
metrics = { | ||
"TotalNoOfServers": len(servers), | ||
"TotalNoOfRunningServers": sum(1 for server in servers if server["status"] == 1), | ||
"TotalNoOfStoppedServers": sum(1 for server in servers if server["status"] == 0), | ||
"TotalNoOfEnabledServers": sum(1 for server in servers if server["enabled"] == 1), | ||
"TotalNoOfDisabledServers": sum(1 for server in servers if server["enabled"] == 0) | ||
} | ||
return metrics | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--host', help='SAP BIP host', default='localhost') | ||
parser.add_argument('--port', help='SAP BIP port', default='6405') | ||
parser.add_argument('--username', help='SAP BIP username', default='Administrator') | ||
parser.add_argument('--password', help='SAP BIP password', default='Admin123') | ||
args = parser.parse_args() | ||
|
||
try: | ||
logon_token = fetch_logon_token(args.host, args.port, args.username, args.password) | ||
users = fetch_users(args.host, args.port, logon_token) | ||
folders = fetch_folders(args.host, args.port, logon_token) | ||
servers = fetch_servers(args.host, args.port, logon_token) | ||
|
||
server_metrics = calculate_server_metrics(servers) | ||
total_no_of_users = len(users) | ||
total_no_of_folders = len(folders) | ||
|
||
data = { | ||
**DEFAULT_PARAMS, | ||
**server_metrics, | ||
"TotalNoOfUsers": total_no_of_users, | ||
"TotalNoOfFolders": total_no_of_folders, | ||
"users": users, | ||
"folders": folders, | ||
"servers": servers | ||
} | ||
print(json.dumps(data)) | ||
except Exception as e: | ||
error_response = { | ||
**DEFAULT_PARAMS, | ||
"status": 0, | ||
"msg": str(e) | ||
} | ||
print(json.dumps(error_response)) | ||
|
||
if __name__ == "__main__": | ||
main() |