Skip to content

Commit 753aba7

Browse files
D-39625 New logger and timestamp
* D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger * D-39625 New logger
1 parent 97fbae9 commit 753aba7

10 files changed

Lines changed: 93 additions & 92 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ class Hello(BaseTask):
3535
```
3636

3737
## Documentation
38-
Read more about Digital.ai Release Python SDK [here](https://digital.ai/)
38+
Read more about Digital.ai Release Python SDK [here](https://docs.digital.ai/release/docs/category/python-sdk)

digitalai/release/integration/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
from .output_context import OutputContext
44
from .exceptions import AbortException
55
from .reporting_records import BuildRecord, PlanRecord, ItsmRecord,CodeComplianceRecord, DeploymentRecord
6+
from .logger import dai_logger

digitalai/release/integration/base_task.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@
1010
from .input_context import AutomatedTaskAsUserContext, ReleaseContext
1111
from .output_context import OutputContext
1212
from .exceptions import AbortException
13-
14-
logger = logging.getLogger("Digitalai")
13+
from .logger import dai_logger
1514

1615

1716
class BaseTask(ABC):
1817
"""
1918
An abstract base class representing a task that can be executed.
2019
"""
20+
def __init__(self):
21+
self.task_id = None
22+
self.release_context = None
23+
self.release_server_url = None
24+
self.input_properties = None
25+
self.output_context = None
26+
2127
def execute_task(self) -> None:
2228
"""
2329
Executes the task by calling the execute method. If an AbortException is raised during execution,
@@ -28,12 +34,13 @@ def execute_task(self) -> None:
2834
self.output_context = OutputContext(0, "", {}, [])
2935
self.execute()
3036
except AbortException:
31-
logger.debug("Abort requested")
37+
dai_logger.info("Abort requested")
3238
self.set_exit_code(1)
33-
sys.exit(1)
3439
self.set_error_message("Abort requested")
40+
sys.exit(1)
41+
3542
except Exception as e:
36-
logger.error("Unexpected error occurred.", exc_info=True)
43+
dai_logger.error("Unexpected error occurred.", exc_info=True)
3744
self.set_exit_code(1)
3845
self.set_error_message(str(e))
3946

@@ -104,13 +111,13 @@ def add_comment(self, comment: str) -> None:
104111
"""
105112
Logs a comment of the task.
106113
"""
107-
logger.debug(f"##[start: comment]{comment}##[end: comment]")
114+
dai_logger.debug(f"##[start: comment]{comment}##[end: comment]")
108115

109116
def set_status_line(self, status_line: str) -> None:
110117
"""
111118
Set the status of the task.
112119
"""
113-
logger.debug(f"##[start: status]{status_line}##[end: status]")
120+
dai_logger.debug(f"##[start: status]{status_line}##[end: status]")
114121

115122
def add_reporting_record(self, reporting_record: Any) -> None:
116123
"""

digitalai/release/integration/k8s.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from kubernetes import client, config
44
from kubernetes.client import CoreV1Api
5+
from kubernetes.config.config_exception import ConfigException
6+
from .logger import dai_logger
57

68
kubernetes_client: CoreV1Api = None
79
lock = threading.Lock()
@@ -13,8 +15,20 @@ def get_client():
1315
if not kubernetes_client:
1416
with lock:
1517
if not kubernetes_client:
16-
config.load_config()
18+
try:
19+
#dai_logger.info("Attempting to load in-cluster config")
20+
config.load_incluster_config()
21+
#dai_logger.info("Successfully loaded in-cluster config")
22+
except ConfigException:
23+
#dai_logger.warning("In-cluster config failed, attempting default load_config")
24+
try:
25+
config.load_config()
26+
#dai_logger.info("Successfully loaded config using load_config")
27+
except Exception:
28+
dai_logger.exception("Failed to load any Kubernetes config")
29+
raise RuntimeError("Could not configure Kubernetes client")
1730
kubernetes_client = client.CoreV1Api()
31+
#dai_logger.info("Kubernetes client created successfully")
1832

1933
return kubernetes_client
2034

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import logging
2+
import sys
3+
4+
# Define the log format (with milliseconds) and date format
5+
LOG_FORMAT = "%(asctime)s.%(msecs)03d %(levelname)s [%(filename)s:%(lineno)d] - %(message)s"
6+
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
7+
8+
# Create a formatter
9+
_formatter = logging.Formatter(fmt=LOG_FORMAT, datefmt=DATE_FORMAT)
10+
11+
# Create a stream handler (to stdout) and attach the formatter
12+
_handler = logging.StreamHandler(sys.stdout)
13+
_handler.setFormatter(_formatter)
14+
15+
# Get your “dai” logger
16+
dai_logger = logging.getLogger("digital_ai")
17+
dai_logger.setLevel(logging.DEBUG)
18+
dai_logger.propagate = False
19+
if not dai_logger.handlers:
20+
dai_logger.addHandler(_handler)

digitalai/release/integration/logging_config.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

digitalai/release/integration/watcher.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
1-
import logging
21
import os
32
import threading
43

54
from kubernetes import watch
6-
5+
from .logger import dai_logger
76
from digitalai.release.integration import k8s
87

9-
logger = logging.getLogger("Digitalai")
10-
118

129
def start_input_context_watcher(on_input_context_update_func):
13-
logger.debug("Input context watcher started")
10+
dai_logger.info("Input context watcher started")
1411

1512
stop = threading.Event()
1613

1714
try:
1815
start_input_secret_watcher(on_input_context_update_func, stop)
1916
except Exception:
20-
logger.error("Unexpected error occurred.", exc_info=True)
17+
dai_logger.error("Unexpected error occurred.", exc_info=True)
2118
return
2219

2320
# Wait until the watcher is stopped
2421
stop.wait()
2522

2623

2724
def start_input_secret_watcher(on_input_context_update_func, stop):
28-
logger.debug("Input secret watcher started")
25+
dai_logger.info("Input secret watcher started")
2926

3027
kubernetes_client = k8s.get_client()
3128
field_selector = "metadata.name=" + os.getenv("INPUT_CONTEXT_SECRET")
@@ -39,7 +36,7 @@ def start_input_secret_watcher(on_input_context_update_func, stop):
3936

4037
# Checking if 'session-key' field has changed
4138
if old_session_key and old_session_key != new_session_key:
42-
logger.info("Detected input context value change")
39+
dai_logger.info("Detected input context value change")
4340
on_input_context_update_func()
4441

4542
# Set old session-key value

digitalai/release/integration/wrapper.py

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import base64
55
import importlib
66
import json
7-
import logging.config
87
import os
98
import signal
109
import sys
@@ -17,7 +16,7 @@
1716
from .base_task import BaseTask
1817
from .input_context import InputContext
1918
from .job_data_encryptor import AESJobDataEncryptor, NoOpJobDataEncryptor
20-
from .logging_config import LOGGING_CONFIG
19+
from .logger import dai_logger
2120
from .masked_io import MaskedIO
2221
from .output_context import OutputContext
2322

@@ -51,12 +50,6 @@ def get_encryptor():
5150
return encryptor
5251

5352

54-
# Set up logging
55-
logging.config.dictConfig(LOGGING_CONFIG)
56-
57-
# Get the logger
58-
logger = logging.getLogger("Digitalai")
59-
6053
# Initialize the global task object
6154
dai_task_object: BaseTask = None
6255

@@ -66,13 +59,13 @@ def abort_handler(signum, frame):
6659
This function handles the abort request by calling the abort method on the global task object, if it exists.
6760
If the task object does not exist, it logs a message and exits with a status code of 1.
6861
"""
69-
logger.debug("Received SIGTERM to gracefully stop the process")
62+
dai_logger.info("Received SIGTERM to gracefully stop the process")
7063
global dai_task_object
7164

7265
if dai_task_object:
7366
dai_task_object.abort()
7467
else:
75-
logger.debug("Abort requested")
68+
dai_logger.info("Abort requested")
7669
sys.exit(1)
7770

7871

@@ -86,15 +79,17 @@ def get_task_details():
8679
and parsing the JSON data into an InputContext object. Then, set the secrets for the masked standard output
8780
and error streams, build the task properties from the InputContext object.
8881
"""
89-
logger.debug("Preparing for task properties.")
82+
dai_logger.info("Preparing for task properties")
9083
if input_context_file:
91-
logger.debug("Reading input context from file")
84+
dai_logger.info("Reading input context from file")
9285
with open(input_context_file) as data_input:
9386
input_content = data_input.read()
87+
#dai_logger.info("Successfully loaded input context from file")
9488
else:
95-
logger.debug("Reading input context from secret")
96-
secret = k8s.get_client().read_namespaced_secret(input_context_secret, runner_namespace)
97-
89+
k8s_client = k8s.get_client()
90+
dai_logger.info("Reading input context from secret")
91+
secret =k8s_client.read_namespaced_secret(input_context_secret, runner_namespace)
92+
#dai_logger.info("Successfully loaded input context from secret")
9893
global base64_session_key, callback_url
9994
base64_session_key = base64.b64decode(secret.data["session-key"])
10095
callback_url = base64.b64decode(secret.data["url"])
@@ -111,7 +106,7 @@ def get_task_details():
111106
response = requests.get(fetch_url)
112107
response.raise_for_status()
113108
except requests.exceptions.RequestException as e:
114-
logger.error("Failed to fetch data.", exc_info=True)
109+
dai_logger.error("Failed to fetch data.", exc_info=True)
115110
raise e
116111

117112
if response.status_code != 200:
@@ -122,6 +117,7 @@ def get_task_details():
122117
input_content = base64.b64decode(input_content)
123118

124119
decrypted_json = get_encryptor().decrypt(input_content)
120+
#dai_logger.info("Successfully decrypted input context")
125121
global input_context
126122
input_context = InputContext.from_dict(json.loads(decrypted_json))
127123

@@ -140,39 +136,38 @@ def update_output_context(output_context: OutputContext):
140136
dictionary to a JSON string, encrypting the string using the encryptor, and writing the encrypted string
141137
to the output context file or secret and pushing to callback URL.
142138
"""
143-
logger.debug("Creating output context file")
144139
output_content = json.dumps(output_context.to_dict())
145140
encrypted_json = get_encryptor().encrypt(output_content)
146141
try:
147142
if output_context_file:
148-
logger.debug("Writing output context to file")
143+
dai_logger.info("Writing output context to file")
149144
with open(output_context_file, "w") as data_output:
150145
data_output.write(encrypted_json)
151146
if result_secret_key:
152-
logger.debug("Writing output context to secret")
147+
dai_logger.info("Writing output context to secret")
153148
if len(encrypted_json) >= size_of_1Mb:
154-
logger.warning("Result size exceeds 1Mb and is too big to store in secret")
149+
dai_logger.warning("Result size exceeds 1Mb and is too big to store in secret")
155150
else:
156151
namespace, name, key = k8s.split_secret_resource_data(result_secret_key)
157152
secret = k8s.get_client().read_namespaced_secret(name, namespace)
158153
secret.data[key] = encrypted_json
159154
k8s.get_client().replace_namespaced_secret(name, namespace, secret)
160155
if callback_url:
161-
logger.debug("Pushing result using HTTP")
156+
dai_logger.info("Pushing result using HTTP")
162157
url = base64.b64decode(callback_url).decode("UTF-8")
163158
try:
164159
urllib3.PoolManager().request("POST", url, headers={'Content-Type': 'application/json'},
165160
body=encrypted_json)
166161
except Exception:
167162
if should_retry_callback_request(encrypted_json):
168-
logger.error("Cannot finish Callback request.", exc_info=True)
169-
logger.info("Retry flag was set on Callback request, retrying until successful...")
163+
dai_logger.error("Cannot finish Callback request.", exc_info=True)
164+
dai_logger.info("Retry flag was set on Callback request, retrying until successful...")
170165
retry_push_result_infinitely(encrypted_json)
171166
else:
172167
raise
173168

174169
except Exception:
175-
logger.error("Unexpected error occurred.", exc_info=True)
170+
dai_logger.error("Unexpected error occurred.", exc_info=True)
176171

177172

178173
def retry_push_result_infinitely(encrypted_json):
@@ -197,7 +192,7 @@ def retry_push_result_infinitely(encrypted_json):
197192
response = urllib3.PoolManager().request("POST", url, headers={'Content-Type': 'application/json'}, body=encrypted_json)
198193
return response
199194
except Exception as e:
200-
logger.warning(f"Cannot finish retried Callback request: {e}. Retrying in {retry_delay} seconds...")
195+
dai_logger.warning(f"Cannot finish retried Callback request: {e}. Retrying in {retry_delay} seconds...")
201196
time.sleep(retry_delay)
202197
retry_delay = min(retry_delay * backoff_factor, max_backoff)
203198

@@ -216,13 +211,13 @@ def execute_task(task_object: BaseTask):
216211
If an exception is raised during execution, log the error. Finally, update the output context file
217212
using the output context of the task object.
218213
"""
214+
global dai_task_object
219215
try:
220-
global dai_task_object
221216
dai_task_object = task_object
222-
logger.debug("Starting task execution")
217+
dai_logger.info("Starting task execution")
223218
dai_task_object.execute_task()
224219
except Exception:
225-
logger.error("Unexpected error occurred.", exc_info=True)
220+
dai_logger.error("Unexpected error occurred.", exc_info=True)
226221
finally:
227222
update_output_context(dai_task_object.get_output_context())
228223

@@ -261,7 +256,7 @@ def run():
261256
execute_task(task_obj)
262257
except Exception as e:
263258
# Log the error and update the output context file with exit code 1 if an exception is raised
264-
logger.error("Unexpected error occurred.", exc_info=True)
259+
dai_logger.error("Unexpected error occurred.", exc_info=True)
265260
update_output_context(OutputContext(1, str(e), {}, []))
266261
finally:
267262
if execution_mode == "daemon":

0 commit comments

Comments
 (0)