Skip to content

Commit c767764

Browse files
author
Jon Wayne Parrott
committed
Moving logging example.
1 parent 9238959 commit c767764

File tree

11 files changed

+227
-1
lines changed

11 files changed

+227
-1
lines changed

appengine/logging/__init__.py

Whitespace-only changes.

appengine/logging/reading_logs/__init__.py

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
runtime: python27
2+
threadsafe: yes
3+
api_version: 1
4+
5+
handlers:
6+
- url: .*
7+
script: main.app
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Copyright 2015 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Sample Google App Engine application that demonstrates how to use the App
17+
Engine Log Service API to read application logs.
18+
"""
19+
20+
# [START all]
21+
import base64
22+
import datetime
23+
from itertools import islice
24+
from textwrap import dedent
25+
import time
26+
27+
from google.appengine.api.logservice import logservice
28+
import webapp2
29+
30+
31+
def get_logs(offset=None):
32+
# Logs are read backwards from the given end time. This specifies to read
33+
# all logs up until now.
34+
end_time = time.time()
35+
36+
logs = logservice.fetch(
37+
end_time=end_time,
38+
offset=offset,
39+
minimum_log_level=logservice.LOG_LEVEL_INFO,
40+
include_app_logs=True)
41+
42+
return logs
43+
44+
45+
def format_log_entry(entry):
46+
# Format any application logs that happened during this request.
47+
logs = []
48+
for log in entry.app_logs:
49+
date = datetime.datetime.fromtimestamp(
50+
log.time).strftime('%D %T UTC')
51+
logs.append('Date: {}, Message: {}'.format(
52+
date, log.message))
53+
54+
# Format the request log and include the application logs.
55+
date = datetime.datetime.fromtimestamp(
56+
entry.end_time).strftime('%D %T UTC')
57+
58+
output = dedent("""
59+
Date: {}
60+
IP: {}
61+
Method: {}
62+
Resource: {}
63+
Logs:
64+
""".format(date, entry.ip, entry.method, entry.resource))
65+
66+
output += '\n'.join(logs)
67+
68+
return output
69+
70+
71+
class MainPage(webapp2.RequestHandler):
72+
def get(self):
73+
offset = self.request.get('offset', None)
74+
75+
if offset:
76+
offset = base64.urlsafe_b64decode(str(offset))
77+
78+
# Get the logs given the specified offset.
79+
logs = get_logs(offset=offset)
80+
81+
# Output the first 10 logs.
82+
log = None
83+
for log in islice(logs, 10):
84+
self.response.write(
85+
'<pre>{}</pre>'.format(format_log_entry(log)))
86+
87+
offset = log.offset
88+
89+
if not log:
90+
self.response.write('No log entries found.')
91+
92+
# Add a link to view more log entries.
93+
elif offset:
94+
self.response.write(
95+
'<a href="/?offset={}"">More</a'.format(
96+
base64.urlsafe_b64encode(offset)))
97+
98+
99+
app = webapp2.WSGIApplication([
100+
('/', MainPage)
101+
], debug=True)
102+
103+
# [END all]
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from tests import AppEngineTestbedCase
16+
import webtest
17+
18+
from . import main
19+
20+
21+
class TestReadingLogs(AppEngineTestbedCase):
22+
def setUp(self):
23+
super(TestReadingLogs, self).setUp()
24+
25+
self.app = webtest.TestApp(main.app)
26+
27+
def test_get(self):
28+
response = self.app.get('/')
29+
self.assertEqual(response.status_int, 200)
30+
self.assertTrue('No log entries found' in response.text)
31+
self.assertTrue('More' not in response.text)

appengine/logging/writing_logs/__init__.py

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
runtime: python27
2+
threadsafe: yes
3+
api_version: 1
4+
5+
handlers:
6+
- url: .*
7+
script: main.app
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright 2015 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Sample Google App Engine application that demonstrates using the standard
17+
Python logging package. Logs are automatically collected and available via
18+
the Google Cloud Console.
19+
"""
20+
21+
# [START all]
22+
import logging
23+
24+
import webapp2
25+
26+
27+
class MainPage(webapp2.RequestHandler):
28+
def get(self):
29+
logging.debug('This is a debug message')
30+
logging.info('This is an info message')
31+
logging.warning('This is a warning message')
32+
logging.error('This is an error message')
33+
logging.critical('This is a critical message')
34+
35+
try:
36+
raise ValueError('This is a sample value error.')
37+
except ValueError:
38+
logging.exception('A example exception log.')
39+
40+
self.response.out.write('Logging example.')
41+
42+
43+
app = webapp2.WSGIApplication([
44+
('/', MainPage)
45+
], debug=True)
46+
47+
# [END all]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from tests import AppEngineTestbedCase
16+
import webtest
17+
18+
from . import main
19+
20+
21+
class TestWritingLogs(AppEngineTestbedCase):
22+
def setUp(self):
23+
super(TestWritingLogs, self).setUp()
24+
25+
self.app = webtest.TestApp(main.app)
26+
27+
def test_get(self):
28+
response = self.app.get('/')
29+
self.assertEqual(response.status_int, 200)
30+
self.assertTrue('Logging example' in response.text)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Flask==0.10.1
2-
gunicorn==19.3.0
2+
gunicorn==19.4.1

tests/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def setUp(self):
9494
self.testbed.init_taskqueue_stub(root_path='tests/resources')
9595
self.taskqueue_stub = self.testbed.get_stub(
9696
testbed.TASKQUEUE_SERVICE_NAME)
97+
self.testbed.init_logservice_stub()
9798

9899
def tearDown(self):
99100
super(AppEngineTestbedCase, self).tearDown()

0 commit comments

Comments
 (0)