Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

Configure logging to log to Stackdriver #155

Merged
merged 34 commits into from Apr 6, 2017
Merged

Configure logging to log to Stackdriver #155

merged 34 commits into from Apr 6, 2017

Conversation

carise
Copy link
Contributor

@carise carise commented Mar 25, 2017

Logger has a console handler (logging.StreamHandler) and a syslog handler (logging.handlers.SysLogHandler). On GCE instance we install the fluentd logging agent which will transparently pass the syslog entries to stackdriver

resolves #73

@@ -29,11 +29,8 @@
from google.cloud.security.common.data_access.errors import NoResultsError
from google.cloud.security.common.data_access.sql_queries import create_tables
from google.cloud.security.common.data_access.sql_queries import select_data
from google.cloud.security.common.util.log_util import LogUtil
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to add back in logging support?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it wasn't used anywhere in this file.

@@ -18,11 +18,8 @@
import tempfile

from google.cloud.security.common.data_access.errors import CSVFileError
from google.cloud.security.common.util.log_util import LogUtil
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to add back in logging support?

Copy link
Collaborator

@ahoying ahoying left a comment

Choose a reason for hiding this comment

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

Make sure the imports are consistent, since you started cleaning them up in the PR.

We should be importing the module, not the class:
https://google.github.io/styleguide/pyguide.html#Imports

from google.cloud.security.common.gcp_api._base_client import _BaseClient

def is_compute_engine_instance():
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems a bit out of place to put this here. I think a module under ../util would be better.

@@ -0,0 +1,171 @@
# Copyright 2016 Google Inc.
Copy link
Collaborator

Choose a reason for hiding this comment

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

How will this stay in sync with the file in google-cloud-python?

FLAGS = flags.FLAGS
flags.DEFINE_boolean('use_cloud_logging', False,
'Use Cloud Logging, if available.')
flags.DEFINE_boolean('nouse_cloud_logging', False, 'Do not use Cloud Logging.')
Copy link
Collaborator

Choose a reason for hiding this comment

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

DEFINE_boolean automatically creates the no version of the flag, you don't have to do that yourself. The no version will set the flag value False.

And based on the code below, the default value should be None, not False.


# Determine whether to use cloud logger based on environment.
if should_use_cloud_logger is None:
should_use_cloud_logger = is_gce
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be simplified to not require the should_use_cloud_logger var and just the following.

if FLAGS.use_cloud_logging or (FLAGS.use_cloud_logging is None and is_gce):
...

An instance of the configured logger.
"""
formatter = logging.Formatter(LOG_FORMAT)
console_handler = logging.StreamHandler()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we default to SysLogHandler instead? Or maybe use logging.config.fileConfig and include a default logging configuration that can be overridden by changing the configuration file rather than changing the code?

import logging

from google.cloud.security.common.gcp_api._base_client import _BaseClient
# pylint: disable=line-too-long
Copy link
Collaborator

Choose a reason for hiding this comment

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

You need to re-enable this check after the imports to catch the other places in this file where line is too long.

# pylint: disable=line-too-long
"""Cloud Logging Handler.

See: https://github.com/GoogleCloudPlatform/google-cloud-python/blob/master/logging/google/cloud/logging/handlers/handlers.py
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there an issue with just directly using google-cloud-python instead of importing pieces of it? How do we get patches / updates if there are bug fixes?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 on not importing pieces of code like this if we can avoid it. But the issue is different versions of oauth2client being used. Have other people done something similar to here?

Copy link
Contributor

@mirons-google mirons-google left a comment

Choose a reason for hiding this comment

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

Nice! Thanks for working through this one.


Most of this code has been lifted from:

https://github.com/GoogleCloudPlatform/google-cloud-python/blob/master/logging/google/cloud/logging
Copy link
Contributor

Choose a reason for hiding this comment

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

Does licensing allow this? Should we just add to third_party?

"""Convert a timestamp to a string.

Args:
:type value: :class:`datetime.datetime`
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: make pydoc match to the rest of the code-base. Fix throughout please.

from google.cloud.security.common.gcp_api._base_client import _BaseClient

def is_compute_engine_instance():
Copy link
Contributor

Choose a reason for hiding this comment

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

Do callers need the error msg or can we simplify this by just returning a boolean?

# See the License for the specific language governing permissions and
# limitations under the License.

"""Module containing base class for logging transport."""
Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't we just pip install google-cloud-logging and use it as a dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

googleapiclient and google-cloud-python don't play together at all. installing both breaks the entire environment.

console_handler.setFormatter(formatter)
logger_instance = logging.getLogger(module_name)
logger_instance.addHandler(console_handler)
logger_instance.setLevel(logging.INFO)
Copy link
Contributor

Choose a reason for hiding this comment

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

We might want to look into making this an argument at execution.

Args:
module_name: The name of the module for which to configure logging.
"""
(is_gce, _) = compute.is_compute_engine_instance()
Copy link
Contributor

Choose a reason for hiding this comment

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

See my comment above about not needing the error message. I suggest just returning the boolean result.

logger_instance = logging.getLogger(module_name)
logger_instance.addHandler(cloud_handler)

if FLAGS.debug:
Copy link
Contributor

Choose a reason for hiding this comment

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

Why isn't this done in get_logger? It could be confusing to debug the code to understand where this is getting set if we set verbosity in two different spots.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you can't use flags until they are parsed, which happens in app.run(). So the strategy is to attach the default log handler at the toplevel (e.g. module import) and then attach the stackdriver handler after app.run().

@carise
Copy link
Contributor Author

carise commented Mar 31, 2017

I haven't cleaned up all the imports yet, mostly the ones that were nearby the log_util import.

Changed logger to use the SysLogHandler and removed the cloud logging related stuff. PTAL.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 65.867% when pulling 06d2cb5 on configure-logging into 8e614ba on master.

@@ -87,11 +88,11 @@ def test_get_loaded_count(self):
def test_error_is_handled_in_get_loaded_count(self):
"""Test error from get_loaded_count is handled."""

self.pipeline.logger = mock.create_autospec(
LogUtil).setup_logging('foo')
base_pipeline.LOGGER = mock.create_autospec(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@blueandgold FYI I tweaked your pipeline unit tests to reference the [MODULE_NAME].LOGGER property and made the pipeline.logger property a global "LOGGER" variable to be consistent across the codebase. Let me know if this looks ok; I'm not totally sure what's the best way here.

Copy link
Contributor

Choose a reason for hiding this comment

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

No problem if that works. 👍

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 66.167% when pulling f2876d7 on configure-logging into 7d4757d on master.

@carise carise merged commit 009f57d into master Apr 6, 2017
@carise carise deleted the configure-logging branch April 6, 2017 00:15
@carise carise changed the title Configure logging to log to Stackdriver (when flag is set) Configure logging to log to Stackdriver Aug 31, 2017
@blueandgold
Copy link
Contributor

Adding cla: yes label, as the PR author is a googler at the time of this PR was created.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The application and all modules should write logs to stackdriver if configured
5 participants