google-cloud-logging 0.21.0 → 0.21.1

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.
@@ -50,6 +50,10 @@ module Google
50
50
  config.google_cloud = ::ActiveSupport::OrderedOptions.new unless
51
51
  config.respond_to? :google_cloud
52
52
  config.google_cloud.logging = ::ActiveSupport::OrderedOptions.new
53
+ config.google_cloud.logging.monitored_resource =
54
+ ::ActiveSupport::OrderedOptions.new
55
+ config.google_cloud.logging.monitored_resource.labels =
56
+ ::ActiveSupport::OrderedOptions.new
53
57
 
54
58
  initializer "Stackdriver.Logging", before: :initialize_logger do |app|
55
59
  if self.class.use_logging? app.config
@@ -58,16 +62,17 @@ module Google
58
62
 
59
63
  project_id = log_config.project_id || gcp_config.project_id
60
64
  keyfile = log_config.keyfile || gcp_config.keyfile
65
+ resource_type = log_config.monitored_resource.type
66
+ resource_labels = log_config.monitored_resource.labels
61
67
 
62
68
  logging = Google::Cloud::Logging.new project: project_id,
63
69
  keyfile: keyfile
64
70
  resource =
65
- Google::Cloud::Logging::Middleware.build_monitoring_resource
71
+ Logging::Middleware.build_monitored_resource resource_type,
72
+ resource_labels
66
73
  log_name = log_config.log_name || DEFAULT_LOG_NAME
67
74
 
68
- app.config.logger = Google::Cloud::Logging::Logger.new logging,
69
- log_name,
70
- resource
75
+ app.config.logger = logging.logger log_name, resource
71
76
  app.middleware.insert_before Rails::Rack::Logger,
72
77
  Google::Cloud::Logging::Middleware,
73
78
  logger: app.config.logger
@@ -81,9 +86,10 @@ module Google
81
86
  # able to authenticate. Also either Rails needs to be in "production"
82
87
  # environment or config.stackdriver.use_logging is explicitly true.
83
88
  #
84
- # @param config The Rails.application.config
89
+ # @param [Rails::Railtie::Configuration] config The
90
+ # Rails.application.config
85
91
  #
86
- # @return [Boolean]
92
+ # @return [Boolean] Whether to use Stackdriver Logging
87
93
  #
88
94
  def self.use_logging? config
89
95
  gcp_config = config.google_cloud
@@ -254,10 +254,10 @@ module Google
254
254
  parent,
255
255
  page_size: nil,
256
256
  options: nil
257
- req = Google::Logging::V2::ListSinksRequest.new(
258
- parent: parent
259
- )
260
- req.page_size = page_size unless page_size.nil?
257
+ req = Google::Logging::V2::ListSinksRequest.new({
258
+ parent: parent,
259
+ page_size: page_size
260
+ }.delete_if { |_, v| v.nil? })
261
261
  @list_sinks.call(req, options)
262
262
  end
263
263
 
@@ -283,9 +283,9 @@ module Google
283
283
  def get_sink \
284
284
  sink_name,
285
285
  options: nil
286
- req = Google::Logging::V2::GetSinkRequest.new(
286
+ req = Google::Logging::V2::GetSinkRequest.new({
287
287
  sink_name: sink_name
288
- )
288
+ }.delete_if { |_, v| v.nil? })
289
289
  @get_sink.call(req, options)
290
290
  end
291
291
 
@@ -318,10 +318,10 @@ module Google
318
318
  parent,
319
319
  sink,
320
320
  options: nil
321
- req = Google::Logging::V2::CreateSinkRequest.new(
321
+ req = Google::Logging::V2::CreateSinkRequest.new({
322
322
  parent: parent,
323
323
  sink: sink
324
- )
324
+ }.delete_if { |_, v| v.nil? })
325
325
  @create_sink.call(req, options)
326
326
  end
327
327
 
@@ -355,10 +355,10 @@ module Google
355
355
  sink_name,
356
356
  sink,
357
357
  options: nil
358
- req = Google::Logging::V2::UpdateSinkRequest.new(
358
+ req = Google::Logging::V2::UpdateSinkRequest.new({
359
359
  sink_name: sink_name,
360
360
  sink: sink
361
- )
361
+ }.delete_if { |_, v| v.nil? })
362
362
  @update_sink.call(req, options)
363
363
  end
364
364
 
@@ -385,9 +385,9 @@ module Google
385
385
  def delete_sink \
386
386
  sink_name,
387
387
  options: nil
388
- req = Google::Logging::V2::DeleteSinkRequest.new(
388
+ req = Google::Logging::V2::DeleteSinkRequest.new({
389
389
  sink_name: sink_name
390
- )
390
+ }.delete_if { |_, v| v.nil? })
391
391
  @delete_sink.call(req, options)
392
392
  end
393
393
  end
@@ -0,0 +1,81 @@
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
+ module Google
16
+ module Api
17
+ # An object that describes the schema of a MonitoredResource object using a
18
+ # type name and a set of labels. For example, the monitored resource
19
+ # descriptor for Google Compute Engine VM instances has a type of
20
+ # +"gce_instance"+ and specifies the use of the labels +"instance_id"+ and
21
+ # +"zone"+ to identify particular VM instances.
22
+ #
23
+ # Different APIs can support different monitored resource types. APIs generally
24
+ # provide a +list+ method that returns the monitored resource descriptors used
25
+ # by the API.
26
+ # @!attribute [rw] name
27
+ # @return [String]
28
+ # Optional. The resource name of the monitored resource descriptor:
29
+ # +"projects/{project_id}/monitoredResourceDescriptors/{type}"+ where
30
+ # {type} is the value of the +type+ field in this object and
31
+ # {project_id} is a project ID that provides API-specific context for
32
+ # accessing the type. APIs that do not use project information can use the
33
+ # resource name format +"monitoredResourceDescriptors/{type}"+.
34
+ # @!attribute [rw] type
35
+ # @return [String]
36
+ # Required. The monitored resource type. For example, the type
37
+ # +"cloudsql_database"+ represents databases in Google Cloud SQL.
38
+ # The maximum length of this value is 256 characters.
39
+ # @!attribute [rw] display_name
40
+ # @return [String]
41
+ # Optional. A concise name for the monitored resource type that might be
42
+ # displayed in user interfaces. It should be a Title Cased Noun Phrase,
43
+ # without any article or other determiners. For example,
44
+ # +"Google Cloud SQL Database"+.
45
+ # @!attribute [rw] description
46
+ # @return [String]
47
+ # Optional. A detailed description of the monitored resource type that might
48
+ # be used in documentation.
49
+ # @!attribute [rw] labels
50
+ # @return [Array<Google::Api::LabelDescriptor>]
51
+ # Required. A set of labels used to describe instances of this monitored
52
+ # resource type. For example, an individual Google Cloud SQL database is
53
+ # identified by values for the labels +"database_id"+ and +"zone"+.
54
+ class MonitoredResourceDescriptor; end
55
+
56
+ # An object representing a resource that can be used for monitoring, logging,
57
+ # billing, or other purposes. Examples include virtual machine instances,
58
+ # databases, and storage devices such as disks. The +type+ field identifies a
59
+ # MonitoredResourceDescriptor object that describes the resource's
60
+ # schema. Information in the +labels+ field identifies the actual resource and
61
+ # its attributes according to the schema. For example, a particular Compute
62
+ # Engine VM instance could be represented by the following object, because the
63
+ # MonitoredResourceDescriptor for +"gce_instance"+ has labels
64
+ # +"instance_id"+ and +"zone"+:
65
+ #
66
+ # { "type": "gce_instance",
67
+ # "labels": { "instance_id": "12345678901234",
68
+ # "zone": "us-central1-a" }}
69
+ # @!attribute [rw] type
70
+ # @return [String]
71
+ # Required. The monitored resource type. This field must match
72
+ # the +type+ field of a MonitoredResourceDescriptor object. For
73
+ # example, the type of a Cloud SQL database is +"cloudsql_database"+.
74
+ # @!attribute [rw] labels
75
+ # @return [Hash{String => String}]
76
+ # Required. Values for all of the labels listed in the associated monitored
77
+ # resource descriptor. For example, Cloud SQL databases use the labels
78
+ # +"database_id"+ and +"zone"+.
79
+ class MonitoredResource; end
80
+ end
81
+ end
@@ -0,0 +1,80 @@
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
+ module Google
16
+ module Logging
17
+ module Type
18
+ # A common proto for logging HTTP requests. Only contains semantics
19
+ # defined by the HTTP specification. Product-specific logging
20
+ # information MUST be defined in a separate message.
21
+ # @!attribute [rw] request_method
22
+ # @return [String]
23
+ # The request method. Examples: +"GET"+, +"HEAD"+, +"PUT"+, +"POST"+.
24
+ # @!attribute [rw] request_url
25
+ # @return [String]
26
+ # The scheme (http, https), the host name, the path and the query
27
+ # portion of the URL that was requested.
28
+ # Example: +"http://example.com/some/info?color=red"+.
29
+ # @!attribute [rw] request_size
30
+ # @return [Integer]
31
+ # The size of the HTTP request message in bytes, including the request
32
+ # headers and the request body.
33
+ # @!attribute [rw] status
34
+ # @return [Integer]
35
+ # The response code indicating the status of response.
36
+ # Examples: 200, 404.
37
+ # @!attribute [rw] response_size
38
+ # @return [Integer]
39
+ # The size of the HTTP response message sent back to the client, in bytes,
40
+ # including the response headers and the response body.
41
+ # @!attribute [rw] user_agent
42
+ # @return [String]
43
+ # The user agent sent by the client. Example:
44
+ # +"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET CLR 1.0.3705)"+.
45
+ # @!attribute [rw] remote_ip
46
+ # @return [String]
47
+ # The IP address (IPv4 or IPv6) of the client that issued the HTTP
48
+ # request. Examples: +"192.168.1.1"+, +"FE80::0202:B3FF:FE1E:8329"+.
49
+ # @!attribute [rw] server_ip
50
+ # @return [String]
51
+ # The IP address (IPv4 or IPv6) of the origin server that the request was
52
+ # sent to.
53
+ # @!attribute [rw] referer
54
+ # @return [String]
55
+ # The referer URL of the request, as defined in
56
+ # {HTTP/1.1 Header Field Definitions}[http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html].
57
+ # @!attribute [rw] latency
58
+ # @return [Google::Protobuf::Duration]
59
+ # The request processing latency on the server, from the time the request was
60
+ # received until the response was sent.
61
+ # @!attribute [rw] cache_lookup
62
+ # @return [true, false]
63
+ # Whether or not a cache lookup was attempted.
64
+ # @!attribute [rw] cache_hit
65
+ # @return [true, false]
66
+ # Whether or not an entity was served from cache
67
+ # (with or without validation).
68
+ # @!attribute [rw] cache_validated_with_origin_server
69
+ # @return [true, false]
70
+ # Whether or not the response was validated with the origin server before
71
+ # being served from cache. This field is only meaningful if +cache_hit+ is
72
+ # True.
73
+ # @!attribute [rw] cache_fill_bytes
74
+ # @return [Integer]
75
+ # The number of HTTP response bytes inserted into cache. Set only when a
76
+ # cache fill was attempted.
77
+ class HttpRequest; end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,99 @@
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
+ module Google
16
+ module Logging
17
+ module V2
18
+ # An individual entry in a log.
19
+ # @!attribute [rw] log_name
20
+ # @return [String]
21
+ # Required. The resource name of the log to which this log entry
22
+ # belongs. The format of the name is
23
+ # +"projects/<project-id>/logs/<log-id>"+. Examples:
24
+ # +"projects/my-projectid/logs/syslog"+,
25
+ # +"projects/my-projectid/logs/library.googleapis.com%2Fbook_log"+.
26
+ #
27
+ # The log ID part of resource name must be less than 512 characters
28
+ # long and can only include the following characters: upper and
29
+ # lower case alphanumeric characters: [A-Za-z0-9]; and punctuation
30
+ # characters: forward-slash, underscore, hyphen, and period.
31
+ # Forward-slash (+/+) characters in the log ID must be URL-encoded.
32
+ # @!attribute [rw] resource
33
+ # @return [Google::Api::MonitoredResource]
34
+ # Required. The monitored resource associated with this log entry.
35
+ # Example: a log entry that reports a database error would be
36
+ # associated with the monitored resource designating the particular
37
+ # database that reported the error.
38
+ # @!attribute [rw] proto_payload
39
+ # @return [Google::Protobuf::Any]
40
+ # The log entry payload, represented as a protocol buffer. Some
41
+ # Google Cloud Platform services use this field for their log
42
+ # entry payloads.
43
+ # @!attribute [rw] text_payload
44
+ # @return [String]
45
+ # The log entry payload, represented as a Unicode string (UTF-8).
46
+ # @!attribute [rw] json_payload
47
+ # @return [Google::Protobuf::Struct]
48
+ # The log entry payload, represented as a structure that
49
+ # is expressed as a JSON object.
50
+ # @!attribute [rw] timestamp
51
+ # @return [Google::Protobuf::Timestamp]
52
+ # Optional. The time the event described by the log entry occurred. If
53
+ # omitted, Stackdriver Logging will use the time the log entry is received.
54
+ # @!attribute [rw] severity
55
+ # @return [Google::Logging::Type::LogSeverity]
56
+ # Optional. The severity of the log entry. The default value is
57
+ # +LogSeverity.DEFAULT+.
58
+ # @!attribute [rw] insert_id
59
+ # @return [String]
60
+ # Optional. A unique ID for the log entry. If you provide this
61
+ # field, the logging service considers other log entries in the
62
+ # same project with the same ID as duplicates which can be removed. If
63
+ # omitted, Stackdriver Logging will generate a unique ID for this
64
+ # log entry.
65
+ # @!attribute [rw] http_request
66
+ # @return [Google::Logging::Type::HttpRequest]
67
+ # Optional. Information about the HTTP request associated with this
68
+ # log entry, if applicable.
69
+ # @!attribute [rw] labels
70
+ # @return [Hash{String => String}]
71
+ # Optional. A set of user-defined (key, value) data that provides additional
72
+ # information about the log entry.
73
+ # @!attribute [rw] operation
74
+ # @return [Google::Logging::V2::LogEntryOperation]
75
+ # Optional. Information about an operation associated with the log entry, if
76
+ # applicable.
77
+ class LogEntry; end
78
+
79
+ # Additional information about a potentially long-running operation with which
80
+ # a log entry is associated.
81
+ # @!attribute [rw] id
82
+ # @return [String]
83
+ # Optional. An arbitrary operation identifier. Log entries with the
84
+ # same identifier are assumed to be part of the same operation.
85
+ # @!attribute [rw] producer
86
+ # @return [String]
87
+ # Optional. An arbitrary producer identifier. The combination of
88
+ # +id+ and +producer+ must be globally unique. Examples for +producer+:
89
+ # +"MyDivision.MyBigCompany.com"+, +"github.com/MyProject/MyApplication"+.
90
+ # @!attribute [rw] first
91
+ # @return [true, false]
92
+ # Optional. Set this to True if this is the first log entry in the operation.
93
+ # @!attribute [rw] last
94
+ # @return [true, false]
95
+ # Optional. Set this to True if this is the last log entry in the operation.
96
+ class LogEntryOperation; end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,148 @@
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
+ module Google
16
+ module Logging
17
+ module V2
18
+ # The parameters to DeleteLog.
19
+ # @!attribute [rw] log_name
20
+ # @return [String]
21
+ # Required. The resource name of the log to delete. Example:
22
+ # +"projects/my-project/logs/syslog"+.
23
+ class DeleteLogRequest; end
24
+
25
+ # The parameters to WriteLogEntries.
26
+ # @!attribute [rw] log_name
27
+ # @return [String]
28
+ # Optional. A default log resource name that is assigned to all log entries
29
+ # in +entries+ that do not specify a value for +log_name+. Example:
30
+ # +"projects/my-project/logs/syslog"+. See
31
+ # LogEntry.
32
+ # @!attribute [rw] resource
33
+ # @return [Google::Api::MonitoredResource]
34
+ # Optional. A default monitored resource object that is assigned to all log
35
+ # entries in +entries+ that do not specify a value for +resource+. Example:
36
+ #
37
+ # { "type": "gce_instance",
38
+ # "labels": {
39
+ # "zone": "us-central1-a", "instance_id": "00000000000000000000" }}
40
+ #
41
+ # See LogEntry.
42
+ # @!attribute [rw] labels
43
+ # @return [Hash{String => String}]
44
+ # Optional. Default labels that are added to the +labels+ field of all log
45
+ # entries in +entries+. If a log entry already has a label with the same key
46
+ # as a label in this parameter, then the log entry's label is not changed.
47
+ # See LogEntry.
48
+ # @!attribute [rw] entries
49
+ # @return [Array<Google::Logging::V2::LogEntry>]
50
+ # Required. The log entries to write. Values supplied for the fields
51
+ # +log_name+, +resource+, and +labels+ in this +entries.write+ request are
52
+ # added to those log entries that do not provide their own values for the
53
+ # fields.
54
+ #
55
+ # To improve throughput and to avoid exceeding the
56
+ # {quota limit}[https://cloud.google.com/logging/quota-policy] for calls to +entries.write+,
57
+ # you should write multiple log entries at once rather than
58
+ # calling this method for each individual log entry.
59
+ # @!attribute [rw] partial_success
60
+ # @return [true, false]
61
+ # Optional. Whether valid entries should be written even if some other
62
+ # entries fail due to INVALID_ARGUMENT or PERMISSION_DENIED errors. If any
63
+ # entry is not written, the response status will be the error associated
64
+ # with one of the failed entries and include error details in the form of
65
+ # WriteLogEntriesPartialErrors.
66
+ class WriteLogEntriesRequest; end
67
+
68
+ # Result returned from WriteLogEntries.
69
+ # empty
70
+ class WriteLogEntriesResponse; end
71
+
72
+ # The parameters to +ListLogEntries+.
73
+ # @!attribute [rw] project_ids
74
+ # @return [Array<String>]
75
+ # Deprecated. One or more project identifiers or project numbers from which
76
+ # to retrieve log entries. Examples: +"my-project-1A"+, +"1234567890"+. If
77
+ # present, these project identifiers are converted to resource format and
78
+ # added to the list of resources in +resourceNames+. Callers should use
79
+ # +resourceNames+ rather than this parameter.
80
+ # @!attribute [rw] resource_names
81
+ # @return [Array<String>]
82
+ # Optional. One or more cloud resources from which to retrieve log entries.
83
+ # Example: +"projects/my-project-1A"+, +"projects/1234567890"+. Projects
84
+ # listed in +projectIds+ are added to this list.
85
+ # @!attribute [rw] filter
86
+ # @return [String]
87
+ # Optional. A filter that chooses which log entries to return. See {Advanced
88
+ # Logs Filters}[https://cloud.google.com/logging/docs/view/advanced_filters]. Only log entries that
89
+ # match the filter are returned. An empty filter matches all log entries.
90
+ # @!attribute [rw] order_by
91
+ # @return [String]
92
+ # Optional. How the results should be sorted. Presently, the only permitted
93
+ # values are +"timestamp asc"+ (default) and +"timestamp desc"+. The first
94
+ # option returns entries in order of increasing values of
95
+ # +LogEntry.timestamp+ (oldest first), and the second option returns entries
96
+ # in order of decreasing timestamps (newest first). Entries with equal
97
+ # timestamps are returned in order of +LogEntry.insertId+.
98
+ # @!attribute [rw] page_size
99
+ # @return [Integer]
100
+ # Optional. The maximum number of results to return from this request.
101
+ # Non-positive values are ignored. The presence of +nextPageToken+ in the
102
+ # response indicates that more results might be available.
103
+ # @!attribute [rw] page_token
104
+ # @return [String]
105
+ # Optional. If present, then retrieve the next batch of results from the
106
+ # preceding call to this method. +pageToken+ must be the value of
107
+ # +nextPageToken+ from the previous response. The values of other method
108
+ # parameters should be identical to those in the previous call.
109
+ class ListLogEntriesRequest; end
110
+
111
+ # Result returned from +ListLogEntries+.
112
+ # @!attribute [rw] entries
113
+ # @return [Array<Google::Logging::V2::LogEntry>]
114
+ # A list of log entries.
115
+ # @!attribute [rw] next_page_token
116
+ # @return [String]
117
+ # If there might be more results than appear in this response, then
118
+ # +nextPageToken+ is included. To get the next set of results, call this
119
+ # method again using the value of +nextPageToken+ as +pageToken+.
120
+ class ListLogEntriesResponse; end
121
+
122
+ # The parameters to ListMonitoredResourceDescriptors
123
+ # @!attribute [rw] page_size
124
+ # @return [Integer]
125
+ # Optional. The maximum number of results to return from this request.
126
+ # Non-positive values are ignored. The presence of +nextPageToken+ in the
127
+ # response indicates that more results might be available.
128
+ # @!attribute [rw] page_token
129
+ # @return [String]
130
+ # Optional. If present, then retrieve the next batch of results from the
131
+ # preceding call to this method. +pageToken+ must be the value of
132
+ # +nextPageToken+ from the previous response. The values of other method
133
+ # parameters should be identical to those in the previous call.
134
+ class ListMonitoredResourceDescriptorsRequest; end
135
+
136
+ # Result returned from ListMonitoredResourceDescriptors.
137
+ # @!attribute [rw] resource_descriptors
138
+ # @return [Array<Google::Api::MonitoredResourceDescriptor>]
139
+ # A list of resource descriptors.
140
+ # @!attribute [rw] next_page_token
141
+ # @return [String]
142
+ # If there might be more results than appear in this response, then
143
+ # +nextPageToken+ is included. To get the next set of results, call this
144
+ # method again using the value of +nextPageToken+ as +pageToken+.
145
+ class ListMonitoredResourceDescriptorsResponse; end
146
+ end
147
+ end
148
+ end