click_logging_config 2.0.2__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.
@@ -0,0 +1 @@
1
+ 2.0.2
@@ -0,0 +1,5 @@
1
+ # Copyright (c) 2022 Russell Smiley
2
+ #
3
+ # This file is part of click_logging_config.
4
+
5
+ """Quick and easy logging parameters for click commands."""
@@ -0,0 +1,143 @@
1
+ #
2
+ # Copyright (c) 2022 Russell Smiley
3
+ #
4
+ # This file is part of click_logging_config.
5
+ #
6
+ # You should have received a copy of the MIT License along with build_harness.
7
+ # If not, see <https://opensource.org/licenses/MIT>.
8
+ #
9
+
10
+ import copy
11
+ import functools
12
+ import logging
13
+ import pathlib
14
+ import typing
15
+
16
+ import click
17
+ from click.decorators import FC
18
+
19
+ from ._default_values import VALID_LOG_LEVELS
20
+ from ._logging import LoggingConfiguration, LoggingState
21
+ from ._version import __version__
22
+
23
+ log = logging.getLogger(__name__)
24
+
25
+ LOG_STATE_KEY = "logging_state"
26
+
27
+
28
+ def logging_parameters(
29
+ default_configuration: typing.Optional[LoggingConfiguration] = None,
30
+ ) -> typing.Union[typing.Callable[..., typing.Any], click.Command]:
31
+ """Define a set of logging configuration options to a ``click`` command.
32
+
33
+ Args:
34
+ default_configuration: User defined logging default configuration.
35
+
36
+ Returns:
37
+ The decorator function object.
38
+ """
39
+ resolved_configuration: LoggingConfiguration
40
+ if not default_configuration:
41
+ resolved_configuration = LoggingConfiguration()
42
+ else:
43
+ resolved_configuration = typing.cast(
44
+ LoggingConfiguration, default_configuration
45
+ )
46
+
47
+ def decorator(f: FC) -> FC:
48
+ @click.option(
49
+ "--log-console-enable/--log-console-disable",
50
+ "enable_console_log",
51
+ default=resolved_configuration.enable_console_logging,
52
+ help="Enable or disable console logging.",
53
+ is_flag=True,
54
+ show_default=True,
55
+ )
56
+ @click.option(
57
+ "--log-console-json-enable/--log-console-json-disable",
58
+ "enable_console_json",
59
+ default=resolved_configuration.console_logging.json_enabled,
60
+ help="Enable or disable console JSON logging.",
61
+ is_flag=True,
62
+ show_default=True,
63
+ )
64
+ @click.option(
65
+ "--log-file-enable/--log-file-disable",
66
+ "enable_file_log",
67
+ default=resolved_configuration.enable_file_logging,
68
+ help="Enable or disable file logging.",
69
+ is_flag=True,
70
+ show_default=True,
71
+ )
72
+ @click.option(
73
+ "--log-file-json-enable/--log-file-json-disable",
74
+ "enable_file_json",
75
+ default=resolved_configuration.file_logging.json_enabled,
76
+ help="Enable or disable file JSON logging.",
77
+ is_flag=True,
78
+ show_default=True,
79
+ )
80
+ @click.option(
81
+ "--log-file",
82
+ "log_file",
83
+ default=resolved_configuration.file_logging.log_file_path,
84
+ help="The log file to write to.",
85
+ is_eager=True,
86
+ show_default=True,
87
+ type=click.Path(
88
+ dir_okay=False,
89
+ exists=False,
90
+ file_okay=True,
91
+ path_type=pathlib.Path,
92
+ writable=True,
93
+ readable=True,
94
+ ),
95
+ )
96
+ @click.option(
97
+ "--log-level",
98
+ "log_level",
99
+ default=resolved_configuration.log_level,
100
+ help="Select logging level to apply to all enabled log sinks.",
101
+ show_default=True,
102
+ type=click.Choice(VALID_LOG_LEVELS, case_sensitive=False),
103
+ )
104
+ def wrapper(
105
+ *args: typing.Any,
106
+ enable_console_log: bool,
107
+ enable_console_json: bool,
108
+ enable_file_log: bool,
109
+ enable_file_json: bool,
110
+ log_file: pathlib.Path,
111
+ log_level: str,
112
+ **kwargs: typing.Any,
113
+ ) -> typing.Any:
114
+ ctx = click.get_current_context()
115
+ this_object = ctx.ensure_object(dict)
116
+ if LOG_STATE_KEY not in this_object:
117
+ this_configuration = copy.deepcopy(resolved_configuration)
118
+ this_configuration.enable_console_logging = enable_console_log
119
+ this_configuration.console_logging.json_enabled = (
120
+ enable_console_json
121
+ )
122
+ this_configuration.enable_file_logging = enable_file_log
123
+ this_configuration.file_logging.json_enabled = enable_file_json
124
+ this_configuration.file_logging.log_file_path = log_file
125
+ this_configuration.log_level = log_level
126
+
127
+ this_object[LOG_STATE_KEY] = LoggingState(this_configuration)
128
+ log.info(f"Click logging config version, {__version__}")
129
+ elif not isinstance(this_object, dict):
130
+ raise RuntimeError(
131
+ "Unable to define logging state since click context.obj is "
132
+ "not a dictionary"
133
+ )
134
+
135
+ return ctx.invoke(
136
+ f,
137
+ *args,
138
+ **kwargs,
139
+ )
140
+
141
+ return typing.cast(FC, functools.update_wrapper(wrapper, f))
142
+
143
+ return decorator
@@ -0,0 +1,26 @@
1
+ # Copyright (c) 2020 Russell Smiley
2
+ #
3
+ # This file is part of click_logging_config.
4
+ #
5
+ # You should have received a copy of the MIT License along with build_harness.
6
+ # If not, see <https://opensource.org/licenses/MIT>.
7
+
8
+ """Default values."""
9
+
10
+ import pathlib
11
+
12
+ DEFAULT_RELEASE_ID = "0.0.0"
13
+
14
+ DEFAULT_CONSOLE_JSON_ENABLED = False
15
+ DEFAULT_CONSOLE_LOGGING_ENABLED = False
16
+
17
+ DEFAULT_FILE_JSON_ENABLED = True
18
+ DEFAULT_FILE_LOGGING_ENABLED = True
19
+ DEFAULT_FILE_ROTATION_BACKUPS = 10
20
+ DEFAULT_FILE_ROTATION_SIZE_MB = 1
21
+
22
+ DEFAULT_LOG_FILE = pathlib.Path("this.log")
23
+ DEFAULT_LOG_FORMAT = "%(asctime)s::%(levelname)s::%(name)s::%(message)s"
24
+ DEFAULT_LOG_LEVEL = "warning"
25
+
26
+ VALID_LOG_LEVELS = ["critical", "error", "warning", "info", "debug", "notset"]
@@ -0,0 +1,207 @@
1
+ # Copyright (c) 2022 Russell Smiley
2
+ #
3
+ # This file is part of click_logging_config.
4
+ #
5
+ # You should have received a copy of the MIT License along with build_harness.
6
+ # If not, see <https://opensource.org/licenses/MIT>.
7
+
8
+ """Logging configuration and state."""
9
+
10
+ import logging.handlers
11
+ import pathlib
12
+ import typing
13
+
14
+ import json_log_formatter # type: ignore
15
+ import pendulum
16
+ import pydantic
17
+ import pytz
18
+
19
+ from ._default_values import (
20
+ DEFAULT_CONSOLE_JSON_ENABLED,
21
+ DEFAULT_CONSOLE_LOGGING_ENABLED,
22
+ DEFAULT_FILE_JSON_ENABLED,
23
+ DEFAULT_FILE_LOGGING_ENABLED,
24
+ DEFAULT_FILE_ROTATION_BACKUPS,
25
+ DEFAULT_FILE_ROTATION_SIZE_MB,
26
+ DEFAULT_LOG_FILE,
27
+ DEFAULT_LOG_FORMAT,
28
+ DEFAULT_LOG_LEVEL,
29
+ )
30
+
31
+
32
+ class ConsoleLogging(pydantic.BaseModel):
33
+ """Console log configuration parameters."""
34
+
35
+ json_enabled: bool = DEFAULT_CONSOLE_JSON_ENABLED
36
+
37
+
38
+ class FileLogging(pydantic.BaseModel):
39
+ """Log file configuration parameters.
40
+
41
+ In this context file logs are *always* rotated - the rotation just might be
42
+ at a relatively large file size. As a best practice, not rotating log files
43
+ is considered not particularly useful.
44
+ """
45
+
46
+ json_enabled: bool = DEFAULT_FILE_JSON_ENABLED
47
+ log_file_path: pathlib.Path = DEFAULT_LOG_FILE
48
+ file_rotation_size_megabytes: int = DEFAULT_FILE_ROTATION_SIZE_MB
49
+ max_rotation_backup_files: int = DEFAULT_FILE_ROTATION_BACKUPS
50
+
51
+
52
+ class LoggingConfiguration(pydantic.BaseModel):
53
+ """Logging configuration data."""
54
+
55
+ log_level: str = DEFAULT_LOG_LEVEL
56
+
57
+ enable_console_logging: bool = DEFAULT_CONSOLE_LOGGING_ENABLED
58
+ console_logging: ConsoleLogging = ConsoleLogging()
59
+
60
+ enable_file_logging: bool = DEFAULT_FILE_LOGGING_ENABLED
61
+ file_logging: FileLogging = FileLogging()
62
+
63
+
64
+ U = typing.TypeVar("U", bound="Iso8601Formatter")
65
+
66
+
67
+ class Iso8601Formatter(logging.Formatter):
68
+ """Custom formatter with ISO-8601 timestamps."""
69
+
70
+ converter: typing.Callable[..., pendulum.DateTime] = pendulum.from_timestamp # type: ignore [assignment]
71
+
72
+ def formatTime(
73
+ self: U,
74
+ record: logging.LogRecord,
75
+ datefmt: typing.Optional[str] = None,
76
+ timezone: typing.Optional[str] = None,
77
+ ) -> str:
78
+ """Generate formatted time."""
79
+ if timezone:
80
+ v = Iso8601Formatter.converter(
81
+ record.created,
82
+ tz=pytz.timezone(timezone),
83
+ ).isoformat()
84
+ else:
85
+ v = Iso8601Formatter.converter(
86
+ record.created,
87
+ ).isoformat()
88
+
89
+ return v
90
+
91
+
92
+ T = typing.TypeVar("T", bound="LoggingState")
93
+
94
+
95
+ class LoggingState:
96
+ """Logging configuration parameters."""
97
+
98
+ configuration: LoggingConfiguration
99
+ _console_handler: typing.Optional[logging.StreamHandler]
100
+ _rotation_handler: typing.Optional[logging.handlers.RotatingFileHandler]
101
+
102
+ def __init__(
103
+ self: T,
104
+ logging_configuration: LoggingConfiguration,
105
+ ) -> None:
106
+ """Construct ``LoggingState`` object.
107
+
108
+ Args:
109
+ logging_configuration: Logging configuration to be applied.
110
+ """
111
+ self.configuration = logging_configuration
112
+ self._console_handler = None
113
+ self._rotation_handler = None
114
+
115
+ self.set_logging_state()
116
+
117
+ def set_logging_state(self: T) -> None:
118
+ """Apply the logging state from configuration."""
119
+ root_logger = logging.getLogger()
120
+ self.__set_log_level(root_logger)
121
+ self.__set_file_logging(root_logger)
122
+ self.__set_console_logging(root_logger)
123
+
124
+ def __level_value(self: T) -> int:
125
+ """Convert log level text to a ``logging`` framework integer."""
126
+ return getattr(logging, self.configuration.log_level.upper())
127
+
128
+ def __set_file_logging(self: T, root_logger: logging.Logger) -> None:
129
+ """Enable or disable file logging.
130
+
131
+ Args:
132
+ root_logger: Root logger to modify.
133
+ """
134
+ if self.configuration.enable_file_logging:
135
+ # No change if a rotation handler already exists.
136
+ if not self._rotation_handler:
137
+ this_handler = logging.handlers.RotatingFileHandler(
138
+ str(self.configuration.file_logging.log_file_path),
139
+ backupCount=(
140
+ self.configuration.file_logging.max_rotation_backup_files # noqa: E501
141
+ ),
142
+ maxBytes=( # noqa: E501
143
+ self.configuration.file_logging.file_rotation_size_megabytes # noqa: E501
144
+ * (1024**2)
145
+ ),
146
+ )
147
+ this_handler.setLevel(self.__level_value())
148
+ if self.configuration.file_logging.json_enabled:
149
+ this_handler.setFormatter(
150
+ json_log_formatter.VerboseJSONFormatter()
151
+ )
152
+ else:
153
+ this_handler.setFormatter(
154
+ Iso8601Formatter(fmt=DEFAULT_LOG_FORMAT)
155
+ )
156
+
157
+ self._rotation_handler = this_handler
158
+
159
+ root_logger.addHandler(self._rotation_handler)
160
+ elif self._rotation_handler:
161
+ self._rotation_handler.flush()
162
+ self._rotation_handler.close()
163
+ root_logger.removeHandler(self._rotation_handler)
164
+ self._rotation_handler = None
165
+ # else self._rotation_handler is None and not self.enable_file_logging
166
+ # so do nothing
167
+
168
+ def __set_console_logging(self: T, root_logger: logging.Logger) -> None:
169
+ """Enable or disable console logging.
170
+
171
+ Args:
172
+ root_logger: Root logger to modify.
173
+ """
174
+ if self.configuration.enable_console_logging:
175
+ # No change if a console handler already exists.
176
+ if not self._console_handler:
177
+ self._console_handler = logging.StreamHandler()
178
+ self._console_handler.setLevel(self.__level_value())
179
+ if self.configuration.console_logging.json_enabled:
180
+ self._console_handler.setFormatter(
181
+ json_log_formatter.VerboseJSONFormatter()
182
+ )
183
+ else:
184
+ self._console_handler.setFormatter(
185
+ Iso8601Formatter(fmt=DEFAULT_LOG_FORMAT)
186
+ )
187
+
188
+ root_logger.addHandler(self._console_handler)
189
+ elif self._console_handler:
190
+ self._console_handler.flush()
191
+ self._console_handler.close()
192
+ root_logger.removeHandler(self._console_handler)
193
+ self._console_handler = None
194
+ # else self._console_handler is None and not
195
+ # self.enable_console_logging so do nothing
196
+
197
+ def __set_log_level(self: T, root_logger: logging.Logger) -> None:
198
+ """Set log level on any existing handlers.
199
+
200
+ Args:
201
+ root_logger: Root logger to modify.
202
+ """
203
+ for this_handler in root_logger.handlers:
204
+ this_handler.setLevel(self.__level_value())
205
+ # Ensure that the logging level propagates to any subsequently created
206
+ # handlers by setting the root logger level as well.
207
+ root_logger.setLevel(self.__level_value())
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2020 Russell Smiley
2
+ #
3
+ # This file is part of build_harness.
4
+ #
5
+ # You should have received a copy of the MIT License along with build_harness.
6
+ # If not, see <https://opensource.org/licenses/MIT>.
7
+
8
+ """Package version management."""
9
+
10
+ import pathlib
11
+
12
+ from click_logging_config._default_values import DEFAULT_RELEASE_ID
13
+
14
+
15
+ def acquire_version() -> str:
16
+ """Acquire PEP-440 compliant version from VERSION file.
17
+
18
+ Returns:
19
+ Acquired version text.
20
+ Raises:
21
+ RuntimeError: If version is not valid.
22
+ """
23
+ here = pathlib.Path(__file__).parent
24
+ version_file_path = (here / "VERSION").absolute()
25
+
26
+ if version_file_path.is_file():
27
+ with version_file_path.open(mode="r") as version_file:
28
+ version = version_file.read().strip()
29
+ else:
30
+ version = DEFAULT_RELEASE_ID
31
+
32
+ if not version:
33
+ raise RuntimeError("Unable to acquire version")
34
+
35
+ return version
36
+
37
+
38
+ __version__ = acquire_version()
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2024 Russell Smiley
2
+ #
3
+ # This file is part of click_logging_config.
4
+ #
5
+ # You should have received a copy of the MIT License along with
6
+ # click_logging_config.
7
+ # If not, see <https://opensource.org/licenses/MIT>.
8
+ #
9
+
10
+ """Convenience imports of core functionality."""
11
+
12
+ from ._click import logging_parameters # noqa: F401
13
+ from ._logging import LoggingConfiguration, LoggingState # noqa: F401
File without changes
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.4
2
+ Name: click_logging_config
3
+ Version: 2.0.2
4
+ Dynamic: Summary
5
+ Project-URL: source, https://gitlab.com/ci-cd-devops/click_logging_config
6
+ Author-email: Russell Smiley <russell@bytingchipmunk.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE.txt
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Typing :: Typed
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: click>=8.3
14
+ Requires-Dist: json-log-formatter>=1.0
15
+ Requires-Dist: pendulum>=3.1
16
+ Requires-Dist: pydantic<3,>=2
17
+ Requires-Dist: pytz>=2025.2
18
+ Provides-Extra: dev
19
+ Requires-Dist: invoke>=2.2.0; extra == 'dev'
20
+ Requires-Dist: mypy>=1.18.2; extra == 'dev'
21
+ Requires-Dist: pre-commit>=4.3; extra == 'dev'
22
+ Requires-Dist: ruff>=0.14.4; extra == 'dev'
23
+ Requires-Dist: types-pytz>=2025.2; extra == 'dev'
24
+ Requires-Dist: uv>=0.9.8; extra == 'dev'
25
+ Provides-Extra: doc
26
+ Requires-Dist: sphinx-rtd-theme>=2.0; extra == 'doc'
27
+ Requires-Dist: sphinx>=7.4.7; extra == 'doc'
28
+ Provides-Extra: test
29
+ Requires-Dist: pytest-cov>=7.0; extra == 'test'
30
+ Requires-Dist: pytest-mock>=3.15.1; extra == 'test'
31
+ Requires-Dist: pytest>=8.4.2; extra == 'test'
32
+ Description-Content-Type: text/x-rst
33
+
34
+ click-logging-config
35
+ ====================
36
+
37
+ Quick and easy CLI logging options for `click <https://palletsprojects.com/p/click/>`_
38
+ commands using a Python decorator.
39
+
40
+ I found myself implementing logging preferences repeatedly for utilities. Logging
41
+ configuration is pretty simple, but for each new implementation I would
42
+ find myself spending time researching the same options to refresh my memory and
43
+ then implementing something slightly different than the last time. 🙄
44
+
45
+ ``click-logging-config`` is my attempt to stop the circle of re-implementation
46
+ with settings that are useful enough, with configurability to change it if you
47
+ don't like the out-of-box behaviour. It's proving to be pretty useful and I'm
48
+ already using it across several of my other projects. 😄
49
+
50
+ It is released under the MIT license so you are free to use it in lots of
51
+ different ways. As simple as it looks, a tool like this still represents
52
+ research time and implementation effort, so please use the link below to help
53
+ support development.
54
+
55
+ `Support click-logging-config <https://byting-chipmunk.ck.page/products/click-logging-config>`_
56
+
57
+ `Byting Chipmunk <https://bytingchipmunk.com>`_ 🐿
58
+
59
+ *Take a byte off.*
60
+
61
+
62
+ .. contents::
63
+
64
+ .. section-numbering::
65
+
66
+
67
+ Installation
68
+ ------------
69
+
70
+ The ``click-logging-config`` package is available from PyPI. Installing
71
+ into a virtual environment is recommended.
72
+
73
+ .. code-block::
74
+
75
+ python3 -m venv .venv; .venv/bin/pip install click-logging-config
76
+
77
+
78
+ Getting Started
79
+ ---------------
80
+
81
+ Using ``click-logging-config`` is intended to be very simple. A single
82
+ decorator applied to your click command or group adds some click options
83
+ specifically for managing logging context.
84
+
85
+ .. code-block::
86
+
87
+ import click
88
+ import logging
89
+ from click_logging import logging_parameters
90
+
91
+ log = logging.getLogger(__name__)
92
+
93
+ def do_something()
94
+ pass
95
+
96
+ @click.command()
97
+ @click.option("--my-option", type=str)
98
+ # NOTE: Empty braces are required for hard-coded click-logging-config defaults.
99
+ @logging_parameters()
100
+ def my_command(my_option: str) -> None:
101
+ log.info("doing something")
102
+ try:
103
+ do_something(my_option)
104
+ except Exception as e:
105
+ log.critical(f"something bad happened, {str(e)}")
106
+ raise
107
+
108
+
109
+ Application of the ``@logging_parameters`` decorator must be applied immediately
110
+ *above* your click command function and *below* any other click decorators such
111
+ as arguments and options.
112
+
113
+ Having applied the decorator, your command now has the following options
114
+ available to it.
115
+
116
+ .. code-block::
117
+
118
+ --log-console-enable / --log-console-disable
119
+ Enable or disable console logging.
120
+ [default: log-console-disable]
121
+ --log-console-json-enable / --log-console-json-disable
122
+ Enable or disable console JSON logging.
123
+ [default: log-console-json-disable]
124
+ --log-file-enable / --log-file-disable
125
+ Enable or disable file logging.
126
+ [default: log-file-enable]
127
+ --log-file-json-enable / --log-file-json-disable
128
+ Enable or disable file JSON logging.
129
+ [default: log-file-json-enable]
130
+ --log-file FILE The log file to write to. [default: this.log]
131
+ --log-level [critical|error|warning|info|debug|notset]
132
+ Select logging level to apply to all enabled
133
+ log sinks. [default: warning]
134
+
135
+ Note that the single log level configuration parameter applies to both console
136
+ and file logging.
137
+
138
+ The internal defaults are configured for an interactive utility (run by a
139
+ human in a terminal rather than via automation, or in a container). In summary,
140
+
141
+ * disabled console logging (allows your application to use console output, if needed)
142
+ * enabled file logging (1MB rotation size, with 10 rotation backups)
143
+ * "warning" log level
144
+
145
+
146
+ Custom defaults
147
+ ---------------
148
+
149
+ If you don't like the ``click-logging-config`` internal defaults for the options
150
+ you can define your own. The ``LoggingConfiguration`` class is derived from
151
+ ``pydantic.BaseModel``, so one easy way to define your defaults is using a
152
+ dictionary. You only need to define values you want to change - any other value
153
+ will continue using the internal defaults.
154
+
155
+ .. code-block::
156
+
157
+ import pathlib
158
+
159
+ import click
160
+ import logging
161
+ from click_logging import logging_parameters, LoggingConfiguration
162
+
163
+ log = logging.getLogger(__name__)
164
+
165
+ MY_LOGGING_DEFAULTS = LoggingConfiguration.parse_obj(
166
+ {
167
+ "file_logging": {
168
+ # NOTE: file path must be specified using pathlib.Path
169
+ "log_file_path": pathlib.Path("some_other.log"),
170
+ },
171
+ "log_level": "info",
172
+ }
173
+ )
174
+
175
+ def do_something()
176
+ pass
177
+
178
+ @click.command()
179
+ @click.option("--my-option", type=str)
180
+ @logging_parameters(MY_LOGGING_DEFAULTS)
181
+ def my_command(my_option: str) -> None:
182
+ log.info("doing something")
183
+ try:
184
+ do_something(my_option)
185
+ except Exception as e:
186
+ log.critical(f"something bad happened, {str(e)}")
187
+ raise
188
+
189
+
190
+ The table below summarizes the available settings for defaults. Otherwise
191
+ review the ``LoggingConfiguration`` `class definition <https://gitlab.com/ci-cd-devops/click_logging_config/-/blob/main/click_logging_config/_logging.py#L52>`_ .
192
+
193
+ .. csv-table:: Available top-level settings for logging defaults.
194
+ :header: "Setting", "Type", "Hard default", "Description"
195
+
196
+ "log_level", "str", "warning", "Define log level"
197
+ "enable_console_logging", "boolean", "False", "Enable console logging"
198
+ "console_logging", "dict", "", "Console logging specific settings. See table below."
199
+ "enable_file_logging", "bool", "True", "Enable file logging"
200
+ "file_logging", "dict", "", "File logging specific settings. See table below."
201
+
202
+ .. csv-table:: Available console logging defaults.
203
+ :header: "Setting", "Type", "Hard default", "Description"
204
+
205
+ "json_enabled", "bool", "False", "Output JSON logs using ``json_log_formatter``"
206
+
207
+ .. csv-table:: Available file logging defaults.
208
+ :header: "Setting", "Type", "Hard default", "Description"
209
+
210
+ "json_enabled", "bool", "True", "Output JSON logs using ``json_log_formatter``"
211
+ "log_file_path", "pathlib.Path", "./this.log", "Path and name of log file."
212
+ "file_rotation_size_megabytes", "int", "1", "Maximum size of "
213
+ "max_rotation_backup_files", "int", "10", "Maximum number of rotation backup files"
214
+
215
+
216
+ Console logging
217
+ ---------------
218
+
219
+ Console logging can be enabled or disabled, and there is an additional option
220
+ to output line-by-line text based timestamped log entries, or JSON logging via
221
+ the ``json_log_formatter`` framework. The format of text based log entries
222
+ cannot be configured at this time and console logging is always emitted to
223
+ stderr at this time.
224
+
225
+
226
+ File logging
227
+ ------------
228
+
229
+ File rotation on the file log is implemented as a "sensible default" - it cannot
230
+ be disabled at this time, although you might be able to specify a maximum
231
+ rotation of ``1`` to achieve the same end (not tested). The maximum rotation
232
+ size can be specified as a configuration default. File logging itself can be
233
+ enabled or disabled via defaults or the CLI options described above.
234
+
235
+ Similar to console logging the format can be as either text-based or JSON
236
+ logging.
@@ -0,0 +1,12 @@
1
+ click_logging_config/VERSION,sha256=tLFvrqUtwEzP4y97NCCUhVkj6_WZo8rBlARwotbXwmE,6
2
+ click_logging_config/__init__.py,sha256=ApTiqgsbFqWTVWw7C_i6dFHWEgVCDRnQ7OlZ6D9fOAw,146
3
+ click_logging_config/_click.py,sha256=F3Rajiqzg6k--17Il3n0YNY8GK7728bu6HRpHuMw2q0,4896
4
+ click_logging_config/_default_values.py,sha256=bvH2zWLZc-LtdoznV6xuPNhXGAmMlySqsaDEzSncR90,735
5
+ click_logging_config/_logging.py,sha256=t1jz6sb9VmM7pF81tTiy_nk-aPEICIYWs43jvLa8TPk,7178
6
+ click_logging_config/_version.py,sha256=bGmsJRW4pXXOBvC6FMYbVDMBgCE0gEsjhXfP1cjv_Dg,961
7
+ click_logging_config/parameters.py,sha256=IRfUamM2yQbjp5c_TWVxQFu9xVvMmRQPgPjjVx0Ibfs,408
8
+ click_logging_config/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ click_logging_config-2.0.2.dist-info/METADATA,sha256=tTT9ZnvwkHIjIWVjA0X1WRvHYMa2JF3qJoI-BjxlIJA,8613
10
+ click_logging_config-2.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
+ click_logging_config-2.0.2.dist-info/licenses/LICENSE.txt,sha256=YtQuRK_6LysSNNjqInIn-ALBw_A3vqKc8M7K-2u06Dk,1103
12
+ click_logging_config-2.0.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ Copyright 2022 Russell Smiley
2
+
3
+ MIT license https://opensource.org/licenses/MIT
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.