Skip to content

Commit

Permalink
add: command line arguments support
Browse files Browse the repository at this point in the history
  • Loading branch information
dvodop committed Oct 9, 2018
1 parent e317a9a commit 0541f37
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 35 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ All notable changes to this project will be documented in this file.

## [unreleased]
### Changed

## [1.0.1] - 2018.10.09
### Changed
- added date to workbook file name
- added dbname to custom charts titles
- fixed bug in DEBUG logging
- added configuration parameters HOST,PORT,SID,SERVICE_NAME as an alternative to TNS_ALIAS
- added reading password from command line, when it not preset in config file
- fixed opening config files with utf-8 encoding
- added command line arguments support

## [1.0.0] - 2018-09-24
###
Expand Down
60 changes: 57 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,58 @@ AWR SQL queries by [MaksimIvanovPerm](https://github.com/MaksimIvanovPerm)
* cx_Oracle 6.3.1
* xlsxwriter 1.0.5

# Usage

** Minimal run with cli arguments:
```
$ python3 oracle-awr-report.py --host test1.exampledomain.loc --service_name testdb1 --general_conf NONE --username cade --report_conf conf.d/report.conf
```
** Run with main configuration file:
```
$ python3 oracle-awr-report.py
```

## Command line arguments
```
$ python oracle-awr-report.py -h
usage: oracle-awr-report.py [-h] [--author AUTHOR] [--begin_snap BEGIN_SNAP]
[--company COMPANY] [--db_name DB_NAME]
[--dbid DBID] [--end_snap END_SNAP]
[--general_conf GENERAL_CONF] [--host HOST]
[--logging LOGGING] [--password PASSWORD]
[--port PORT] [--prefix PREFIX]
[--report_conf REPORT_CONF]
[--service_name SERVICE_NAME] [--sid SID]
[--tnsalias TNS_ALIAS] [--username USERNAME]
optional arguments:
-h, --help show this help message and exit
--author AUTHOR Report Author
--begin_snap BEGIN_SNAP
For AWR: start snap_id
--company COMPANY Report Company
--db_name DB_NAME Database name, printed in report
--dbid DBID For AWR: database dbid
--end_snap END_SNAP For AWR: end snap_id
--general_conf GENERAL_CONF
Path to main configuration file. If set in NONE, don't
use configuration file.
--host HOST Database host address
--logging LOGGING Logging level. Can be one of
DEBUG/INFO/WARNING/ERROR/CRITICAL
--password PASSWORD Database password
--port PORT Database port
--prefix PREFIX Path to report
--report_conf REPORT_CONF
Path to report configration file
--service_name SERVICE_NAME
Database SERVICE_NAME.
--sid SID Database SID. If not set - use service_name
--tnsalias TNS_ALIAS tnslias for db connection. If not set - use host,
port, sid/service_name
--username USERNAME Database username
```

## Main configuration **conf.d/general.conf**
_All config files openes with utf-8 encoding_

Expand All @@ -43,7 +95,7 @@ _All config files openes with utf-8 encoding_
| BEGIN_SNAP | awr begin snap_id | - | +
| END_SNAP | awr end snap_id | - | +
| PREFIX | path to report file | - | -
| DB_NAME | database title | + | -
| DB_NAME | database title | - | -
| AUTHOR | report author | - | -
| COMPANY | report company | - | -
| LOGGING | log level, one of: DEBUG, INFO, WARNING, ERROR, CRITICAL | - | +
Expand All @@ -65,8 +117,8 @@ where chart config file is one of following:

Example:
```
1:RDBMSServiceTime.sql:Database Service Time Stucture:default
2:WaitTimeStructure.sql:Database Wait Time Structure:default
1:RDBMSServiceTime.sql:Стр-ра сервисного времени субд:default
2:WaitTimeStructure.sql:Стр-ра времени ожиданий субд:default
3:RedoStat.sql::conf.d/redostat.conf
```

Expand Down Expand Up @@ -103,3 +155,5 @@ Example:

## Report worksheet example
![DB wait time structure](DOC/oracle-awr-report.png)

Added GPG sing to commits
181 changes: 149 additions & 32 deletions oracle-awr-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import xlsxwriter
import logging
import getpass
import argparse

from datetime import date
from xlsxwriter.utility import xl_rowcol_to_cell
Expand Down Expand Up @@ -131,60 +132,176 @@ def add_chart_to_xlsx(v_d_worksheet_title, v_d_chart_title, v_d_title, v_d_data)


os.environ["NLS_LANG"] = "AMERICAN_AMERICA.AL32UTF8"

# ==================================================================
# parsing of configuration file "general.conf" BEGIN
# parsing of main configuration file
# and command line arguments BEGIN
# ==================================================================
# add command line arguments for argparse
parser = argparse.ArgumentParser()
parser.add_argument('--author',
help='Report Author'
)
parser.add_argument('--begin_snap',
type=int,
help='For AWR: start snap_id'
)
parser.add_argument('--company',
help='Report Company'
)
parser.add_argument('--db_name',
help='Database name, printed in report'
)
parser.add_argument('--dbid',
type=int,
help='For AWR: database dbid'
)
parser.add_argument('--end_snap',
type=int, help='For AWR: end snap_id'
)
parser.add_argument('--general_conf',
help='Path to main configuration file. If set in NONE, don' + "'" + 't use configuration file.'
)
parser.add_argument('--host',
help='Database host address'
)
parser.add_argument('--logging',
help='Logging level. Can be one of DEBUG/INFO/WARNING/ERROR/CRITICAL'
)
parser.add_argument('--password',
help='Database password'
)
parser.add_argument('--port',
type=int, help='Database port'
)
parser.add_argument('--prefix',
help='Path to report'
)
parser.add_argument('--report_conf',
help='Path to report configration file'
)
parser.add_argument('--service_name',
help='Database SERVICE_NAME.'
)
parser.add_argument('--sid',
help='Database SID. If not set - use service_name'
)
parser.add_argument('--tnsalias',
metavar='TNS_ALIAS',
help='tnslias for db connection. If not set - use host, port, sid/service_name'
)
parser.add_argument('--username',
help='Database username'
)

# parse command line arguments
args = parser.parse_args()

# check GENERAL_CONF argument
if args.general_conf:
v_configuration["GENERAL_CONF"] = args.general_conf
else:
v_configuration["GENERAL_CONF"] = "conf.d/general.conf"

# default logging parameters
logging.basicConfig(level=logging.WARNING,
format='%(asctime)s %(levelname)s %(message)s')

try:
# try to open main configuration file
if sys.version_info.major >= 3:
v_config_file = open("conf.d/general.conf", encoding="utf_8")
if sys.version_info.major == 2:
v_config_file = open("conf.d/general.conf")
except OSError as err:
logging.error("OS error: {0}".format(err))
raise
except Exception:
logging.error("Unexpected error:", sys.exc_info()[0])
raise
# for all rows in file
for v_text_string in v_config_file.readlines():
# if row is not empty and don't start from #
if not v_text_string.startswith("\n") and not v_text_string.startswith("#"):
v_parameter_name, v_parameter_value = v_text_string.split('=')
v_configuration[v_parameter_name] = v_parameter_value.replace("\n", "").replace("\"", "")
v_config_file.close()
# if using GENERAL_CONF, open it and parse
if v_configuration.get("GENERAL_CONF") and v_configuration["GENERAL_CONF"] != "NONE":
try:
# try to open main configuration file
if sys.version_info.major >= 3:
v_config_file = open(v_configuration["GENERAL_CONF"], encoding="utf_8")
if sys.version_info.major == 2:
v_config_file = open(v_configuration["GENERAL_CONF"])
except OSError as err:
logging.critical("OS error: {0}".format(err))
raise
except Exception:
logging.critical("Unexpected error:", sys.exc_info()[0])
raise
# for all rows in file
for v_text_string in v_config_file.readlines():
# if row is not empty and don't start from #
if not v_text_string.startswith("\n") and not v_text_string.startswith("#"):
v_parameter_name, v_parameter_value = v_text_string.split('=')
v_configuration[v_parameter_name] = v_parameter_value.replace("\r", "").replace("\n", "").replace("\"", "")

# early-using arguments
if args.logging:
v_configuration["LOGGING"] = args.logging
if args.prefix:
v_configuration["PREFIX"] = args.prefix
if args.password:
v_configuration["PASSWORD"] = args.password

# LOGGING
v_logger = logging.getLogger()
if not v_configuration.get("LOGGING"):
v_log_level = 30
elif v_configuration["LOGGING"] == "DEBUG":
elif v_configuration["LOGGING"].upper() == "DEBUG":
v_log_level = 10
elif v_configuration["LOGGING"] == "INFO":
elif v_configuration["LOGGING"].upper() == "INFO":
v_log_level = 20
elif v_configuration["LOGGING"] == "WARNING":
elif v_configuration["LOGGING"].upper() == "WARNING":
v_log_level = 30
elif v_configuration["LOGGING"] == "ERROR":
elif v_configuration["LOGGING"].upper() == "ERROR":
v_log_level = 40
elif v_configuration["LOGGING"] == "CRITICAL":
elif v_configuration["LOGGING"].upper() == "CRITICAL":
v_log_level = 50
v_logger.setLevel(v_log_level)

if v_configuration.get("PREFIX"):
v_prefix = v_configuration["PREFIX"]

# If we have not password in config file - ask it from command line
# save command line arguments to configuration parameters
if args.author:
v_configuration["AUTHOR"] = args.author
if args.begin_snap:
v_configuration["BEGIN_SNAP"] = args.begin_snap
if args.company:
v_configuration["COMPANY"] = args.company
if args.db_name:
v_configuration["DB_NAME"] = args.db_name
if args.dbid:
v_configuration["DBID"] = args.dbid
if args.end_snap:
v_configuration["END_SNAP"] = args.end_snap
if args.host:
v_configuration["HOST"] = args.host
if args.port:
v_configuration["PORT"] = args.port
if args.report_conf:
v_configuration["REPORT_CONF"] = args.report_conf
if args.service_name:
v_configuration["SERVICE_NAME"] = args.service_name
if args.sid:
v_configuration["SID"] = args.sid
if args.tnsalias:
v_configuration["TNS_ALIAS"] = args.tnsalias
if args.username:
v_configuration["USERNAME"] = args.username

if not v_configuration.get("DB_NAME"):
v_configuration["DB_NAME"] = ""

# check mandatory parameters
if not v_configuration.get("TNS_ALIAS") and not v_configuration.get("HOST") and not (v_configuration.get("SID") or v_configuration.get("SERVICE_NAME")):
v_logger.error("Not set database access parameters! Use TNS_ALIAS or HOST, SID/SERVICE_NAME parameters!")
exit(1)
if not v_configuration.get("USERNAME"):
v_logger.error("Not set database username! Use USERNAME parameter!")
exit(1)
if not v_configuration.get("REPORT_CONF"):
v_logger.error("Not set path to report configuration file. Use REPORT_CONF!")
exit(1)
# If we have not password - ask it from command line
if not v_configuration.get("PASSWORD"):
print("Please, enter password for Database")
v_configuration["PASSWORD"] = getpass.getpass('Password:')

# ==================================================================
# parsing of configuration file "general.conf" END
# parsing of main configuration file
# and command line arguments END
# ==================================================================


Expand Down Expand Up @@ -330,7 +447,7 @@ def add_chart_to_xlsx(v_d_worksheet_title, v_d_chart_title, v_d_title, v_d_data)

for v_line in v_config_file.readlines():
if not v_line.startswith("\n") and not v_line.startswith("#"):
v = v_line.replace("\n", "")
v = v_line.replace("\r", "").replace("\n", "")
v_conf.append(v.split(":"))

v_config_file.close()
Expand Down Expand Up @@ -402,7 +519,7 @@ def add_chart_to_xlsx(v_d_worksheet_title, v_d_chart_title, v_d_title, v_d_data)
# read config
for v_line in v_config_file.readlines():
if not v_line.startswith("\n") and not v_line.startswith("#"):
v_text_string = v_line.replace("\n", "")
v_text_string = v_line.replace("\r", "").replace("\n", "")
v_column_conf.append(v_text_string.split(":"))
v_config_file.close()
v_logger.debug('Successfully read column config file ' + i[4])
Expand Down Expand Up @@ -458,7 +575,7 @@ def add_chart_to_xlsx(v_d_worksheet_title, v_d_chart_title, v_d_title, v_d_data)
# read config
for v_line in v_config_file.readlines():
if not v_line.startswith("\n") and not v_line.startswith("#"):
v_text_string = v_line.replace("\n", "")
v_text_string = v_line.replace("\r", "").replace("\n", "")
v_chart_conf.append(v_text_string.split(":"))
v_config_file.close()
v_logger.debug('Successfully read chart config file ' + i[3])
Expand Down

0 comments on commit 0541f37

Please sign in to comment.