google-cloud-logging 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +18 -0
  3. data/AUTHENTICATION.md +178 -0
  4. data/CHANGELOG.md +407 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +188 -0
  7. data/INSTRUMENTATION.md +71 -0
  8. data/LICENSE +201 -0
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +321 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/lib/google-cloud-logging.rb +161 -0
  13. data/lib/google/cloud/logging.rb +188 -0
  14. data/lib/google/cloud/logging/async_writer.rb +513 -0
  15. data/lib/google/cloud/logging/convert.rb +70 -0
  16. data/lib/google/cloud/logging/credentials.rb +44 -0
  17. data/lib/google/cloud/logging/entry.rb +528 -0
  18. data/lib/google/cloud/logging/entry/http_request.rb +167 -0
  19. data/lib/google/cloud/logging/entry/list.rb +178 -0
  20. data/lib/google/cloud/logging/entry/operation.rb +91 -0
  21. data/lib/google/cloud/logging/entry/source_location.rb +85 -0
  22. data/lib/google/cloud/logging/errors.rb +101 -0
  23. data/lib/google/cloud/logging/log/list.rb +156 -0
  24. data/lib/google/cloud/logging/logger.rb +633 -0
  25. data/lib/google/cloud/logging/metric.rb +168 -0
  26. data/lib/google/cloud/logging/metric/list.rb +170 -0
  27. data/lib/google/cloud/logging/middleware.rb +307 -0
  28. data/lib/google/cloud/logging/project.rb +838 -0
  29. data/lib/google/cloud/logging/rails.rb +232 -0
  30. data/lib/google/cloud/logging/resource.rb +85 -0
  31. data/lib/google/cloud/logging/resource_descriptor.rb +137 -0
  32. data/lib/google/cloud/logging/resource_descriptor/list.rb +175 -0
  33. data/lib/google/cloud/logging/service.rb +239 -0
  34. data/lib/google/cloud/logging/sink.rb +315 -0
  35. data/lib/google/cloud/logging/sink/list.rb +168 -0
  36. data/lib/google/cloud/logging/version.rb +22 -0
  37. metadata +304 -0
@@ -0,0 +1,175 @@
1
+ # Copyright 2016 Google LLC
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
+ # https://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 "delegate"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Logging
21
+ class ResourceDescriptor
22
+ ##
23
+ # ResourceDescriptor::List is a special case Array with additional
24
+ # values.
25
+ class List < DelegateClass(::Array)
26
+ ##
27
+ # If not empty, indicates that there are more records that match
28
+ # the request and this value should be passed to continue.
29
+ attr_accessor :token
30
+
31
+ ##
32
+ # @private Create a new ResourceDescriptor::List with an array of
33
+ # ResourceDescriptor instances.
34
+ def initialize arr = []
35
+ super arr
36
+ end
37
+
38
+ ##
39
+ # Whether there is a next page of resource descriptors.
40
+ #
41
+ # @return [Boolean]
42
+ #
43
+ # @example
44
+ # require "google/cloud/logging"
45
+ #
46
+ # logging = Google::Cloud::Logging.new
47
+ #
48
+ # resource_descriptors = logging.resource_descriptors
49
+ # if resource_descriptors.next?
50
+ # next_resource_descriptors = resource_descriptors.next
51
+ # end
52
+ #
53
+ def next?
54
+ !token.nil?
55
+ end
56
+
57
+ ##
58
+ # Retrieve the next page of resource descriptors.
59
+ #
60
+ # @return [Sink::List]
61
+ #
62
+ # @example
63
+ # require "google/cloud/logging"
64
+ #
65
+ # logging = Google::Cloud::Logging.new
66
+ #
67
+ # resource_descriptors = logging.resource_descriptors
68
+ # if resource_descriptors.next?
69
+ # next_resource_descriptors = resource_descriptors.next
70
+ # end
71
+ #
72
+ def next
73
+ return nil unless next?
74
+ ensure_service!
75
+ list_grpc = @service.list_resource_descriptors(
76
+ token: token, max: @max
77
+ )
78
+ self.class.from_grpc list_grpc, @service, @max
79
+ end
80
+
81
+ ##
82
+ # Retrieves remaining results by repeatedly invoking {#next} until
83
+ # {#next?} returns `false`. Calls the given block once for each
84
+ # result, which is passed as the argument to the block.
85
+ #
86
+ # An Enumerator is returned if no block is given.
87
+ #
88
+ # This method will make repeated API calls until all remaining results
89
+ # are retrieved. (Unlike `#each`, for example, which merely iterates
90
+ # over the results returned by a single API call.) Use with caution.
91
+ #
92
+ # @param [Integer] request_limit The upper limit of API requests to
93
+ # make to load all resource descriptors. Default is no limit.
94
+ # @yield [resource_descriptor] The block for accessing each resource
95
+ # descriptor.
96
+ # @yieldparam [ResourceDescriptor] resource_descriptor The resource
97
+ # descriptor object.
98
+ #
99
+ # @return [Enumerator]
100
+ #
101
+ # @example Iterating each resource descriptor by passing a block:
102
+ # require "google/cloud/logging"
103
+ #
104
+ # logging = Google::Cloud::Logging.new
105
+ # resource_descriptors = logging.resource_descriptors
106
+ #
107
+ # resource_descriptors.all do |rd|
108
+ # puts rd.type
109
+ # end
110
+ #
111
+ # @example Using the enumerator by not passing a block:
112
+ # require "google/cloud/logging"
113
+ #
114
+ # logging = Google::Cloud::Logging.new
115
+ # resource_descriptors = logging.resource_descriptors
116
+ #
117
+ # all_types = resource_descriptors.all.map do |rd|
118
+ # rd.type
119
+ # end
120
+ #
121
+ # @example Limit the number of API calls made:
122
+ # require "google/cloud/logging"
123
+ #
124
+ # logging = Google::Cloud::Logging.new
125
+ # resource_descriptors = logging.resource_descriptors
126
+ #
127
+ # resource_descriptors.all(request_limit: 10) do |rd|
128
+ # puts rd.type
129
+ # end
130
+ #
131
+ def all request_limit: nil
132
+ request_limit = request_limit.to_i if request_limit
133
+ unless block_given?
134
+ return enum_for :all, request_limit: request_limit
135
+ end
136
+ results = self
137
+ loop do
138
+ results.each { |r| yield r }
139
+ if request_limit
140
+ request_limit -= 1
141
+ break if request_limit < 0
142
+ end
143
+ break unless results.next?
144
+ results = results.next
145
+ end
146
+ end
147
+
148
+ ##
149
+ # @private New ResourceDescriptor::List from a
150
+ # Google::Cloud::Logging::V2::ListMonitoredResourceDescriptorsResponse
151
+ # object.
152
+ def self.from_grpc grpc_list, service, max = nil
153
+ rds = new(Array(grpc_list.resource_descriptors).map do |grpc|
154
+ ResourceDescriptor.from_grpc grpc
155
+ end)
156
+ token = grpc_list.next_page_token
157
+ token = nil if token == "".freeze
158
+ rds.instance_variable_set :@token, token
159
+ rds.instance_variable_set :@service, service
160
+ rds.instance_variable_set :@max, max
161
+ rds
162
+ end
163
+
164
+ protected
165
+
166
+ ##
167
+ # Raise an error unless an active service is available.
168
+ def ensure_service!
169
+ raise "Must have active service" unless @service
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,239 @@
1
+ # Copyright 2016 Google LLC
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
+ # https://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 "google/cloud/errors"
17
+ require "google/cloud/logging/version"
18
+ require "google/cloud/logging/v2"
19
+ require "uri"
20
+
21
+ module Google
22
+ module Cloud
23
+ module Logging
24
+ ##
25
+ # @private Represents the gRPC Logging service, including all the API
26
+ # methods.
27
+ class Service
28
+ attr_accessor :project, :credentials, :timeout, :host
29
+
30
+ ##
31
+ # Creates a new Service instance.
32
+ def initialize project, credentials, timeout: nil, host: nil
33
+ @project = project
34
+ @credentials = credentials
35
+ @timeout = timeout
36
+ @host = host
37
+ end
38
+
39
+ def logging
40
+ return mocked_logging if mocked_logging
41
+ @logging ||= \
42
+ V2::LoggingService::Client.new do |config|
43
+ config.credentials = credentials if credentials
44
+ config.timeout = timeout if timeout
45
+ config.endpoint = host if host
46
+ config.lib_name = "gccl"
47
+ config.lib_version = Google::Cloud::Logging::VERSION
48
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
49
+ end
50
+ end
51
+ attr_accessor :mocked_logging
52
+
53
+ def sinks
54
+ return mocked_sinks if mocked_sinks
55
+ @sinks ||= \
56
+ V2::ConfigService::Client.new do |config|
57
+ config.credentials = credentials if credentials
58
+ config.timeout = timeout if timeout
59
+ config.endpoint = host if host
60
+ config.lib_name = "gccl"
61
+ config.lib_version = Google::Cloud::Logging::VERSION
62
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
63
+ end
64
+ end
65
+ attr_accessor :mocked_sinks
66
+
67
+ def metrics
68
+ return mocked_metrics if mocked_metrics
69
+ @metrics ||= \
70
+ V2::MetricsService::Client.new do |config|
71
+ config.credentials = credentials if credentials
72
+ config.timeout = timeout if timeout
73
+ config.endpoint = host if host
74
+ config.lib_name = "gccl"
75
+ config.lib_version = Google::Cloud::Logging::VERSION
76
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
77
+ end
78
+ end
79
+ attr_accessor :mocked_metrics
80
+
81
+ def list_entries resources: nil, filter: nil, order: nil, token: nil,
82
+ max: nil, projects: nil
83
+
84
+ project_ids = Array(projects).map { |p| "projects/#{p}" }
85
+ resource_names = Array(resources) + project_ids
86
+ resource_names = ["projects/#{@project}"] if resource_names.empty?
87
+ paged_enum = logging.list_log_entries resource_names: resource_names,
88
+ filter: filter,
89
+ order_by: order,
90
+ page_size: max,
91
+ page_token: token
92
+ paged_enum.response
93
+ end
94
+
95
+ def write_entries entries, log_name: nil, resource: nil, labels: nil,
96
+ partial_success: nil
97
+ # Fix log names so they are the full path
98
+ entries = Array(entries).each do |entry|
99
+ entry.log_name = log_path entry.log_name
100
+ end
101
+ resource = resource.to_grpc if resource
102
+ labels = Hash[labels.map { |k, v| [String(k), String(v)] }] if labels
103
+ logging.write_log_entries entries: entries,
104
+ log_name: log_path(log_name),
105
+ resource: resource,
106
+ labels: labels,
107
+ partial_success: partial_success
108
+ end
109
+
110
+ def list_logs resource: nil, token: nil, max: nil
111
+ parent = resource || "projects/#{@project}"
112
+ paged_enum = logging.list_logs parent: parent,
113
+ page_size: max,
114
+ page_token: token
115
+ paged_enum.response
116
+ end
117
+
118
+ def delete_log name
119
+ logging.delete_log log_name: log_path(name)
120
+ end
121
+
122
+ def list_resource_descriptors token: nil, max: nil
123
+ logging.list_monitored_resource_descriptors page_size: max, page_token: token
124
+ end
125
+
126
+ def list_sinks token: nil, max: nil
127
+ paged_enum = sinks.list_sinks parent: project_path, page_size: max, page_token: token
128
+ paged_enum.response
129
+ end
130
+
131
+ def create_sink name, destination, filter, unique_writer_identity: nil
132
+ sink = Google::Cloud::Logging::V2::LogSink.new(
133
+ {
134
+ name: name, destination: destination, filter: filter
135
+ }.delete_if { |_, v| v.nil? }
136
+ )
137
+ sinks.create_sink parent: project_path,
138
+ sink: sink,
139
+ unique_writer_identity: unique_writer_identity
140
+ end
141
+
142
+ def get_sink name
143
+ sinks.get_sink sink_name: sink_path(name)
144
+ end
145
+
146
+ def update_sink name, destination, filter, unique_writer_identity: nil
147
+ sink = Google::Cloud::Logging::V2::LogSink.new(
148
+ {
149
+ name: name, destination: destination, filter: filter
150
+ }.delete_if { |_, v| v.nil? }
151
+ )
152
+ sinks.update_sink sink_name: sink_path(name),
153
+ sink: sink,
154
+ unique_writer_identity: unique_writer_identity
155
+ end
156
+
157
+ def delete_sink name
158
+ sinks.delete_sink sink_name: sink_path(name)
159
+ end
160
+
161
+ def list_metrics token: nil, max: nil
162
+ paged_enum = metrics.list_log_metrics parent: project_path,
163
+ page_size: max,
164
+ page_token: token
165
+ paged_enum.response
166
+ end
167
+
168
+ def create_metric name, filter, description
169
+ metric = Google::Cloud::Logging::V2::LogMetric.new(
170
+ { name: name, description: description,
171
+ filter: filter }.delete_if { |_, v| v.nil? }
172
+ )
173
+ metrics.create_log_metric parent: project_path, metric: metric
174
+ end
175
+
176
+ def get_metric name
177
+ metrics.get_log_metric metric_name: metric_path(name)
178
+ end
179
+
180
+ def update_metric name, description, filter
181
+ metric = Google::Cloud::Logging::V2::LogMetric.new(
182
+ { name: name, description: description,
183
+ filter: filter }.delete_if { |_, v| v.nil? }
184
+ )
185
+ metrics.update_log_metric metric_name: metric_path(name), metric: metric
186
+ end
187
+
188
+ def delete_metric name
189
+ metrics.delete_log_metric metric_name: metric_path(name)
190
+ end
191
+
192
+ def log_path log_name
193
+ return nil if log_name.nil?
194
+ return log_name if log_name.empty?
195
+ return log_name if log_name.to_s.include? "/"
196
+ "#{project_path}/logs/#{log_name}"
197
+ end
198
+
199
+ def inspect
200
+ "#{self.class}(#{@project})"
201
+ end
202
+
203
+ protected
204
+
205
+ def project_path
206
+ "projects/#{@project}"
207
+ end
208
+
209
+ def sink_path sink_name
210
+ return sink_name if sink_name.to_s.include? "/"
211
+ "#{project_path}/sinks/#{sink_name}"
212
+ end
213
+
214
+ def metric_path metric_name
215
+ return metric_name if metric_name.to_s.include? "/"
216
+ "#{project_path}/metrics/#{metric_name}"
217
+ end
218
+
219
+ ##
220
+ # @private Get a Google::Protobuf::Timestamp object from a Time object.
221
+ def time_to_timestamp time
222
+ return nil if time.nil?
223
+ # Make sure we have a Time object
224
+ return nil unless time.respond_to? :to_time
225
+ time = time.to_time
226
+ Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
227
+ end
228
+
229
+ ##
230
+ # @private Get a Time object from a Google::Protobuf::Timestamp object.
231
+ def timestamp_to_time timestamp
232
+ return nil if timestamp.nil?
233
+ # Time.at takes microseconds, so convert nano seconds to microseconds
234
+ Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,315 @@
1
+ # Copyright 2016 Google LLC
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
+ # https://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 "google/cloud/logging/sink/list"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Logging
21
+ ##
22
+ # # Sink
23
+ #
24
+ # Used to export log entries outside Stackdriver Logging. When you create
25
+ # a sink, new log entries are exported. Stackdriver Logging does not send
26
+ # previously-ingested log entries to the sink's destination.
27
+ #
28
+ # A logs filter controls which log entries are exported.
29
+ #
30
+ # Before creating the sink, ensure that you have granted the sink's
31
+ # _unique writer identity_ permission to write logs to the destination.
32
+ # See [Destination
33
+ # permissions](https://cloud.google.com/logging/docs/export/configure_export_v2#dest-auth).
34
+ #
35
+ # You can retrieve an existing sink with {Project#sink}.
36
+ #
37
+ # @see https://cloud.google.com/logging/docs/export
38
+ # Overview of logs exports
39
+ # @see https://cloud.google.com/logging/docs/reference/v2/rpc/google.logging.v2#configservicev2
40
+ # ConfigService API which includes sink methods
41
+ #
42
+ # @example
43
+ # require "google/cloud/storage"
44
+ #
45
+ # storage = Google::Cloud::Storage.new
46
+ # bucket = storage.create_bucket "my-logs-bucket"
47
+ #
48
+ # # Grant owner permission to Stackdriver Logging service
49
+ # email = "cloud-logs@google.com"
50
+ # bucket.acl.add_owner "group-#{email}"
51
+ #
52
+ # require "google/cloud/logging"
53
+ #
54
+ # logging = Google::Cloud::Logging.new
55
+ # sink = logging.create_sink "my-sink",
56
+ # "storage.googleapis.com/#{bucket.id}"
57
+ #
58
+ class Sink
59
+ ##
60
+ # @private The gRPC Service object.
61
+ attr_accessor :service
62
+
63
+ ##
64
+ # @private The Google API Client object.
65
+ attr_accessor :grpc
66
+
67
+ ##
68
+ # @private Create an empty Sink object.
69
+ def initialize
70
+ @service = nil
71
+ @grpc = Google::Cloud::Logging::V2::LogSink.new
72
+ end
73
+
74
+ ##
75
+ # The client-assigned sink identifier. Sink identifiers are limited to
76
+ # 1000 characters and can include only the following characters: `A-Z`,
77
+ # `a-z`, `0-9`, and the special characters `_-.`.
78
+ def name
79
+ @grpc.name
80
+ end
81
+
82
+ ##
83
+ # The export destination. See [Properties of
84
+ # Sinks](https://cloud.google.com/logging/docs/export#sink-terms).
85
+ def destination
86
+ @grpc.destination
87
+ end
88
+
89
+ ##
90
+ # Updates the export destination. See [Properties of
91
+ # Sinks](https://cloud.google.com/logging/docs/export#sink-terms).
92
+ def destination= destination
93
+ @grpc.destination = destination
94
+ end
95
+
96
+ ##
97
+ # An [advanced logs
98
+ # filter](https://cloud.google.com/logging/docs/view/advanced-queries)
99
+ # that defines the log entries to be exported. The filter must be
100
+ # consistent with the log entry format designed by the `version`
101
+ # parameter, regardless of the format of the log entry that was
102
+ # originally written to Stackdriver Logging.
103
+ def filter
104
+ @grpc.filter
105
+ end
106
+
107
+ ##
108
+ # Updates the [advanced logs
109
+ # filter](https://cloud.google.com/logging/docs/view/advanced-queries)
110
+ # that defines the log entries to be exported. The filter must be
111
+ # consistent with the log entry format designed by the `version`
112
+ # parameter, regardless of the format of the log entry that was
113
+ # originally written to Stackdriver Logging.
114
+ def filter= filter
115
+ @grpc.filter = filter
116
+ end
117
+
118
+ ##
119
+ # **Deprecated.** The log entry version used when exporting log entries
120
+ # from this sink. This version does not have to correspond to the
121
+ # version of the log entry when it was written to Stackdriver Logging.
122
+ #
123
+ # @deprecated The v2 format is used by default and cannot be changed.
124
+ def version
125
+ warn "[DEPRECATION] version is deprecated."
126
+ :V2
127
+ end
128
+
129
+ ##
130
+ # **Deprecated.** Updates the log entry version used when exporting log
131
+ # entries from this sink. This version does not have to correspond to
132
+ # the version of the log entry when it was written to Stackdriver
133
+ # Logging. Accepted values are `:VERSION_FORMAT_UNSPECIFIED`, `:V2`, and
134
+ # `:V1`.
135
+ #
136
+ # @deprecated The v2 format is used by default and cannot be changed.
137
+ def version= _version
138
+ warn "[DEPRECATION] version= is deprecated and will be ignored."
139
+ end
140
+
141
+ ##
142
+ # Helper to determine if the sink's version is
143
+ # `VERSION_FORMAT_UNSPECIFIED`.
144
+ #
145
+ # @deprecated The v2 format is used by default and cannot be changed.
146
+ def unspecified?
147
+ warn "[DEPRECATION] unspecified? is deprecated."
148
+ false
149
+ end
150
+
151
+ ##
152
+ # Helper to determine if the sink's version is `V2`.
153
+ #
154
+ # @deprecated The v2 format is used by default and cannot be changed.
155
+ def v2?
156
+ warn "[DEPRECATION] v2? is deprecated."
157
+ true
158
+ end
159
+
160
+ ##
161
+ # Helper to determine if the sink's version is `V1`.
162
+ #
163
+ # @deprecated The v2 format is used by default and cannot be changed.
164
+ def v1?
165
+ warn "[DEPRECATION] v1? is deprecated."
166
+ false
167
+ end
168
+
169
+ ##
170
+ # **Deprecated.** The time at which this sink will begin exporting log
171
+ # entries. If this value is present, then log entries are exported only
172
+ # if `start_at` is less than the log entry's timestamp. Optional.
173
+ #
174
+ # @deprecated This field is ignored when creating or updating sinks.
175
+ def start_at
176
+ warn "[DEPRECATION] start_at is deprecated."
177
+ nil
178
+ end
179
+ alias start_time start_at
180
+
181
+ ##
182
+ # **Deprecated.** Sets the time at which this sink will begin exporting
183
+ # log entries. If this value is present, then log entries are exported
184
+ # only if `start_at` is less than the log entry's timestamp. Optional.
185
+ #
186
+ # @deprecated This field is ignored when creating or updating sinks.
187
+ def start_at= _new_start_at
188
+ warn "[DEPRECATION] start_at= is deprecated and will be ignored."
189
+ end
190
+ alias start_time= start_at=
191
+
192
+ ##
193
+ # **Deprecated.** Time at which this sink will stop exporting log
194
+ # entries. If this value is present, then log entries are exported only
195
+ # if the log entry's timestamp is less than `end_at`. Optional.
196
+ #
197
+ # @deprecated This field is ignored when creating or updating sinks.
198
+ def end_at
199
+ warn "[DEPRECATION] end_at is deprecated."
200
+ nil
201
+ end
202
+ alias end_time end_at
203
+
204
+ ##
205
+ # **Deprecated.** Sets the time at which this sink will stop exporting
206
+ # log entries. If this value is present, then log entries are exported
207
+ # only if the log entry's timestamp is less than `end_at`. Optional.
208
+ #
209
+ # @deprecated This field is ignored when creating or updating sinks.
210
+ def end_at= _new_end_at
211
+ warn "[DEPRECATION] end_at= is deprecated and will be ignored."
212
+ end
213
+ alias end_time= end_at=
214
+
215
+ ##
216
+ # An IAM identity (a service account or group) that will write exported
217
+ # log entries to the destination on behalf of Stackdriver Logging. You
218
+ # must grant this identity write-access to the destination. Consult the
219
+ # destination service's documentation to determine the exact role that
220
+ # must be granted.
221
+ def writer_identity
222
+ @grpc.writer_identity
223
+ end
224
+
225
+ ##
226
+ # Updates the logs-based sink.
227
+ #
228
+ # @param [Boolean] unique_writer_identity Whether the sink will have a
229
+ # dedicated service account returned in the sink's `writer_identity`.
230
+ # Set this field to be true to export logs from one project to a
231
+ # different project. This field is ignored for non-project sinks
232
+ # (e.g. organization sinks) because those sinks are required to have
233
+ # dedicated service accounts. Optional.
234
+ #
235
+ # @example
236
+ # require "google/cloud/logging"
237
+ #
238
+ # logging = Google::Cloud::Logging.new
239
+ # sink = logging.sink "severe_errors"
240
+ # sink.filter = "logName:syslog AND severity>=ERROR"
241
+ # sink.save
242
+ #
243
+ def save unique_writer_identity: nil
244
+ ensure_service!
245
+ @grpc = service.update_sink \
246
+ name, destination, filter,
247
+ unique_writer_identity: unique_writer_identity
248
+ end
249
+
250
+ ##
251
+ # Reloads the logs-based sink with current data from the Logging
252
+ # service.
253
+ def reload!
254
+ ensure_service!
255
+ @grpc = service.get_sink name
256
+ end
257
+ alias refresh! reload!
258
+
259
+ ##
260
+ # Permanently deletes the logs-based sink.
261
+ #
262
+ # @return [Boolean] Returns `true` if the sink was deleted.
263
+ #
264
+ # @example
265
+ # require "google/cloud/logging"
266
+ #
267
+ # logging = Google::Cloud::Logging.new
268
+ # sink = logging.sink "severe_errors"
269
+ # sink.delete
270
+ #
271
+ def delete
272
+ ensure_service!
273
+ service.delete_sink name
274
+ true
275
+ end
276
+
277
+ ##
278
+ # @private New Sink from a Google::Cloud::Logging::V2::LogSink object.
279
+ def self.from_grpc grpc, service
280
+ new.tap do |f|
281
+ f.grpc = grpc
282
+ f.service = service
283
+ end
284
+ end
285
+
286
+ protected
287
+
288
+ ##
289
+ # @private Raise an error unless an active connection to the service is
290
+ # available.
291
+ def ensure_service!
292
+ raise "Must have active connection to service" unless service
293
+ end
294
+
295
+ ##
296
+ # @private Get a Google::Protobuf::Timestamp object from a Time object.
297
+ def time_to_timestamp time
298
+ return nil if time.nil?
299
+ # Make sure we have a Time object
300
+ return nil unless time.respond_to? :to_time
301
+ time = time.to_time
302
+ Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
303
+ end
304
+
305
+ ##
306
+ # @private Get a Time object from a Google::Protobuf::Timestamp object.
307
+ def timestamp_to_time timestamp
308
+ return nil if timestamp.nil?
309
+ # Time.at takes microseconds, so convert nano seconds to microseconds
310
+ Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
311
+ end
312
+ end
313
+ end
314
+ end
315
+ end