Skip to content

feat(logger): customizing logger output #140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 28, 2020

Conversation

michaelbrewer
Copy link
Contributor

@michaelbrewer michaelbrewer commented Aug 27, 2020

Issue #, if available: #138 and #143

Description of changes:

NOTE: sampling_rate and service can not be suppressed

Ensure that the initial key seq is: level,location,message,timestamp so by default messages in Cloudwatch logs are easier to read:

>>> logger = Logger()
>>> logger.info("Eggs")
{'level': 'INFO', 'location': 'method_name:126', 'message': 'Eggs', 'timestamp': '2020-08-27 15:32:51,285', 'service': 'app', 'sampling_rate': 0.0}

Also allow for reordering override via format_keys

>>> logger = Logger(format_keys=["message"])
>>> logger.info("Foo")
{'message': 'Message', 'level': 'INFO', 'location': 'method_name:139', 'timestamp': '2020-08-27 15:36:11,494', 'service': 'app', 'sampling_rate': 0.0}

You can also suppress timestamp or location fields by passing them in as None

>>> logger = Logger(stream=stdout, location=None, timestamp=None)
>>> logger.info("magnus")
{"level": "INFO", "message": "magnus", "service": "app", "sampling_rate": 0.0}

Finally you can already customize the format for location and timestamp. So putting it all together:

>>> logger = Logger(location="%(module)s.%(funcName)s:%(lineno)d", timestamp=None, format_keys=["location", "message"])
>>> logger.info("takeoff")
{"location": "space.fly:7", "message": "takeoff", "level": "INFO", "service": "falcon", "sampling_rate": 0.0}

Checklist

Ensure that the initial key seq is: timestamp,level,location,message

Closes #138
@codecov-commenter
Copy link

codecov-commenter commented Aug 27, 2020

Codecov Report

Merging #140 into develop will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##           develop      #140   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           24        24           
  Lines          706       705    -1     
  Branches        67        68    +1     
=========================================
- Hits           706       705    -1     
Impacted Files Coverage Δ
aws_lambda_powertools/logging/formatter.py 100.00% <100.00%> (ø)
aws_lambda_powertools/logging/logger.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f137ba7...42f6b22. Read the comment docs.

@michaelbrewer
Copy link
Contributor Author

@heitorlessa maybe we can make the order configurable or get some feedback on what it should be.

Michael Brewer added 3 commits August 27, 2020 11:12
  Changes:
  * add `format_key` to allow for a custom order
  * remove unessarly verbose `json_formatter` with just `str`
  * update tests
Some keys like `location` and `timestamp` can be suppressed by setting
them to None.

Changes:
* logger.py - Convert some methods to static functions
* test_aws_lambda_logging - Add more tests and some which can be used
  for documentation
@michaelbrewer michaelbrewer changed the title feat(logger): readable log_dict seq feat(logger): customizing logger output Aug 27, 2020
Copy link
Contributor

@heitorlessa heitorlessa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made a few comments ;)

Additional thoughts:

  • I'm not 100% sure format_keys is descriptive enough for whoever unfamiliar with powertools to read and understand what's going on; I'll think through alternatives e.g. sort_keys, keys_order, log_record_order
  • You had a comment about suppressing sampling_rate and possibly others in the future, has that changed? This doesn't address that
    • In hindsight (6:22am), ignore this. I think we should continue to be opinionated about what can be changed or else this will become harder to maintain

@@ -292,6 +273,29 @@ def structure_logs(self, append: bool = False, **kwargs):
handler.setFormatter(JsonFormatter(**self._default_log_keys, **kwargs))


def _get_log_level(level: Union[str, int]) -> Union[str, int]:
Copy link
Contributor

@heitorlessa heitorlessa Aug 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plz make this a classmethod, not a separate function - it's still part of the encapsulated logger class logic

return log_level


def _get_caller_filename():
Copy link
Contributor

@heitorlessa heitorlessa Aug 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plz make this a classmethod, not a separate function - it's still part of the encapsulated logger class logic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heitorlessa should I use @staticmethod then ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, yes, that's what I meant - staticmethod.

"level": "%(levelname)s",
"location": "%(funcName)s:%(lineno)d",
}
self.format_dict = dict.fromkeys(kwargs.pop("format_keys", ["level", "location", "message", "timestamp"]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add a comment about insertion order here?

@michaelbrewer
Copy link
Contributor Author

made a few comments ;)

Additional thoughts:

  • I'm not 100% sure format_keys is descriptive enough for whoever unfamiliar with powertools to read and understand what's going on

Maybe ordered_message_keys? Kind of unsure of the name. :)

  • You had a comment about suppressing sampling_rate and possibly others in the future, has that changed? This doesn't address that

For service and sample_rate I would have to add a check for if it was set to None, vs just being left out. I will have to think about how.

@heitorlessa
Copy link
Contributor

made a few comments ;)
Additional thoughts:

  • I'm not 100% sure format_keys is descriptive enough for whoever unfamiliar with powertools to read and understand what's going on

Maybe ordered_message_keys? Kind of unsure of the name. :)

  • You had a comment about suppressing sampling_rate and possibly others in the future, has that changed? This doesn't address that

For service and sample_rate I would have to add a check for if it was set to None, vs just being left out. I will have to think about how.

What about log_record_order? Seems explicit enough to me even as sleepy as I am now.

I'd suggest keeping as is in terms of suppression, there could be side effects on these two:

  • If the customer wants to use the dynamic sampling feat (I have a list of customers already using in prod)
  • service is integral to Powertools terminologies, and this will degrade ops capabilities when creating metrics/visualization from logs etc

@michaelbrewer
Copy link
Contributor Author

I will keep the log suppression as it then. We should make have a better overview of Powertools in the main website which highlights this. I still don't quite understand log sampling :-)

Changes:
* Add missing comments and docs
* formatter - Group the kwargs code
* logger - convert back to class static methods
@heitorlessa heitorlessa self-assigned this Aug 28, 2020


def test_log_dict_key_custom_seq(stdout):
# GIVEN a logger configuration with format_keys set to ["message"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# GIVEN a logger configuration with format_keys set to ["message"]
# GIVEN a logger configuration with log_record_order set to ["message"]

@heitorlessa
Copy link
Contributor

Thank you @michaelbrewer - I've just noticed I don't have push permissions to your branch to update a tiny typo in the test comments, so I'm merging as-is and will fix-later.

@heitorlessa heitorlessa merged commit a7d7c86 into aws-powertools:develop Aug 28, 2020
@michaelbrewer
Copy link
Contributor Author

Thank you @michaelbrewer - I've just noticed I don't have push permissions to your branch to update a tiny typo in the test comments, so I'm merging as-is and will fix-later.

Oops. Thanks.

@michaelbrewer michaelbrewer deleted the fix-log-key-order branch February 22, 2021 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants