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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5603a0560a10f3f6d0c6a6cd9a35ad8dcec9965
4
- data.tar.gz: 92d67d00bfb992d723ccb5628f4f3f53c75e1a48
3
+ metadata.gz: 4841b00bed08c35d62dfd337ccd15cf5df775de9
4
+ data.tar.gz: a3158e01aaccb61471b504d7a66983c24a58a560
5
5
  SHA512:
6
- metadata.gz: 381abeeea878aa676f40fbd444c022f2639f05d175c6457efd02e26c0eaa54ade5b1e032ac2dd553aa067afc594cb790be2828c230122d121a9d221dcc239657
7
- data.tar.gz: 880a1741725629a5588795d1d7f38bbd340cd3a814a93e597bacdfa595080d191ecc25e1313aa2fd8e931406fb74415227ca561d3794c7bca6d0a8fbfb79433f
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
- * A way to configure the Logger to log to the Google Cloud Console.
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. You may provide additional configuration via the
31
- `config.appengine` object. See below for more details.
32
-
33
- If you are using a different Rack-based framework such as
34
- [Sinatra](http://sinatrarb.com/), you can use the provided middlewares. See
35
- the more detailed instructions below.
36
-
37
- ## Google Cloud Console logger integration
38
-
39
- In order for your application logs to appear in the Google Cloud Console with
40
- the correct severities and other metadata, they should be written in a
41
- specific format to a specific location. The logger module in this gem provides
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
@@ -24,5 +24,6 @@ end
24
24
 
25
25
  require 'appengine/version'
26
26
  require 'appengine/env'
27
- require 'appengine/logger'
28
27
  require 'appengine/railtie' if defined?(::Rails)
28
+
29
+ require "stackdriver"
data/lib/appengine/env.rb CHANGED
@@ -16,25 +16,15 @@
16
16
 
17
17
  module AppEngine
18
18
 
19
-
20
- # == Environment information
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
- # Returns the Trace ID string from a Rack environment, or nil if no trace
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
@@ -31,25 +31,7 @@ module AppEngine
31
31
  #
32
32
  # === Configuration
33
33
  #
34
- # The following configuration parameters are supported.
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
@@ -16,6 +16,6 @@
16
16
  module AppEngine
17
17
 
18
18
  # The current version of this gem, as a string.
19
- VERSION = '0.2.0'.freeze
19
+ VERSION = '0.3.0'.freeze
20
20
 
21
21
  end
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 test_extract_trace_id_absent
27
- env = {}
28
- trace_id = Env.extract_trace_id(env)
29
- assert_nil(trace_id)
30
- end
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.2.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: 2016-05-04 00:00:00.000000000 Z
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.11'
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.11'
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 interpretation of App Engine headers.
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.4.5.1
131
+ rubygems_version: 2.6.8
114
132
  signing_key:
115
133
  specification_version: 4
116
134
  summary: Google App Engine integration tools
@@ -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