Skip to content

Commit

Permalink
Adding logger modules
Browse files Browse the repository at this point in the history
Signed-off-by: Peizhao Mei <[email protected]>
  • Loading branch information
pem70 committed May 23, 2024
1 parent c2f6b65 commit cc36dba
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 14 deletions.
10 changes: 9 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,13 @@
"python.testing.pytestArgs": ["tests"],
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
"rust-analyzer.linkedProjects": ["./src/secrets/Cargo.toml"],
"rust-analyzer.linkedProjects": [
"./src/secrets/Cargo.toml"
],
"python.analysis.extraPaths": [
"./src/core",
"./src/zos_console",
"./src/zos_files",
"./src/zos_jobs"
],
}
15 changes: 15 additions & 0 deletions src/core/zowe/core_for_zowe_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,18 @@
from .session import Session
from .session_constants import *
from .zosmf_profile import ZosmfProfile

import logging
import os

dirname = os.path.join(os.path.expanduser("~"), ".zowe/logs")

if not os.path.isdir(dirname):
os.makedirs(dirname)

logging.basicConfig(
filename=os.path.join(dirname, "python_sdk_logs.log"),
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%m/%d/%Y %I:%M:%S %p",
)
19 changes: 16 additions & 3 deletions src/core/zowe/core_for_zowe_sdk/config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import commentjson
import requests

import logging

from .credential_manager import CredentialManager
from .custom_warnings import ProfileNotFoundWarning, ProfileParsingWarning
from .exceptions import ProfileNotFound
Expand Down Expand Up @@ -71,6 +73,8 @@ class ConfigFile:
jsonc: Optional[dict] = None
_missing_secure_props: list = field(default_factory=list)

__logger = logging.getLogger(__name__)

@property
def filename(self) -> str:
if self.type == TEAM_CONFIG:
Expand Down Expand Up @@ -101,11 +105,13 @@ def location(self, dirname: str) -> None:
if os.path.isdir(dirname):
self._location = dirname
else:
self.__logger.error(f"given path {dirname} is not valid")
raise FileNotFoundError(f"given path {dirname} is not valid")

def init_from_file(
self,
validate_schema: Optional[bool] = True,
suppress_config_file_warnings: Optional[bool] = True,
) -> None:
"""
Initializes the class variable after
Expand All @@ -118,7 +124,9 @@ def init_from_file(
pass

if self.filepath is None or not os.path.isfile(self.filepath):
warnings.warn(f"Config file does not exist at {self.filepath}")
if not suppress_config_file_warnings:
self.__logger.warning(f"Config file does not exist at {self.filepath}")
warnings.warn(f"Config file does not exist at {self.filepath}")

Check warning on line 129 in src/core/zowe/core_for_zowe_sdk/config_file.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/config_file.py#L128-L129

Added lines #L128 - L129 were not covered by tests
return

with open(self.filepath, encoding="UTF-8", mode="r") as fileobj:
Expand Down Expand Up @@ -148,7 +156,8 @@ def validate_schema(self) -> None:

path_schema_json = self.schema_path
if path_schema_json is None: # check if the $schema property is not defined
warnings.warn(f"$schema property could not found")
self.__logger.warning(f"Could not find $schema property")
warnings.warn(f"Could not find $schema property")

Check warning on line 160 in src/core/zowe/core_for_zowe_sdk/config_file.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/config_file.py#L159-L160

Added lines #L159 - L160 were not covered by tests

# validate the $schema property
if path_schema_json:
Expand Down Expand Up @@ -213,6 +222,7 @@ def get_profile(
self.init_from_file(validate_schema)

if profile_name is None and profile_type is None:
self.__logger.error(f"Failed to load profile '{profile_name}' because Could not find profile as both profile_name and profile_type is not set")

Check warning on line 225 in src/core/zowe/core_for_zowe_sdk/config_file.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/config_file.py#L225

Added line #L225 was not covered by tests
raise ProfileNotFound(
profile_name=profile_name,
error_msg="Could not find profile as both profile_name and profile_type is not set.",
Expand Down Expand Up @@ -250,7 +260,6 @@ def autodiscover_config_dir(self) -> None:
break

current_dir = os.path.dirname(current_dir)

raise FileNotFoundError(f"Could not find the file {self.filename}")

def get_profilename_from_profiletype(self, profile_type: str) -> str:
Expand All @@ -268,6 +277,7 @@ def get_profilename_from_profiletype(self, profile_type: str) -> str:
try:
profilename = self.defaults[profile_type]
except KeyError:
self.__logger.warn(f"Given profile type '{profile_type}' has no default profilename")

Check warning on line 280 in src/core/zowe/core_for_zowe_sdk/config_file.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/config_file.py#L280

Added line #L280 was not covered by tests
warnings.warn(
f"Given profile type '{profile_type}' has no default profilename",
ProfileParsingWarning,
Expand All @@ -282,12 +292,14 @@ def get_profilename_from_profiletype(self, profile_type: str) -> str:
if profile_type == temp_profile_type:
return key
except KeyError:
self.__logger.warning(f"Profile '{key}' has no type attribute")

Check warning on line 295 in src/core/zowe/core_for_zowe_sdk/config_file.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/config_file.py#L295

Added line #L295 was not covered by tests
warnings.warn(
f"Profile '{key}' has no type attribute",
ProfileParsingWarning,
)

# if no profile with matching type found, we raise an exception
self.__logger.error(f"No profile with matching profile_type '{profile_type}' found")

Check warning on line 302 in src/core/zowe/core_for_zowe_sdk/config_file.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/config_file.py#L302

Added line #L302 was not covered by tests
raise ProfileNotFound(
profile_name=profile_type,
error_msg=f"No profile with matching profile_type '{profile_type}' found",
Expand Down Expand Up @@ -334,6 +346,7 @@ def load_profile_properties(self, profile_name: str) -> dict:
props = {**profile.get("properties", {}), **props}
secure_fields.extend(profile.get("secure", []))
else:
self.__logger.warning(f"Profile {profile_name} not found")
warnings.warn(f"Profile {profile_name} not found", ProfileNotFoundWarning)
lst.pop()

Expand Down
5 changes: 5 additions & 0 deletions src/core/zowe/core_for_zowe_sdk/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
Copyright Contributors to the Zowe Project.
"""

from .exceptions import MissingConnectionArgs
import logging


class ApiConnection:
Expand All @@ -28,8 +30,11 @@ class ApiConnection:
"""

def __init__(self, host_url, user, password, ssl_verification=True):
logger = logging.getLogger(__name__)

"""Construct an ApiConnection object."""
if not host_url or not user or not password:
logger.error("Missing connection argument")
raise MissingConnectionArgs()

self.host_url = host_url
Expand Down
9 changes: 8 additions & 1 deletion src/core/zowe/core_for_zowe_sdk/credential_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
Copyright Contributors to the Zowe Project.
"""

import base64
import sys
from typing import Optional

import commentjson

import logging

from .constants import constants
from .exceptions import SecureProfileLoadFailed

Expand All @@ -27,6 +30,7 @@

class CredentialManager:
secure_props = {}
__logger = logging.getLogger(__name__)

@staticmethod
def load_secure_props() -> None:
Expand All @@ -49,6 +53,7 @@ def load_secure_props() -> None:
return

except Exception as exc:
CredentialManager.__logger.error(f"Fail to load secure profile {constants["ZoweServiceName"]}")
raise SecureProfileLoadFailed(constants["ZoweServiceName"], error_msg=str(exc)) from exc

secure_config: str
Expand All @@ -75,7 +80,9 @@ def save_secure_props() -> None:
if sys.platform == "win32":
# Delete the existing credential
CredentialManager._delete_credential(constants["ZoweServiceName"], constants["ZoweAccountName"])
CredentialManager._set_credential(constants["ZoweServiceName"], constants["ZoweAccountName"], encoded_credential)
CredentialManager._set_credential(
constants["ZoweServiceName"], constants["ZoweAccountName"], encoded_credential
)

@staticmethod
def _get_credential(service_name: str, account_name: str) -> Optional[str]:
Expand Down
15 changes: 13 additions & 2 deletions src/core/zowe/core_for_zowe_sdk/profile_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import warnings
from copy import deepcopy
from typing import Optional
import logging

import jsonschema
from deepmerge import always_merger
Expand Down Expand Up @@ -57,10 +58,13 @@ def __init__(self, appname: str = "zowe", show_warnings: bool = True):
self.project_config = ConfigFile(type=TEAM_CONFIG, name=appname)
self.project_user_config = ConfigFile(type=USER_CONFIG, name=appname)

self.__logger = logging.getLogger(__name__)

self.global_config = ConfigFile(type=TEAM_CONFIG, name=GLOBAL_CONFIG_NAME)
try:
self.global_config.location = GLOBAL_CONFIG_LOCATION
except Exception:
self.__logger.warning("Could not find Global Config Directory")
warnings.warn(
"Could not find Global Config Directory, please provide one.",
ConfigNotFoundWarning,
Expand All @@ -70,6 +74,7 @@ def __init__(self, appname: str = "zowe", show_warnings: bool = True):
try:
self.global_user_config.location = GLOBAL_CONFIG_LOCATION
except Exception:
self.__logger.warning("Could not find Global User Config Directory")
warnings.warn(
"Could not find Global User Config Directory, please provide one.",
ConfigNotFoundWarning,
Expand Down Expand Up @@ -218,6 +223,7 @@ def load(
check_missing_props: bool = True,
validate_schema: Optional[bool] = True,
override_with_env: Optional[bool] = False,
suppress_config_file_warnings: Optional[bool] = True,
) -> dict:
"""Load connection details from a team config profile.
Returns
Expand All @@ -236,7 +242,9 @@ def load(
If `profile_type` is not base, then we will load properties from both
`profile_type` and base profiles and merge them together.
"""

if profile_name is None and profile_type is None:
self.__logger.error(f"Failed to load profile as both profile_name and profile_type are not set")

Check warning on line 247 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L247

Added line #L247 was not covered by tests
raise ProfileNotFound(
profile_name=profile_name,
error_msg="Could not find profile as both profile_name and profile_type is not set.",
Expand All @@ -254,12 +262,13 @@ def load(
cfg_name = None
cfg_schema = None
cfg_schema_dir = None

for cfg_layer in (self.project_user_config, self.project_config, self.global_user_config, self.global_config):
if cfg_layer.profiles is None:
try:
cfg_layer.init_from_file(validate_schema)
cfg_layer.init_from_file(validate_schema, suppress_config_file_warnings)
except SecureProfileLoadFailed:
self.__logger.warning(f"Could not load secure properties for {cfg_layer.filepath}")
warnings.warn(
f"Could not load secure properties for {cfg_layer.filepath}",
SecurePropsNotFoundWarning,
Expand Down Expand Up @@ -314,6 +323,7 @@ def load(
missing_props.add(item)

if len(missing_props) > 0:
self.__logger.error(f"Failed to load secure values: {missing_props}")

Check warning on line 326 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L326

Added line #L326 was not covered by tests
raise SecureValuesNotFound(values=missing_props)

warnings.resetwarnings()
Expand Down Expand Up @@ -366,6 +376,7 @@ def get_highest_priority_layer(self, json_path: str) -> Optional[ConfigFile]:
highest_layer = layer

if highest_layer is None:
self.__logger.error(f"Could not find a valid layer for {json_path}")

Check warning on line 379 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L379

Added line #L379 was not covered by tests
raise FileNotFoundError(f"Could not find a valid layer for {json_path}")

return highest_layer
Expand Down
5 changes: 5 additions & 0 deletions src/core/zowe/core_for_zowe_sdk/request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import requests
import urllib3
import logging

from .exceptions import InvalidRequestMethod, RequestFailed, UnexpectedStatus

Expand Down Expand Up @@ -40,6 +41,7 @@ def __init__(self, session_arguments):
self.session_arguments = session_arguments
self.valid_methods = ["GET", "POST", "PUT", "DELETE"]
self.__handle_ssl_warnings()
self.__logger = logging.getLogger(__name__)

def __handle_ssl_warnings(self):
"""Turn off warnings if the SSL verification argument if off."""
Expand Down Expand Up @@ -104,6 +106,7 @@ def __validate_method(self):
If the input request method is not supported
"""
if self.method not in self.valid_methods:
self.__logger.error(f"Invalid HTTP method input {self.method}")

Check warning on line 109 in src/core/zowe/core_for_zowe_sdk/request_handler.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/request_handler.py#L109

Added line #L109 was not covered by tests
raise InvalidRequestMethod(self.method)

def __send_request(self, stream=False):
Expand All @@ -126,12 +129,14 @@ def __validate_response(self):
# Automatically checks if status code is between 200 and 400
if self.response:
if self.response.status_code not in self.expected_code:
self.__logger.error(f"The status code from z/OSMF was: {self.expected_code}\nExpected: {self.response.status_code}\nRequest output:{self.response.text}")

Check warning on line 132 in src/core/zowe/core_for_zowe_sdk/request_handler.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/request_handler.py#L132

Added line #L132 was not covered by tests
raise UnexpectedStatus(self.expected_code, self.response.status_code, self.response.text)
else:
output_str = str(self.response.request.url)
output_str += "\n" + str(self.response.request.headers)
output_str += "\n" + str(self.response.request.body)
output_str += "\n" + str(self.response.text)
self.__logger.error(f"HTTP Request has failed with status code {self.response.status_code}. \n {output_str}")

Check warning on line 139 in src/core/zowe/core_for_zowe_sdk/request_handler.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/request_handler.py#L139

Added line #L139 was not covered by tests
raise RequestFailed(self.response.status_code, output_str)

def __normalize_response(self):
Expand Down
4 changes: 4 additions & 0 deletions src/core/zowe/core_for_zowe_sdk/sdk_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"""

import urllib
import logging

from . import session_constants
from .exceptions import UnsupportedAuthType
Expand All @@ -28,6 +29,8 @@ def __init__(self, profile, default_url):
session = Session(profile)
self.session: ISession = session.load()

self.logger = logging.getLogger(__name__)

self.default_service_url = default_url
self.default_headers = {
"Content-Type": "application/json",
Expand All @@ -53,6 +56,7 @@ def __init__(self, profile, default_url):
elif self.session.type == session_constants.AUTH_TYPE_TOKEN:
self.default_headers["Cookie"] = f"{self.session.tokenType}={self.session.tokenValue}"
else:
self.logger.error("Unsupported authorization type")

Check warning on line 59 in src/core/zowe/core_for_zowe_sdk/sdk_api.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/sdk_api.py#L59

Added line #L59 was not covered by tests
raise UnsupportedAuthType(self.session.type)

def _create_custom_request_arguments(self):
Expand Down
5 changes: 5 additions & 0 deletions src/core/zowe/core_for_zowe_sdk/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from . import session_constants

import logging

@dataclass
class ISession:
Expand Down Expand Up @@ -42,9 +43,12 @@ class Session:

def __init__(self, props: dict) -> None:
# set host and port
self.__logger = logging.getLogger(__name__)

if props.get("host") is not None:
self.session: ISession = ISession(host=props.get("host"))
else:
self.__logger.error("Host not supplied")

Check warning on line 51 in src/core/zowe/core_for_zowe_sdk/session.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/session.py#L51

Added line #L51 was not covered by tests
raise Exception("Host must be supplied")

# determine authentication type
Expand All @@ -61,6 +65,7 @@ def __init__(self, props: dict) -> None:
self.session.tokenValue = props.get("tokenValue")
self.session.type = session_constants.AUTH_TYPE_BEARER
else:
self.__logger.error("Authentication method not supplied")

Check warning on line 68 in src/core/zowe/core_for_zowe_sdk/session.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/session.py#L68

Added line #L68 was not covered by tests
raise Exception("An authentication method must be supplied")

# set additional parameters
Expand Down
Loading

0 comments on commit cc36dba

Please sign in to comment.