-
Notifications
You must be signed in to change notification settings - Fork 34
Added GCP logs in Household and Metadata services to assist further investigation of the 502 errors #2682
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
base: master
Are you sure you want to change the base?
Added GCP logs in Household and Metadata services to assist further investigation of the 502 errors #2682
Changes from all commits
ba788ab
155edb9
0f95cb3
214e951
217b48f
a131e0f
8a629f8
899ad20
846f38f
03a69bd
cf7b86f
721a6e1
e86d3fa
047ad3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| .venv | ||
| /venv | ||
| __pycache__ | ||
| **/__pycache__ | ||
| *.egg-info | ||
| .pytest_cache | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| - bump: patch | ||
| changes: | ||
| added: | ||
| - Added GCP logs in Household and Metadata services to assist further investigation of the 502 errors. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import logging | ||
| import json | ||
| import sys | ||
|
|
||
|
|
||
| class JsonFormatter(logging.Formatter): | ||
| """Formatter that outputs logs as structured JSON.""" | ||
|
|
||
| def format(self, record): | ||
| log_record = { | ||
| "severity": record.levelname, | ||
| "event": getattr(record, "event", None), | ||
| "input": getattr(record, "input", None), | ||
| "message": record.getMessage(), | ||
| } | ||
| if record.exc_info: | ||
| log_record["exception"] = self.formatException(record.exc_info) | ||
| return json.dumps(log_record, indent=2) | ||
|
|
||
|
|
||
| def get_logger(name="policyengine-api", level=logging.INFO): | ||
| logger = logging.getLogger(name) | ||
| logger.setLevel(level) | ||
|
|
||
| # If no handlers are set, add a StreamHandler with JSON formatting | ||
| if not logger.handlers: | ||
| handler = logging.StreamHandler(sys.stdout) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: I'm curious if this worked in GCP correctly. I believe you said you tested locally and it does; is that correct?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve tested it locally and confirmed the logger outputs JSON in the terminal; if you want, we can also verify the logs in GCP Logs Explorer once the lower environment is set up.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would argue that creating and sending a GCP log to the prod server is a low-risk activity for the following reasons:
Prior to the deployment of any QA environments, and assuming you have the necessary permissions, could you write a Python script using the relevant log-writing snippet to confirm that this structure logs correctly to GCP? I'd have my money on it logging everything as a massive piece of text.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @anth-volk - I tested it by sending logs from local and it’s working correctly — the logs are showing up as structured JSON with the expected fields instead of one large text string in log explorer |
||
| handler.setFormatter(JsonFormatter()) | ||
| logger.addHandler(handler) | ||
| return logger | ||
|
|
||
|
|
||
| def log_struct(event, input_data, message, severity="INFO", logger=None): | ||
| """ | ||
| Implementation-agnostic structured logger. | ||
| """ | ||
| if logger is None: | ||
| logger = get_logger() | ||
|
|
||
| log_func = getattr(logger, severity.lower(), logger.info) | ||
| log_func(message, extra={"event": event, "input": input_data}) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question, not blocking: Why not add the try/catch on this and the policy table below?
I'd rather get this over the line, so please don't block on this, just curious on thinking.