google-cloud-logging 0.21.2 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0758635d13fae9220da1dd1b95478cb80307ce3f
4
- data.tar.gz: d5dd229ab4f849b1145c9b98da3684b763c3af86
3
+ metadata.gz: 2658b3d8de071df00d572f934df7ba5ae0be360d
4
+ data.tar.gz: 18b9dd38df8bc706d2aa821b0f6030fdda4abef3
5
5
  SHA512:
6
- metadata.gz: 1ad8e872864d97efef6ed58e463ab945082a697f9f70d5f91ce26c1ecf319d5954c1401349fcb73b10372756966447e81c75d64ff7d96a49c4cfaba13503a001
7
- data.tar.gz: da1d3f340ac647a47adcdd276ed8df241bcf900cae54a5546ff17336d8ff56addb9a0fd814b4b03dbce4d68640f3fa0801a9d3504536206e2adc3434be10f4e7
6
+ metadata.gz: 889cb152ecd3759eb2b586a18dd6043ea47f85d565e80c55b65f70a23fabbcefd140409f6c27a298ccb6992cf196e6178368c6bbea100a33112bd522ae38d58d
7
+ data.tar.gz: 7ef4b2783d70281cdc5b0a4216098cf9e0a49c359a8af8f52d17e9b947d70ae4628d72ef06b56d77eaaefc1eb2d71b96e3bb329e1b50dfdff0bd9745c6d6d326
data/.yardopts CHANGED
@@ -1,8 +1,5 @@
1
1
  --no-private
2
2
  --title=Stackdriver Logging
3
- --exclude lib/google/logging
4
- --exclude lib/google/cloud/logging/v2
5
- --exclude lib/google/cloud/logging/v2.rb
6
3
  --markup markdown
7
4
 
8
5
  ./lib/**/*.rb
@@ -62,7 +62,7 @@ module Google
62
62
  #
63
63
  # logging = Google::Cloud::Logging.new
64
64
  #
65
- # entries = dataset.entries
65
+ # entries = logging.entries
66
66
  # if entries.next?
67
67
  # next_entries = entries.next
68
68
  # end
@@ -70,9 +70,9 @@ module Google
70
70
  def next
71
71
  return nil unless next?
72
72
  ensure_service!
73
- grpc = @service.list_entries token: token, projects: @projects,
73
+ grpc = @service.list_entries token: token, resources: @resources,
74
74
  filter: @filter, order: @order,
75
- max: @max
75
+ max: @max, projects: @projects
76
76
  self.class.from_grpc grpc, @service
77
77
  end
78
78
 
@@ -100,7 +100,7 @@ module Google
100
100
  # logging = Google::Cloud::Logging.new
101
101
  # entries = logging.entries order: "timestamp desc"
102
102
  #
103
- # entries.all do |entry|
103
+ # entries.all do |e|
104
104
  # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}"
105
105
  # end
106
106
  #
@@ -120,7 +120,7 @@ module Google
120
120
  # logging = Google::Cloud::Logging.new
121
121
  # entries = logging.entries order: "timestamp desc"
122
122
  #
123
- # entries.all(request_limit: 10) do |entry|
123
+ # entries.all(request_limit: 10) do |e|
124
124
  # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}"
125
125
  # end
126
126
  #
@@ -144,8 +144,8 @@ module Google
144
144
  ##
145
145
  # @private New Entry::List from a
146
146
  # Google::Logging::V2::ListLogEntryResponse object.
147
- def self.from_grpc grpc_list, service, projects: nil, filter: nil,
148
- order: nil, max: nil
147
+ def self.from_grpc grpc_list, service, resources: nil, filter: nil,
148
+ order: nil, max: nil, projects: nil
149
149
  entries = new(Array(grpc_list.entries).map do |grpc_entry|
150
150
  Entry.from_grpc grpc_entry
151
151
  end)
@@ -154,6 +154,7 @@ module Google
154
154
  entries.instance_variable_set "@token", token
155
155
  entries.instance_variable_set "@service", service
156
156
  entries.instance_variable_set "@projects", projects
157
+ entries.instance_variable_set "@resources", resources
157
158
  entries.instance_variable_set "@filter", filter
158
159
  entries.instance_variable_set "@order", order
159
160
  entries.instance_variable_set "@max", max
@@ -86,7 +86,7 @@ module Google
86
86
  #
87
87
  # resource = logging.resource "gae_app", labels: {
88
88
  # "module_id" => "1",
89
- # "version_id" => "20150925t173233" }
89
+ # "version_id" => "20150925t173233"
90
90
  # }
91
91
  #
92
92
  # logger = Google::Cloud::Logging::Logger.new writer,
@@ -324,7 +324,7 @@ module Google
324
324
  ##
325
325
  # Untrack the trace_id that's associated with current Thread
326
326
  #
327
- # @return The trace_id that's being deleted
327
+ # @return [String] The trace_id that's being deleted
328
328
  def delete_trace_id
329
329
  trace_ids.delete current_thread_id
330
330
  end
@@ -63,7 +63,7 @@ module Google
63
63
  #
64
64
  # logging = Google::Cloud::Logging.new
65
65
  #
66
- # metrics = dataset.metrics
66
+ # metrics = logging.metrics
67
67
  # if metrics.next?
68
68
  # next_metrics = metrics.next
69
69
  # end
@@ -78,32 +78,36 @@ module Google
78
78
  # based on the current environment.
79
79
  #
80
80
  # @example If both type and labels are provided, it returns resource:
81
- # rc = Middleware.build_monitored_resource "aws_ec2_instance",
82
- # { instance_id: "ec2-id",
83
- # aws_account: "aws-id" }
81
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource(
82
+ # "aws_ec2_instance",
83
+ # {
84
+ # instance_id: "ec2-id",
85
+ # aws_account: "aws-id"
86
+ # }
87
+ # )
84
88
  # rc.type #=> "aws_ec2_instance"
85
89
  # rc.labels #=> { instance_id: "ec2-id", aws_account: "aws-id" }
86
90
  #
87
91
  # @example If running from GAE, returns default resource:
88
- # rc = Middleware.build_monitored_resource
92
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
89
93
  # rc.type #=> "gae_app"
90
- # rc.labels #=> { module_id: [GAE module name],
91
- # # version_id: [GAE module version] }
94
+ # rc.labels # { module_id: [GAE module name],
95
+ # # version_id: [GAE module version] }
92
96
  #
93
97
  # @example If running from GKE, returns default resource:
94
- # rc = Middleware.build_monitored_resource
98
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
95
99
  # rc.type #=> "container"
96
- # rc.labels #=> { cluster_name: [GKE cluster name],
97
- # # namespace_id: [GKE namespace_id] }
100
+ # rc.labels # { cluster_name: [GKE cluster name],
101
+ # # namespace_id: [GKE namespace_id] }
98
102
  #
99
103
  # @example If running from GCE, return default resource:
100
- # rc = Middleware.build_monitored_resource
104
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
101
105
  # rc.type #=> "gce_instance"
102
- # rc.labels #=> { instance_id: [GCE VM instance id],
103
- # # zone: [GCE vm group zone] }
106
+ # rc.labels # { instance_id: [GCE VM instance id],
107
+ # # zone: [GCE vm group zone] }
104
108
  #
105
109
  # @example Otherwise default to generic "global" type:
106
- # rc = Middleware.build_monitored_resource
110
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
107
111
  # rc.type #=> "global"
108
112
  # rc.labels #=> {}
109
113
  #
@@ -132,25 +136,25 @@ module Google
132
136
  # the correct monitoring resource types and labels.
133
137
  #
134
138
  # @example If running from GAE, returns default resource:
135
- # rc = Middleware.build_monitored_resource
139
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
136
140
  # rc.type #=> "gae_app"
137
- # rc.labels #=> { module_id: [GAE module name],
138
- # # version_id: [GAE module version] }
141
+ # rc.labels # { module_id: [GAE module name],
142
+ # # version_id: [GAE module version] }
139
143
  #
140
144
  # @example If running from GKE, returns default resource:
141
- # rc = Middleware.build_monitored_resource
145
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
142
146
  # rc.type #=> "container"
143
- # rc.labels #=> { cluster_name: [GKE cluster name],
144
- # # namespace_id: [GKE namespace_id] }
147
+ # rc.labels # { cluster_name: [GKE cluster name],
148
+ # # namespace_id: [GKE namespace_id] }
145
149
  #
146
150
  # @example If running from GCE, return default resource:
147
- # rc = Middleware.build_monitored_resource
151
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
148
152
  # rc.type #=> "gce_instance"
149
- # rc.labels #=> { instance_id: [GCE VM instance id],
150
- # # zone: [GCE vm group zone] }
153
+ # rc.labels # { instance_id: [GCE VM instance id],
154
+ # # zone: [GCE vm group zone] }
151
155
  #
152
156
  # @example Otherwise default to generic "global" type:
153
- # rc = Middleware.build_monitored_resource
157
+ # rc = Google::Cloud::Logging::Middleware.build_monitored_resource
154
158
  # rc.type #=> "global"
155
159
  # rc.labels #=> {}
156
160
  #
@@ -88,9 +88,11 @@ module Google
88
88
  # Lists log entries. Use this method to retrieve log entries from Cloud
89
89
  # Logging.
90
90
  #
91
- # @param [String, Array] projects One or more project IDs or project
92
- # numbers from which to retrieve log entries. If `nil`, the ID of the
93
- # receiving project instance will be used.
91
+ # @param [String, Array<String>] resources One or more cloud resources
92
+ # from which to retrieve log entries. If both `resources` and
93
+ # `projects` are `nil`, the ID of the receiving project instance will
94
+ # be used. Examples: `"projects/my-project-1A"`,
95
+ # `"projects/1234567890"`.
94
96
  # @param [String] filter An [advanced logs
95
97
  # filter](https://cloud.google.com/logging/docs/view/advanced_filters).
96
98
  # The filter is compared against all log entries in the projects
@@ -102,6 +104,12 @@ module Google
102
104
  # @param [String] token A previously-returned page token representing
103
105
  # part of the larger set of results to view.
104
106
  # @param [Integer] max Maximum number of entries to return.
107
+ # @param [String, Array<String>] projects One or more project IDs or
108
+ # project numbers from which to retrieve log entries. Each value will
109
+ # be formatted as a project resource name and added to any values
110
+ # passed to `resources`. If both `resources` and `projects` are `nil`,
111
+ # the ID of the receiving project instance will be used. This is
112
+ # deprecated in favor of `resources`.
105
113
  #
106
114
  # @return [Array<Google::Cloud::Logging::Entry>] (See
107
115
  # {Google::Cloud::Logging::Entry::List})
@@ -143,13 +151,16 @@ module Google
143
151
  # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}"
144
152
  # end
145
153
  #
146
- def entries projects: nil, filter: nil, order: nil, token: nil, max: nil
154
+ def entries resources: nil, filter: nil, order: nil, token: nil,
155
+ max: nil, projects: nil
147
156
  ensure_service!
148
- list_grpc = service.list_entries projects: projects, filter: filter,
149
- order: order, token: token, max: max
157
+ list_grpc = service.list_entries resources: resources, filter: filter,
158
+ order: order, token: token, max: max,
159
+ projects: projects
150
160
  Entry::List.from_grpc list_grpc, service,
151
- projects: projects, max: max,
152
- filter: filter, order: order
161
+ resources: resources, max: max,
162
+ filter: filter, order: order,
163
+ projects: projects
153
164
  end
154
165
  alias_method :find_entries, :entries
155
166
 
@@ -533,6 +544,13 @@ module Google
533
544
  # consistent with the log entry format designed by the `version`
534
545
  # parameter, regardless of the format of the log entry that was
535
546
  # originally written to Stackdriver Logging.
547
+ # @param [Time, nil] start_at The time at which this sink will begin
548
+ # exporting log entries. If this value is present, then log entries
549
+ # are exported only if `start_at` is less than the log entry's
550
+ # timestamp. Optional.
551
+ # @param [Time, nil] end_at Time at which this sink will stop exporting
552
+ # log entries. If this value is present, then log entries are exported
553
+ # only if the log entry's timestamp is less than `end_at`. Optional.
536
554
  # @param [Symbol] version The log entry version used when exporting log
537
555
  # entries from this sink. This version does not have to correspond to
538
556
  # the version of the log entry when it was written to Stackdriver
@@ -540,6 +558,12 @@ module Google
540
558
  # Version 2 is currently the preferred format. An unspecified version
541
559
  # format currently defaults to V2 in the service. The default value is
542
560
  # `:unspecified`.
561
+ # @param [Boolean] unique_writer_identity Whether the sink will have a
562
+ # dedicated service account returned in the sink's `writer_identity`.
563
+ # Set this field to be true to export logs from one project to a
564
+ # different project. This field is ignored for non-project sinks
565
+ # (e.g. organization sinks) because those sinks are required to have
566
+ # dedicated service accounts. Optional.
543
567
  #
544
568
  # @return [Google::Cloud::Logging::Sink] a project sink
545
569
  #
@@ -561,10 +585,15 @@ module Google
561
585
  # sink = logging.create_sink "my-sink",
562
586
  # "storage.googleapis.com/#{bucket.id}"
563
587
  #
564
- def create_sink name, destination, filter: nil, version: :unspecified
588
+ def create_sink name, destination, filter: nil, start_at: nil,
589
+ end_at: nil, version: :unspecified,
590
+ unique_writer_identity: nil
565
591
  version = Sink.resolve_version version
566
592
  ensure_service!
567
- grpc = service.create_sink name, destination, filter, version
593
+ grpc = service.create_sink \
594
+ name, destination, filter, version,
595
+ start_time: start_at, end_time: end_at,
596
+ unique_writer_identity: unique_writer_identity
568
597
  Sink.from_grpc grpc, service
569
598
  end
570
599
  alias_method :new_sink, :create_sink
@@ -587,7 +616,7 @@ module Google
587
616
  # require "google/cloud/logging"
588
617
  #
589
618
  # logging = Google::Cloud::Logging.new
590
- # sink = logging.sink "non-existing-sink" #=> nil
619
+ # sink = logging.sink "non-existing-sink" # nil
591
620
  #
592
621
  def sink sink_name
593
622
  ensure_service!
@@ -686,7 +715,7 @@ module Google
686
715
  # require "google/cloud/logging"
687
716
  #
688
717
  # logging = Google::Cloud::Logging.new
689
- # metric = logging.metric "non_existing_metric" #=> nil
718
+ # metric = logging.metric "non_existing_metric" # nil
690
719
  #
691
720
  def metric name
692
721
  ensure_service!
@@ -37,7 +37,7 @@ module Google
37
37
  # resource_descriptor = logging.resource_descriptors.first
38
38
  # resource_descriptor.type #=> "cloudsql_database"
39
39
  # resource_descriptor.name #=> "Cloud SQL Database"
40
- # resource_descriptor.labels.map &:key #=> ["database_id", "region"]
40
+ # resource_descriptor.labels.map &:key #=> ["database_id", "zone"]
41
41
  #
42
42
  class ResourceDescriptor
43
43
  ##
@@ -33,7 +33,7 @@ module Google
33
33
  client_config: nil
34
34
  @project = project
35
35
  @credentials = credentials
36
- @host = host || V2::LoggingServiceV2Api::SERVICE_ADDRESS
36
+ @host = host || V2::LoggingServiceV2Client::SERVICE_ADDRESS
37
37
  @timeout = timeout
38
38
  @client_config = client_config || {}
39
39
  end
@@ -53,7 +53,7 @@ module Google
53
53
  def logging
54
54
  return mocked_logging if mocked_logging
55
55
  @logging ||= \
56
- V2::LoggingServiceV2Api.new(
56
+ V2::LoggingServiceV2Client.new(
57
57
  service_path: host,
58
58
  channel: channel,
59
59
  timeout: timeout,
@@ -66,7 +66,7 @@ module Google
66
66
  def sinks
67
67
  return mocked_sinks if mocked_sinks
68
68
  @sinks ||= \
69
- V2::ConfigServiceV2Api.new(
69
+ V2::ConfigServiceV2Client.new(
70
70
  service_path: host,
71
71
  channel: channel,
72
72
  timeout: timeout,
@@ -79,7 +79,7 @@ module Google
79
79
  def metrics
80
80
  return mocked_metrics if mocked_metrics
81
81
  @metrics ||= \
82
- V2::MetricsServiceV2Api.new(
82
+ V2::MetricsServiceV2Client.new(
83
83
  service_path: host,
84
84
  channel: channel,
85
85
  timeout: timeout,
@@ -93,10 +93,12 @@ module Google
93
93
  credentials == :this_channel_is_insecure
94
94
  end
95
95
 
96
- def list_entries projects: nil, filter: nil, order: nil, token: nil,
97
- max: nil
96
+ def list_entries resources: nil, filter: nil, order: nil, token: nil,
97
+ max: nil, projects: nil
98
98
 
99
- project_ids = Array(projects || @project)
99
+ project_ids = Array(projects).map { |p| "projects/#{p}" }
100
+ resource_names = Array(resources) + project_ids
101
+ resource_names = ["projects/#{@project}"] if resource_names.empty?
100
102
  call_opts = default_options
101
103
  if token
102
104
  call_opts = Google::Gax::CallOptions.new(kwargs: default_headers,
@@ -104,11 +106,9 @@ module Google
104
106
  end
105
107
 
106
108
  execute do
107
- paged_enum = logging.list_log_entries project_ids,
108
- filter: filter,
109
- order_by: order,
110
- page_size: max,
111
- options: call_opts
109
+ paged_enum = logging.list_log_entries \
110
+ resource_names, filter: filter, order_by: order, page_size: max,
111
+ options: call_opts
112
112
  paged_enum.page.response
113
113
  end
114
114
  end
@@ -162,13 +162,19 @@ module Google
162
162
  end
163
163
  end
164
164
 
165
- def create_sink name, destination, filter, version
165
+ def create_sink name, destination, filter, version, start_time: nil,
166
+ end_time: nil, unique_writer_identity: nil
166
167
  sink = Google::Logging::V2::LogSink.new({
167
168
  name: name, destination: destination, filter: filter,
168
- output_version_format: version }.delete_if { |_, v| v.nil? })
169
+ output_version_format: version,
170
+ start_time: time_to_timestamp(start_time),
171
+ end_time: time_to_timestamp(end_time)
172
+ }.delete_if { |_, v| v.nil? })
169
173
 
170
174
  execute do
171
- sinks.create_sink project_path, sink, options: default_options
175
+ sinks.create_sink project_path, sink,
176
+ unique_writer_identity: unique_writer_identity,
177
+ options: default_options
172
178
  end
173
179
  end
174
180
 
@@ -176,13 +182,18 @@ module Google
176
182
  execute { sinks.get_sink sink_path(name), options: default_options }
177
183
  end
178
184
 
179
- def update_sink name, destination, filter, version
185
+ def update_sink name, destination, filter, version, start_time: nil,
186
+ end_time: nil, unique_writer_identity: nil
180
187
  sink = Google::Logging::V2::LogSink.new({
181
188
  name: name, destination: destination, filter: filter,
182
- output_version_format: version }.delete_if { |_, v| v.nil? })
189
+ output_version_format: version,
190
+ start_time: time_to_timestamp(start_time),
191
+ end_time: time_to_timestamp(end_time) }.delete_if { |_, v| v.nil? })
183
192
 
184
193
  execute do
185
- sinks.update_sink sink_path(name), sink, options: default_options
194
+ sinks.update_sink sink_path(name), sink,
195
+ unique_writer_identity: unique_writer_identity,
196
+ options: default_options
186
197
  end
187
198
  end
188
199
 
@@ -276,6 +287,24 @@ module Google
276
287
  Google::Gax::CallOptions.new kwargs: default_headers
277
288
  end
278
289
 
290
+ ##
291
+ # @private Get a Google::Protobuf::Timestamp object from a Time object.
292
+ def time_to_timestamp time
293
+ return nil if time.nil?
294
+ # Make sure we have a Time object
295
+ return nil unless time.respond_to? :to_time
296
+ time = time.to_time
297
+ Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
298
+ end
299
+
300
+ ##
301
+ # @private Get a Time object from a Google::Protobuf::Timestamp object.
302
+ def timestamp_to_time timestamp
303
+ return nil if timestamp.nil?
304
+ # Time.at takes microseconds, so convert nano seconds to microseconds
305
+ Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
306
+ end
307
+
279
308
  def execute
280
309
  yield
281
310
  rescue Google::Gax::GaxError => e
@@ -25,6 +25,11 @@ module Google
25
25
  # a sink, new log entries are exported. Stackdriver Logging does not send
26
26
  # previously-ingested log entries to the sink's destination.
27
27
  #
28
+ # A logs filter controls which log entries are exported. Sinks can have a
29
+ # start time and an end time; these can be used to place log entries from
30
+ # an exact time range into a particular destination. If both `start_at`
31
+ # and `end_at` are present, then `start_at` must be less than `end_at`.
32
+ #
28
33
  # Before creating the sink, ensure that you have granted
29
34
  # `cloud-logs@google.com` permission to write logs to the destination. See
30
35
  # [Permissions for writing exported
@@ -152,9 +157,62 @@ module Google
152
157
  version == :V1
153
158
  end
154
159
 
160
+ ##
161
+ # The time at which this sink will begin exporting log entries. If this
162
+ # value is present, then log entries are exported only if `start_at`
163
+ # is less than the log entry's timestamp. Optional.
164
+ def start_at
165
+ timestamp_to_time @grpc.start_time
166
+ end
167
+ alias_method :start_time, :start_at
168
+
169
+ ##
170
+ # Sets the time at which this sink will begin exporting log entries. If
171
+ # this value is present, then log entries are exported only if
172
+ # `start_at` is less than the log entry's timestamp. Optional.
173
+ def start_at= new_start_at
174
+ @grpc.start_time = time_to_timestamp new_start_at
175
+ end
176
+ alias_method :start_time=, :start_at=
177
+
178
+ ##
179
+ # Time at which this sink will stop exporting log entries. If this
180
+ # value is present, then log entries are exported only if the log
181
+ # entry's timestamp is less than `end_at`. Optional.
182
+ def end_at
183
+ timestamp_to_time @grpc.end_time
184
+ end
185
+ alias_method :end_time, :end_at
186
+
187
+ ##
188
+ # Sets the time at which this sink will stop exporting log entries. If
189
+ # this value is present, then log entries are exported only if the log
190
+ # entry's timestamp is less than `end_at`. Optional.
191
+ def end_at= new_end_at
192
+ @grpc.end_time = time_to_timestamp new_end_at
193
+ end
194
+ alias_method :end_time=, :end_at=
195
+
196
+ ##
197
+ # An IAM identity (a service account or group) that will write exported
198
+ # log entries to the destination on behalf of Stackdriver Logging. You
199
+ # must grant this identity write-access to the destination. Consult the
200
+ # destination service's documentation to determine the exact role that
201
+ # must be granted.
202
+ def writer_identity
203
+ @grpc.writer_identity
204
+ end
205
+
155
206
  ##
156
207
  # Updates the logs-based sink.
157
208
  #
209
+ # @param [Boolean] unique_writer_identity Whether the sink will have a
210
+ # dedicated service account returned in the sink's `writer_identity`.
211
+ # Set this field to be true to export logs from one project to a
212
+ # different project. This field is ignored for non-project sinks
213
+ # (e.g. organization sinks) because those sinks are required to have
214
+ # dedicated service accounts. Optional.
215
+ #
158
216
  # @example
159
217
  # require "google/cloud/logging"
160
218
  #
@@ -163,9 +221,12 @@ module Google
163
221
  # sink.filter = "logName:syslog AND severity>=ERROR"
164
222
  # sink.save
165
223
  #
166
- def save
224
+ def save unique_writer_identity: nil
167
225
  ensure_service!
168
- @grpc = service.update_sink name, destination, filter, version
226
+ @grpc = service.update_sink \
227
+ name, destination, filter, version,
228
+ start_time: start_at, end_time: end_at,
229
+ unique_writer_identity: unique_writer_identity
169
230
  end
170
231
 
171
232
  ##
@@ -222,6 +283,24 @@ module Google
222
283
  def ensure_service!
223
284
  fail "Must have active connection to service" unless service
224
285
  end
286
+
287
+ ##
288
+ # @private Get a Google::Protobuf::Timestamp object from a Time object.
289
+ def time_to_timestamp time
290
+ return nil if time.nil?
291
+ # Make sure we have a Time object
292
+ return nil unless time.respond_to? :to_time
293
+ time = time.to_time
294
+ Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
295
+ end
296
+
297
+ ##
298
+ # @private Get a Time object from a Google::Protobuf::Timestamp object.
299
+ def timestamp_to_time timestamp
300
+ return nil if timestamp.nil?
301
+ # Time.at takes microseconds, so convert nano seconds to microseconds
302
+ Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
303
+ end
225
304
  end
226
305
  end
227
306
  end