Skip to content

Commit

Permalink
Merge pull request #146 from GoogleCloudPlatform/logging
Browse files Browse the repository at this point in the history
Moving logging example.
  • Loading branch information
Jonathan Wayne Parrott committed Dec 4, 2015
2 parents 9238959 + c767764 commit 52ce21f
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 1 deletion.
Empty file added appengine/logging/__init__.py
Empty file.
Empty file.
7 changes: 7 additions & 0 deletions appengine/logging/reading_logs/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: .*
script: main.app
103 changes: 103 additions & 0 deletions appengine/logging/reading_logs/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Sample Google App Engine application that demonstrates how to use the App
Engine Log Service API to read application logs.
"""

# [START all]
import base64
import datetime
from itertools import islice
from textwrap import dedent
import time

from google.appengine.api.logservice import logservice
import webapp2


def get_logs(offset=None):
# Logs are read backwards from the given end time. This specifies to read
# all logs up until now.
end_time = time.time()

logs = logservice.fetch(
end_time=end_time,
offset=offset,
minimum_log_level=logservice.LOG_LEVEL_INFO,
include_app_logs=True)

return logs


def format_log_entry(entry):
# Format any application logs that happened during this request.
logs = []
for log in entry.app_logs:
date = datetime.datetime.fromtimestamp(
log.time).strftime('%D %T UTC')
logs.append('Date: {}, Message: {}'.format(
date, log.message))

# Format the request log and include the application logs.
date = datetime.datetime.fromtimestamp(
entry.end_time).strftime('%D %T UTC')

output = dedent("""
Date: {}
IP: {}
Method: {}
Resource: {}
Logs:
""".format(date, entry.ip, entry.method, entry.resource))

output += '\n'.join(logs)

return output


class MainPage(webapp2.RequestHandler):
def get(self):
offset = self.request.get('offset', None)

if offset:
offset = base64.urlsafe_b64decode(str(offset))

# Get the logs given the specified offset.
logs = get_logs(offset=offset)

# Output the first 10 logs.
log = None
for log in islice(logs, 10):
self.response.write(
'<pre>{}</pre>'.format(format_log_entry(log)))

offset = log.offset

if not log:
self.response.write('No log entries found.')

# Add a link to view more log entries.
elif offset:
self.response.write(
'<a href="/?offset={}"">More</a'.format(
base64.urlsafe_b64encode(offset)))


app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)

# [END all]
31 changes: 31 additions & 0 deletions appengine/logging/reading_logs/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tests import AppEngineTestbedCase
import webtest

from . import main


class TestReadingLogs(AppEngineTestbedCase):
def setUp(self):
super(TestReadingLogs, self).setUp()

self.app = webtest.TestApp(main.app)

def test_get(self):
response = self.app.get('/')
self.assertEqual(response.status_int, 200)
self.assertTrue('No log entries found' in response.text)
self.assertTrue('More' not in response.text)
Empty file.
7 changes: 7 additions & 0 deletions appengine/logging/writing_logs/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: .*
script: main.app
47 changes: 47 additions & 0 deletions appengine/logging/writing_logs/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Sample Google App Engine application that demonstrates using the standard
Python logging package. Logs are automatically collected and available via
the Google Cloud Console.
"""

# [START all]
import logging

import webapp2


class MainPage(webapp2.RequestHandler):
def get(self):
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

try:
raise ValueError('This is a sample value error.')
except ValueError:
logging.exception('A example exception log.')

self.response.out.write('Logging example.')


app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)

# [END all]
30 changes: 30 additions & 0 deletions appengine/logging/writing_logs/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tests import AppEngineTestbedCase
import webtest

from . import main


class TestWritingLogs(AppEngineTestbedCase):
def setUp(self):
super(TestWritingLogs, self).setUp()

self.app = webtest.TestApp(main.app)

def test_get(self):
response = self.app.get('/')
self.assertEqual(response.status_int, 200)
self.assertTrue('Logging example' in response.text)
2 changes: 1 addition & 1 deletion managed_vms/hello_world_custom/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Flask==0.10.1
gunicorn==19.3.0
gunicorn==19.4.1
1 change: 1 addition & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def setUp(self):
self.testbed.init_taskqueue_stub(root_path='tests/resources')
self.taskqueue_stub = self.testbed.get_stub(
testbed.TASKQUEUE_SERVICE_NAME)
self.testbed.init_logservice_stub()

def tearDown(self):
super(AppEngineTestbedCase, self).tearDown()
Expand Down

0 comments on commit 52ce21f

Please sign in to comment.