Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/amplitude/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
from amplitude.event import BaseEvent, EventOptions, Identify, Revenue, IdentifyEvent, \
GroupIdentifyEvent, RevenueEvent, Plan, IngestionMetadata
from amplitude.config import Config
from amplitude.constants import PluginType
from amplitude.constants import PluginType, EventLogLevel
from amplitude.plugin import EventPlugin, DestinationPlugin
6 changes: 5 additions & 1 deletion src/amplitude/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class Config:
Provide storage instance for events buffer.
plan (amplitude.event.Plan, optional): Tracking plan information. Default to None.
ingestion_metadata (amplitude.event.IngestionMetadata, optional): Ingestion metadata. Default to None.
event_log_level (amplitude.constants.EventLogLevel, optional): Level used to log each event after it is
sent or dropped. EventLogLevel.NONE disables these logs. Default to EventLogLevel.INFO.

Properties:
options: A dictionary contains minimum id length information. None if min_id_length not set.
Expand All @@ -57,7 +59,8 @@ def __init__(self, api_key: str = None,
server_url: Optional[str] = None,
storage_provider: Optional[StorageProvider] = None,
plan: Plan = None,
ingestion_metadata: IngestionMetadata = None):
ingestion_metadata: IngestionMetadata = None,
event_log_level: constants.EventLogLevel = constants.EventLogLevel.INFO):
"""The constructor of Config class"""
self.api_key: str = api_key
self._flush_queue_size: int = flush_queue_size
Expand All @@ -74,6 +77,7 @@ def __init__(self, api_key: str = None,
self.opt_out: bool = False
self.plan: Plan = plan
self.ingestion_metadata: IngestionMetadata = ingestion_metadata
self.event_log_level: constants.EventLogLevel = event_log_level

def get_storage(self) -> Storage:
"""Use configured StorageProvider to create a Storage instance then return.
Expand Down
6 changes: 6 additions & 0 deletions src/amplitude/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,9 @@ class PluginType(Enum):
ENRICHMENT = 1
DESTINATION = 2
OBSERVE = 3


class EventLogLevel(Enum):
NONE = 0
DEBUG = 1
INFO = 2
7 changes: 6 additions & 1 deletion src/amplitude/processor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from amplitude.constants import EventLogLevel
from amplitude.exception import InvalidAPIKeyError
from amplitude.http_client import HttpStatus

Expand Down Expand Up @@ -83,5 +84,9 @@ def callback(self, events, code, message):
self.configuration.logger.exception(f"Error callback for event {event}")

def log(self, events, code, message):
level = self.configuration.event_log_level
if level == EventLogLevel.NONE:
return
log_fn = self.configuration.logger.debug if level == EventLogLevel.DEBUG else self.configuration.logger.info
for event in events:
self.configuration.logger.info(message, extra={'code':code, 'event':event})
log_fn(message, extra={'code':code, 'event':event})
30 changes: 29 additions & 1 deletion src/test/test_processor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import unittest
from unittest.mock import MagicMock

from amplitude import Config, BaseEvent
from amplitude import Config, BaseEvent, EventLogLevel
from amplitude.http_client import Response, HttpStatus
from amplitude.processor import ResponseProcessor

Expand All @@ -25,6 +25,34 @@ def test_process_response_with_unknown_status_retries_events(self):
configuration.callback.assert_not_called()
event_callback.assert_not_called()

def _process_success(self, configuration):
configuration.logger = MagicMock()
processor = ResponseProcessor()
processor.setup(configuration, MagicMock())
event = BaseEvent("test_event", "test_user")
processor.process_response(Response(HttpStatus.SUCCESS), [event])
return event

def test_log_event_at_info_level_by_default(self):
configuration = Config()
event = self._process_success(configuration)
configuration.logger.info.assert_called_once_with(
"Event sent successfully.", extra={'code': 200, 'event': event})
configuration.logger.debug.assert_not_called()

def test_log_event_at_debug_level(self):
configuration = Config(event_log_level=EventLogLevel.DEBUG)
event = self._process_success(configuration)
configuration.logger.debug.assert_called_once_with(
"Event sent successfully.", extra={'code': 200, 'event': event})
configuration.logger.info.assert_not_called()

def test_log_event_disabled(self):
configuration = Config(event_log_level=EventLogLevel.NONE)
self._process_success(configuration)
configuration.logger.info.assert_not_called()
configuration.logger.debug.assert_not_called()


if __name__ == '__main__':
unittest.main()
Loading