Skip to content

feat: implement logger #121

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 12 commits into from
Oct 31, 2023
Merged

feat: implement logger #121

merged 12 commits into from
Oct 31, 2023

Conversation

exaby73
Copy link
Contributor

@exaby73 exaby73 commented Jul 18, 2023

Closes #79

@exaby73 exaby73 marked this pull request as ready for review July 19, 2023 11:32
@Salakar Salakar changed the title Implement logger feat: implement logger Aug 4, 2023
@exaby73
Copy link
Contributor Author

exaby73 commented Sep 25, 2023

Demo of logging

Sample code
from firebase_functions import https_fn, logger, options
from firebase_admin import initialize_app

options.set_global_options(max_instances=10)

initialize_app()


@https_fn.on_request()
def on_request_example(req: https_fn.Request) -> https_fn.Response:
    args = req.args
    logger.log(message=f'Log from function: ', args=args)
    return https_fn.Response('OK')

After deployment via firebase deploy --only functions, you paste the generated link in your browser and add any query params which will be translated into the args variable used in the function.

For example: https://<generated>.run.app?foo=bar

Result in Cloud Logging
image

Note: when selecting the Cloud Function from Cloud Logging, it generates the following query:

resource.type="cloud_function"
resource.labels.function_name="on_request_example"

This unfortunately doesn't show our logs. Instead, if you select the service name (same as function name) from Cloud Run Revision, it'll generate the following query:

resource.type="cloud_run_revision"
resource.labels.service_name="on-request-example"

Alternatively, you could directly paste this query, replacing resource.labels.service_name

@taeold
Copy link
Collaborator

taeold commented Sep 28, 2023

q: why does the example you shared in #121 (comment) emit a textPayload not a jsonPayload as I'd expect when you give the log a structured data like a dictionary?

@exaby73
Copy link
Contributor Author

exaby73 commented Oct 3, 2023

@taeold The code was adapted from the node logger

@taeold
Copy link
Collaborator

taeold commented Oct 10, 2023

@exaby73 I'm not sure I understand what you mean. The purpose of nodejs logger is so that it's easy to emit structured log entry from valid JS object and not to emit them as just text message.

e.g.

exports.helloLogs = functions.https.onRequest(async (request, response) => {
  functions.logger.warn("Hello wolrd!", { foo: "bar" });
  response.send("hello world");
});

image

If the python logger isn't doing any work to generate structued logs using jsonPayload and can't set appropriate logging levels that corresponds to logging levels in Cloud Logging, then it's no more useful than print() calls.

Can you confirm if:

  1. Python logger is capable of emitting structured logs based on dictionary input
  2. Python logger sets correct logging level

@exaby73
Copy link
Contributor Author

exaby73 commented Oct 19, 2023

@taeold I've updated the logger to support jsonPayload. The *args will be joined with a space to produce the message key and the **kwargs will be spread into the jsonPayload. Here is the result of calling logger.log("Hello World!", foo="Bar"):

image

@@ -114,7 +114,7 @@ def _auth_user_record_from_token_data(token_data: dict[str, _typing.Any]):
return AuthUserRecord(
uid=token_data["uid"],
email=token_data.get("email"),
email_verified=token_data.get("email_verified"),
email_verified=bool(token_data.get("email_verified")),
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm this feels unrelated? should we make a separate PR for this or is this necessary for log impl?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mypy was updated and was causing CI to fail because the types didn't match. I'm open to suggestions. This is mainly a linting fix

Copy link

Choose a reason for hiding this comment

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

maybe clearest to make the mypy related linting fixes in a separate PR, and have only the logging things here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without these, the CI doesn't pass. Possibly can make a separate PR for these that can merged into main, before we merge this in so that we can have those changes rebased into this branch. I'll look into doing this next week :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

eh let's save ourselves some time and push it in this PR.

@@ -387,6 +387,8 @@ def timestamp_conversion(time: str) -> _dt.datetime:
elif precision_timestamp == PrecisionTimestamp.SECONDS:
return second_timestamp_conversion(time)

raise ValueError("Invalid timestamp")
Copy link
Collaborator

Choose a reason for hiding this comment

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

likewise - related to log impl?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again a lint failure here because the function wasn't ending in a return and the if, elif is not exhaustive

@@ -114,7 +114,7 @@ def _auth_user_record_from_token_data(token_data: dict[str, _typing.Any]):
return AuthUserRecord(
uid=token_data["uid"],
email=token_data.get("email"),
email_verified=token_data.get("email_verified"),
email_verified=bool(token_data.get("email_verified")),
Copy link
Collaborator

Choose a reason for hiding this comment

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

eh let's save ourselves some time and push it in this PR.

@taeold taeold merged commit 90211ab into main Oct 31, 2023
@taeold
Copy link
Collaborator

taeold commented Oct 31, 2023

@exaby73 thank you!!

@exaby73 exaby73 deleted the feat/logger branch October 31, 2023 16:22
@jaclar jaclar mentioned this pull request Nov 23, 2023
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.

Add a logger module to integrate with Cloud Logging
3 participants