diff --git a/google-cloud-logging/acceptance/logging/logging_test.rb b/google-cloud-logging/acceptance/logging/logging_test.rb index e94dc729df5b..4fa6d565da65 100644 --- a/google-cloud-logging/acceptance/logging/logging_test.rb +++ b/google-cloud-logging/acceptance/logging/logging_test.rb @@ -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 diff --git a/google-cloud-logging/lib/google/cloud/logging/project.rb b/google-cloud-logging/lib/google/cloud/logging/project.rb index e0a92b33309f..ff33d5a0c17b 100644 --- a/google-cloud-logging/lib/google/cloud/logging/project.rb +++ b/google-cloud-logging/lib/google/cloud/logging/project.rb @@ -540,6 +540,13 @@ 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 @@ -547,6 +554,12 @@ def sinks token: nil, max: nil # 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 # @@ -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 diff --git a/google-cloud-logging/lib/google/cloud/logging/service.rb b/google-cloud-logging/lib/google/cloud/logging/service.rb index ca86eefd8372..2695a4a5eeed 100644 --- a/google-cloud-logging/lib/google/cloud/logging/service.rb +++ b/google-cloud-logging/lib/google/cloud/logging/service.rb @@ -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, @@ -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 @@ -165,13 +165,19 @@ 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 @@ -179,13 +185,18 @@ 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 @@ -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 + 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 diff --git a/google-cloud-logging/lib/google/cloud/logging/sink.rb b/google-cloud-logging/lib/google/cloud/logging/sink.rb index cf0594bc7271..f0f048534c8d 100644 --- a/google-cloud-logging/lib/google/cloud/logging/sink.rb +++ b/google-cloud-logging/lib/google/cloud/logging/sink.rb @@ -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 @@ -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" # @@ -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 ## @@ -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 + 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 diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/config_service_v2_api.rb b/google-cloud-logging/lib/google/cloud/logging/v2/config_service_v2_api.rb index 434bedd0c860..7a500dd01587 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/config_service_v2_api.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/config_service_v2_api.rb @@ -32,8 +32,8 @@ module Google module Cloud module Logging module V2 - # Service for configuring sinks used to export log entries outside Stackdriver - # Logging. + # Service for configuring sinks used to export log entries outside of + # Stackdriver Logging. # # @!attribute [r] config_service_v2_stub # @return [Google::Logging::V2::ConfigServiceV2::Stub] @@ -212,8 +212,10 @@ def initialize \ # Lists sinks. # # @param parent [String] - # Required. The cloud resource containing the sinks. - # Example: +"projects/my-logging-project"+. + # Required. The resource name where this sink was created: + # + # "projects/[PROJECT_ID]" + # "organizations/[ORGANIZATION_ID]" # @param page_size [Integer] # The maximum number of resources contained in the underlying API # response. If page streaming is performed per-resource, this @@ -264,8 +266,10 @@ def list_sinks \ # Gets a sink. # # @param sink_name [String] - # Required. The resource name of the sink to return. - # Example: +"projects/my-project-id/sinks/my-sink-id"+. + # Required. The resource name of the sink to return: + # + # "projects/[PROJECT_ID]/sinks/[SINK_ID]" + # "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]" # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. @@ -292,12 +296,19 @@ def get_sink \ # Creates a sink. # # @param parent [String] - # Required. The resource in which to create the sink. - # Example: +"projects/my-project-id"+. - # The new sink must be provided in the request. + # Required. The resource in which to create the sink: + # + # "projects/[PROJECT_ID]" + # "organizations/[ORGANIZATION_ID]" # @param sink [Google::Logging::V2::LogSink] # Required. The new sink, whose +name+ parameter is a sink identifier that # is not already in use. + # @param unique_writer_identity [true, false] + # Optional. 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. # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. @@ -317,10 +328,12 @@ def get_sink \ def create_sink \ parent, sink, + unique_writer_identity: nil, options: nil req = Google::Logging::V2::CreateSinkRequest.new({ parent: parent, - sink: sink + sink: sink, + unique_writer_identity: unique_writer_identity }.delete_if { |_, v| v.nil? }) @create_sink.call(req, options) end @@ -329,12 +342,22 @@ def create_sink \ # # @param sink_name [String] # Required. The resource name of the sink to update, including the parent - # resource and the sink identifier. If the sink does not exist, this method - # creates the sink. Example: +"projects/my-project-id/sinks/my-sink-id"+. + # resource and the sink identifier: + # + # "projects/[PROJECT_ID]/sinks/[SINK_ID]" + # "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]" + # + # Example: +"projects/my-project-id/sinks/my-sink-id"+. # @param sink [Google::Logging::V2::LogSink] # Required. The updated sink, whose name is the same identifier that appears # as part of +sinkName+. If +sinkName+ does not exist, then # this method creates a new sink. + # @param unique_writer_identity [true, false] + # Optional. 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. # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. @@ -354,10 +377,12 @@ def create_sink \ def update_sink \ sink_name, sink, + unique_writer_identity: nil, options: nil req = Google::Logging::V2::UpdateSinkRequest.new({ sink_name: sink_name, - sink: sink + sink: sink, + unique_writer_identity: unique_writer_identity }.delete_if { |_, v| v.nil? }) @update_sink.call(req, options) end @@ -366,9 +391,12 @@ def update_sink \ # # @param sink_name [String] # Required. The resource name of the sink to delete, including the parent - # resource and the sink identifier. Example: - # +"projects/my-project-id/sinks/my-sink-id"+. It is an error if the sink - # does not exist. + # resource and the sink identifier: + # + # "projects/[PROJECT_ID]/sinks/[SINK_ID]" + # "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]" + # + # It is an error if the sink does not exist. # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/log_entry.rb b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/log_entry.rb index 74cb15f3c3ec..f029ef66563a 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/log_entry.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/log_entry.rb @@ -18,17 +18,22 @@ module V2 # An individual entry in a log. # @!attribute [rw] log_name # @return [String] - # Required. The resource name of the log to which this log entry - # belongs. The format of the name is - # +"projects//logs/"+. Examples: - # +"projects/my-projectid/logs/syslog"+, - # +"projects/my-projectid/logs/library.googleapis.com%2Fbook_log"+. + # Required. The resource name of the log to which this log entry belongs: # - # The log ID part of resource name must be less than 512 characters - # long and can only include the following characters: upper and - # lower case alphanumeric characters: [A-Za-z0-9]; and punctuation - # characters: forward-slash, underscore, hyphen, and period. - # Forward-slash (+/+) characters in the log ID must be URL-encoded. + # "projects/[PROJECT_ID]/logs/[LOG_ID]" + # "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]" + # + # +[LOG_ID]+ must be URL-encoded within +log_name+. Example: + # +"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"+. + # +[LOG_ID]+ must be less than 512 characters long and can only include the + # following characters: upper and lower case alphanumeric characters, + # forward-slash, underscore, hyphen, and period. + # + # For backward compatibility, if +log_name+ begins with a forward-slash, such + # as +/projects/...+, then the log entry is ingested as usual but the + # forward-slash is removed. Listing the log entry will not show the leading + # slash and filtering for a log name with a leading slash will never return + # any results. # @!attribute [rw] resource # @return [Google::Api::MonitoredResource] # Required. The monitored resource associated with this log entry. @@ -45,8 +50,8 @@ module V2 # The log entry payload, represented as a Unicode string (UTF-8). # @!attribute [rw] json_payload # @return [Google::Protobuf::Struct] - # The log entry payload, represented as a structure that - # is expressed as a JSON object. + # The log entry payload, represented as a structure that is + # expressed as a JSON object. # @!attribute [rw] timestamp # @return [Google::Protobuf::Timestamp] # Optional. The time the event described by the log entry occurred. If diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging.rb b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging.rb index d758e7fe7fe3..380bcc2bddcd 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging.rb @@ -18,16 +18,31 @@ module V2 # The parameters to DeleteLog. # @!attribute [rw] log_name # @return [String] - # Required. The resource name of the log to delete. Example: - # +"projects/my-project/logs/syslog"+. + # Required. The resource name of the log to delete: + # + # "projects/[PROJECT_ID]/logs/[LOG_ID]" + # "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]" + # + # +[LOG_ID]+ must be URL-encoded. For example, + # +"projects/my-project-id/logs/syslog"+, + # +"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"+. + # For more information about log names, see + # LogEntry. class DeleteLogRequest; end # The parameters to WriteLogEntries. # @!attribute [rw] log_name # @return [String] # Optional. A default log resource name that is assigned to all log entries - # in +entries+ that do not specify a value for +log_name+. Example: - # +"projects/my-project/logs/syslog"+. See + # in +entries+ that do not specify a value for +log_name+: + # + # "projects/[PROJECT_ID]/logs/[LOG_ID]" + # "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]" + # + # +[LOG_ID]+ must be URL-encoded. For example, + # +"projects/my-project-id/logs/syslog"+ or + # +"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"+. + # For more information about log names, see # LogEntry. # @!attribute [rw] resource # @return [Google::Api::MonitoredResource] @@ -73,20 +88,25 @@ class WriteLogEntriesResponse; end # @!attribute [rw] project_ids # @return [Array] # Deprecated. One or more project identifiers or project numbers from which - # to retrieve log entries. Examples: +"my-project-1A"+, +"1234567890"+. If + # to retrieve log entries. Example: +"my-project-1A"+. If # present, these project identifiers are converted to resource format and # added to the list of resources in +resourceNames+. Callers should use # +resourceNames+ rather than this parameter. # @!attribute [rw] resource_names # @return [Array] - # Optional. One or more cloud resources from which to retrieve log entries. - # Example: +"projects/my-project-1A"+, +"projects/1234567890"+. Projects - # listed in +projectIds+ are added to this list. + # Required. One or more cloud resources from which to retrieve log + # entries: + # + # "projects/[PROJECT_ID]" + # "organizations/[ORGANIZATION_ID]" + # + # Projects listed in the +project_ids+ field are added to this list. # @!attribute [rw] filter # @return [String] # Optional. A filter that chooses which log entries to return. See {Advanced # Logs Filters}[https://cloud.google.com/logging/docs/view/advanced_filters]. Only log entries that # match the filter are returned. An empty filter matches all log entries. + # The maximum length of the filter is 20000 characters. # @!attribute [rw] order_by # @return [String] # Optional. How the results should be sorted. Presently, the only permitted diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_config.rb b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_config.rb index e364177f4e2f..396e7429e5ad 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_config.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_config.rb @@ -15,33 +15,38 @@ module Google module Logging module V2 - # Describes a sink used to export log entries outside Stackdriver Logging. + # Describes a sink used to export log entries outside of Stackdriver Logging. + # 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_time+ and + # +end_time+ are present, then +start_time+ must be less than +end_time+. # @!attribute [rw] name # @return [String] # Required. The client-assigned sink identifier, unique within the # project. Example: +"my-syslog-errors-to-pubsub"+. Sink identifiers are - # limited to 1000 characters and can include only the following characters: - # +A-Z+, +a-z+, +0-9+, and the special characters +_-.+. The maximum length - # of the name is 100 characters. + # limited to 100 characters and can include only the following characters: + # upper and lower-case alphanumeric characters, underscores, hyphens, and + # periods. # @!attribute [rw] destination # @return [String] - # Required. The export destination. See - # {Exporting Logs With Sinks}[https://cloud.google.com/logging/docs/api/tasks/exporting-logs]. - # Examples: + # Required. The export destination: + # + # "storage.googleapis.com/[GCS_BUCKET]" + # "bigquery.googleapis.com/projects/[PROJECT_ID]/datasets/[DATASET]" + # "pubsub.googleapis.com/projects/[PROJECT_ID]/topics/[TOPIC_ID]" # - # "storage.googleapis.com/my-gcs-bucket" - # "bigquery.googleapis.com/projects/my-project-id/datasets/my-dataset" - # "pubsub.googleapis.com/projects/my-project/topics/my-topic" + # For more information, see + # {Exporting Logs With Sinks}[https://cloud.google.com/logging/docs/api/tasks/exporting-logs]. # @!attribute [rw] filter # @return [String] # Optional. An {advanced logs filter}[https://cloud.google.com/logging/docs/view/advanced_filters]. # Only log entries matching the filter are exported. The filter # must be consistent with the log entry format specified by the # +outputVersionFormat+ parameter, regardless of the format of the - # log entry that was originally written to Stackdriver Logging. - # Example filter (V2 format): + # log entry that was originally ingested by Stackdriver Logging. + # The following example uses field names in the v2 log entry format: # - # logName=projects/my-projectid/logs/syslog AND severity>=ERROR + # logName="projects/[PROJECT_ID]/logs/[LOG_ID]" AND severity>=ERROR # @!attribute [rw] output_version_format # @return [Google::Logging::V2::LogSink::VersionFormat] # Optional. The log entry version to use for this sink's exported log @@ -50,18 +55,23 @@ module V2 # v2 format is used. # @!attribute [rw] writer_identity # @return [String] - # Output only. The iam identity to which the destination needs to grant write - # access. This may be a service account or a group. - # Examples (Do not assume these specific values): - # "serviceAccount:cloud-logs@system.gserviceaccount.com" - # "group:cloud-logs@google.com" - # - # For GCS destinations, the role "roles/owner" is required on the bucket - # For Cloud Pubsub destinations, the role "roles/pubsub.publisher" is - # required on the topic - # For BigQuery, the role "roles/editor" is required on the dataset + # Output only. 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. + # @!attribute [rw] start_time + # @return [Google::Protobuf::Timestamp] + # Optional. The time at which this sink will begin exporting log entries. If + # this value is present, then log entries are exported only if +start_time+ + # <=+entry.timestamp+. + # @!attribute [rw] end_time + # @return [Google::Protobuf::Timestamp] + # Optional. Time at which this sink will stop exporting log entries. If this + # value is present, then log entries are exported only if +entry.timestamp+ < + # +end_time+. class LogSink - # Available log entry formats. Log entries can be written to Cloud + # Available log entry formats. Log entries can be written to Stackdriver # Logging in either format and can be exported in either format. # Version 2 is the preferred format. module VersionFormat @@ -79,8 +89,10 @@ module VersionFormat # The parameters to +ListSinks+. # @!attribute [rw] parent # @return [String] - # Required. The cloud resource containing the sinks. - # Example: +"projects/my-logging-project"+. + # Required. The resource name where this sink was created: + # + # "projects/[PROJECT_ID]" + # "organizations/[ORGANIZATION_ID]" # @!attribute [rw] page_token # @return [String] # Optional. If present, then retrieve the next batch of results from the @@ -108,42 +120,66 @@ class ListSinksResponse; end # The parameters to +GetSink+. # @!attribute [rw] sink_name # @return [String] - # Required. The resource name of the sink to return. - # Example: +"projects/my-project-id/sinks/my-sink-id"+. + # Required. The resource name of the sink to return: + # + # "projects/[PROJECT_ID]/sinks/[SINK_ID]" + # "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]" class GetSinkRequest; end # The parameters to +CreateSink+. # @!attribute [rw] parent # @return [String] - # Required. The resource in which to create the sink. - # Example: +"projects/my-project-id"+. - # The new sink must be provided in the request. + # Required. The resource in which to create the sink: + # + # "projects/[PROJECT_ID]" + # "organizations/[ORGANIZATION_ID]" # @!attribute [rw] sink # @return [Google::Logging::V2::LogSink] # Required. The new sink, whose +name+ parameter is a sink identifier that # is not already in use. + # @!attribute [rw] unique_writer_identity + # @return [true, false] + # Optional. 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. class CreateSinkRequest; end # The parameters to +UpdateSink+. # @!attribute [rw] sink_name # @return [String] # Required. The resource name of the sink to update, including the parent - # resource and the sink identifier. If the sink does not exist, this method - # creates the sink. Example: +"projects/my-project-id/sinks/my-sink-id"+. + # resource and the sink identifier: + # + # "projects/[PROJECT_ID]/sinks/[SINK_ID]" + # "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]" + # + # Example: +"projects/my-project-id/sinks/my-sink-id"+. # @!attribute [rw] sink # @return [Google::Logging::V2::LogSink] # Required. The updated sink, whose name is the same identifier that appears # as part of +sinkName+. If +sinkName+ does not exist, then # this method creates a new sink. + # @!attribute [rw] unique_writer_identity + # @return [true, false] + # Optional. 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. class UpdateSinkRequest; end # The parameters to +DeleteSink+. # @!attribute [rw] sink_name # @return [String] # Required. The resource name of the sink to delete, including the parent - # resource and the sink identifier. Example: - # +"projects/my-project-id/sinks/my-sink-id"+. It is an error if the sink - # does not exist. + # resource and the sink identifier: + # + # "projects/[PROJECT_ID]/sinks/[SINK_ID]" + # "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]" + # + # It is an error if the sink does not exist. class DeleteSinkRequest; end end end diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_metrics.rb b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_metrics.rb index b8c0744f412d..9ae87ef50a51 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_metrics.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/doc/google/logging/v2/logging_metrics.rb @@ -19,21 +19,32 @@ module V2 # number of log entries that match a logs filter. # @!attribute [rw] name # @return [String] - # Required. The client-assigned metric identifier. Example: - # +"severe_errors"+. Metric identifiers are limited to 100 - # characters and can include only the following characters: +A-Z+, - # +a-z+, +0-9+, and the special characters +_-.,+!*',()%/+. The - # forward-slash character (+/+) denotes a hierarchy of name pieces, - # and it cannot be the first character of the name. The '%' character - # is used to URL encode unsafe and reserved characters and must be - # followed by two hexadecimal digits according to RFC 1738. + # Required. The client-assigned metric identifier. + # Examples: +"error_count"+, +"nginx/requests"+. + # + # Metric identifiers are limited to 100 characters and can include + # only the following characters: +A-Z+, +a-z+, +0-9+, and the + # special characters +_-.,+!*',()%/+. The forward-slash character + # (+/+) denotes a hierarchy of name pieces, and it cannot be the + # first character of the name. + # + # The metric identifier in this field must not be + # {URL-encoded}[https://en.wikipedia.org/wiki/Percent-encoding]. + # However, when the metric identifier appears as the +[METRIC_ID]+ + # part of a +metric_name+ API parameter, then the metric identifier + # must be URL-encoded. Example: + # +"projects/my-project/metrics/nginx%2Frequests"+. # @!attribute [rw] description # @return [String] # Optional. A description of this metric, which is used in documentation. # @!attribute [rw] filter # @return [String] # Required. An {advanced logs filter}[https://cloud.google.com/logging/docs/view/advanced_filters]. - # Example: +"resource.type=gae_app AND severity>=ERROR"+. + # Example: + # + # "resource.type=gae_app AND severity>=ERROR" + # + # The maximum length of the filter is 20000 characters. # @!attribute [rw] version # @return [Google::Logging::V2::LogMetric::ApiVersion] # Output only. The API version that created or updated this metric. @@ -53,8 +64,9 @@ module ApiVersion # The parameters to ListLogMetrics. # @!attribute [rw] parent # @return [String] - # Required. The resource name containing the metrics. - # Example: +"projects/my-project-id"+. + # Required. The name of the project containing the metrics: + # + # "projects/[PROJECT_ID]" # @!attribute [rw] page_token # @return [String] # Optional. If present, then retrieve the next batch of results from the @@ -82,15 +94,17 @@ class ListLogMetricsResponse; end # The parameters to GetLogMetric. # @!attribute [rw] metric_name # @return [String] - # The resource name of the desired metric. - # Example: +"projects/my-project-id/metrics/my-metric-id"+. + # The resource name of the desired metric: + # + # "projects/[PROJECT_ID]/metrics/[METRIC_ID]" class GetLogMetricRequest; end # The parameters to CreateLogMetric. # @!attribute [rw] parent # @return [String] - # The resource name of the project in which to create the metric. - # Example: +"projects/my-project-id"+. + # The resource name of the project in which to create the metric: + # + # "projects/[PROJECT_ID]" # # The new metric must be provided in the request. # @!attribute [rw] metric @@ -102,24 +116,24 @@ class CreateLogMetricRequest; end # The parameters to UpdateLogMetric. # @!attribute [rw] metric_name # @return [String] - # The resource name of the metric to update. - # Example: +"projects/my-project-id/metrics/my-metric-id"+. + # The resource name of the metric to update: # - # The updated metric must be provided in the request and have the - # same identifier that is specified in +metricName+. - # If the metric does not exist, it is created. + # "projects/[PROJECT_ID]/metrics/[METRIC_ID]" + # + # The updated metric must be provided in the request and it's + # +name+ field must be the same as +[METRIC_ID]+ If the metric + # does not exist in +[PROJECT_ID]+, then a new metric is created. # @!attribute [rw] metric # @return [Google::Logging::V2::LogMetric] - # The updated metric, whose name must be the same as the - # metric identifier in +metricName+. If +metricName+ does not - # exist, then a new metric is created. + # The updated metric. class UpdateLogMetricRequest; end # The parameters to DeleteLogMetric. # @!attribute [rw] metric_name # @return [String] - # The resource name of the metric to delete. - # Example: +"projects/my-project-id/metrics/my-metric-id"+. + # The resource name of the metric to delete: + # + # "projects/[PROJECT_ID]/metrics/[METRIC_ID]" class DeleteLogMetricRequest; end end end diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/logging_service_v2_api.rb b/google-cloud-logging/lib/google/cloud/logging/v2/logging_service_v2_api.rb index affd0b4588d2..b1699d6cb031 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/logging_service_v2_api.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/logging_service_v2_api.rb @@ -208,12 +208,20 @@ def initialize \ # Service calls - # Deletes a log and all its log entries. - # The log will reappear if it receives new entries. + # Deletes all the log entries in a log. + # The log reappears if it receives new entries. # # @param log_name [String] - # Required. The resource name of the log to delete. Example: - # +"projects/my-project/logs/syslog"+. + # Required. The resource name of the log to delete: + # + # "projects/[PROJECT_ID]/logs/[LOG_ID]" + # "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]" + # + # +[LOG_ID]+ must be URL-encoded. For example, + # +"projects/my-project-id/logs/syslog"+, + # +"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"+. + # For more information about log names, see + # LogEntry. # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. @@ -242,8 +250,15 @@ def delete_log \ # # @param log_name [String] # Optional. A default log resource name that is assigned to all log entries - # in +entries+ that do not specify a value for +log_name+. Example: - # +"projects/my-project/logs/syslog"+. See + # in +entries+ that do not specify a value for +log_name+: + # + # "projects/[PROJECT_ID]/logs/[LOG_ID]" + # "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]" + # + # +[LOG_ID]+ must be URL-encoded. For example, + # +"projects/my-project-id/logs/syslog"+ or + # +"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"+. + # For more information about log names, see # LogEntry. # @param resource [Google::Api::MonitoredResource] # Optional. A default monitored resource object that is assigned to all log @@ -312,18 +327,23 @@ def write_log_entries \ # # @param project_ids [Array] # Deprecated. One or more project identifiers or project numbers from which - # to retrieve log entries. Examples: +"my-project-1A"+, +"1234567890"+. If + # to retrieve log entries. Example: +"my-project-1A"+. If # present, these project identifiers are converted to resource format and # added to the list of resources in +resourceNames+. Callers should use # +resourceNames+ rather than this parameter. # @param resource_names [Array] - # Optional. One or more cloud resources from which to retrieve log entries. - # Example: +"projects/my-project-1A"+, +"projects/1234567890"+. Projects - # listed in +projectIds+ are added to this list. + # Required. One or more cloud resources from which to retrieve log + # entries: + # + # "projects/[PROJECT_ID]" + # "organizations/[ORGANIZATION_ID]" + # + # Projects listed in the +project_ids+ field are added to this list. # @param filter [String] # Optional. A filter that chooses which log entries to return. See {Advanced # Logs Filters}[https://cloud.google.com/logging/docs/view/advanced_filters]. Only log entries that # match the filter are returned. An empty filter matches all log entries. + # The maximum length of the filter is 20000 characters. # @param order_by [String] # Optional. How the results should be sorted. Presently, the only permitted # values are +"timestamp asc"+ (default) and +"timestamp desc"+. The first @@ -352,15 +372,15 @@ def write_log_entries \ # LoggingServiceV2Api = Google::Cloud::Logging::V2::LoggingServiceV2Api # # logging_service_v2_api = LoggingServiceV2Api.new - # project_ids = [] + # resource_names = [] # # # Iterate over all results. - # logging_service_v2_api.list_log_entries(project_ids).each do |element| + # logging_service_v2_api.list_log_entries(resource_names).each do |element| # # Process element. # end # # # Or iterate over results one page at a time. - # logging_service_v2_api.list_log_entries(project_ids).each_page do |page| + # logging_service_v2_api.list_log_entries(resource_names).each_page do |page| # # Process each page at a time. # page.each do |element| # # Process element. @@ -368,15 +388,15 @@ def write_log_entries \ # end def list_log_entries \ - project_ids, - resource_names: nil, + resource_names, + project_ids: nil, filter: nil, order_by: nil, page_size: nil, options: nil req = Google::Logging::V2::ListLogEntriesRequest.new({ - project_ids: project_ids, resource_names: resource_names, + project_ids: project_ids, filter: filter, order_by: order_by, page_size: page_size diff --git a/google-cloud-logging/lib/google/cloud/logging/v2/metrics_service_v2_api.rb b/google-cloud-logging/lib/google/cloud/logging/v2/metrics_service_v2_api.rb index e681a86bc622..70edb4c3013f 100644 --- a/google-cloud-logging/lib/google/cloud/logging/v2/metrics_service_v2_api.rb +++ b/google-cloud-logging/lib/google/cloud/logging/v2/metrics_service_v2_api.rb @@ -211,8 +211,9 @@ def initialize \ # Lists logs-based metrics. # # @param parent [String] - # Required. The resource name containing the metrics. - # Example: +"projects/my-project-id"+. + # Required. The name of the project containing the metrics: + # + # "projects/[PROJECT_ID]" # @param page_size [Integer] # The maximum number of resources contained in the underlying API # response. If page streaming is performed per-resource, this @@ -263,8 +264,9 @@ def list_log_metrics \ # Gets a logs-based metric. # # @param metric_name [String] - # The resource name of the desired metric. - # Example: +"projects/my-project-id/metrics/my-metric-id"+. + # The resource name of the desired metric: + # + # "projects/[PROJECT_ID]/metrics/[METRIC_ID]" # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. @@ -291,8 +293,9 @@ def get_log_metric \ # Creates a logs-based metric. # # @param parent [String] - # The resource name of the project in which to create the metric. - # Example: +"projects/my-project-id"+. + # The resource name of the project in which to create the metric: + # + # "projects/[PROJECT_ID]" # # The new metric must be provided in the request. # @param metric [Google::Logging::V2::LogMetric] @@ -328,16 +331,15 @@ def create_log_metric \ # Creates or updates a logs-based metric. # # @param metric_name [String] - # The resource name of the metric to update. - # Example: +"projects/my-project-id/metrics/my-metric-id"+. + # The resource name of the metric to update: # - # The updated metric must be provided in the request and have the - # same identifier that is specified in +metricName+. - # If the metric does not exist, it is created. + # "projects/[PROJECT_ID]/metrics/[METRIC_ID]" + # + # The updated metric must be provided in the request and it's + # +name+ field must be the same as +[METRIC_ID]+ If the metric + # does not exist in +[PROJECT_ID]+, then a new metric is created. # @param metric [Google::Logging::V2::LogMetric] - # The updated metric, whose name must be the same as the - # metric identifier in +metricName+. If +metricName+ does not - # exist, then a new metric is created. + # The updated metric. # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. @@ -368,8 +370,9 @@ def update_log_metric \ # Deletes a logs-based metric. # # @param metric_name [String] - # The resource name of the metric to delete. - # Example: +"projects/my-project-id/metrics/my-metric-id"+. + # The resource name of the metric to delete: + # + # "projects/[PROJECT_ID]/metrics/[METRIC_ID]" # @param options [Google::Gax::CallOptions] # Overrides the default settings for this call, e.g, timeout, # retries, etc. diff --git a/google-cloud-logging/lib/google/logging/v2/logging_config_pb.rb b/google-cloud-logging/lib/google/logging/v2/logging_config_pb.rb index 275ef9d9986a..186214e04325 100644 --- a/google-cloud-logging/lib/google/logging/v2/logging_config_pb.rb +++ b/google-cloud-logging/lib/google/logging/v2/logging_config_pb.rb @@ -13,6 +13,8 @@ optional :filter, :string, 5 optional :output_version_format, :enum, 6, "google.logging.v2.LogSink.VersionFormat" optional :writer_identity, :string, 8 + optional :start_time, :message, 10, "google.protobuf.Timestamp" + optional :end_time, :message, 11, "google.protobuf.Timestamp" end add_enum "google.logging.v2.LogSink.VersionFormat" do value :VERSION_FORMAT_UNSPECIFIED, 0 @@ -34,10 +36,12 @@ add_message "google.logging.v2.CreateSinkRequest" do optional :parent, :string, 1 optional :sink, :message, 2, "google.logging.v2.LogSink" + optional :unique_writer_identity, :bool, 3 end add_message "google.logging.v2.UpdateSinkRequest" do optional :sink_name, :string, 1 optional :sink, :message, 2, "google.logging.v2.LogSink" + optional :unique_writer_identity, :bool, 3 end add_message "google.logging.v2.DeleteSinkRequest" do optional :sink_name, :string, 1 diff --git a/google-cloud-logging/lib/google/logging/v2/logging_config_services_pb.rb b/google-cloud-logging/lib/google/logging/v2/logging_config_services_pb.rb index a16ea1325e6e..039c3819aae7 100644 --- a/google-cloud-logging/lib/google/logging/v2/logging_config_services_pb.rb +++ b/google-cloud-logging/lib/google/logging/v2/logging_config_services_pb.rb @@ -23,8 +23,8 @@ module Google module Logging module V2 module ConfigServiceV2 - # Service for configuring sinks used to export log entries outside Stackdriver - # Logging. + # Service for configuring sinks used to export log entries outside of + # Stackdriver Logging. class Service include GRPC::GenericService diff --git a/google-cloud-logging/lib/google/logging/v2/logging_services_pb.rb b/google-cloud-logging/lib/google/logging/v2/logging_services_pb.rb index 6bac4de5afc1..f7579b1d7f2c 100644 --- a/google-cloud-logging/lib/google/logging/v2/logging_services_pb.rb +++ b/google-cloud-logging/lib/google/logging/v2/logging_services_pb.rb @@ -32,8 +32,8 @@ class Service self.unmarshal_class_method = :decode self.service_name = 'google.logging.v2.LoggingServiceV2' - # Deletes a log and all its log entries. - # The log will reappear if it receives new entries. + # Deletes all the log entries in a log. + # The log reappears if it receives new entries. rpc :DeleteLog, DeleteLogRequest, Google::Protobuf::Empty # Writes log entries to Stackdriver Logging. All log entries are # written by this method. diff --git a/google-cloud-logging/test/google/cloud/logging/project/list_entries_test.rb b/google-cloud-logging/test/google/cloud/logging/project/list_entries_test.rb index 4ec2ec2fd779..7c0c19576828 100644 --- a/google-cloud-logging/test/google/cloud/logging/project/list_entries_test.rb +++ b/google-cloud-logging/test/google/cloud/logging/project/list_entries_test.rb @@ -21,7 +21,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(num_entries)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock entries = logging.entries @@ -38,7 +38,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(num_entries)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock entries = logging.find_entries @@ -54,8 +54,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(2)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock first_entries = logging.entries @@ -78,8 +78,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(2)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [["project1", "project2", "project3"], resource_names: nil, filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [["project1", "project2", "project3"], resource_names: nil, filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [[], project_ids: ["project1", "project2", "project3"], filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [[], project_ids: ["project1", "project2", "project3"], filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock first_entries = logging.entries projects: ["project1", "project2", "project3"], @@ -107,8 +107,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(2)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock first_entries = logging.entries @@ -130,8 +130,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(2)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [["project1", "project2", "project3"], resource_names: nil, filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [["project1", "project2", "project3"], resource_names: nil, filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [[], project_ids: ["project1", "project2", "project3"], filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [[], project_ids: ["project1", "project2", "project3"], filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock first_entries = logging.entries projects: ["project1", "project2", "project3"], @@ -155,8 +155,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(2)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock all_entries = logging.entries.all.to_a @@ -172,8 +172,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(2)))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [["project1", "project2", "project3"], resource_names: nil, filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [["project1", "project2", "project3"], resource_names: nil, filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [[], project_ids: ["project1", "project2", "project3"], filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [[], project_ids: ["project1", "project2", "project3"], filter: 'resource.type:"gce_"', order_by: "timestamp", page_size: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock all_entries = logging.entries(projects: ["project1", "project2", "project3"], @@ -191,8 +191,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "second_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock all_entries = logging.entries.all.take(5) @@ -208,8 +208,8 @@ second_list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "second_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, first_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] - mock.expect :list_log_entries, second_list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: token_options("next_page_token")] + mock.expect :list_log_entries, first_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] + mock.expect :list_log_entries, second_list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: token_options("next_page_token")] logging.service.mocked_logging = mock all_entries = logging.entries.all(request_limit: 1).to_a @@ -224,7 +224,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [["project1"], resource_names: nil, filter: nil, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [[], project_ids: ["project1"], filter: nil, order_by: nil, page_size: nil, options: default_options] logging.service.mocked_logging = mock entries = logging.entries projects: "project1" @@ -241,7 +241,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [["project1", "project2", "project3"], resource_names: nil, filter: nil, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [[], project_ids: ["project1", "project2", "project3"], filter: nil, order_by: nil, page_size: nil, options: default_options] logging.service.mocked_logging = mock entries = logging.entries projects: ["project1", "project2", "project3"] @@ -258,7 +258,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/project1", "projects/project2", "projects/project3"], filter: nil, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/project1", "projects/project2", "projects/project3"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock entries = logging.entries resources: ["projects/project1", "projects/project2", "projects/project3"] @@ -277,7 +277,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: adv_logs_filter, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: adv_logs_filter, order_by: nil, page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock @@ -295,7 +295,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: "timestamp", page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: nil, order_by: "timestamp", page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock @@ -313,7 +313,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: "timestamp desc", page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: nil, order_by: "timestamp desc", page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock @@ -331,7 +331,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: 3, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: 3, project_ids: nil, options: default_options] logging.service.mocked_logging = mock @@ -349,7 +349,7 @@ list_res = OpenStruct.new(page: OpenStruct.new(response: Google::Logging::V2::ListLogEntriesResponse.decode_json(list_entries_json(3, "next_page_token")))) mock = Minitest::Mock.new - mock.expect :list_log_entries, list_res, [[], resource_names: ["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, options: default_options] + mock.expect :list_log_entries, list_res, [["projects/#{project}"], filter: nil, order_by: nil, page_size: nil, project_ids: nil, options: default_options] logging.service.mocked_logging = mock diff --git a/google-cloud-logging/test/google/cloud/logging/project/sinks_test.rb b/google-cloud-logging/test/google/cloud/logging/project/sinks_test.rb index db3bb2e866fb..7fad3b81b4e8 100644 --- a/google-cloud-logging/test/google/cloud/logging/project/sinks_test.rb +++ b/google-cloud-logging/test/google/cloud/logging/project/sinks_test.rb @@ -227,10 +227,11 @@ new_sink = Google::Logging::V2::LogSink.new name: new_sink_name, destination: new_sink_destination create_res = Google::Logging::V2::LogSink.decode_json(empty_sink_hash.merge("name" => new_sink_name, - "destination" => new_sink_destination).to_json) + "destination" => new_sink_destination, + "writer_identity" => "roles/owner").to_json) mock = Minitest::Mock.new - mock.expect :create_sink, create_res, ["projects/test", new_sink, options: default_options] + mock.expect :create_sink, create_res, ["projects/test", new_sink, unique_writer_identity: nil, options: default_options] logging.service.mocked_sinks = mock sink = logging.create_sink new_sink_name, new_sink_destination @@ -242,32 +243,48 @@ sink.destination.must_equal new_sink_destination sink.filter.must_be :empty? sink.must_be :unspecified? + sink.start_at.must_be :nil? + sink.start_time.must_be :nil? + sink.end_at.must_be :nil? + sink.end_time.must_be :nil? + sink.writer_identity.must_equal "roles/owner" end it "creates a sink with additional attributes" do new_sink_name = "new-sink-#{Time.now.to_i}" new_sink_destination = "storage.googleapis.com/new-sinks" new_sink_filter = "logName:syslog AND severity>=WARN" + start_timestamp = Time.now + end_timestamp = Time.now + (3600*24) + start_timestamp_grpc = Google::Protobuf::Timestamp.new seconds: start_timestamp.to_i, nanos: start_timestamp.nsec + end_timestamp_grpc = Google::Protobuf::Timestamp.new seconds: end_timestamp.to_i, nanos: end_timestamp.nsec new_sink = Google::Logging::V2::LogSink.new( name: new_sink_name, destination: new_sink_destination, filter: new_sink_filter, - output_version_format: :V2 + output_version_format: :V2, + start_time: start_timestamp_grpc, + end_time: end_timestamp_grpc ) create_res = Google::Logging::V2::LogSink.decode_json(empty_sink_hash.merge( "name" => new_sink_name, "destination" => new_sink_destination, "filter" => new_sink_filter, - "output_version_format" => "V2").to_json) + "output_version_format" => "V2", + "start_time" => start_timestamp_grpc, + "end_time" => end_timestamp_grpc, + "writer_identity" => "roles/owner").to_json) mock = Minitest::Mock.new - mock.expect :create_sink, create_res, ["projects/test", new_sink, options: default_options] + mock.expect :create_sink, create_res, ["projects/test", new_sink, unique_writer_identity: nil, options: default_options] logging.service.mocked_sinks = mock sink = logging.create_sink new_sink_name, new_sink_destination, filter: new_sink_filter, - version: :v2 + version: :v2, + start_at: start_timestamp, + end_at: end_timestamp mock.verify @@ -276,6 +293,40 @@ sink.destination.must_equal new_sink_destination sink.filter.must_equal new_sink_filter sink.must_be :v2? + sink.start_at.must_equal start_timestamp + sink.start_time.must_equal start_timestamp + sink.end_at.must_equal end_timestamp + sink.end_time.must_equal end_timestamp + sink.writer_identity.must_equal "roles/owner" + end + + it "creates a sink with unique_writer_identity" do + new_sink_name = "new-sink-#{Time.now.to_i}" + new_sink_destination = "storage.googleapis.com/new-sinks" + new_sink = Google::Logging::V2::LogSink.new name: new_sink_name, destination: new_sink_destination + + create_res = Google::Logging::V2::LogSink.decode_json(empty_sink_hash.merge("name" => new_sink_name, + "destination" => new_sink_destination, + "writer_identity" => "serviceAccount:cloud-logs@system.gserviceaccount.com").to_json) + + mock = Minitest::Mock.new + mock.expect :create_sink, create_res, ["projects/test", new_sink, unique_writer_identity: true, options: default_options] + logging.service.mocked_sinks = mock + + sink = logging.create_sink new_sink_name, new_sink_destination, unique_writer_identity: true + + mock.verify + + sink.must_be_kind_of Google::Cloud::Logging::Sink + sink.name.must_equal new_sink_name + sink.destination.must_equal new_sink_destination + sink.filter.must_be :empty? + sink.must_be :unspecified? + sink.start_at.must_be :nil? + sink.start_time.must_be :nil? + sink.end_at.must_be :nil? + sink.end_time.must_be :nil? + sink.writer_identity.must_equal "serviceAccount:cloud-logs@system.gserviceaccount.com" end it "gets a sink" do @@ -292,6 +343,11 @@ sink.must_be_kind_of Google::Cloud::Logging::Sink sink.name.must_equal sink_name + sink.start_at.wont_be :nil? + sink.start_time.wont_be :nil? + sink.end_at.must_be :nil? + sink.end_time.must_be :nil? + sink.writer_identity.must_equal "roles/owner" end def list_sinks_json count = 2, token = nil diff --git a/google-cloud-logging/test/google/cloud/logging/sink_test.rb b/google-cloud-logging/test/google/cloud/logging/sink_test.rb index 891a82be97e9..411fba937827 100644 --- a/google-cloud-logging/test/google/cloud/logging/sink_test.rb +++ b/google-cloud-logging/test/google/cloud/logging/sink_test.rb @@ -25,6 +25,11 @@ sink.destination.must_equal sink_hash["destination"] sink.filter.must_equal sink_hash["filter"] sink.version.must_equal :VERSION_FORMAT_UNSPECIFIED + sink.writer_identity.must_equal "roles/owner" + sink.start_at.must_be_close_to Time.at(sink_hash["start_time"]["seconds"], sink_hash["start_time"]["nanos"]/1000.0) + sink.start_time.must_be_close_to Time.at(sink_hash["start_time"]["seconds"], sink_hash["start_time"]["nanos"]/1000.0) + sink.end_at.must_equal nil + sink.end_time.must_equal nil end it "can set different sink format versions" do @@ -42,22 +47,63 @@ sink.must_be :v1? end + it "can set different start and end times" do + time = Time.at(sink_hash["start_time"]["seconds"], sink_hash["start_time"]["nanos"]/1000.0) + + sink.start_at.must_be_close_to time + sink.start_time.must_be_close_to time + sink.end_at.must_equal nil + sink.end_time.must_equal nil + + sink.start_time = nil + sink.end_time = time + + sink.start_at.must_equal nil + sink.start_time.must_equal nil + sink.end_at.must_be_close_to time + sink.end_time.must_be_close_to time + + sink.start_at = time + sink.end_at = nil + + sink.start_at.must_be_close_to time + sink.start_time.must_be_close_to time + sink.end_at.must_equal nil + sink.end_time.must_equal nil + + sink.start_at = nil + sink.end_at = time + + sink.start_at.must_equal nil + sink.start_time.must_equal nil + sink.end_at.must_be_close_to time + sink.end_time.must_be_close_to time + end + it "can save itself" do + now = Time.now + now_grpc = Google::Protobuf::Timestamp.new(seconds: now.to_i, nanos: now.nsec) + sink_grpc.start_time = nil + sink_grpc.end_time = now_grpc + new_sink_destination = "storage.googleapis.com/new-sink-bucket" new_sink_filter = "logName:syslog AND severity>=WARN" new_sink = Google::Logging::V2::LogSink.new( name: sink.name, destination: new_sink_destination, filter: new_sink_filter, - output_version_format: :V1 + output_version_format: :V1, + end_time: now_grpc ) mock = Minitest::Mock.new - mock.expect :update_sink, sink_grpc, ["projects/test/sinks/#{sink.name}", new_sink, options: default_options] + mock.expect :update_sink, sink_grpc, ["projects/test/sinks/#{sink.name}", new_sink, unique_writer_identity: nil, options: default_options] sink.service.mocked_sinks = mock sink.destination = new_sink_destination sink.filter = new_sink_filter sink.version = :v1 + sink.start_at = nil + sink.end_at = now sink.save mock.verify @@ -66,6 +112,47 @@ sink.destination.must_equal new_sink_destination sink.filter.must_equal new_sink_filter sink.must_be :v1? + sink.writer_identity.must_equal "roles/owner" + end + + it "can save itself with unique_writer_identity" do + now = Time.now + now_grpc = Google::Protobuf::Timestamp.new(seconds: now.to_i, nanos: now.nsec) + + sink_grpc.writer_identity = "serviceAccount:cloud-logs@system.gserviceaccount.com" + + new_sink_destination = "storage.googleapis.com/new-sink-bucket" + new_sink_filter = "logName:syslog AND severity>=WARN" + new_sink = Google::Logging::V2::LogSink.new( + name: sink.name, + destination: new_sink_destination, + filter: new_sink_filter, + output_version_format: :V1, + end_time: now_grpc + ) + mock = Minitest::Mock.new + mock.expect :update_sink, sink_grpc, ["projects/test/sinks/#{sink.name}", new_sink, unique_writer_identity: true, options: default_options] + sink.service.mocked_sinks = mock + + sink.destination = new_sink_destination + sink.filter = new_sink_filter + sink.version = :v1 + sink.start_at = nil + sink.end_at = now + + sink.save unique_writer_identity: true + + mock.verify + + sink.must_be_kind_of Google::Cloud::Logging::Sink + sink.destination.must_equal new_sink_destination + sink.filter.must_equal new_sink_filter + sink.must_be :v1? + sink.start_at.must_be :nil? + sink.start_time.must_be :nil? + sink.end_at.wont_be :nil? + sink.end_time.wont_be :nil? + sink.writer_identity.must_equal "serviceAccount:cloud-logs@system.gserviceaccount.com" end it "can refresh itself" do diff --git a/google-cloud-logging/test/helper.rb b/google-cloud-logging/test/helper.rb index 5056a4b74a7a..4ee562704264 100644 --- a/google-cloud-logging/test/helper.rb +++ b/google-cloud-logging/test/helper.rb @@ -150,7 +150,9 @@ def random_sink_hash "name" => "my-severe-errors-to-pubsub", "destination" => "storage.googleapis.com/a-bucket", "filter" => "logName:syslog AND severity>=ERROR", - "output_version_format" => :VERSION_FORMAT_UNSPECIFIED + "output_version_format" => :VERSION_FORMAT_UNSPECIFIED, + "writer_identity" => "roles/owner", + "start_time" => { "seconds" => 1479920135, "nanos" => 711253000 } } end