Skip to content
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

Log statements are not grouped to parent request in App Engine Standard P3 #110

Closed
MeLight opened this issue Dec 3, 2020 · 17 comments · Fixed by #129
Closed

Log statements are not grouped to parent request in App Engine Standard P3 #110

MeLight opened this issue Dec 3, 2020 · 17 comments · Fixed by #129
Assignees
Labels
api: logging Issues related to the googleapis/python-logging API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@MeLight
Copy link

MeLight commented Dec 3, 2020

Environment details

  • OS type and version: App Engine Python 3 Standard

Steps to reproduce

  1. Add couple of logging statements
  2. Go to Logs Explorer on your cloud console

Code example

import google.cloud.logging
import logging

client = google.cloud.logging.Client()

client.get_default_handler()
client.setup_logging()

logging.info("Testing lines")
logging.info("Again!")

Result:
image
As you can see every statement is on it's own line, as opposed to what's expected - the statements should be grouped under one log like in App Engine Standard Python2
image

How to group the statements to the parent request?

@product-auto-label product-auto-label bot added the api: logging Issues related to the googleapis/python-logging API. label Dec 3, 2020
@yoshi-automation yoshi-automation added triage me I really want to be triaged. 🚨 This issue needs some love. labels Dec 4, 2020
@snarfed
Copy link

snarfed commented Dec 8, 2020

I'm also seeing this, no matter what I try. Looks like it's the default with google-cloud-logging on App Engine Standard: the built in Python root logger sends to Cloud Logging, with resource type gae_app and log name projects/[PROJECT]/logs/app - good! - but those log lines aren't attached and rendered with the appengine.googleapis.com/request_log log entry.

I first noticed this change when I migrated to App Engine Python 3 a while back. I managed to fix it for google-cloud-logging 1.x with the code below, which I found here:

import google.cloud.logging
from google.cloud.logging.handlers import AppEngineHandler, setup_logging
logging_client = google.cloud.logging.Client()
setup_logging(AppEngineHandler(logging_client, name='stdout'))

... but this no longer works with google-cloud-logging 2.0. I've tried a bunch of variants, including no manual setup at all (ie relying on the default integration on App Engine), but no luck so far.

@daniel-sanche daniel-sanche added priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. and removed triage me I really want to be triaged. labels Dec 8, 2020
@yoshi-automation yoshi-automation removed the 🚨 This issue needs some love. label Dec 8, 2020
@daniel-sanche
Copy link
Contributor

Thanks the the report. We're working on improving the cross-platform tests to make sure everything's consistent across GCP platforms, and this bug should be fixed by that effort. I'll try to bump of the priority of this one though, and see if I can fix it a bit earlier

What framework are you using for your web server to handle these requests?

@snarfed
Copy link

snarfed commented Dec 9, 2020

Thank you @daniel-sanche! Sounds good. I'll also try downgrading to 1.x in the meantime to see if that fixes it.

I'm on webapp2 (don't judge 😆), v3.0.0b1 for Python 3 support. My app is open source. Here's its current google-cloud-logging setup code.

@daniel-sanche
Copy link
Contributor

@MeLight
I tried out a deployment on AppEngine standard today, and I was able to see grouping as normal (although I did see duplicate logs, and I saw the child logs both at the root, and under the request):
image

Here's the doumentation for how grouping works from the go library. The parent should be created automatically for you on AppEngine. Is the trace id being set properly in your logs? It should be set automatically using flask and django, but it may not be set if you're using a different web framework

@daniel-sanche
Copy link
Contributor

@snarfed

Unfortunately I don't think we can fully support webapp2 going forward. They only officially support Python 2, and that's been dropped by GCP libraries going forward. I don't think we can justify maintaining tests/integrations for a library that doesn't officially support Python 3 yet.

What I will do though, is make sure you have a way to manually set the trace id on your logs. I'll work on that today

@MeLight
Copy link
Author

MeLight commented Dec 10, 2020

@daniel-sanche thanks for the reply. I'm using Flask. I'm not sure it's set correctly. Where do I check/how do I set the trace?

@daniel-sanche
Copy link
Contributor

If it's set properly, you should see a trace field as part of your Log Entry payload. Your payload structure should look something like mine from my image. It would be helpful if you could attach a screenshot of your current logs

Currently the trace is set automatically for the library, but I'm working on a feature to let users manually override the value

@MeLight
Copy link
Author

MeLight commented Dec 13, 2020

@daniel-sanche nope, no trace.
image

@snarfed
Copy link

snarfed commented Dec 15, 2020

What I will do though, is make sure you have a way to manually set the trace id on your logs. I'll work on that today

Thanks again for looking at this! Any progress so far? Let me know if there's anything I can do to help.

@daniel-sanche
Copy link
Contributor

nope, no trace.

Hmm, and you said you're using flask on App Engine Standard? And you ran client.setup_logging()? That should automatically add trace ids to your logs. If you can share some more code with me I can try to debug further.

The root of your issue is that the trace ids aren't being added. If we can solve that, you should start seeing the grouping work as expected

@daniel-sanche
Copy link
Contributor

Thanks again for looking at this! Any progress so far? Let me know if there's anything I can do to help.

I opened two PRs around this (#120, #129), when they are merged, you will be able to add traces manually:

trace_header = webapp2.get_request().headers.get("X-CLOUD-TRACE-CONTEXT")
trace_id = trace_header.split("/", 1)[0]

logging.info('log test', extra={'trace':trace_id})

Unfortunately with the holidays coming up, we're going to be on a release freeze soon, so I likely won't be able to push the release until January

@snarfed
Copy link

snarfed commented Dec 22, 2020

Thanks @daniel-sanche! I tried this just now, using your sample code, but it didn't seem to work. Log browser (legacy) screenshot below, app log entry above, HTTP request below. I see the trace id in the HTTP request, and I emitted the trace id attached in extra in the the app log line, and they match, but I don't see it in the app log's fields. Should I?

image

Here's my setup_logging invocation:

    from google.cloud.logging.handlers import AppEngineHandler, setup_logging
    setup_logging(AppEngineHandler(logging_client, name='stdout'),
                  log_level=logging.DEBUG)

@snarfed
Copy link

snarfed commented Dec 22, 2020

(I installed your PR with git+https://github.com/snarfed/python-logging.git@manual_data#egg=manual_data in requirements.txt.)

snarfed added a commit to snarfed/webutil that referenced this issue Dec 31, 2020
This reverts commit 13e29b9.

...temporarily, until we figure out googleapis/python-logging#110.
snarfed added a commit to snarfed/oauth-dropins that referenced this issue Dec 31, 2020
snarfed added a commit to snarfed/oauth-dropins that referenced this issue Dec 31, 2020
snarfed added a commit to snarfed/granary that referenced this issue Dec 31, 2020
snarfed added a commit to snarfed/bridgy-fed that referenced this issue Dec 31, 2020
@snarfed
Copy link

snarfed commented Dec 31, 2020

I've downgraded to 1.15.1 for now. We can figure out explicit trace id in the new year!

snarfed added a commit to snarfed/bridgy that referenced this issue Jan 1, 2021
@snarfed
Copy link

snarfed commented Jan 7, 2021

Fwiw, I just noticed that this is also tracked (I guess?) in https://issuetracker.google.com/issues/118770775.

snarfed added a commit to snarfed/webutil that referenced this issue Mar 6, 2021
…e id

makes log lines attach to their HTTP request and show grouped in cloud console log browser. google-cloud-logging used to do this automatically for webapp2, based on the X-Cloud-Trace-Context header, but it dropped webapp2 as of google-cloud-logging 2.0.

background:
googleapis/python-logging#110 (comment)
googleapis/python-logging#149 (comment)

also note that AppEngineHandler is evidently deprecated, so I may need to port that whole class into webutil eventually. :(
googleapis/python-logging#202
@snarfed
Copy link

snarfed commented Mar 6, 2021

Figured out my problem. I was still using AppEngineHandler, which seemed not to cooperate with the new extra kwarg. When I dropped that and switched to a plain vanilla logging client, it worked. Looking at AppEngineHandler.emit, if the trace id in extra ends up in record.trace, it seems like it should still be ok, but evidently not. 🤷

I'll also plug @oittaa's #149 (comment) for lifting X-Cloud-Trace-Context into the log record's trace id automatically, I'd obviously prefer that too!

@snarfed
Copy link

snarfed commented Mar 6, 2021

Here's the shim log handler class I added that extracts the trace header from webapp2:

class Webapp2TraceHandler(AppEngineHandler):
  """Log handler that adds trace id based on webapp2 request header.

  https://github.com/googleapis/python-logging/issues/110#issuecomment-745534629
  https://github.com/googleapis/python-logging/issues/149#issuecomment-782693201

  Also note that AppEngineHandler is evidently deprecated, so I may need to
  port that whole class into webutil eventually. :(
  https://github.com/googleapis/python-logging/issues/202
  """
  def emit(self, record):
    try:
      import webapp2
      trace = webapp2.get_request().headers.get('X-Cloud-Trace-Context')
      if trace:
        trace_id = trace.split('/', 1)[0]
        record.trace = f'projects/{APP_ID}/traces/{trace_id}'
    except (ImportError, AssertionError):
      pass

    return super().emit(record)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: logging Issues related to the googleapis/python-logging API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants