diff --git a/newrelic/api/log.py b/newrelic/api/log.py index bb710e524..8a33534b7 100644 --- a/newrelic/api/log.py +++ b/newrelic/api/log.py @@ -89,10 +89,11 @@ def log_record_to_dict(cls, record): output.update(get_linking_metadata()) DEFAULT_LOG_RECORD_KEYS = cls.DEFAULT_LOG_RECORD_KEYS - if len(record.__dict__) > len(DEFAULT_LOG_RECORD_KEYS): - for key in record.__dict__: - if key not in DEFAULT_LOG_RECORD_KEYS: - output["extra." + key] = getattr(record, key) + # If any keys are present in record that aren't in the default, + # add them to the output record. + keys_to_add = set(record.__dict__.keys()) - DEFAULT_LOG_RECORD_KEYS + for key in keys_to_add: + output["extra." + key] = getattr(record, key) if record.exc_info: output.update(format_exc_info(record.exc_info)) diff --git a/tests/agent_features/test_logs_in_context.py b/tests/agent_features/test_logs_in_context.py index 8693c0f08..8f97ee226 100644 --- a/tests/agent_features/test_logs_in_context.py +++ b/tests/agent_features/test_logs_in_context.py @@ -61,6 +61,48 @@ def __str__(self): __repr__ = __str__ +def test_newrelic_logger_min_extra_keys_no_error(log_buffer): + extra = { + "string": "foo", + } + _logger.info("Hello %s", "World", extra=extra) + + log_buffer.seek(0) + message = json.load(log_buffer) + + timestamp = message.pop("timestamp") + thread_id = message.pop("thread.id") + process_id = message.pop("process.id") + filename = message.pop("file.name") + line_number = message.pop("line.number") + + assert isinstance(timestamp, int) + assert isinstance(thread_id, int) + assert isinstance(process_id, int) + assert filename.endswith("/test_logs_in_context.py") + assert isinstance(line_number, int) + + expected = { + "entity.name": "Python Agent Test (agent_features)", + "entity.type": "SERVICE", + "message": "Hello World", + "log.level": "INFO", + "logger.name": "test_logs_in_context", + "thread.name": "MainThread", + "process.name": "MainProcess", + "extra.string": "foo", + } + expected_extra_txn_keys = ( + "entity.guid", + "hostname", + ) + + for k, v in expected.items(): + assert message.pop(k) == v + + assert set(message.keys()) == set(expected_extra_txn_keys) + + def test_newrelic_logger_no_error(log_buffer): extra = { "string": "foo",