Skip to content

Commit

Permalink
add no date param
Browse files Browse the repository at this point in the history
  • Loading branch information
karaposu committed Dec 7, 2024
1 parent 1ec436c commit 3d1f3d9
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 25 deletions.
59 changes: 46 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ For detailed documentation which talks about best practices and limitations, see
______


no_datetime, which, if set to True, will omit the datetime portion from the log output. This is useful in scenarios where the logging infrastructure (e.g., Google Cloud Logging / Cloud Operations) already provides a timestamp and adding a local datetime is redundant.



## Installation

Expand Down Expand Up @@ -372,23 +375,53 @@ By leveraging:
You can create clear, organized, and hierarchical log outputs that significantly enhance readability and make debugging easier.


## Parameters

- **level** (int, default: `logging.DEBUG`):
Sets the global logging level. Use `logging.DEBUG` for verbose output, `logging.INFO` for general messages, or `logging.WARNING`/`logging.ERROR` for fewer, more critical logs.

- **log_file** (str or None, default: `None`):
If provided, logs will also be written to the specified file. This allows persistent record keeping of logs.

- **include_func** (bool, default: `False`):
If `True`, include the name of the logging function in the log message.

- **include_module** (bool, default: `False`):
If `True`, include the name of the module (logger name) in the log message.

- **func_module_format** (str or None, default: `None`):
A format string specifying how to display the function and module names. Use `{funcName}` and `{moduleName}` as placeholders. If not provided, a sensible default is chosen based on `include_func` and `include_module`.

- **truncate_messages** (bool, default: `False`):
If `True`, long messages will be truncated for cleaner, more readable output.

- **min_func_name_col** (int, default: `120`):
The column at which the function/module name information starts, allowing for consistent alignment of log messages.

- **indent_modules** (bool, default: `False`):
If `True`, logs from modules other than `__main__` are automatically indented, helping visually distinguish which parts of the code produce which logs.

- **indent_packages** (bool, default: `False`):
If `True`, indentation is based on the depth of the package hierarchy. Deeper package structures result in increased indentation.

- **indent_spaces** (int, default: `4`):
The number of spaces used for each indentation level.

- **datefmt** (str or None, default: `None`):
Custom datetime format string for timestamps. If not set, a default format is used.

- **debug** (bool, default: `False`):
If `True`, enables debug mode for the formatter itself, which can be helpful when troubleshooting logging configuration issues.

- **log_file_keep_ANSI** (bool, default: `False`):
If `False`, ANSI color codes are stripped from logs written to the file. Set `True` to preserve colors in the file logs.

- **log_file_no_indent** (bool, default: `False`):
If `True`, indentation logic (based on modules, packages, and function calls) is disabled for file logs, resulting in a cleaner, left-aligned output in the file.

## Parameters for `setup_logging`
- **no_datetime** (bool, default: `False`):
If `True`, the datetime portion is omitted from the logs entirely. Useful if your log processing infrastructure (e.g., GCP Log Explorer) already timestamps logs.

- `level` (int): Logging level (e.g., `logging.INFO`, `logging.DEBUG`).
- `include_func` (bool, optional): Include function names in log messages. Default is `False`.
- `include_module` (bool, optional): Include module names in log messages. Default is `False`.
- `func_module_format` (str, optional): Format string for combining function and module names. Default is `'{funcName}'`.
- Placeholders:
- `{funcName}`: Function name.
- `{moduleName}`: Module (logger) name.
- `truncate_messages` (bool, optional): Truncate long messages. Default is `False`.
- `min_func_name_col` (int, optional): Column at which function/module names should start. Default is `80`.
- `use_logger_hierarchy` (bool, optional): Indent logs based on the logger's name hierarchy. Default is `False`.
- `indent_spaces` (int, optional): Number of spaces per indentation level. Default is `4`.
- `datefmt` (str, optional): Date format string.



Expand Down
6 changes: 5 additions & 1 deletion examples/logging_to_a_file_example.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from indented_logger import setup_logging, log_indent
import logging

# to test this from indented_logger root
# python -m examples.logging_to_a_file_example

# Configure to log both to console and file:
# - Console: With ANSI colors and indentation
# - File: No ANSI colors, no indentation
Expand All @@ -9,7 +12,8 @@
log_file='application.log',
include_func=True,
log_file_keep_ANSI=False, # No ANSI in file
log_file_no_indent=False # No indentation in file logs
log_file_no_indent=False , # No indentation in file logs
no_datetime=True
)

logger = logging.getLogger(__name__)
Expand Down
35 changes: 28 additions & 7 deletions indented_logger/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class IndentFormatter(logging.Formatter):
def __init__(self, include_func=False, include_module=False, func_module_format=None,
truncate_messages=False, min_func_name_col=120, indent_modules=False,
indent_packages=False, datefmt=None, indent_spaces=4, debug=False,
disable_colors=False, disable_indent=False):
disable_colors=False, disable_indent=False, no_datetime=False):
self.include_func = include_func
self.include_module = include_module
self.truncate_messages = truncate_messages
Expand All @@ -29,6 +29,7 @@ def __init__(self, include_func=False, include_module=False, func_module_format=
self.debug = debug
self.disable_colors = disable_colors
self.disable_indent = disable_indent
self.no_datetime = no_datetime

self.func_module_format = self.build_func_module_format(func_module_format)

Expand Down Expand Up @@ -93,18 +94,20 @@ def get_func_module_info(self, record):
return ''

def apply_padding(self, asctime, levelname, message, func_module_info):
# If datetime is not included, asctime is empty
asctime_text = '' if self.no_datetime else asctime
stripped_message = self.strip_color_codes(message) if not self.disable_colors else message
current_length = len(asctime) + 3 + len(levelname) + 3 + len(stripped_message)
current_length = len(asctime_text) + (3 if asctime_text else 0) + len(levelname) + 3 + len(stripped_message)
desired_column = self.min_func_name_col

return ' ' * max(0, desired_column - current_length) if func_module_info else ''

def format(self, record):
indent = self.get_indent(record)
message = self.get_colored_message(record, indent)

asctime = self.formatTime(record, self.datefmt)
asctime_colored = self.apply_colors(asctime, 'cyan') if not self.disable_colors else asctime
# If no_datetime is True, we won't format time
asctime = self.formatTime(record, self.datefmt) if not self.no_datetime else ''
asctime_colored = self.apply_colors(asctime, 'cyan') if (not self.disable_colors and not self.no_datetime) else asctime

levelname = f"{record.levelname:<8}"
func_module_info = self.get_func_module_info(record)
Expand All @@ -120,8 +123,26 @@ def format(self, record):

formatted_message = super().format(record)

if self.usesTime() and not self.disable_colors:
formatted_message = formatted_message.replace(asctime, asctime_colored, 1)
# Remove datetime from the formatted message if no_datetime is True
if self.no_datetime:
# original fmt: '%(asctime)s - %(levelname)-8s - %(message)s'
# Remove the asctime and the trailing ' - ' that follows it
# Since asctime might be empty, we just ensure we don't leave double dashes
parts = formatted_message.split(' - ', 2)
if len(parts) > 1:
# parts[0]: asctime, parts[1]: level, parts[2]: rest
# if no_datetime: we just don't include asctime
# Rebuild string without asctime
if len(parts) == 3:
# [asctime, level, message(+func)]
formatted_message = f"{parts[1]} - {parts[2]}"
else:
# If formatting changed, fallback
formatted_message = ' - '.join(parts[1:])

else:
if self.usesTime() and not self.disable_colors:
formatted_message = formatted_message.replace(asctime, asctime_colored, 1)

return formatted_message
finally:
Expand Down
11 changes: 8 additions & 3 deletions indented_logger/logging_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def setup_logging(level=logging.DEBUG,
datefmt=None,
debug=False,
log_file_keep_ANSI=False,
log_file_no_indent=False):
log_file_no_indent=False,
no_datetime=False):
"""
Set up logging with indentation and optional file output.
Expand Down Expand Up @@ -66,7 +67,10 @@ def setup_logging(level=logging.DEBUG,
indent_packages=indent_packages,
indent_spaces=indent_spaces,
datefmt=datefmt,
debug=debug
debug=debug,
disable_colors=False,
disable_indent=False,
no_datetime=no_datetime
)

# File formatter with optional removal of ANSI and indentation
Expand All @@ -85,7 +89,8 @@ def setup_logging(level=logging.DEBUG,
datefmt=datefmt,
debug=debug,
disable_colors=(not log_file_keep_ANSI),
disable_indent=log_file_no_indent
disable_indent=log_file_no_indent,
no_datetime=no_datetime
)

logger = logging.getLogger()
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='indented_logger', # Package name
version='0.3.2', # Version of your package
version='0.3.3', # Version of your package
author='Enes Kuzucu', # Your name

description='A module to use common logger module with indentation support ', # Short description
Expand Down

0 comments on commit 3d1f3d9

Please sign in to comment.