cloe-logging 0.3.9__py3-none-any.whl → 0.3.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloe_logging/formatters/devops_formatter.py +2 -2
- cloe_logging/handlers/log_analytics_handler.py +10 -2
- cloe_logging/handlers/snowflake_handler.py +10 -2
- cloe_logging/handlers/unity_catalog_handler.py +16 -6
- cloe_logging/logger_factory.py +9 -5
- {cloe_logging-0.3.9.dist-info → cloe_logging-0.3.11.dist-info}/METADATA +2 -2
- {cloe_logging-0.3.9.dist-info → cloe_logging-0.3.11.dist-info}/RECORD +8 -8
- {cloe_logging-0.3.9.dist-info → cloe_logging-0.3.11.dist-info}/WHEEL +1 -1
|
@@ -9,8 +9,8 @@ class DevOpsFormatter(logging.Formatter):
|
|
|
9
9
|
info_format = "%(message)s" # "%(name)s -- %(message)s"
|
|
10
10
|
section_format = "%(name)s -- %(message)s"
|
|
11
11
|
|
|
12
|
-
def __init__(self, fmt="%(levelno)s: %(msg)s", section_info=False):
|
|
13
|
-
super().__init__(fmt=fmt)
|
|
12
|
+
def __init__(self, fmt="%(levelno)s: %(msg)s", datefmt=None, section_info=False):
|
|
13
|
+
super().__init__(fmt=fmt, datefmt=datefmt)
|
|
14
14
|
self._section_info = section_info
|
|
15
15
|
|
|
16
16
|
def parse_progress(self, message: str) -> str:
|
|
@@ -7,9 +7,11 @@ from datetime import UTC, datetime
|
|
|
7
7
|
|
|
8
8
|
try:
|
|
9
9
|
import requests
|
|
10
|
+
|
|
11
|
+
_REQUESTS_AVAILABLE = True
|
|
10
12
|
except ImportError:
|
|
11
13
|
requests = None # type: ignore
|
|
12
|
-
|
|
14
|
+
_REQUESTS_AVAILABLE = False
|
|
13
15
|
|
|
14
16
|
from cloe_logging.utility.serializer import create_logserializer
|
|
15
17
|
|
|
@@ -37,6 +39,7 @@ class LogAnalyticsHandler(logging.Handler):
|
|
|
37
39
|
test_connectivity: bool = True,
|
|
38
40
|
column_split_char: str = "|",
|
|
39
41
|
key_value_split_char: str = ":",
|
|
42
|
+
datefmt: str | None = None,
|
|
40
43
|
**kwargs, # noqa: ARG002 required to work with the Factory
|
|
41
44
|
):
|
|
42
45
|
"""Initializes a new instance of the LogAnalyticsHandler class.
|
|
@@ -48,6 +51,7 @@ class LogAnalyticsHandler(logging.Handler):
|
|
|
48
51
|
column_split_char (str, optional): The character used to split columns in the log message. Defaults to "|".
|
|
49
52
|
key_value_split_char (str, optional): The character used to split keys and values in the log message.
|
|
50
53
|
Defaults to ":".
|
|
54
|
+
datefmt (str, optional): The format of the date/time in log messages. If None, uses the default format.
|
|
51
55
|
test_connectivity (bool, optional): Whether to test connectivity to Azure Log Analytics when initializing
|
|
52
56
|
the handler. Defaults to True.
|
|
53
57
|
"""
|
|
@@ -60,9 +64,13 @@ class LogAnalyticsHandler(logging.Handler):
|
|
|
60
64
|
raise ValueError(
|
|
61
65
|
"The workspace_id, shared_key, and log_type must be provided or set as environment variables."
|
|
62
66
|
)
|
|
67
|
+
if not _REQUESTS_AVAILABLE:
|
|
68
|
+
raise ImportError(
|
|
69
|
+
"Requests library is not installed. Install it with: pip install cloe-logging[log-analytics]"
|
|
70
|
+
)
|
|
63
71
|
logging.Handler.__init__(self)
|
|
64
72
|
self.session = requests.Session()
|
|
65
|
-
formatter = logging.Formatter("timestamp:%(asctime)s | level: %(levelname)-8s | %(message)s")
|
|
73
|
+
formatter = logging.Formatter("timestamp:%(asctime)s | level: %(levelname)-8s | %(message)s", datefmt=datefmt)
|
|
66
74
|
self.setFormatter(formatter)
|
|
67
75
|
self.serializer = create_logserializer()
|
|
68
76
|
self.serializer.column_split_char = self.column_split_char
|
|
@@ -6,10 +6,12 @@ try:
|
|
|
6
6
|
ConnectionParameters,
|
|
7
7
|
)
|
|
8
8
|
from cloe_util_snowflake_connector.snowflake_interface import SnowflakeInterface # type: ignore[import-not-found]
|
|
9
|
+
|
|
10
|
+
_SNOWFLAKE_AVAILABLE = True
|
|
9
11
|
except ImportError:
|
|
10
12
|
ConnectionParameters = None # type: ignore
|
|
11
13
|
SnowflakeInterface = None # type: ignore
|
|
12
|
-
|
|
14
|
+
_SNOWFLAKE_AVAILABLE = False
|
|
13
15
|
from cloe_logging.utility.serializer import create_logserializer
|
|
14
16
|
|
|
15
17
|
|
|
@@ -26,6 +28,7 @@ class SnowflakeHandler(logging.Handler):
|
|
|
26
28
|
target_table: str = "",
|
|
27
29
|
column_split_char: str = "|",
|
|
28
30
|
key_value_split_char: str = ":",
|
|
31
|
+
datefmt: str | None = None,
|
|
29
32
|
**kwargs, # noqa: ARG002 required to work with the Factory
|
|
30
33
|
):
|
|
31
34
|
"""Initializes a new instance of the SnowflakeHandler class.
|
|
@@ -37,6 +40,7 @@ class SnowflakeHandler(logging.Handler):
|
|
|
37
40
|
column_split_char (str, optional): The character used to split columns in the log message. Defaults to "|".
|
|
38
41
|
key_value_split_char (str, optional): The character used to split keys and values in the log message.
|
|
39
42
|
Defaults to ":".
|
|
43
|
+
datefmt (str, optional): The format of the date/time in log messages. If None, uses the default format.
|
|
40
44
|
"""
|
|
41
45
|
self.column_split_char: str = column_split_char
|
|
42
46
|
self.key_value_split_char: str = key_value_split_char
|
|
@@ -45,7 +49,7 @@ class SnowflakeHandler(logging.Handler):
|
|
|
45
49
|
self.target_table: str = os.environ.get("CLOE_SNOWFLAKE_TABLE", target_table)
|
|
46
50
|
logging.Handler.__init__(self)
|
|
47
51
|
self.connection = self._get_snowflake_connection()
|
|
48
|
-
formatter = logging.Formatter("timestamp:%(asctime)s | level: %(levelname)-8s | %(message)s")
|
|
52
|
+
formatter = logging.Formatter("timestamp:%(asctime)s | level: %(levelname)-8s | %(message)s", datefmt=datefmt)
|
|
49
53
|
self.setFormatter(formatter)
|
|
50
54
|
self.serializer = create_logserializer()
|
|
51
55
|
|
|
@@ -80,6 +84,10 @@ class SnowflakeHandler(logging.Handler):
|
|
|
80
84
|
return hash((self.target_db, self.target_schema, self.target_table))
|
|
81
85
|
|
|
82
86
|
def _get_snowflake_connection(self) -> SnowflakeInterface:
|
|
87
|
+
if not _SNOWFLAKE_AVAILABLE:
|
|
88
|
+
raise ImportError(
|
|
89
|
+
"Snowflake dependencies are not installed. Install them with: pip install cloe-logging[snowflake]"
|
|
90
|
+
)
|
|
83
91
|
conn_params = ConnectionParameters.init_from_env_variables()
|
|
84
92
|
return SnowflakeInterface(conn_params)
|
|
85
93
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
-
from typing import cast
|
|
3
|
+
from typing import TYPE_CHECKING, cast
|
|
4
4
|
|
|
5
5
|
try:
|
|
6
6
|
from databricks.sdk import WorkspaceClient # type: ignore[import-not-found]
|
|
7
7
|
from databricks.sdk.service.sql import ExecuteStatementRequestOnWaitTimeout # type: ignore[import-not-found]
|
|
8
|
+
|
|
9
|
+
_DATABRICKS_AVAILABLE = True
|
|
8
10
|
except ImportError:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
_DATABRICKS_AVAILABLE = False
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from databricks.sdk import WorkspaceClient # type: ignore[import-not-found]
|
|
12
15
|
|
|
13
16
|
from ..formatters import DictFormatter
|
|
14
17
|
|
|
@@ -29,7 +32,8 @@ class UnityCatalogHandler(logging.Handler):
|
|
|
29
32
|
warehouse_id: str | None = None,
|
|
30
33
|
column_split_char: str = "|",
|
|
31
34
|
key_value_split_char: str = ":",
|
|
32
|
-
|
|
35
|
+
datefmt: str | None = None,
|
|
36
|
+
workspace_client: "WorkspaceClient | None" = None,
|
|
33
37
|
formatter: DictFormatter | None = None,
|
|
34
38
|
**kwargs, # required to work with the Factory
|
|
35
39
|
):
|
|
@@ -48,6 +52,7 @@ class UnityCatalogHandler(logging.Handler):
|
|
|
48
52
|
warehouse_id: The ID of the Databricks warehouse.
|
|
49
53
|
column_split_char: The character used to split columns in the log message. Defaults to "|".
|
|
50
54
|
key_value_split_char: The character used to split keys and values in the log message. Defaults to ":".
|
|
55
|
+
datefmt: The format of the date/time in log messages. If None, uses the default format.
|
|
51
56
|
workspace_client: An instance of WorkspaceClient for dependency injection.
|
|
52
57
|
formatter: An instance of DictFormatter for dependency injection.
|
|
53
58
|
"""
|
|
@@ -64,10 +69,15 @@ class UnityCatalogHandler(logging.Handler):
|
|
|
64
69
|
" schema, and table to create a DatabricksHandler."
|
|
65
70
|
)
|
|
66
71
|
self.table_identifier = f"{self.catalog}.{self.schema}.{self.table}"
|
|
72
|
+
if not _DATABRICKS_AVAILABLE:
|
|
73
|
+
raise ImportError("Databricks SDK is not installed. Install it with: pip install cloe-logging[databricks]")
|
|
67
74
|
self.workspace_client = workspace_client or WorkspaceClient(host=self.workspace_url)
|
|
68
75
|
super().__init__(**kwargs)
|
|
69
76
|
self.setFormatter(
|
|
70
|
-
formatter
|
|
77
|
+
formatter
|
|
78
|
+
or DictFormatter(
|
|
79
|
+
column_split_char=column_split_char, key_value_split_char=key_value_split_char, datefmt=datefmt
|
|
80
|
+
)
|
|
71
81
|
)
|
|
72
82
|
self.ensure_table_exists(columns)
|
|
73
83
|
|
cloe_logging/logger_factory.py
CHANGED
|
@@ -15,6 +15,7 @@ class LoggerFactory:
|
|
|
15
15
|
logger_name: str = __name__,
|
|
16
16
|
logging_level: int = logging.INFO,
|
|
17
17
|
log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
18
|
+
datefmt: str | None = None,
|
|
18
19
|
**kwargs,
|
|
19
20
|
) -> logging.Logger:
|
|
20
21
|
"""Creates a logger with the specified handler types.
|
|
@@ -24,6 +25,7 @@ class LoggerFactory:
|
|
|
24
25
|
logger_name: The name of the logger.
|
|
25
26
|
logging_level: The logging level for the logger.
|
|
26
27
|
log_format: The format of the log messages.
|
|
28
|
+
datefmt: The format of the date/time in log messages. If None, uses the default format.
|
|
27
29
|
kwargs: Additional arguments to pass to the handler.
|
|
28
30
|
|
|
29
31
|
Note:
|
|
@@ -38,7 +40,7 @@ class LoggerFactory:
|
|
|
38
40
|
handler_types = [handler_types]
|
|
39
41
|
|
|
40
42
|
for handler_type in handler_types:
|
|
41
|
-
handler = LoggerFactory.get_handler(handler_type, log_format, **kwargs)
|
|
43
|
+
handler = LoggerFactory.get_handler(handler_type, log_format, datefmt=datefmt, **kwargs)
|
|
42
44
|
LoggerFactory.add_handler_if_not_exists(logger, handler)
|
|
43
45
|
return logger
|
|
44
46
|
|
|
@@ -46,6 +48,7 @@ class LoggerFactory:
|
|
|
46
48
|
def get_handler(
|
|
47
49
|
handler_type: str,
|
|
48
50
|
log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
51
|
+
datefmt: str | None = None,
|
|
49
52
|
**kwargs,
|
|
50
53
|
) -> logging.Handler:
|
|
51
54
|
handler_functions: dict[str, Callable] = {
|
|
@@ -55,18 +58,19 @@ class LoggerFactory:
|
|
|
55
58
|
"snowflake": LoggerFactory.get_snowflake_handler,
|
|
56
59
|
"log_analytics": LoggerFactory.get_log_analytics_handler,
|
|
57
60
|
}
|
|
58
|
-
handler = handler_functions[handler_type](**kwargs, log_format=log_format)
|
|
61
|
+
handler = handler_functions[handler_type](**kwargs, log_format=log_format, datefmt=datefmt)
|
|
59
62
|
return cast(logging.Handler, handler)
|
|
60
63
|
|
|
61
64
|
@staticmethod
|
|
62
|
-
def get_console_handler(log_format: str, **kwargs) -> logging.Handler: # noqa: ARG004
|
|
65
|
+
def get_console_handler(log_format: str, datefmt: str | None = None, **kwargs) -> logging.Handler: # noqa: ARG004
|
|
63
66
|
handler = logging.StreamHandler()
|
|
64
|
-
handler.setFormatter(logging.Formatter(log_format))
|
|
67
|
+
handler.setFormatter(logging.Formatter(log_format, datefmt=datefmt))
|
|
65
68
|
return handler
|
|
66
69
|
|
|
67
70
|
@staticmethod
|
|
68
71
|
def get_file_handler(
|
|
69
72
|
log_format: str,
|
|
73
|
+
datefmt: str | None = None,
|
|
70
74
|
filename: str | None = None,
|
|
71
75
|
mode: str = "a",
|
|
72
76
|
encoding: str | None = None,
|
|
@@ -76,7 +80,7 @@ class LoggerFactory:
|
|
|
76
80
|
if filename is None:
|
|
77
81
|
raise ValueError("filename is required for file logger")
|
|
78
82
|
handler = logging.FileHandler(filename, mode, encoding, delay)
|
|
79
|
-
handler.setFormatter(logging.Formatter(log_format))
|
|
83
|
+
handler.setFormatter(logging.Formatter(log_format, datefmt=datefmt))
|
|
80
84
|
return handler
|
|
81
85
|
|
|
82
86
|
@classmethod
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloe-logging
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.11
|
|
4
4
|
Summary: A Standardized Solution for logging to various targets.
|
|
5
5
|
Author-email: David Achilles <david.achilles@accenture.com>, Ole Steinbrueck <ole.steinbrueck@accenture.com>
|
|
6
6
|
License: Proprietary
|
|
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Classifier: Topic :: Database
|
|
15
|
-
Requires-Python: <3.
|
|
15
|
+
Requires-Python: <3.14,>=3.11
|
|
16
16
|
Requires-Dist: pydantic<3.0.0,>=2.7.0
|
|
17
17
|
Requires-Dist: typing-extensions<5.0.0,>=4.12.2
|
|
18
18
|
Provides-Extra: databricks
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
cloe_logging/__init__.py,sha256=3rsW-XtJbAaENMtN9ah2qRZyQnZOtqTnkCE_OqXBLNw,74
|
|
2
|
-
cloe_logging/logger_factory.py,sha256=
|
|
2
|
+
cloe_logging/logger_factory.py,sha256=XnC6hhr--_2Zwk--G7OHqcWfip_SF2p-RRAL7NQMvfk,5970
|
|
3
3
|
cloe_logging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
cloe_logging/decorators/__init__.py,sha256=ZFfADCScnpZ3ofxNgle1UybF322cdH9vuIGCx3S9wUU,71
|
|
5
5
|
cloe_logging/decorators/devops_decorator.py,sha256=npuOLa2HLxPlhTN9HMa_EBqyVWQxv8HvlTtaICyfVRw,1961
|
|
6
6
|
cloe_logging/formatters/__init__.py,sha256=1hhmT6qeIGuom63oHrg_2SHQZpLWG2GclMSTmF-fR_g,136
|
|
7
|
-
cloe_logging/formatters/devops_formatter.py,sha256=
|
|
7
|
+
cloe_logging/formatters/devops_formatter.py,sha256=Sgf8eUj4AqP9kfMR4N-VKMPnGAl9KeSgmp09xzX-6Po,3346
|
|
8
8
|
cloe_logging/formatters/dict_formatter.py,sha256=QGUcCx3KrCAXFGkYD3SY4s13k0OIgSBn6fhijgJ4m0Y,1553
|
|
9
9
|
cloe_logging/handlers/__init__.py,sha256=5RTIz8UooLgVc9h5GnXvI2yF-FkOKiJBfHbSKHKitRE,236
|
|
10
|
-
cloe_logging/handlers/log_analytics_handler.py,sha256=
|
|
11
|
-
cloe_logging/handlers/snowflake_handler.py,sha256=
|
|
12
|
-
cloe_logging/handlers/unity_catalog_handler.py,sha256=
|
|
10
|
+
cloe_logging/handlers/log_analytics_handler.py,sha256=YMm9CgUluXC0dziNnAlIokP_lDdN7N1L1v61iIWCmWs,9370
|
|
11
|
+
cloe_logging/handlers/snowflake_handler.py,sha256=9AdgQbpx2x_KRbmuAB6rT4ZYJEdP0y_n_grL324cXSY,5375
|
|
12
|
+
cloe_logging/handlers/unity_catalog_handler.py,sha256=55bzN5WpZodvwXF6v9Tc7pvpGXoW0m2RAFHrba001F0,7252
|
|
13
13
|
cloe_logging/utility/__init__.py,sha256=wp758l5P1M20bNUbbGojSkBUscFUgRd_TLLdnHgQ_l8,70
|
|
14
14
|
cloe_logging/utility/serializer.py,sha256=a_XNHC3DTPongLXcEBp7UCvVdmdjT-qAQ9ZHubCV0oI,2656
|
|
15
|
-
cloe_logging-0.3.
|
|
16
|
-
cloe_logging-0.3.
|
|
17
|
-
cloe_logging-0.3.
|
|
15
|
+
cloe_logging-0.3.11.dist-info/METADATA,sha256=5cvMi8OEqTu5lH8_ZFPRhvMbqsuxn1Wiq_-GSGzPr-U,2488
|
|
16
|
+
cloe_logging-0.3.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
17
|
+
cloe_logging-0.3.11.dist-info/RECORD,,
|