-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
70 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,84 @@ | ||
import logging | ||
import json | ||
import re | ||
|
||
# NOTE: We can essentially just use `json.dumps` and make structured logging our default format. | ||
class DefaultFormatter(logging.Formatter): | ||
def format(self, record): | ||
# Base format with time, severity, and main message | ||
# base_message = f"{self.formatTime(record)} - {record.levelname} - {record.name} - {record.getMessage()}" | ||
base_message = super().format(record) | ||
|
||
# Add any extra fields below: | ||
extra_info = [] | ||
if hasattr(record, 'client_id'): | ||
extra_info.append(f"client_id={record.client_id}") | ||
if hasattr(record, 'response_id'): | ||
extra_info.append(f"client_id={record.client_id}") | ||
if hasattr(record, 'httpRequest'): | ||
extra_info.append(f"httpRequest={record.httpRequest}") | ||
if hasattr(record, 'json_fields'): | ||
for key, val in record.json_fields.items(): | ||
extra_info.append(f"{key}={val}") | ||
|
||
# Combine base message with extra fields | ||
if extra_info: | ||
base_message += " | " + " - ".join(extra_info) | ||
|
||
return base_message | ||
|
||
|
||
# NOTE: Option 1: Allow users to configure log levels. | ||
# def setup_logging(log_level, namespace="google"): | ||
|
||
# # NOTE: A logger with namespace="google" is only configured if all of the below conditions hold true: | ||
# # - A root logger is not configured. | ||
# # - N/A: A logger with namespace="google" is not already configured (This statement is removed.) | ||
# # - GOOGLE_SDK_PYTHON_LOGGING_LEVEL is set. | ||
# if not logging.getLogger().hasHandlers() and log_level: | ||
|
||
# class BaseLogger: | ||
# # define a module for our repositories | ||
# logger = logging.getLogger(namespace) | ||
# try: | ||
# logger.setLevel(log_level) | ||
# except ValueError: | ||
# logger.setLevel("WARNING") | ||
# logger.warning(f"Configured log level `{log_level}` is incorrect. Defaulting to WARNING.") | ||
|
||
# def __init__(self, log_level=logging.DEBUG): | ||
# self._logger = logging.getLogger("google") | ||
# self._logger.setLevel(log_level) | ||
# # Default settings | ||
# console_handler = logging.StreamHandler() | ||
# console_handler.setLevel(log_level) | ||
# formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") | ||
# # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(user_id)s - %(request_id)s - %(message)s') # Include extra fields | ||
# # formatter = DefaultFormatter() | ||
# console_handler.setFormatter(formatter) | ||
# self._logger.addHandler(console_handler) | ||
|
||
# def get_logger(self): | ||
# return self._logger | ||
|
||
|
||
# class DefaultFormatter(logging.Formatter): | ||
# def format(self, record): | ||
# log_obj = { | ||
# 'timestamp': self.formatTime(record), | ||
# 'severity': record.levelname, | ||
# 'name': record.name, | ||
# 'message': record.getMessage(), | ||
# } | ||
# if hasattr(record, 'request'): | ||
# log_obj['request'] = record.request | ||
# if hasattr(record, 'response'): | ||
# log_obj['response'] = record.response | ||
# if hasattr(record, 'client_id'): | ||
# log_obj['client_id'] = record.client_id | ||
|
||
# return json.dumps(log_obj) | ||
# logger.addHandler(console_handler) | ||
|
||
|
||
# NOTE: Option 2: Allow users to configure log systems. | ||
def setup_logging(namespace): | ||
|
||
# Instantiate a base logger unconditionally to avoid propogating logs to the root logger. | ||
base_logger = logging.getLogger("google") | ||
base_logger.propagate = False | ||
|
||
# If a namespace is not provided, we don't need to do anything. | ||
if not namespace: | ||
return | ||
|
||
def setup_logging(log_level, namespace="google"): | ||
# If the provided namespace does not start with "google", we don't need to do anything. | ||
# We can update the regex to be more strict about the format of the namespace. | ||
match = re.search(f"google", namespace) | ||
if not match: | ||
# TODO: raise an error? silently ignore? | ||
return | ||
|
||
# NOTE: A logger with namespace="google" is only configured if all of the below conditions hold true: | ||
# - A root logger is not configured. | ||
# - N/A: A logger with namespace="google" is not already configured (This statement is removed.) | ||
# - GOOGLE_SDK_PYTHON_LOGGING_LEVEL is set. | ||
if not logging.getLogger().hasHandlers() and log_level: | ||
|
||
# define a module for our repositories | ||
logger = logging.getLogger(namespace) | ||
try: | ||
logger.setLevel(log_level) | ||
except ValueError: | ||
logger.setLevel("WARNING") | ||
logger.warning(f"Configured log level `{log_level}` is incorrect. Defaulting to WARNING.") | ||
|
||
# Default settings | ||
|
||
# This will either create a module level logger or get the reference of the base logger instantiated above. | ||
logger = logging.getLogger(namespace) | ||
|
||
# Set default settings. | ||
if not logger.hasHandlers() and logger.level == logging.NOTSET: | ||
console_handler = logging.StreamHandler() | ||
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") | ||
logger.setLevel("DEBUG") | ||
formatter = DefaultFormatter('%(asctime)s %(levelname)s %(name)s %(message)s') | ||
# formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") | ||
console_handler.setFormatter(formatter) | ||
logger.addHandler(console_handler) |