appengine 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +20 -29
- data/lib/appengine.rb +2 -1
- data/lib/appengine/env.rb +4 -14
- data/lib/appengine/railtie.rb +1 -38
- data/lib/appengine/version.rb +1 -1
- data/test/test_env.rb +5 -25
- metadata +26 -8
- data/lib/appengine/logger.rb +0 -188
- data/test/test_logger.rb +0 -151
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4841b00bed08c35d62dfd337ccd15cf5df775de9
|
4
|
+
data.tar.gz: a3158e01aaccb61471b504d7a66983c24a58a560
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27445f16fa0d99b081992a8ea08427730dc4375b05f7a083763c5e6f9ee338652a6e8798eb47bc5293e51d9a4a22fe3c79322ca934284973826c3f7f6faf5741
|
7
|
+
data.tar.gz: 734a601f646ee785f5af7f9cbdf77af271a6e2bc25ae80abeaad0a8c92a26562462d2be953fa981ea4a04b48b1646c316dc08022658ad4d954e755dc5fb48406
|
data/README.md
CHANGED
@@ -9,7 +9,14 @@ environment.
|
|
9
9
|
|
10
10
|
Currently, it includes:
|
11
11
|
|
12
|
-
*
|
12
|
+
* Automatic Stackdriver instrumentation for Rails apps. This means logs,
|
13
|
+
error reports, and latency traces are reported to the cloud console.
|
14
|
+
* A placeholder for a class that provides app engine environment information
|
15
|
+
such as project ID and VM info.
|
16
|
+
|
17
|
+
Planned for the near future:
|
18
|
+
|
19
|
+
* Streamlined implementation of health checks and other lifecycle hooks.
|
13
20
|
|
14
21
|
For more information on using Google Cloud Platform to deploy Ruby apps,
|
15
22
|
please visit http://cloud.google.com/ruby
|
@@ -27,34 +34,18 @@ may need to include the line:
|
|
27
34
|
require "appengine"
|
28
35
|
|
29
36
|
in your `config/application.rb` file if you aren't already requiring all
|
30
|
-
bundled gems.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
tools to make that happen.
|
43
|
-
|
44
|
-
If you are using Ruby on Rails, and you do not otherwise customize your
|
45
|
-
Rails logger, then the provided Railtie will direct your logs to the Cloud
|
46
|
-
Console "out of the box". Normally, this is configured to take effect when
|
47
|
-
running in the `production` environment, but you may also configure it for
|
48
|
-
other environments. See the documentation for the `AppEngine::Railtie` class
|
49
|
-
for more details.
|
50
|
-
|
51
|
-
If you are running a different Rack-based framework such as Sinatra, you
|
52
|
-
should install the provided `AppEngine::Logger::Middleware` in your middleware
|
53
|
-
stack. This should be installed instead of the normal `Rack::Logger`. It will
|
54
|
-
automatically create a logger that directs entries to the Cloud Console, and
|
55
|
-
will make it available via the standard `Rack::RACK_LOGGER` key in the Rack
|
56
|
-
environment. You may also create your own logger directly using the
|
57
|
-
`AppEngine::Logger.create()` method.
|
37
|
+
bundled gems.
|
38
|
+
|
39
|
+
## Logging and monitoring
|
40
|
+
|
41
|
+
This library automatically installs the "stackdriver" gem, which instruments
|
42
|
+
your application to report logs, unhandled exceptions, and latency traces to
|
43
|
+
your project's Google Cloud Console. For more information on the application
|
44
|
+
monitoring features of Google App Engine, see:
|
45
|
+
|
46
|
+
* [google-cloud-logging instrumentation](http://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-logging/latest/guides/instrumentation)
|
47
|
+
* [google-cloud-error_reporting instrumentation](http://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-error_reporting/latest/guides/instrumentation)
|
48
|
+
* [google-cloud-trace instrumentation](http://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-trace/latest/guides/instrumentation)
|
58
49
|
|
59
50
|
## Development and support
|
60
51
|
|
data/lib/appengine.rb
CHANGED
data/lib/appengine/env.rb
CHANGED
@@ -16,25 +16,15 @@
|
|
16
16
|
|
17
17
|
module AppEngine
|
18
18
|
|
19
|
-
|
20
|
-
#
|
19
|
+
##
|
20
|
+
# A collection of functions for extracting App Engine environment information.
|
21
21
|
#
|
22
|
-
# A collection of functions for extracting App Engine environment information
|
23
|
-
# from the Rack environment
|
24
|
-
|
25
22
|
module Env
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
# ID was found.
|
30
|
-
|
31
|
-
def self.extract_trace_id(env)
|
32
|
-
trace_context = env['HTTP_X_CLOUD_TRACE_CONTEXT'].to_s
|
33
|
-
return nil if trace_context.empty?
|
34
|
-
return trace_context.sub(/\/.*/, '')
|
24
|
+
def self.app_engine?
|
25
|
+
::ENV["GAE_INSTANCE"] ? true : false
|
35
26
|
end
|
36
27
|
|
37
|
-
|
38
28
|
end
|
39
29
|
|
40
30
|
end
|
data/lib/appengine/railtie.rb
CHANGED
@@ -31,25 +31,7 @@ module AppEngine
|
|
31
31
|
#
|
32
32
|
# === Configuration
|
33
33
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# [<tt>config.appengine.use_cloud_logger</tt>]
|
37
|
-
# Set to true to cause the Rails logger to log to Google Cloud Console.
|
38
|
-
# By default, this is true in the production environment and false in
|
39
|
-
# all other environments. You may override this setting in individual
|
40
|
-
# environment config files.
|
41
|
-
#
|
42
|
-
# [<tt>config.appengine.logfile</tt>]
|
43
|
-
# The path to the log file when <tt>use_cloud_logger</tt> is active.
|
44
|
-
# You should normally leave this as the default when deploying to Google
|
45
|
-
# App Engine, but you may set it to a different path if you want to test
|
46
|
-
# logging in a development environment.
|
47
|
-
#
|
48
|
-
# [<tt>config.appengine.trace_id_var</tt>]
|
49
|
-
# The name of a fiber-local variable to store the current request's trace
|
50
|
-
# ID. This is used to communicate request and trace information between
|
51
|
-
# Rack and the cloud logger. You may change it if you need to control
|
52
|
-
# fiber-local variable names.
|
34
|
+
# This is a placeholder for now.
|
53
35
|
|
54
36
|
class Railtie < ::Rails::Railtie
|
55
37
|
|
@@ -57,25 +39,6 @@ module AppEngine
|
|
57
39
|
|
58
40
|
config.appengine = ::ActiveSupport::OrderedOptions.new
|
59
41
|
|
60
|
-
config.appengine.use_cloud_logger = ::Rails.env.to_s == 'production'
|
61
|
-
config.appengine.logfile = ::AppEngine::Logger::DEFAULT_LOG_FILENAME
|
62
|
-
config.appengine.trace_id_var = ::AppEngine::Logger::DEFAULT_TRACE_ID_VAR
|
63
|
-
|
64
|
-
|
65
|
-
initializer 'google.appengine.logger', before: :initialize_logger do |app|
|
66
|
-
if app.config.appengine.use_cloud_logger
|
67
|
-
app.config.logger = ::AppEngine::Logger.create(
|
68
|
-
logfile: app.config.appengine.logfile,
|
69
|
-
trace_id_var: app.config.appengine.trace_id_var)
|
70
|
-
app.config.log_formatter = app.config.logger.formatter
|
71
|
-
|
72
|
-
app.middleware.insert_before(::Rails::Rack::Logger,
|
73
|
-
::AppEngine::Logger::Middleware,
|
74
|
-
logger: app.config.logger,
|
75
|
-
trace_id_var: app.config.appengine.trace_id_var)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
42
|
# :startdoc:
|
80
43
|
|
81
44
|
end
|
data/lib/appengine/version.rb
CHANGED
data/test/test_env.rb
CHANGED
@@ -23,31 +23,11 @@ module AppEngine
|
|
23
23
|
class TestEnv < ::Minitest::Test # :nodoc:
|
24
24
|
|
25
25
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def test_extract_trace_id_empty
|
34
|
-
env = {'HTTP_X_CLOUD_TRACE_CONTEXT' => ''}
|
35
|
-
trace_id = Env.extract_trace_id(env)
|
36
|
-
assert_nil(trace_id)
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
def test_extract_trace_id_simple
|
41
|
-
env = {'HTTP_X_CLOUD_TRACE_CONTEXT' => 'abcdefg'}
|
42
|
-
trace_id = Env.extract_trace_id(env)
|
43
|
-
assert_equal('abcdefg', trace_id)
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
def test_extract_trace_id_with_suffix
|
48
|
-
env = {'HTTP_X_CLOUD_TRACE_CONTEXT' => 'abcdefg/hijk/lmnop'}
|
49
|
-
trace_id = Env.extract_trace_id(env)
|
50
|
-
assert_equal('abcdefg', trace_id)
|
26
|
+
def test_app_engine
|
27
|
+
::ENV["GAE_INSTANCE"] = "instance-123"
|
28
|
+
assert Env.app_engine?
|
29
|
+
::ENV.delete "GAE_INSTANCE"
|
30
|
+
refute Env.app_engine?
|
51
31
|
end
|
52
32
|
|
53
33
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appengine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Tanner
|
@@ -9,22 +9,42 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: stackdriver
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.4'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.4.1
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - "~>"
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0.4'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.1
|
14
34
|
- !ruby/object:Gem::Dependency
|
15
35
|
name: bundler
|
16
36
|
requirement: !ruby/object:Gem::Requirement
|
17
37
|
requirements:
|
18
38
|
- - "~>"
|
19
39
|
- !ruby/object:Gem::Version
|
20
|
-
version: '1.
|
40
|
+
version: '1.14'
|
21
41
|
type: :development
|
22
42
|
prerelease: false
|
23
43
|
version_requirements: !ruby/object:Gem::Requirement
|
24
44
|
requirements:
|
25
45
|
- - "~>"
|
26
46
|
- !ruby/object:Gem::Version
|
27
|
-
version: '1.
|
47
|
+
version: '1.14'
|
28
48
|
- !ruby/object:Gem::Dependency
|
29
49
|
name: minitest
|
30
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -69,7 +89,7 @@ dependencies:
|
|
69
89
|
version: '4.2'
|
70
90
|
description: The appengine gem is a set of classes, plugins, and tools for integration
|
71
91
|
with Google App Engine. It provides access to the App Engine runtime environment,
|
72
|
-
including logging to the Google Cloud Console and
|
92
|
+
including logging to the Google Cloud Console and interrogation of hosting properties.
|
73
93
|
However, it is not required for deploying your Ruby application to App Engine.
|
74
94
|
email:
|
75
95
|
- adamtanner@google.com
|
@@ -85,11 +105,9 @@ files:
|
|
85
105
|
- Rakefile
|
86
106
|
- lib/appengine.rb
|
87
107
|
- lib/appengine/env.rb
|
88
|
-
- lib/appengine/logger.rb
|
89
108
|
- lib/appengine/railtie.rb
|
90
109
|
- lib/appengine/version.rb
|
91
110
|
- test/test_env.rb
|
92
|
-
- test/test_logger.rb
|
93
111
|
homepage: https://github.com/GoogleCloudPlatform/appengine-ruby
|
94
112
|
licenses:
|
95
113
|
- Apache 2.0
|
@@ -110,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
128
|
version: '0'
|
111
129
|
requirements: []
|
112
130
|
rubyforge_project:
|
113
|
-
rubygems_version: 2.
|
131
|
+
rubygems_version: 2.6.8
|
114
132
|
signing_key:
|
115
133
|
specification_version: 4
|
116
134
|
summary: Google App Engine integration tools
|
data/lib/appengine/logger.rb
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
# Copyright 2016 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
|
-
|
16
|
-
require 'json'
|
17
|
-
require 'logger'
|
18
|
-
|
19
|
-
|
20
|
-
module AppEngine
|
21
|
-
|
22
|
-
|
23
|
-
# == AppEngine Logger integration
|
24
|
-
#
|
25
|
-
# A collection of tools for talking to the StackDriver logs in the Google
|
26
|
-
# Cloud Console.
|
27
|
-
#
|
28
|
-
# For logs to appear in the Google Cloud Console, they must be written in
|
29
|
-
# JSON format to files matching the pattern "/var/log/app_engine/app*.json".
|
30
|
-
# We provide an appropriate formatter, and a LogDevice that omits the
|
31
|
-
# log header line.
|
32
|
-
#
|
33
|
-
# Logs should also be annotated with the request's Trace ID. We provide
|
34
|
-
# a Rack Middleware to extract that ID from the environment and annotate
|
35
|
-
# log entries. It uses a fiber-local variable to store the Trace ID for
|
36
|
-
# the current request being handled by that fiber.
|
37
|
-
|
38
|
-
module Logger
|
39
|
-
|
40
|
-
|
41
|
-
# The name of a fiber-local variable storing the trace ID for the current
|
42
|
-
# request.
|
43
|
-
DEFAULT_TRACE_ID_VAR = :_google_appengine_trace_id
|
44
|
-
|
45
|
-
# The default path to the log file.
|
46
|
-
DEFAULT_LOG_FILENAME = '/var/log/app_engine/app-ruby.json'
|
47
|
-
|
48
|
-
# A map from Ruby severity names to Google Cloud severity names.
|
49
|
-
SEV_MAP = {
|
50
|
-
'DEBUG' => 'DEBUG',
|
51
|
-
'INFO' => 'INFO',
|
52
|
-
'WARN' => 'WARNING',
|
53
|
-
'ERROR' => 'ERROR',
|
54
|
-
'FATAL' => 'CRITICAL'
|
55
|
-
}
|
56
|
-
|
57
|
-
|
58
|
-
# == AppEngie Formatter
|
59
|
-
#
|
60
|
-
# A formatter that generates the appropriate JSON format for log entries.
|
61
|
-
# Pulls the trace ID from the fiber-local variable, if present.
|
62
|
-
#
|
63
|
-
# (see ::Logger::Formatter)
|
64
|
-
|
65
|
-
class Formatter
|
66
|
-
|
67
|
-
|
68
|
-
# Create a new formatter. You may optionally override the fiber-local
|
69
|
-
# variable name used for the trace ID.
|
70
|
-
|
71
|
-
def initialize(trace_id_var: DEFAULT_TRACE_ID_VAR)
|
72
|
-
@trace_id_var = trace_id_var
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
def call(severity, time, progname, msg) # :nodoc:
|
77
|
-
msg = msg.to_s
|
78
|
-
return '' if msg.empty?
|
79
|
-
entry = {
|
80
|
-
message: (progname.to_s != '') ? "#{progname}: #{msg}" : msg,
|
81
|
-
timestamp: {seconds: time.to_i, nanos: time.nsec},
|
82
|
-
severity: SEV_MAP.fetch(severity.to_s, 'CRITICAL')
|
83
|
-
}
|
84
|
-
trace_id = ::Thread.current[@trace_id_var]
|
85
|
-
if trace_id
|
86
|
-
entry[:traceId] = trace_id.to_s
|
87
|
-
end
|
88
|
-
::JSON.generate(entry) + "\n"
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
# == AppEngine LogDevice
|
95
|
-
#
|
96
|
-
# A ::Logger::LogDevice subclass that omits the log header line.
|
97
|
-
|
98
|
-
class LogDevice < ::Logger::LogDevice
|
99
|
-
|
100
|
-
def add_log_header(file) # :nodoc:
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
|
106
|
-
# == Rack Middleware for AppEngine logger
|
107
|
-
#
|
108
|
-
# A Rack middleware that sets the logger in the Rack environment, and
|
109
|
-
# stashes the trace ID for the current request in a fiber-local variable
|
110
|
-
# for the logger to use when formatting log entries.
|
111
|
-
#
|
112
|
-
# In a standard Rack application, you should use this middleware instead
|
113
|
-
# of the standard ::Rack::Logger.
|
114
|
-
|
115
|
-
class Middleware
|
116
|
-
|
117
|
-
|
118
|
-
# Create a new AppEngine logging Middleware.
|
119
|
-
# The argument is an options hash supporting the following keys:
|
120
|
-
#
|
121
|
-
# [<tt>:logger</tt>]
|
122
|
-
# A global logger to use. This should generally be a logger created
|
123
|
-
# by AppEngine::Logger.create(). The middleware sets env["rack.logger"]
|
124
|
-
# accordingly. If omitted, a default logger is created automatically
|
125
|
-
# when the middleware is constructed.
|
126
|
-
# [<tt>:trace_id_var</tt>]
|
127
|
-
# The name of the fiber-local variable to use to stack the trace ID.
|
128
|
-
# Defaults to the value of DEFAULT_TRACE_ID_VAR. You generally should
|
129
|
-
# not need to modify this value unless you need to control fiber-local
|
130
|
-
# variable names.
|
131
|
-
# [<tt>:logfile</tt>]
|
132
|
-
# If you do not specify a <tt>:logger</tt>, a logger is created that
|
133
|
-
# opens this file. Defaults to the value of DEFAULT_LOG_FILENAME.
|
134
|
-
# Generally, you should leave this setting to the default for
|
135
|
-
# deployments, because App Engine expects log files in a particular
|
136
|
-
# location. However, if you want to test log generation into a
|
137
|
-
# different directory in development, you may set it here.
|
138
|
-
|
139
|
-
def initialize(app,
|
140
|
-
logger: nil,
|
141
|
-
trace_id_var: DEFAULT_TRACE_ID_VAR,
|
142
|
-
logfile: DEFAULT_LOG_FILENAME)
|
143
|
-
@app = app
|
144
|
-
@trace_id_var = trace_id_var
|
145
|
-
@logger = logger || Logger.create(trace_id_var: trace_id_var, logfile: logfile)
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
def call(env) # :nodoc:
|
150
|
-
env['rack.logger'] = @logger
|
151
|
-
::Thread.current[@trace_id_var] = Env.extract_trace_id(env)
|
152
|
-
begin
|
153
|
-
@app.call(env)
|
154
|
-
ensure
|
155
|
-
::Thread.current[@trace_id_var] = nil
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
# Creates a new logger for AppEngine that writes to the correct location
|
163
|
-
# using the correct formatting.
|
164
|
-
# The argument is an options hash supporting the following keys:
|
165
|
-
#
|
166
|
-
# [<tt>:trace_id_var</tt>]
|
167
|
-
# The name of the fiber-local variable to use to stack the trace ID.
|
168
|
-
# Defaults to the value of DEFAULT_TRACE_ID_VAR. You generally should
|
169
|
-
# not need to modify this value unless you need to control fiber-local
|
170
|
-
# variable names.
|
171
|
-
# [<tt>:logfile</tt>]
|
172
|
-
# Log file to write to. Defaults to the value of DEFAULT_LOG_FILENAME.
|
173
|
-
# Generally, you should leave this setting to the default for
|
174
|
-
# deployments, because App Engine expects log files in a particular
|
175
|
-
# location. However, if you want to test log generation into a
|
176
|
-
# different directory in development, you may set it here.
|
177
|
-
|
178
|
-
def self.create(trace_id_var: DEFAULT_TRACE_ID_VAR, logfile: DEFAULT_LOG_FILENAME)
|
179
|
-
if logfile.kind_of?(::String)
|
180
|
-
::FileUtils.mkdir_p(::File.dirname(logfile))
|
181
|
-
end
|
182
|
-
logger = ::Logger.new(LogDevice.new(logfile))
|
183
|
-
logger.formatter = Formatter.new(trace_id_var: trace_id_var)
|
184
|
-
logger
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|
188
|
-
end
|
data/test/test_logger.rb
DELETED
@@ -1,151 +0,0 @@
|
|
1
|
-
# Copyright 2016 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
|
-
|
16
|
-
require 'minitest/autorun'
|
17
|
-
require 'appengine'
|
18
|
-
|
19
|
-
|
20
|
-
module AppEngine
|
21
|
-
module Tests # :nodoc:
|
22
|
-
|
23
|
-
class TestFormatter < ::Minitest::Test # :nodoc:
|
24
|
-
|
25
|
-
|
26
|
-
def setup
|
27
|
-
@time_sec = 1461544128
|
28
|
-
@time_nsec = 580791000
|
29
|
-
@time = ::Time.at(@time_sec, @time_nsec / 1000)
|
30
|
-
@trace_id = 'a1b2c3d4e5f6'
|
31
|
-
::Thread.current[::AppEngine::Logger::DEFAULT_TRACE_ID_VAR] = @trace_id
|
32
|
-
@formatter = ::AppEngine::Logger::Formatter.new
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
def test_format_empty
|
37
|
-
result = @formatter.call('ERROR', @time, 'prog', '')
|
38
|
-
assert_equal('', result)
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
def test_format_with_progname
|
43
|
-
result = @formatter.call('ERROR', @time, 'prog', 'this message')
|
44
|
-
assert_equal(
|
45
|
-
"{\"message\":\"prog: this message\"," +
|
46
|
-
"\"timestamp\":{\"seconds\":#{@time_sec},\"nanos\":#{@time_nsec}}," +
|
47
|
-
"\"severity\":\"ERROR\"," +
|
48
|
-
"\"traceId\":\"#{@trace_id}\"}\n",
|
49
|
-
result)
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
def test_format_with_no_trace_id
|
54
|
-
::Thread.current[::AppEngine::Logger::DEFAULT_TRACE_ID_VAR] = nil
|
55
|
-
result = @formatter.call('ERROR', @time, '', 'this message')
|
56
|
-
assert_equal(
|
57
|
-
"{\"message\":\"this message\"," +
|
58
|
-
"\"timestamp\":{\"seconds\":#{@time_sec},\"nanos\":#{@time_nsec}}," +
|
59
|
-
"\"severity\":\"ERROR\"}\n",
|
60
|
-
result)
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
def test_format_with_warning_severity
|
65
|
-
result = @formatter.call('WARN', @time, '', 'this message')
|
66
|
-
assert_equal(
|
67
|
-
"{\"message\":\"this message\"," +
|
68
|
-
"\"timestamp\":{\"seconds\":#{@time_sec},\"nanos\":#{@time_nsec}}," +
|
69
|
-
"\"severity\":\"WARNING\"," +
|
70
|
-
"\"traceId\":\"#{@trace_id}\"}\n",
|
71
|
-
result)
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
def test_format_with_critical_severity
|
76
|
-
result = @formatter.call('FATAL', @time, '', 'this message')
|
77
|
-
assert_equal(
|
78
|
-
"{\"message\":\"this message\"," +
|
79
|
-
"\"timestamp\":{\"seconds\":#{@time_sec},\"nanos\":#{@time_nsec}}," +
|
80
|
-
"\"severity\":\"CRITICAL\"," +
|
81
|
-
"\"traceId\":\"#{@trace_id}\"}\n",
|
82
|
-
result)
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
def test_format_with_unknown_severity
|
87
|
-
result = @formatter.call('UNKNOWN', @time, '', 'this message')
|
88
|
-
assert_equal(
|
89
|
-
"{\"message\":\"this message\"," +
|
90
|
-
"\"timestamp\":{\"seconds\":#{@time_sec},\"nanos\":#{@time_nsec}}," +
|
91
|
-
"\"severity\":\"CRITICAL\"," +
|
92
|
-
"\"traceId\":\"#{@trace_id}\"}\n",
|
93
|
-
result)
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
class TestLogger < ::Minitest::Test # :nodoc:
|
101
|
-
|
102
|
-
|
103
|
-
def test_no_logging
|
104
|
-
lines = run_test do |logger|
|
105
|
-
end
|
106
|
-
assert_equal([], lines)
|
107
|
-
end
|
108
|
-
|
109
|
-
|
110
|
-
def test_basic_log
|
111
|
-
trace_id = "tracetrace"
|
112
|
-
lines = run_test(trace_id) do |logger|
|
113
|
-
logger.progname = "rails"
|
114
|
-
logger.info("Hello")
|
115
|
-
logger.warn("This is a warning")
|
116
|
-
end
|
117
|
-
assert_equal(2, lines.size)
|
118
|
-
assert_log_entry("rails: Hello", "INFO", trace_id, lines[0])
|
119
|
-
assert_log_entry("rails: This is a warning", "WARNING", trace_id, lines[1])
|
120
|
-
end
|
121
|
-
|
122
|
-
|
123
|
-
def assert_log_entry(expected_message, expected_severity, expected_trace_id, line)
|
124
|
-
if line =~ /^\{"message":"(.*)","timestamp":\{"seconds":\d+,"nanos":\d+\},"severity":"(\w+)"(,"traceId":"(\w+)")?\}\n$/
|
125
|
-
message = $1
|
126
|
-
severity = $2
|
127
|
-
trace_id = $4
|
128
|
-
assert_equal(expected_message, message)
|
129
|
-
assert_equal(expected_severity, severity)
|
130
|
-
assert_equal(expected_trace_id, trace_id)
|
131
|
-
else
|
132
|
-
flunk("Bad format: #{line.inspect}")
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
|
-
def run_test(trace_id=nil)
|
138
|
-
stringio = ::StringIO.new('', 'w')
|
139
|
-
app = ::Proc.new { |env|
|
140
|
-
yield(env['rack.logger'])
|
141
|
-
}
|
142
|
-
middleware = ::AppEngine::Logger::Middleware.new(app, logfile: stringio)
|
143
|
-
middleware.call({'HTTP_X_CLOUD_TRACE_CONTEXT' => trace_id})
|
144
|
-
::StringIO.new(stringio.string).each_line.to_a
|
145
|
-
end
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
-
|
150
|
-
end
|
151
|
-
end
|