Skip to content

Commit 6418ead

Browse files
rohangujarathiZhankuil
authored and
Namrata Madan
committed
update: logging improvements (aws#901)
Co-authored-by: Zhankui Lu <[email protected]>
1 parent f3b8bb5 commit 6418ead

File tree

7 files changed

+76
-20
lines changed

7 files changed

+76
-20
lines changed

src/sagemaker/remote_function/client.py

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
_CANCELLED = "CANCELLED"
5353
_FINISHED = "FINISHED"
5454

55-
logging_config.basic_config()
5655
logger = logging_config.get_logger()
5756

5857

src/sagemaker/remote_function/invoke_function.py

-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ def _execute_remote_function(sagemaker_session, s3_base_uri, s3_kms_key, run_in_
7878
def main():
7979
"""Entry point for invoke function script"""
8080

81-
logging_config.basic_config()
8281
logger = logging_config.get_logger()
8382

8483
exit_code = SUCCESS_EXIT_CODE

src/sagemaker/remote_function/logging_config.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,25 @@
1414
from __future__ import absolute_import
1515

1616
import logging
17+
import time
18+
19+
20+
class _UTCFormatter(logging.Formatter):
21+
"""Class that overrides the default local time provider in log formatter."""
22+
23+
converter = time.gmtime
1724

1825

1926
def get_logger():
2027
"""Return a logger with the name 'sagemaker'"""
21-
logger = logging.getLogger("sagemaker")
22-
logger.setLevel(logging.INFO)
23-
return logger
24-
28+
sagemaker_logger = logging.getLogger("sagemaker.remote_function")
29+
if len(sagemaker_logger.handlers) == 0:
30+
sagemaker_logger.setLevel(logging.INFO)
31+
handler = logging.StreamHandler()
32+
formatter = _UTCFormatter("%(asctime)s %(name)s %(levelname)-8s %(message)s")
33+
handler.setFormatter(formatter)
34+
sagemaker_logger.addHandler(handler)
35+
# don't stream logs with the root logger handler
36+
sagemaker_logger.propagate = 0
2537

26-
def basic_config():
27-
"""Set logger configuration."""
28-
logging.basicConfig(format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s")
38+
return sagemaker_logger

src/sagemaker/remote_function/runtime_environment/bootstrap_runtime_environment.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
from __future__ import absolute_import
1515

1616
import argparse
17-
import logging
1817
import sys
1918
import os
2019
import shutil
2120
import pathlib
2221

2322
if __package__ is None or __package__ == "":
24-
from runtime_environment_manager import RuntimeEnvironmentManager
23+
from runtime_environment_manager import RuntimeEnvironmentManager, get_logger
2524
else:
2625
from sagemaker.remote_function.runtime_environment.runtime_environment_manager import (
2726
RuntimeEnvironmentManager,
27+
get_logger,
2828
)
2929

3030
SUCCESS_EXIT_CODE = 0
@@ -37,10 +37,7 @@
3737
SAGEMAKER_WHL_CHANNEL = "sagemaker_whl_file"
3838

3939

40-
logging.basicConfig(
41-
format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s", level=logging.INFO
42-
)
43-
logger = logging.getLogger("sagemaker")
40+
logger = get_logger()
4441

4542

4643
def main():

src/sagemaker/remote_function/runtime_environment/runtime_environment_manager.py

+26-5
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,38 @@
1414

1515
from __future__ import absolute_import
1616

17+
1718
import logging
1819
import sys
1920
import shlex
2021
import os
2122
import subprocess
2223
import tempfile
24+
import time
25+
26+
27+
class _UTCFormatter(logging.Formatter):
28+
"""Class that overrides the default local time provider in log formatter."""
29+
30+
converter = time.gmtime
31+
32+
33+
def get_logger():
34+
"""Return a logger with the name 'sagemaker'"""
35+
sagemaker_logger = logging.getLogger("sagemaker.remote_function")
36+
if len(sagemaker_logger.handlers) == 0:
37+
sagemaker_logger.setLevel(logging.INFO)
38+
handler = logging.StreamHandler()
39+
formatter = _UTCFormatter("%(asctime)s %(name)s %(levelname)-8s %(message)s")
40+
handler.setFormatter(formatter)
41+
sagemaker_logger.addHandler(handler)
42+
# don't stream logs with the root logger handler
43+
sagemaker_logger.propagate = 0
44+
45+
return sagemaker_logger
46+
2347

24-
logging.basicConfig(
25-
format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s", level=logging.INFO
26-
)
27-
logger = logging.getLogger("sagemaker")
48+
logger = get_logger()
2849

2950

3051
class RuntimeEnvironmentManager:
@@ -143,7 +164,7 @@ def bootstrap(
143164
"""Bootstraps the runtime environment by installing the additional dependencies if any.
144165
145166
Args:
146-
dependencies_s3_uri (str): S3 URI where dependencies file exists.
167+
local_dependencies_file (str): path where dependencies file exists.
147168
conda_env (str): conda environment to be activated. Default is None.
148169
149170
Returns: None

tests/integ/sagemaker/remote_function/test_decorator.py

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import pytest
1818
import os
19+
import logging
1920
import pandas as pd
2021
from sagemaker.experiments.run import Run, load_run
2122
from tests.integ.sagemaker.experiments.helpers import cleanup_exp_resources
@@ -68,6 +69,7 @@ def test_decorated_function_raises_exception(
6869
sagemaker_session=sagemaker_session,
6970
)
7071
def divide(x, y):
72+
logging.warning(f"{x}/{y}")
7173
return x / y
7274

7375
with pytest.raises(ZeroDivisionError):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
from __future__ import absolute_import
14+
15+
import logging
16+
17+
from sagemaker.remote_function.logging_config import get_logger
18+
19+
20+
def test_logger_config():
21+
logging.basicConfig(level=logging.INFO)
22+
23+
logger_1 = get_logger()
24+
assert len(logger_1.handlers) == 1
25+
26+
logger_2 = get_logger()
27+
assert logger_2 is logger_1
28+
assert len(logger_2.handlers) == 1

0 commit comments

Comments
 (0)