Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion google-cloud-logging/acceptance/logging/logging_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,42 @@
pubsub_dest = "pubsub.googleapis.com/projects/#{logging.project}/topics/#{prefix}-topic"
sink = logging.create_sink "#{prefix}-sink",
pubsub_dest,
filter: "severity = ALERT"
filter: "severity = ALERT",
start_at: Time.now

sink.name.must_equal "#{prefix}-sink"
sink.destination.must_equal pubsub_dest
sink.filter.must_equal "severity = ALERT"
sink.start_at.wont_be :nil?
sink.end_at.must_be :nil?

sink.filter = "severity >= WARNING"
sink.start_at = nil
sink.end_at = Time.parse "2020-01-01"

sink.save

sink.name.must_equal "#{prefix}-sink"
sink.destination.must_equal pubsub_dest
sink.filter.must_equal "severity >= WARNING"
sink.start_at.must_be :nil?
sink.end_at.wont_be :nil?

sink.refresh!

sink.name.must_equal "#{prefix}-sink"
sink.destination.must_equal pubsub_dest
sink.filter.must_equal "severity >= WARNING"
sink.start_at.must_be :nil?
sink.end_at.wont_be :nil?

dup_sink = logging.sink "#{prefix}-sink"

dup_sink.name.must_equal "#{prefix}-sink"
dup_sink.destination.must_equal pubsub_dest
dup_sink.filter.must_equal "severity >= WARNING"
dup_sink.start_at.must_be :nil?
dup_sink.end_at.wont_be :nil?

logging.sinks.wont_be :empty?
logging.sinks(max: 1).length.must_equal 1
Expand Down
22 changes: 20 additions & 2 deletions google-cloud-logging/lib/google/cloud/logging/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -540,13 +540,26 @@ def sinks token: nil, max: nil
# consistent with the log entry format designed by the `version`
# parameter, regardless of the format of the log entry that was
# originally written to Stackdriver Logging.
# @param [Time, nil] start_at The time at which this sink will begin
# exporting log entries. If this value is present, then log entries
# are exported only if `start_at` is less than the log entry's
# timestamp. Optional.
# @param [Time, nil] end_at Time at which this sink will stop exporting
# log entries. If this value is present, then log entries are exported
# only if the log entry's timestamp is less than `end_at`. Optional.
# @param [Symbol] version The log entry version used when exporting log
# entries from this sink. This version does not have to correspond to
# the version of the log entry when it was written to Stackdriver
# Logging. Accepted values are `:unspecified`, `:v2`, and `:v1`.
# Version 2 is currently the preferred format. An unspecified version
# format currently defaults to V2 in the service. The default value is
# `:unspecified`.
# @param [Boolean] unique_writer_identity Whether the sink will have a
# dedicated service account returned in the sink's `writer_identity`.
# Set this field to be true to export logs from one project to a
# different project. This field is ignored for non-project sinks
# (e.g. organization sinks) because those sinks are required to have
# dedicated service accounts. Optional.
#
# @return [Google::Cloud::Logging::Sink] a project sink
#
Expand All @@ -568,10 +581,15 @@ def sinks token: nil, max: nil
# sink = logging.create_sink "my-sink",
# "storage.googleapis.com/#{bucket.id}"
#
def create_sink name, destination, filter: nil, version: :unspecified
def create_sink name, destination, filter: nil, start_at: nil,
end_at: nil, version: :unspecified,
unique_writer_identity: nil
version = Sink.resolve_version version
ensure_service!
grpc = service.create_sink name, destination, filter, version
grpc = service.create_sink \
name, destination, filter, version,
start_time: start_at, end_time: end_at,
unique_writer_identity: unique_writer_identity
Sink.from_grpc grpc, service
end
alias_method :new_sink, :create_sink
Expand Down
47 changes: 38 additions & 9 deletions google-cloud-logging/lib/google/cloud/logging/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def list_entries resources: nil, filter: nil, order: nil, token: nil,
if project_ids.empty? && resource_names.empty?
resource_names = ["projects/#{@project}"]
end
resource_names = nil if resource_names.empty?
project_ids = nil if project_ids.empty?
call_opts = default_options
if token
call_opts = Google::Gax::CallOptions.new(kwargs: default_headers,
Expand All @@ -110,8 +110,8 @@ def list_entries resources: nil, filter: nil, order: nil, token: nil,

execute do
paged_enum = logging.list_log_entries \
project_ids, resource_names: resource_names, filter: filter,
order_by: order, page_size: max, options: call_opts
resource_names, filter: filter, order_by: order, page_size: max,
options: call_opts, project_ids: project_ids
paged_enum.page.response
end
end
Expand Down Expand Up @@ -165,27 +165,38 @@ def list_sinks token: nil, max: nil
end
end

def create_sink name, destination, filter, version
def create_sink name, destination, filter, version, start_time: nil,
end_time: nil, unique_writer_identity: nil
sink = Google::Logging::V2::LogSink.new({
name: name, destination: destination, filter: filter,
output_version_format: version }.delete_if { |_, v| v.nil? })
output_version_format: version,
start_time: time_to_timestamp(start_time),
end_time: time_to_timestamp(end_time)
}.delete_if { |_, v| v.nil? })

execute do
sinks.create_sink project_path, sink, options: default_options
sinks.create_sink project_path, sink,
unique_writer_identity: unique_writer_identity,
options: default_options
end
end

def get_sink name
execute { sinks.get_sink sink_path(name), options: default_options }
end

def update_sink name, destination, filter, version
def update_sink name, destination, filter, version, start_time: nil,
end_time: nil, unique_writer_identity: nil
sink = Google::Logging::V2::LogSink.new({
name: name, destination: destination, filter: filter,
output_version_format: version }.delete_if { |_, v| v.nil? })
output_version_format: version,
start_time: time_to_timestamp(start_time),
end_time: time_to_timestamp(end_time) }.delete_if { |_, v| v.nil? })

execute do
sinks.update_sink sink_path(name), sink, options: default_options
sinks.update_sink sink_path(name), sink,
unique_writer_identity: unique_writer_identity,
options: default_options
end
end

Expand Down Expand Up @@ -279,6 +290,24 @@ def default_options
Google::Gax::CallOptions.new kwargs: default_headers
end

##
# @private Get a Google::Protobuf::Timestamp object from a Time object.
def time_to_timestamp time
return nil if time.nil?
# Make sure we have a Time object
return nil unless time.respond_to? :to_time

This comment was marked as spam.

This comment was marked as spam.

time = time.to_time
Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
end

##
# @private Get a Time object from a Google::Protobuf::Timestamp object.
def timestamp_to_time timestamp
return nil if timestamp.nil?
# Time.at takes microseconds, so convert nano seconds to microseconds
Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
end

def execute
yield
rescue Google::Gax::GaxError => e
Expand Down
83 changes: 81 additions & 2 deletions google-cloud-logging/lib/google/cloud/logging/sink.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ module Logging
# a sink, new log entries are exported. Stackdriver Logging does not send
# previously-ingested log entries to the sink's destination.
#
# A logs filter controls which log entries are exported. Sinks can have a
# start time and an end time; these can be used to place log entries from
# an exact time range into a particular destination. If both `start_at`
# and `end_at` are present, then `start_at` must be less than `end_at`.
#
# Before creating the sink, ensure that you have granted
# `cloud-logs@google.com` permission to write logs to the destination. See
# [Permissions for writing exported
Expand Down Expand Up @@ -152,9 +157,62 @@ def v1?
version == :V1
end

##
# The time at which this sink will begin exporting log entries. If this
# value is present, then log entries are exported only if `start_at`
# is less than the log entry's timestamp. Optional.
def start_at
timestamp_to_time @grpc.start_time
end
alias_method :start_time, :start_at

##
# Sets the time at which this sink will begin exporting log entries. If
# this value is present, then log entries are exported only if
# `start_at` is less than the log entry's timestamp. Optional.
def start_at= new_start_at
@grpc.start_time = time_to_timestamp new_start_at
end
alias_method :start_time=, :start_at=

##
# Time at which this sink will stop exporting log entries. If this
# value is present, then log entries are exported only if the log
# entry's timestamp is less than `end_at`. Optional.
def end_at
timestamp_to_time @grpc.end_time
end
alias_method :end_time, :end_at

##
# Sets the time at which this sink will stop exporting log entries. If
# this value is present, then log entries are exported only if the log
# entry's timestamp is less than `end_at`. Optional.
def end_at= new_end_at
@grpc.end_time = time_to_timestamp new_end_at
end
alias_method :end_time=, :end_at=

##
# An IAM identity (a service account or group) that will write exported
# log entries to the destination on behalf of Stackdriver Logging. You
# must grant this identity write-access to the destination. Consult the
# destination service's documentation to determine the exact role that
# must be granted.
def writer_identity
@grpc.writer_identity
end

##
# Updates the logs-based sink.
#
# @param [Boolean] unique_writer_identity Whether the sink will have a
# dedicated service account returned in the sink's `writer_identity`.
# Set this field to be true to export logs from one project to a
# different project. This field is ignored for non-project sinks
# (e.g. organization sinks) because those sinks are required to have
# dedicated service accounts. Optional.
#
# @example
# require "google/cloud/logging"
#
Expand All @@ -163,9 +221,12 @@ def v1?
# sink.filter = "logName:syslog AND severity>=ERROR"
# sink.save
#
def save
def save unique_writer_identity: nil
ensure_service!
@grpc = service.update_sink name, destination, filter, version
@grpc = service.update_sink \
name, destination, filter, version,
start_time: start_at, end_time: end_at,
unique_writer_identity: unique_writer_identity
end

##
Expand Down Expand Up @@ -222,6 +283,24 @@ def self.resolve_version version
def ensure_service!
fail "Must have active connection to service" unless service
end

##
# @private Get a Google::Protobuf::Timestamp object from a Time object.
def time_to_timestamp time
return nil if time.nil?
# Make sure we have a Time object
return nil unless time.respond_to? :to_time

This comment was marked as spam.

time = time.to_time
Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
end

##
# @private Get a Time object from a Google::Protobuf::Timestamp object.
def timestamp_to_time timestamp
return nil if timestamp.nil?
# Time.at takes microseconds, so convert nano seconds to microseconds
Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
end
end
end
end
Expand Down
Loading