google-cloud-logging-2.7.0/0000755000004100000410000000000015170601174015556 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/OVERVIEW.md0000644000004100000410000002433415170601174017354 0ustar www-datawww-data# Stackdriver Logging The Stackdriver Logging service collects and stores logs from applications and services on the Google Cloud Platform, giving you fine-grained, programmatic control over your projects' logs. You can use the Stackdriver Logging API to: * [Read and filter log entries](#listing-log-entries) * [Export your log entries](#exporting-log-entries) to Cloud Storage, BigQuery, or Cloud Pub/Sub * [Create logs-based metrics](#creating-logs-based-metrics) for use in Cloud Monitoring * [Write log entries](#writing-log-entries) For general information about Stackdriver Logging, read [Stackdriver Logging Documentation](https://cloud.google.com/logging/docs/). The goal of google-cloud is to provide an API that is comfortable to Rubyists. Your authentication credentials are detected automatically in Google Cloud Platform (GCP), including Google Compute Engine (GCE), Google Kubernetes Engine (GKE), Google App Engine (GAE), Google Cloud Functions (GCF) and Cloud Run. In other environments you can configure authentication easily, either directly in your code or via environment variables. Read more about the options for connecting in the {file:AUTHENTICATION.md Authentication Guide}. ## Listing log entries Stackdriver Logging gathers log entries from many services, including Google App Engine and Google Compute Engine. (See the [List of Log Types](https://cloud.google.com/logging/docs/view/logs_index).) In addition, you can write your own log entries to the service. {Google::Cloud::Logging::Project#entries Project#entries} returns the {Google::Cloud::Logging::Entry Entry} records belonging to your project: ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new entries = logging.entries entries.each do |e| puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" end ``` You can narrow the results to a single log using an [advanced logs filter](https://cloud.google.com/logging/docs/view/advanced_filters). A log is a named collection of entries. Logs can be produced by Google Cloud Platform services, by third-party services, or by your applications. For example, the log `compute.googleapis.com/activity_log` is produced by Google Compute Engine. Logs are simply referenced by name in google-cloud. There is no `Log` type in google-cloud or `Log` resource in the Stackdriver Logging API. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new entries = logging.entries filter: "logName:syslog" entries.each do |e| puts "[#{e.timestamp}] #{e.payload.inspect}" end ``` You can also order the log entries by `timestamp`. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new entries = logging.entries order: "timestamp desc" entries.each do |e| puts "[#{e.timestamp}] #{e.log_name}" end ``` ## Exporting log entries Stackdriver Logging lets you export log entries to destinations including Google Cloud Storage buckets (for long term log storage), Google BigQuery datasets (for log analysis), and Google Pub/Sub (for streaming to other applications). ### Creating sinks A {Google::Cloud::Logging::Sink Sink} is an object that lets you to specify a set of log entries to export. In addition to the name of the sink and the export destination, {Google::Cloud::Logging::Project#create_sink Project#create_sink} accepts an [advanced logs filter](https://cloud.google.com/logging/docs/view/advanced_filters) to narrow the collection. Before creating the sink, ensure that you have granted `cloud-logs@google.com` permission to write logs to the destination. See [Exporting Logs (V2)](https://cloud.google.com/logging/docs/export/configure_export_v2). ```ruby require "google/cloud/storage" require "google/cloud/logging" storage = Google::Cloud::Storage.new bucket = storage.create_bucket "my-logs-bucket" # Grant owner permission to Stackdriver Logging service email = "cloud-logs@google.com" bucket.acl.add_owner "group-#{email}" logging = Google::Cloud::Logging.new sink = logging.create_sink "my-sink", "storage.googleapis.com/#{bucket.id}" ``` When you create a sink, only new log entries are exported. Stackdriver Logging does not send previously-ingested log entries to the sink's destination. ### Listing sinks You can also list the sinks belonging to your project with {Google::Cloud::Logging::Project#sinks Project#sinks}. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new sinks = logging.sinks sinks.each do |s| puts "#{s.name}: #{s.filter} -> #{s.destination}" end ``` ## Creating logs-based metrics You can use log entries in your project as the basis for [Google Cloud Monitoring](https://cloud.google.com/monitoring/docs) metrics. These metrics can then be used to produce Cloud Monitoring reports and alerts. ### Creating metrics A metric is a measured value that can be used to assess a system. Use {Google::Cloud::Logging::Project#create_metric Project#create_metric} to configure a {Google::Cloud::Logging::Metric Metric} based on a collection of log entries matching an [advanced logs filter](https://cloud.google.com/logging/docs/view/advanced_filters). ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new metric = logging.create_metric "errors", "severity>=ERROR" ``` ### Listing metrics You can also list the metrics belonging to your project with {Google::Cloud::Logging::Project#metrics Project#metrics}. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new metrics = logging.metrics metrics.each do |m| puts "#{m.name}: #{m.filter}" end ``` ## Writing log entries An {Google::Cloud::Logging::Entry} is composed of metadata and a payload. The payload is traditionally a message string, but in Stackdriver Logging it can also be a JSON or protocol buffer object. A single log can have entries with different payload types. In addition to the payload, your argument(s) to {Google::Cloud::Logging::Project#write_entries Project#write_entries} must also contain a log name and a resource. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new entry = logging.entry entry.payload = "Job started." entry.log_name = "my_app_log" entry.resource.type = "gae_app" entry.resource.labels[:module_id] = "1" entry.resource.labels[:version_id] = "20150925t173233" logging.write_entries entry ``` To write a JSON payload to the log, simply pass a hash argument: ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new entry = logging.entry entry.payload = { "stats" => { "a" => 8, "b" => 12.5} } entry.log_name = "my_app_log" entry.resource.type = "gae_app" entry.resource.labels[:module_id] = "1" entry.resource.labels[:version_id] = "20150925t173233" logging.write_entries entry ``` If you write a collection of log entries, you can provide the log name, resource, and/or labels hash to be used for all of the entries, and omit these values from the individual entries. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new entry1 = logging.entry entry1.payload = "Job started." entry2 = logging.entry entry2.payload = "Job completed." labels = { job_size: "large", job_code: "red" } resource = logging.resource "gae_app", "module_id" => "1", "version_id" => "20150925t173233" logging.write_entries [entry1, entry2], log_name: "my_app_log", resource: resource, labels: labels ``` Normally, writing log entries is done synchronously; the call to {Google::Cloud::Logging::Project#write_entries Project#write_entries} will block until it has either completed transmitting the data or encountered an error. To "fire and forget" without blocking, use {Google::Cloud::Logging::AsyncWriter AsyncWriter}; it spins up a background thread that writes log entries in batches. Calls to {Google::Cloud::Logging::AsyncWriter#write_entries AsyncWriter#write_entries} simply add entries to its work queue and return immediately. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new async = logging.async_writer entry1 = logging.entry entry1.payload = "Job started." entry2 = logging.entry entry2.payload = "Job completed." labels = { job_size: "large", job_code: "red" } resource = logging.resource "gae_app", "module_id" => "1", "version_id" => "20150925t173233" async.write_entries [entry1, entry2], log_name: "my_app_log", resource: resource, labels: labels, partial_success: true ``` ### Creating a Ruby Logger implementation If your environment requires a logger instance that is API-compatible with Ruby's standard library [Logger](https://ruby-doc.org/current/stdlibs/logger/), you can use {Google::Cloud::Logging::Project#logger Project#logger} to create one. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new resource = logging.resource "gae_app", module_id: "1", version_id: "20150925t173233" logger = logging.logger "my_app_log", resource, env: :production logger.info "Job started." ``` By default, the logger instance writes log entries asynchronously in a background thread using an {Google::Cloud::Logging::AsyncWriter AsyncWriter}. If you want to customize or disable asynchronous writing, you may call the Logger constructor directly. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new resource = logging.resource "gae_app", module_id: "1", version_id: "20150925t173233" logger = Google::Cloud::Logging::Logger.new logging, "my_app_log", resource, {env: :production} logger.info "Log entry written synchronously." ``` ## Configuring timeout You can configure the request `timeout` value in seconds. ```ruby require "google/cloud/logging" logging = Google::Cloud::Logging.new timeout: 120 ``` ## Additional information Stackdriver Logging can be configured to be used in Rack applications or to use gRPC's logging. To learn more, see the {file:INSTRUMENTATION.md Instrumentation Guide} and {file:LOGGING.md Logging guide}. google-cloud-logging-2.7.0/google-cloud-logging.gemspec0000644000004100000410000000550115170601174023130 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: google-cloud-logging 2.7.0 ruby lib Gem::Specification.new do |s| s.name = "google-cloud-logging".freeze s.version = "2.7.0".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Mike Moore".freeze, "Chris Smith".freeze] s.date = "1980-01-02" s.description = "google-cloud-logging is the official library for Stackdriver Logging.".freeze s.email = ["mike@blowmage.com".freeze, "quartzmo@gmail.com".freeze] s.files = [".yardopts".freeze, "AUTHENTICATION.md".freeze, "CHANGELOG.md".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "INSTRUMENTATION.md".freeze, "LICENSE".freeze, "LOGGING.md".freeze, "OVERVIEW.md".freeze, "TROUBLESHOOTING.md".freeze, "lib/google-cloud-logging.rb".freeze, "lib/google/cloud/logging.rb".freeze, "lib/google/cloud/logging/async_writer.rb".freeze, "lib/google/cloud/logging/convert.rb".freeze, "lib/google/cloud/logging/credentials.rb".freeze, "lib/google/cloud/logging/entry.rb".freeze, "lib/google/cloud/logging/entry/http_request.rb".freeze, "lib/google/cloud/logging/entry/list.rb".freeze, "lib/google/cloud/logging/entry/operation.rb".freeze, "lib/google/cloud/logging/entry/source_location.rb".freeze, "lib/google/cloud/logging/errors.rb".freeze, "lib/google/cloud/logging/log/list.rb".freeze, "lib/google/cloud/logging/logger.rb".freeze, "lib/google/cloud/logging/metric.rb".freeze, "lib/google/cloud/logging/metric/list.rb".freeze, "lib/google/cloud/logging/middleware.rb".freeze, "lib/google/cloud/logging/project.rb".freeze, "lib/google/cloud/logging/rails.rb".freeze, "lib/google/cloud/logging/resource.rb".freeze, "lib/google/cloud/logging/resource_descriptor.rb".freeze, "lib/google/cloud/logging/resource_descriptor/list.rb".freeze, "lib/google/cloud/logging/service.rb".freeze, "lib/google/cloud/logging/sink.rb".freeze, "lib/google/cloud/logging/sink/list.rb".freeze, "lib/google/cloud/logging/version.rb".freeze] s.homepage = "https://github.com/googleapis/google-cloud-ruby/tree/master/google-cloud-logging".freeze s.licenses = ["Apache-2.0".freeze] s.required_ruby_version = Gem::Requirement.new(">= 3.2".freeze) s.rubygems_version = "3.6.9".freeze s.summary = "API Client library for Stackdriver Logging".freeze s.specification_version = 4 s.add_runtime_dependency(%q.freeze, ["~> 1.1".freeze]) s.add_runtime_dependency(%q.freeze, ["~> 1.5".freeze]) s.add_runtime_dependency(%q.freeze, [">= 0.0".freeze, "< 2.a".freeze]) s.add_runtime_dependency(%q.freeze, ["~> 1.3".freeze]) end google-cloud-logging-2.7.0/AUTHENTICATION.md0000644000004100000410000001457315170601174020231 0ustar www-datawww-data# Authentication In general, the google-cloud-logging library uses [Service Account](https://cloud.google.com/iam/docs/creating-managing-service-accounts) credentials to connect to Google Cloud services. When running within [Google Cloud Platform environments](#google-cloud-platform-environments) the credentials will be discovered automatically. When running on other environments, the Service Account credentials can be specified by providing the path to the [JSON keyfile](https://cloud.google.com/iam/docs/managing-service-account-keys) for the account (or the JSON itself) in [environment variables](#environment-variables). Additionally, Cloud SDK credentials can also be discovered automatically, but this is only recommended during development. ## Quickstart 1. [Create a service account and credentials](#creating-a-service-account). 2. Set the [environment variable](#environment-variables). ```sh export LOGGING_CREDENTIALS=/path/to/json` ``` 3. Initialize the client. ```ruby require "google/cloud/logging" client = Google::Cloud::Logging.new ``` ## Project and Credential Lookup The google-cloud-logging library aims to make authentication as simple as possible, and provides several mechanisms to configure your system without providing **Project ID** and **Service Account Credentials** directly in code. **Project ID** is discovered in the following order: 1. Specify project ID in method arguments 2. Specify project ID in configuration 3. Discover project ID in environment variables 4. Discover GCE project ID 5. Discover project ID in credentials JSON **Credentials** are discovered in the following order: > [!WARNING] > If you accept a credential configuration (JSON file or Hash) from an > external source for authentication to Google Cloud, you must validate it before > providing it to a Google API client library. Providing an unvalidated credential > configuration to Google APIs can compromise the security of your systems and data. 1. Specify credentials in method arguments 2. Specify credentials in configuration 3. Discover credentials path in environment variables 4. Discover credentials JSON in environment variables 5. Discover credentials file in the Cloud SDK's path 6. Discover GCE credentials ### Google Cloud Platform environments When running on Google Cloud Platform (GCP), including Google Compute Engine (GCE), Google Kubernetes Engine (GKE), Google App Engine (GAE), Google Cloud Functions (GCF) and Cloud Run, the **Project ID** and **Credentials** and are discovered automatically. Code should be written as if already authenticated. ### Environment Variables The **Project ID** and **Credentials JSON** can be placed in environment variables instead of declaring them directly in code. Each service has its own environment variable, allowing for different service accounts to be used for different services. (See the READMEs for the individual service gems for details.) The path to the **Credentials JSON** file can be stored in the environment variable, or the **Credentials JSON** itself can be stored for environments such as Docker containers where writing files is difficult or not encouraged. The environment variables that google-cloud-logging checks for project ID are: 1. `LOGGING_PROJECT` 2. `GOOGLE_CLOUD_PROJECT` The environment variables that google-cloud-logging checks for credentials are configured on `Google::Cloud::Logging::V2::LoggingService::Credentials`: 1. `LOGGING_CREDENTIALS` - Path to JSON file, or JSON contents 2. `LOGGING_KEYFILE` - Path to JSON file, or JSON contents 3. `GOOGLE_CLOUD_CREDENTIALS` - Path to JSON file, or JSON contents 4. `GOOGLE_CLOUD_KEYFILE` - Path to JSON file, or JSON contents 5. `GOOGLE_APPLICATION_CREDENTIALS` - Path to JSON file ```ruby require "google/cloud/logging" ENV["LOGGING_PROJECT"] = "my-project-id" ENV["LOGGING_CREDENTIALS"] = "path/to/keyfile.json" client = Google::Cloud::Logging.new ``` ### Configuration The **Project ID** and the path to the **Credentials JSON** file can be configured instead of placing them in environment variables or providing them as arguments. ```ruby require "googleauth" require "google/cloud/logging" credentials = ::Google::Auth::ServiceAccountCredentials.make_creds( json_key_io: ::File.open("/path/to/keyfile.json") ) Google::Cloud::Logging.configure do |config| config.project_id = "my-project-id" config.credentials = credentials end client = Google::Cloud::Logging.new ``` ### Cloud SDK This option allows for an easy way to authenticate during development. If credentials are not provided in code or in environment variables, then Cloud SDK credentials are discovered. To configure your system for this, simply: 1. [Download and install the Cloud SDK](https://cloud.google.com/sdk) 2. Authenticate using OAuth 2.0 `$ gcloud auth login` 3. Write code as if already authenticated. **NOTE:** This is _not_ recommended for running in production. The Cloud SDK *should* only be used during development. ## Creating a Service Account Google Cloud requires a **Project ID** and **Service Account Credentials** to connect to the APIs. You will use the **Project ID** and **JSON key file** to connect to most services with google-cloud-logging. If you are not running this client within [Google Cloud Platform environments](#google-cloud-platform-environments), you need a Google Developers service account. 1. Visit the [Google Cloud Console](https://console.cloud.google.com/project). 1. Create a new project or click on an existing project. 1. Activate the menu in the upper left and select **APIs & Services**. From here, you will enable the APIs that your application requires. *Note: You may need to enable billing in order to use these services.* 1. Select **Credentials** from the side navigation. Find the "Create credentials" drop down near the top of the page, and select "Service account" to be guided through downloading a new JSON key file. If you want to re-use an existing service account, you can easily generate a new key file. Just select the account you wish to re-use click the pencil tool on the right side to edit the service account, select the **Keys** tab, and then select **Add Key**. The key file you download will be used by this library to authenticate API requests and should be stored in a secure location. ## Troubleshooting If you're having trouble authenticating you can ask for help by following the {file:TROUBLESHOOTING.md Troubleshooting Guide}. google-cloud-logging-2.7.0/CONTRIBUTING.md0000644000004100000410000001373615170601174020021 0ustar www-datawww-data# Contributing to Google Cloud Logging 1. **Sign one of the contributor license agreements below.** 2. Fork the repo, develop and test your code changes. 3. Send a pull request. ## Contributor License Agreements Before we can accept your pull requests you'll need to sign a Contributor License Agreement (CLA): - **If you are an individual writing original source code** and **you own the intellectual property**, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual). - **If you work for a company that wants to allow you to contribute your work**, then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). You can sign these electronically (just scroll to the bottom). After that, we'll be able to accept your pull requests. ## Setup In order to use the google-cloud-logging console and run the project's tests, there is a small amount of setup: 1. Install Ruby. google-cloud-logging requires Ruby 2.5+. You may choose to manage your Ruby and gem installations with [RVM](https://rvm.io/), [rbenv](https://github.com/rbenv/rbenv), or [chruby](https://github.com/postmodern/chruby). 2. Install [Bundler](http://bundler.io/). ```sh $ gem install bundler ``` 3. Install the top-level project dependencies. ```sh $ bundle install ``` 4. Install the Logging dependencies. ```sh $ cd google-cloud-logging/ $ bundle install ``` ## Console In order to run code interactively, you can automatically load google-cloud-logging and its dependencies in IRB. This requires that your developer environment has already been configured by following the steps described in the {file:AUTHENTICATION.md Authentication Guide}. An IRB console can be created with: ```sh $ cd google-cloud-logging/ $ bundle exec rake console ``` ## Logging Tests Tests are very important part of google-cloud-logging. All contributions should include tests that ensure the contributed code behaves as expected. To run the unit tests, documentation tests, and code style checks together for a package: ``` sh $ cd google-cloud-logging/ $ bundle exec rake ci ``` To run the command above, plus all acceptance tests, use `rake ci:acceptance` or its handy alias, `rake ci:a`. ### Logging Unit Tests The project uses the [minitest](https://github.com/seattlerb/minitest) library, including [specs](https://github.com/seattlerb/minitest#specs), [mocks](https://github.com/seattlerb/minitest#mocks) and [minitest-autotest](https://github.com/seattlerb/minitest-autotest). To run the Logging unit tests: ``` sh $ cd google-cloud-logging/ $ bundle exec rake test ``` ### Logging Documentation Tests The project tests the code examples in the gem's [YARD](https://github.com/lsegal/yard)-based documentation. The example testing functions in a way that is very similar to unit testing, and in fact the library providing it, [yard-doctest](https://github.com/p0deje/yard-doctest), is based on the project's unit test library, [minitest](https://github.com/seattlerb/minitest). To run the Logging documentation tests: ``` sh $ cd google-cloud-logging/ $ bundle exec rake doctest ``` If you add, remove or modify documentation examples when working on a pull request, you may need to update the setup for the tests. The stubs and mocks required to run the tests are located in `support/doctest_helper.rb`. Please note that much of the setup is matched by the title of the [`@example`](http://www.rubydoc.info/gems/yard/file/docs/Tags.md#example) tag. If you alter an example's title, you may encounter breaking tests. ### Logging Acceptance Tests The Logging acceptance tests interact with the live service API. Follow the instructions in the {file:AUTHENTICATION.md Authentication Guide} for enabling the Logging API. Occasionally, some API features may not yet be generally available, making it difficult for some contributors to successfully run the entire acceptance test suite. However, please ensure that you do successfully run acceptance tests for any code areas covered by your pull request. To run the acceptance tests, first create and configure a project in the Google Developers Console, as described in the {file:AUTHENTICATION.md Authentication Guide}. Be sure to download the JSON KEY file. Make note of the PROJECT_ID and the KEYFILE location on your system. Before you can run the Logging acceptance tests, you must first create indexes used in the tests. #### Running the Logging acceptance tests To run the Logging acceptance tests: ``` sh $ cd google-cloud-logging/ $ bundle exec rake acceptance[\\{my-project-id},\\{/path/to/keyfile.json}] ``` Or, if you prefer you can store the values in the `GCLOUD_TEST_PROJECT` and `GCLOUD_TEST_KEYFILE` environment variables: ``` sh $ cd google-cloud-logging/ $ export GCLOUD_TEST_PROJECT=\\{my-project-id} $ export GCLOUD_TEST_KEYFILE=\\{/path/to/keyfile.json} $ bundle exec rake acceptance ``` If you want to use a different project and credentials for acceptance tests, you can use the more specific `LOGGING_TEST_PROJECT` and `LOGGING_TEST_KEYFILE` environment variables: ``` sh $ cd google-cloud-logging/ $ export LOGGING_TEST_PROJECT=\\{my-project-id} $ export LOGGING_TEST_KEYFILE=\\{/path/to/keyfile.json} $ bundle exec rake acceptance ``` ## Coding Style Please follow the established coding style in the library. The style is is largely based on [The Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) with a few exceptions based on seattle-style: * Avoid parenthesis when possible, including in method definitions. * Always use double quotes strings. ([Option B](https://github.com/bbatsov/ruby-style-guide#strings)) You can check your code against these rules by running Rubocop like so: ```sh $ cd google-cloud-logging/ $ bundle exec rake rubocop ``` ## Code of Conduct Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. See {file:CODE_OF_CONDUCT.md Code of Conduct} for more information. google-cloud-logging-2.7.0/lib/0000755000004100000410000000000015170601174016324 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google-cloud-logging.rb0000644000004100000410000001516715170601174022667 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## # This file is here to be autorequired by bundler, so that the # Google::Cloud.logging and Google::Cloud#logging methods can be available, but # the library and all dependencies won't be loaded until required and used. gem "google-cloud-core" require "google/cloud" unless defined? Google::Cloud.new require "google/cloud/config" require "googleauth" module Google module Cloud ## # Creates a new object for connecting to the Stackdriver Logging service. # Each call creates a new connection. # # For more information on connecting to Google Cloud see the # {file:AUTHENTICATION.md Authentication Guide}. # # @param [String, Array] scope The OAuth 2.0 scopes controlling the # set of resources and operations that the connection can access. See # [Using OAuth 2.0 to Access Google # APIs](https://developers.google.com/identity/protocols/OAuth2). # # The default scope is: # # * `https://www.googleapis.com/auth/logging.admin` # # @param [Integer] timeout Default timeout to use in requests. Optional. # # @return [Google::Cloud::Logging::Project] # # @example # require "google/cloud" # # gcloud = Google::Cloud.new # logging = gcloud.logging # # entries = logging.entries # entries.each do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # # @example The default scope can be overridden with the `scope` option: # require "google/cloud" # # gcloud = Google::Cloud.new # platform_scope = "https://www.googleapis.com/auth/cloud-platform" # logging = gcloud.logging scope: platform_scope # def logging scope: nil, timeout: nil timeout ||= @timeout Google::Cloud.logging @project, @keyfile, scope: scope, timeout: timeout end ## # Creates a new object for connecting to the Stackdriver Logging service. # Each call creates a new connection. # # For more information on connecting to Google Cloud see the # {file:AUTHENTICATION.md Authentication Guide}. # # @param [String] project_id Project identifier for the Stackdriver Logging # service you are connecting to. If not present, the default project for # the credentials is used. # @param [Google::Auth::Credentials] credentials A Google::Auth::Credentials # object. (See {Logging::Credentials}) # @note Warning: Passing a `String` to a keyfile path or a `Hash` of credentials # is deprecated. Providing an unvalidated credential configuration to # Google APIs can compromise the security of your systems and data. # # @example # # # The recommended way to provide credentials is to use the `make_creds` method # # on the appropriate credentials class for your environment. # # credentials = ::Google::Auth::ServiceAccountCredentials.make_creds( # json_key_io: ::File.open("/path/to/keyfile.json") # ) # # logging = Google::Cloud::Logging.new( # project_id: "my-project-id", # credentials: credentials # ) # @param [String, Array] scope The OAuth 2.0 scopes controlling the # set of resources and operations that the connection can access. See # [Using OAuth 2.0 to Access Google # APIs](https://developers.google.com/identity/protocols/OAuth2). # # The default scope is: # # * `https://www.googleapis.com/auth/logging.admin` # # @param [Integer] timeout Default timeout to use in requests. Optional. # # @return [Google::Cloud::Logging::Project] # # @example # require "google/cloud" # # logging = Google::Cloud.logging # # entries = logging.entries # entries.each do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # def self.logging project_id = nil, credentials = nil, scope: nil, timeout: nil require "google/cloud/logging" Google::Cloud::Logging.new project_id: project_id, credentials: credentials, scope: scope, timeout: timeout end end end # Add logging to top-level configuration Google::Cloud.configure do |config| unless config.field? :use_logging config.add_field! :use_logging, nil, enum: [true, false] end end # Set the default logging configuration Google::Cloud.configure.add_config! :logging do |config| default_project = Google::Cloud::Config.deferred do ENV["LOGGING_PROJECT"] end default_creds = Google::Cloud::Config.deferred do Google::Cloud::Config.credentials_from_env \ "LOGGING_CREDENTIALS", "LOGGING_CREDENTIALS_JSON", "LOGGING_KEYFILE", "LOGGING_KEYFILE_JSON" end default_scopes = [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/logging.admin", "https://www.googleapis.com/auth/logging.read", "https://www.googleapis.com/auth/logging.write" ] config.add_field! :project_id, default_project, match: String, allow_nil: true config.add_alias! :project, :project_id config.add_field! :credentials, default_creds, match: [String, Hash, Google::Auth::Credentials], allow_nil: true config.add_alias! :keyfile, :credentials config.add_field! :scope, default_scopes, match: [String, Array] config.add_field! :quota_project, nil, match: String config.add_field! :timeout, nil, match: Integer config.add_field! :endpoint, "logging.googleapis.com", match: String config.add_field! :log_name, nil, match: String config.add_field! :log_name_map, nil, match: Hash config.add_field! :labels, nil, match: Hash config.add_config! :monitored_resource do |mrconfig| mrconfig.add_field! :type, nil, match: String mrconfig.add_field! :labels, nil, match: Hash end config.add_field! :set_default_logger_on_rails_init, nil, enum: [true, false] config.add_field! :on_error, nil, match: Proc end google-cloud-logging-2.7.0/lib/google/0000755000004100000410000000000015170601174017600 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/0000755000004100000410000000000015170601174020706 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging.rb0000644000004100000410000002130715170601174022664 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google-cloud-logging" require "google/cloud/logging/project" require "google/cloud/config" require "google/cloud/env" require "stackdriver/core" module Google module Cloud ## # # Stackdriver Logging # # The Stackdriver Logging service collects and stores logs from applications # and services on the Google Cloud Platform, giving you fine-grained, # programmatic control over your projects' logs. You can use the Stackdriver # Logging API to: # # * Read and filter log entries # * Export your log entries to Cloud Storage, BigQuery, or Cloud Pub/Sub # * Create logs-based metrics for use in Cloud Monitoring # * Write log entries # # For general information about Stackdriver Logging, read [Stackdriver # Logging Documentation](https://cloud.google.com/logging/docs/). # # See {file:OVERVIEW.md Stackdriver Logging Overview}. # module Logging ## # Creates a new object for connecting to the Stackdriver Logging service. # Each call creates a new connection. # # For more information on connecting to Google Cloud see the # {file:AUTHENTICATION.md Authentication Guide}. # # @param [String] project_id Project identifier for the Stackdriver # Logging service you are connecting to. If not present, the default # project for the credentials is used. # @param [Google::Auth::Credentials] credentials A Google::Auth::Credentials # object. (See {Logging::Credentials}) # @note Warning: Passing a `String` to a keyfile path or a `Hash` of credentials # is deprecated. Providing an unvalidated credential configuration to # Google APIs can compromise the security of your systems and data. # # @example # # # The recommended way to provide credentials is to use the `make_creds` method # # on the appropriate credentials class for your environment. # # require "googleauth" # # credentials = ::Google::Auth::ServiceAccountCredentials.make_creds( # json_key_io: ::File.open("/path/to/keyfile.json") # ) # # logging = Google::Cloud::Logging.new( # project_id: "my-project-id", # credentials: credentials # ) # @param [String, Array] scope The OAuth 2.0 scopes controlling # the set of resources and operations that the connection can access. # See [Using OAuth 2.0 to Access Google # APIs](https://developers.google.com/identity/protocols/OAuth2). # # The default scope is: # # * `https://www.googleapis.com/auth/logging.admin` # # @param [Integer] timeout Default timeout to use in requests. Optional. # @param [String] endpoint Override of the endpoint host name. Optional. # If the param is nil, uses the default endpoint. # @param [String] project Alias for the `project_id` argument. Deprecated. # @param [String] keyfile Alias for the `credentials` argument. # Deprecated. # # @return [Google::Cloud::Logging::Project] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entries = logging.entries # entries.each do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # def self.new project_id: nil, credentials: nil, scope: nil, timeout: nil, endpoint: nil, project: nil, keyfile: nil project_id ||= project || default_project_id scope ||= configure.scope timeout ||= configure.timeout endpoint ||= configure.endpoint credentials ||= keyfile || default_credentials(scope: scope) unless credentials.is_a? Google::Auth::Credentials credentials = Logging::Credentials.new credentials, scope: scope end if credentials.respond_to? :project_id project_id ||= credentials.project_id end project_id = project_id.to_s # Always cast to a string raise ArgumentError, "project_id is missing" if project_id.empty? service = Logging::Service.new project_id, credentials, host: endpoint, timeout: timeout Logging::Project.new service end ## # Configure the Google::Cloud::Logging::Middleware when used in a # Rack-based application. # # The following Stackdriver Logging configuration parameters are # supported: # # * `project_id` - (String) Project identifier for the Stackdriver # Logging service you are connecting to. (The parameter `project` is # considered deprecated, but may also be used.) # * `credentials` - (String, Hash, Google::Auth::Credentials) The path to # the keyfile as a String, the contents of the keyfile as a Hash, or a # Google::Auth::Credentials object. (See {Logging::Credentials}) (The # parameter `keyfile` is considered deprecated, but may also be used.) # * `scope` - (String, Array) The OAuth 2.0 scopes controlling # the set of resources and operations that the connection can access. # * `quota_project` - (String) The project ID for a project that can be # used by client libraries for quota and billing purposes. # * `timeout` - (Integer) Default timeout to use in requests. # * `endpoint` - (String) Override of the endpoint host name, or `nil` # to use the default endpoint. # * `log_name` - (String) Name of the application log file. Default: # `"ruby_app_log"` # * `log_name_map` - (Hash) Map specific request routes to other log. # Default: `{ "/_ah/health" => "ruby_health_check_log" }` # * `monitored_resource.type` (String) Resource type name. See [full # list](https://cloud.google.com/logging/docs/api/v2/resource-list). # Self discovered on GCP. # * `monitored_resource.labels` -(Hash) Resource labels. See [full # list](https://cloud.google.com/logging/docs/api/v2/resource-list). # Self discovered on GCP. # * `labels` - (Hash) User defined labels. A `Hash` of label names to # string label values or callables/`Proc` which are functions of the # Rack environment. # * `set_default_logger_on_rails_init` - (Boolean) Whether Google Cloud # Logging Logger should be allowed to start background threads and open # gRPC connections during Rails initialization. This should only be used # with a non-forking web server. Web servers such as Puma and Unicorn # should not set this, and instead set the Rails logger to a Google # Cloud Logging Logger object on the worker process by calling # {Railtie.set_default_logger} at the appropriate time, such as a # post-fork hook. # * `on_error` - (Proc) A Proc to be run when an error is encountered # on a background thread. The Proc must take the error object as the # single argument. (See {AsyncWriter.on_error}.) # # See the [Configuration # Guide](https://googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html) # for full configuration parameters. # # @return [Google::Cloud::Config] The configuration object # the Google::Cloud::Logging module uses. # def self.configure yield Google::Cloud.configure.logging if block_given? Google::Cloud.configure.logging end ## # @private Default project. def self.default_project_id Google::Cloud.configure.logging.project_id || Google::Cloud.configure.project_id || Google::Cloud.env.project_id end ## # @private Default credentials. def self.default_credentials scope: nil Google::Cloud.configure.logging.credentials || Google::Cloud.configure.credentials || Logging::Credentials.default(scope: scope) end end end # @private Logging = Cloud::Logging unless const_defined? :Logging end google-cloud-logging-2.7.0/lib/google/cloud/logging/0000755000004100000410000000000015170601174022334 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging/logger.rb0000644000004100000410000005244615170601174024153 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "logger" require "concurrent" module Google module Cloud module Logging ## # # Logger # # An API-compatible replacement for ruby's Logger that logs to the # Stackdriver Logging Service. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # logger = logging.logger "my_app_log", resource, env: :production # logger.info "Job started." # # @example Provide a hash to write a JSON payload to the log: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # logger = logging.logger "my_app_log", resource, env: :production # # payload = { "stats" => { "a" => 8, "b" => 12.5} } # logger.info payload # class Logger ## # A RequestInfo represents data about the request being handled by the # current thread. It is used to configure logs coming from that thread. # # The trace_id is a String that controls the trace ID sent with the log # entry. If it is nil, no trace ID is sent. # # The log_name is a String that controls the name of the Stackdriver # log to write to. If it is nil, the default log_name for this Logger # is used. RequestInfo = ::Struct.new :trace_id, :log_name, :env, :trace_sampled ## # The Google Cloud writer object that calls to `#write_entries` are made # on. Either an AsyncWriter or Project object. attr_reader :writer ## # The Google Cloud log_name to write the log entry with. attr_reader :log_name alias progname log_name ## # The Google Cloud resource to write the log entry with. attr_reader :resource ## # The Google Cloud labels to write the log entry with. attr_reader :labels ## # The logging severity threshold (e.g. `Logger::INFO`) attr_reader :level alias sev_threshold level alias local_level level ## # Boolean flag that indicates whether this logger can be silenced or # not. attr_accessor :silencer ## # This logger does not use a formatter, but it provides a default # Logger::Formatter for API compatibility with the standard Logger. attr_accessor :formatter ## # This logger does not use a formatter, but it implements this # attribute for API compatibility with the standard Logger. attr_accessor :datetime_format ## # The project ID this logger is sending data to. If set, this value is # used to set the trace field of log entries. attr_accessor :project ## # This logger treats progname as an alias for log_name. def progname= name @log_name = name end ## # A Hash of Thread IDs to Stackdriver request trace ID. The # Stackdriver trace ID is a shared request identifier across all # Stackdriver services. # # This method is deprecated and returns a Hash containing only the # current Thread ID/trace_id now. # # @deprecated Use request_info # def trace_ids current_request_info = request_info return {} if current_request_info.nil? { current_thread_id => current_request_info.trace_id } end ## # Create a new Logger instance. # # @param [#write_entries] writer The object that will transmit log # entries. Generally, to create a logger that blocks on transmitting # log entries, pass the Project; otherwise, to create a logger that # transmits log entries in the background, pass an AsyncWriter. You # may also pass any other object that responds to `#write_entries`. # @param [String] log_name A log resource name to be associated with the # written log entries. # @param [Google::Cloud::Logging::Resource] resource The monitored # resource to be associated with written log entries. # @param [Hash] labels A set of user-defined data to be associated with # written log entries. # # @return [Google::Cloud::Logging::Logger] a Logger object that can be # used in place of a ruby standard library logger object. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # writer = logging.async_writer max_queue_size: 1000 # # resource = logging.resource "gae_app", labels: { # "module_id" => "1", # "version_id" => "20150925t173233" # } # # logger = Google::Cloud::Logging::Logger.new writer, # "my_app_log", # resource, # env: :production # logger.info "Job started." # def initialize writer, log_name, resource, labels = nil @writer = writer @log_name = log_name @resource = resource @labels = labels || {} @level = 0 # DEBUG is the default behavior @request_info_var = Concurrent::ThreadLocalVar.new @closed = false # Unused, but present for API compatibility @formatter = ::Logger::Formatter.new @datetime_format = "" @silencer = true # The writer is usually a Project or AsyncWriter. logging = @writer.respond_to?(:logging) ? @writer.logging : @writer @project = logging.project if logging.respond_to? :project end ## # Log a `DEBUG` entry. # # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def debug message = nil, &block if block_given? add ::Logger::DEBUG, nil, message, &block else add ::Logger::DEBUG, message end end ## # Log an `INFO` entry. # # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def info message = nil, &block if block_given? add ::Logger::INFO, nil, message, &block else add ::Logger::INFO, message end end ## # Log a `WARN` entry. # # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def warn message = nil, &block if block_given? add ::Logger::WARN, nil, message, &block else add ::Logger::WARN, message end end ## # Log an `ERROR` entry. # # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def error message = nil, &block if block_given? add ::Logger::ERROR, nil, message, &block else add ::Logger::ERROR, message end end ## # Log a `FATAL` entry. # # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def fatal message = nil, &block if block_given? add ::Logger::FATAL, nil, message, &block else add ::Logger::FATAL, message end end ## # Log an `UNKNOWN` entry. This will be printed no matter what the # logger's current severity level is. # # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def unknown message = nil, &block if block_given? add ::Logger::UNKNOWN, nil, message, &block else add ::Logger::UNKNOWN, message end end ## # Log a message if the given severity is high enough. This is the # generic logging method. Users will be more inclined to use {#debug}, # {#info}, {#warn}, {#error}, and {#fatal}. # # @param [Integer, String, Symbol] severity the integer code for or the # name of the severity level # @param [String, Hash] message The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). # @yield Evaluates to the message to log. This is not evaluated unless # the logger's level is sufficient to log the message. This allows you # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # def add severity, message = nil, progname = nil return if @closed severity = derive_severity(severity) || ::Logger::UNKNOWN return true if severity < @level message ||= block_given? ? yield : progname # TODO: Figure out what to do with the progname write_entry severity, message unless @closed true end alias log add ## # Logs the given message at UNKNOWN severity. # # @param [String] msg The log entry payload as a string. # def << msg unknown msg self end ## # Returns `true` if the current severity level allows for sending # `DEBUG` messages. def debug? @level <= ::Logger::DEBUG end ## # Returns `true` if the current severity level allows for sending `INFO` # messages. def info? @level <= ::Logger::INFO end ## # Returns `true` if the current severity level allows for sending `WARN` # messages. def warn? @level <= ::Logger::WARN end ## # Returns `true` if the current severity level allows for sending # `ERROR` messages. def error? @level <= ::Logger::ERROR end ## # Returns `true` if the current severity level allows for sending # `FATAL` messages. def fatal? @level <= ::Logger::FATAL end ## # Returns `true` if the current severity level allows for sending # `UNKNOWN` messages. def unknown? @level <= ::Logger::UNKNOWN end ## # Sets the logging severity level. # # @param [Integer, String, Symbol] severity the integer code for or the # name of the severity level # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # logger = logging.logger "my_app_log", resource, env: :production # # logger.level = "INFO" # logger.debug "Job started." # No log entry written # def level= severity new_level = derive_severity severity if new_level.nil? raise ArgumentError, "invalid log level: #{severity}" end @level = new_level end alias sev_threshold= level= alias local_level= level= ## # Close the logging "device". This effectively disables logging from # this logger; any further log messages will be silently ignored. The # logger may be re-enabled by calling #reopen. # def close @closed = true self end ## # Re-enable logging if the logger has been closed. # # Note that this method accepts a "logdev" argument for compatibility # with the standard Ruby Logger class; however, this argument is # ignored because this logger does not use a log device. # def reopen _logdev = nil @closed = false self end ## # Track a given trace_id by associating it with the current # Thread # # @deprecated Use add_request_info # def add_trace_id trace_id add_request_info trace_id: trace_id end ## # Associate request data with the current Thread. You may provide # either the individual pieces of data (trace ID, log name) or a # populated RequestInfo object. # # @param [RequestInfo] info Info about the current request. Optional. # If not present, a new RequestInfo is created using the remaining # parameters. # @param [String, nil] trace_id The trace ID, or `nil` if no trace ID # should be logged. # @param [String, nil] log_name The log name to use, or nil to use # this logger's default. # @param [Hash, nil] env The request's Rack environment or `nil` if not # available. # def add_request_info info: nil, env: nil, trace_id: nil, log_name: nil, trace_sampled: nil info ||= RequestInfo.new trace_id, log_name, env, trace_sampled @request_info_var.value = info info end ## # Get the request data for the current Thread # # @return [RequestInfo, nil] The request data for the current thread, # or `nil` if there is no data set. # def request_info @request_info_var.value end ## # Untrack the RequestInfo that's associated with current Thread # # @return [RequestInfo] The info that's being deleted # def delete_request_info @request_info_var.value = nil end ## # @deprecated Use delete_request_info alias delete_trace_id delete_request_info ## # No-op method. Created to match the spec of ActiveSupport::Logger#flush # method when used in Rails application. def flush self end ## # Filter out low severity messages within block. # # @param [Integer] temp_level Severity threshold to filter within the # block. Messages with lower severity will be blocked. Default # ::Logger::ERROR # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # logger = logging.logger "my_app_log", resource, env: :production # # logger.silence do # logger.info "Info message" # No log entry written # logger.error "Error message" # Log entry written # end def silence temp_level = ::Logger::ERROR if silencer begin old_level = level self.level = temp_level yield self ensure self.level = old_level end else yield self end end protected ## # @private Write a log entry to the Stackdriver Logging service. def write_entry severity, message entry = Entry.new.tap do |e| e.timestamp = Time.now e.severity = gcloud_severity severity e.payload = message end actual_log_name = log_name info = request_info if info actual_log_name = info.log_name || actual_log_name unless info.trace_id.nil? || @project.nil? entry.trace = "projects/#{@project}/traces/#{info.trace_id}" end entry.trace_sampled = info.trace_sampled if entry.trace_sampled.nil? end writer.write_entries entry, log_name: actual_log_name, resource: resource, labels: entry_labels(info) end ## # @private generate the labels hash for a log entry. def entry_labels info merged_labels = {} if info && !info.trace_id.nil? merged_labels["traceId"] = info.trace_id if Google::Cloud.env.app_engine? merged_labels["appengine.googleapis.com/trace_id"] = info.trace_id end end request_env = info&.env || {} compute_labels(request_env).merge merged_labels end ## # @private Get the logger level number from severity value object. def derive_severity severity return severity if severity.is_a? Integer downcase_severity = severity.to_s.downcase case downcase_severity when "debug".freeze then ::Logger::DEBUG when "info".freeze then ::Logger::INFO when "warn".freeze then ::Logger::WARN when "error".freeze then ::Logger::ERROR when "fatal".freeze then ::Logger::FATAL when "unknown".freeze then ::Logger::UNKNOWN end end ## # @private Get Google Cloud deverity from logger level number. def gcloud_severity severity_int [:DEBUG, :INFO, :WARNING, :ERROR, :CRITICAL, :DEFAULT][severity_int] rescue StandardError :DEFAULT end ## # @private Get current thread id def current_thread_id Thread.current.object_id end private ## # @private Compute values for labels def compute_labels request_env labels.to_h.transform_values do |value_or_proc| compute_label_value request_env, value_or_proc end end ## # @private Compute individual label value. # Value can be a Proc (function of the request env) or a static value. def compute_label_value request_env, value_or_proc if value_or_proc.respond_to? :call value_or_proc.call request_env else value_or_proc end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/sink.rb0000644000004100000410000002575115170601174023637 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/logging/sink/list" module Google module Cloud module Logging ## # # Sink # # Used to export log entries outside Stackdriver Logging. When you create # 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. # # Before creating the sink, ensure that you have granted the sink's # _unique writer identity_ permission to write logs to the destination. # See [Destination # permissions](https://cloud.google.com/logging/docs/export/configure_export_v2#dest-auth). # # You can retrieve an existing sink with {Project#sink}. # # @see https://cloud.google.com/logging/docs/export # Overview of logs exports # @see https://cloud.google.com/logging/docs/reference/v2/rpc/google.logging.v2#configservicev2 # ConfigService API which includes sink methods # # @example # require "google/cloud/storage" # # storage = Google::Cloud::Storage.new # bucket = storage.create_bucket "my-logs-bucket" # # # Grant owner permission to Stackdriver Logging service # email = "cloud-logs@google.com" # bucket.acl.add_owner "group-#{email}" # # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sink = logging.create_sink "my-sink", # "storage.googleapis.com/#{bucket.id}" # class Sink ## # @private The gRPC Service object. attr_accessor :service ## # @private The Google API Client object. attr_accessor :grpc ## # @private Create an empty Sink object. def initialize @service = nil @grpc = Google::Cloud::Logging::V2::LogSink.new end ## # The client-assigned sink identifier. Sink identifiers are limited to # 1000 characters and can include only the following characters: `A-Z`, # `a-z`, `0-9`, and the special characters `_-.`. def name @grpc.name end ## # The export destination. See [Properties of # Sinks](https://cloud.google.com/logging/docs/export#sink-terms). def destination @grpc.destination end ## # Updates the export destination. See [Properties of # Sinks](https://cloud.google.com/logging/docs/export#sink-terms). def destination= destination @grpc.destination = destination end ## # An [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced-queries) # that defines the log entries to be exported. The filter must be # 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. def filter @grpc.filter end ## # Updates the [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced-queries) # that defines the log entries to be exported. The filter must be # 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. def filter= filter @grpc.filter = filter end ## # **Deprecated.** 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. # # @deprecated The v2 format is used by default and cannot be changed. def version warn "[DEPRECATION] version is deprecated." :V2 end ## # **Deprecated.** Updates 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 `:VERSION_FORMAT_UNSPECIFIED`, `:V2`, and # `:V1`. # # @deprecated The v2 format is used by default and cannot be changed. def version= _version warn "[DEPRECATION] version= is deprecated and will be ignored." end ## # Helper to determine if the sink's version is # `VERSION_FORMAT_UNSPECIFIED`. # # @deprecated The v2 format is used by default and cannot be changed. def unspecified? warn "[DEPRECATION] unspecified? is deprecated." false end ## # Helper to determine if the sink's version is `V2`. # # @deprecated The v2 format is used by default and cannot be changed. def v2? warn "[DEPRECATION] v2? is deprecated." true end ## # Helper to determine if the sink's version is `V1`. # # @deprecated The v2 format is used by default and cannot be changed. def v1? warn "[DEPRECATION] v1? is deprecated." false end ## # **Deprecated.** 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. # # @deprecated This field is ignored when creating or updating sinks. def start_at warn "[DEPRECATION] start_at is deprecated." nil end alias start_time start_at ## # **Deprecated.** 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. # # @deprecated This field is ignored when creating or updating sinks. def start_at= _new_start_at warn "[DEPRECATION] start_at= is deprecated and will be ignored." end alias start_time= start_at= ## # **Deprecated.** 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. # # @deprecated This field is ignored when creating or updating sinks. def end_at warn "[DEPRECATION] end_at is deprecated." nil end alias end_time end_at ## # **Deprecated.** 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. # # @deprecated This field is ignored when creating or updating sinks. def end_at= _new_end_at warn "[DEPRECATION] end_at= is deprecated and will be ignored." end alias 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" # # logging = Google::Cloud::Logging.new # sink = logging.sink "severe_errors" # sink.filter = "logName:syslog AND severity>=ERROR" # sink.save # def save unique_writer_identity: nil ensure_service! @grpc = service.update_sink \ name, destination, filter, unique_writer_identity: unique_writer_identity end ## # Reloads the logs-based sink with current data from the Logging # service. def reload! ensure_service! @grpc = service.get_sink name end alias refresh! reload! ## # Permanently deletes the logs-based sink. # # @return [Boolean] Returns `true` if the sink was deleted. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sink = logging.sink "severe_errors" # sink.delete # def delete ensure_service! service.delete_sink name true end ## # @private New Sink from a Google::Cloud::Logging::V2::LogSink object. def self.from_grpc grpc, service new.tap do |f| f.grpc = grpc f.service = service end end protected ## # @private Raise an error unless an active connection to the service is # available. def ensure_service! raise "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 end google-cloud-logging-2.7.0/lib/google/cloud/logging/resource_descriptor/0000755000004100000410000000000015170601174026421 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging/resource_descriptor/list.rb0000644000004100000410000001364315170601174027730 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "delegate" module Google module Cloud module Logging class ResourceDescriptor ## # ResourceDescriptor::List is a special case Array with additional # values. class List < DelegateClass(::Array) ## # If not empty, indicates that there are more records that match # the request and this value should be passed to continue. attr_accessor :token ## # @private Create a new ResourceDescriptor::List with an array of # ResourceDescriptor instances. def initialize arr = [] super arr end ## # Whether there is a next page of resource descriptors. # # @return [Boolean] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource_descriptors = logging.resource_descriptors # if resource_descriptors.next? # next_resource_descriptors = resource_descriptors.next # end # def next? !token.nil? end ## # Retrieve the next page of resource descriptors. # # @return [Sink::List] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource_descriptors = logging.resource_descriptors # if resource_descriptors.next? # next_resource_descriptors = resource_descriptors.next # end # def next return nil unless next? ensure_service! list_grpc = @service.list_resource_descriptors( token: token, max: @max ) self.class.from_grpc list_grpc, @service, @max end ## # Retrieves remaining results by repeatedly invoking {#next} until # {#next?} returns `false`. Calls the given block once for each # result, which is passed as the argument to the block. # # An Enumerator is returned if no block is given. # # This method will make repeated API calls until all remaining results # are retrieved. (Unlike `#each`, for example, which merely iterates # over the results returned by a single API call.) Use with caution. # # @param [Integer] request_limit The upper limit of API requests to # make to load all resource descriptors. Default is no limit. # @yield [resource_descriptor] The block for accessing each resource # descriptor. # @yieldparam [ResourceDescriptor] resource_descriptor The resource # descriptor object. # # @return [Enumerator] # # @example Iterating each resource descriptor by passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptors = logging.resource_descriptors # # resource_descriptors.all do |rd| # puts rd.type # end # # @example Using the enumerator by not passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptors = logging.resource_descriptors # # all_types = resource_descriptors.all.map do |rd| # rd.type # end # # @example Limit the number of API calls made: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptors = logging.resource_descriptors # # resource_descriptors.all(request_limit: 10) do |rd| # puts rd.type # end # def all request_limit: nil, &block request_limit = request_limit.to_i if request_limit unless block_given? return enum_for :all, request_limit: request_limit end results = self loop do results.each(&block) if request_limit request_limit -= 1 break if request_limit.negative? end break unless results.next? results = results.next end end ## # @private New ResourceDescriptor::List from a # Google::Cloud::Logging::V2::ListMonitoredResourceDescriptorsResponse # object. def self.from_grpc grpc_list, service, max = nil rds = new(Array(grpc_list.resource_descriptors).map do |grpc| ResourceDescriptor.from_grpc grpc end) token = grpc_list.next_page_token token = nil if token == "".freeze rds.instance_variable_set :@token, token rds.instance_variable_set :@service, service rds.instance_variable_set :@max, max rds end protected ## # Raise an error unless an active service is available. def ensure_service! raise "Must have active service" unless @service end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/resource_descriptor.rb0000644000004100000410000001132215170601174026745 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/logging/resource_descriptor/list" module Google module Cloud module Logging ## # # ResourceDescriptor # # Describes a type of monitored resource supported by Stackdriver Logging. # Each ResourceDescriptor has a type name, such as `cloudsql_database`, # `gae_app`, or `gce_instance`. It also specifies a set of labels that # must all be given values in a {Resource} instance to represent an actual # instance of the type. # # ResourceDescriptor instances are read-only. You cannot create your own # instances, but you can list them with {Project#resource_descriptors}. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptor = logging.resource_descriptors.first # resource_descriptor.type #=> "cloudsql_database" # resource_descriptor.name #=> "Cloud SQL Database" # resource_descriptor.labels.map &:key #=> ["database_id", "zone"] # class ResourceDescriptor ## # @private New ResourceDescriptor from a Google API Client object. def initialize @labels = [] end ## # The monitored resource type. For example, `cloudsql_database`. attr_reader :type ## # A display name for the monitored resource type. For example, # `Cloud SQL Database`. attr_reader :name ## # A detailed description of the monitored resource type, which is used # in documentation. attr_reader :description ## # A set of definitions of the labels that can be used to describe # instances of this monitored resource type. For example, Cloud SQL # databases must be labeled with their `database_id` and their `region`. # # @return [Array] # attr_reader :labels ## # @private New ResourceDescriptor from a # Google::Api::MonitoredResourceDescriptor object. def self.from_grpc grpc labels = Array(grpc.labels).map do |g| LabelDescriptor.from_grpc g end new.tap do |r| r.instance_variable_set :@type, grpc.type r.instance_variable_set :@name, grpc.display_name r.instance_variable_set :@description, grpc.description r.instance_variable_set :@labels, labels end end ## # # LabelDescriptor # # A definition of a label that can be used to describe instances of a # {Resource}. For example, Cloud SQL databases must be labeled with # their `database_id`. See {ResourceDescriptor#labels}. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptor = logging.resource_descriptors.first # label_descriptor = resource_descriptor.labels.first # label_descriptor.key #=> "database_id" # label_descriptor.description #=> "The ID of the database." # class LabelDescriptor ## # The key (name) of the label. attr_reader :key ## # The type of data that can be assigned to the label. # # @return [Symbol, nil] Returns `:string`, `:boolean`, `:integer`, or # `nil` if there is no type. # attr_reader :type ## # A human-readable description for the label. attr_reader :description ## # @private New LabelDescriptor from a Google::Api::LabelDescriptor # object. def self.from_grpc grpc type_sym = { STRING: :string, BOOL: :boolean, INT64: :integer }[grpc.value_type] new.tap do |l| l.instance_variable_set :@key, grpc.key l.instance_variable_set :@type, type_sym l.instance_variable_set :@description, grpc.description end end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/service.rb0000644000004100000410000002125015170601174024321 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/errors" require "google/cloud/logging/version" require "google/cloud/logging/v2" require "uri" module Google module Cloud module Logging ## # @private Represents the gRPC Logging service, including all the API # methods. class Service attr_accessor :project attr_accessor :credentials attr_accessor :timeout attr_accessor :host ## # Creates a new Service instance. def initialize project, credentials, timeout: nil, host: nil @project = project @credentials = credentials @timeout = timeout @host = host end def logging return mocked_logging if mocked_logging @logging ||= V2::LoggingService::Client.new do |config| config.credentials = credentials if credentials config.timeout = timeout if timeout config.endpoint = host if host config.lib_name = "gccl" config.lib_version = Google::Cloud::Logging::VERSION config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" } end end attr_accessor :mocked_logging def sinks return mocked_sinks if mocked_sinks @sinks ||= V2::ConfigService::Client.new do |config| config.credentials = credentials if credentials config.timeout = timeout if timeout config.endpoint = host if host config.lib_name = "gccl" config.lib_version = Google::Cloud::Logging::VERSION config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" } end end attr_accessor :mocked_sinks def metrics return mocked_metrics if mocked_metrics @metrics ||= V2::MetricsService::Client.new do |config| config.credentials = credentials if credentials config.timeout = timeout if timeout config.endpoint = host if host config.lib_name = "gccl" config.lib_version = Google::Cloud::Logging::VERSION config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" } end end attr_accessor :mocked_metrics def list_entries resources: nil, filter: nil, order: nil, token: nil, max: nil, projects: nil project_ids = Array(projects).map { |p| "projects/#{p}" } resource_names = Array(resources) + project_ids resource_names = ["projects/#{@project}"] if resource_names.empty? paged_enum = logging.list_log_entries resource_names: resource_names, filter: filter, order_by: order, page_size: max, page_token: token paged_enum.response end def write_entries entries, log_name: nil, resource: nil, labels: nil, partial_success: nil # Fix log names so they are the full path entries = Array(entries).each do |entry| entry.log_name = log_path entry.log_name end resource = resource.to_grpc if resource labels = labels.to_h { |k, v| [String(k), String(v)] } if labels logging.write_log_entries entries: entries, log_name: log_path(log_name), resource: resource, labels: labels, partial_success: partial_success end def list_logs resource: nil, token: nil, max: nil parent = resource || "projects/#{@project}" logging.list_logs parent: parent, page_size: max, page_token: token end def delete_log name logging.delete_log log_name: log_path(name) end def list_resource_descriptors token: nil, max: nil paged_enum = logging.list_monitored_resource_descriptors page_size: max, page_token: token paged_enum.response end def list_sinks token: nil, max: nil paged_enum = sinks.list_sinks parent: project_path, page_size: max, page_token: token paged_enum.response end def create_sink name, destination, filter, unique_writer_identity: nil sink = Google::Cloud::Logging::V2::LogSink.new( { name: name, destination: destination, filter: filter }.compact ) sinks.create_sink parent: project_path, sink: sink, unique_writer_identity: unique_writer_identity end def get_sink name sinks.get_sink sink_name: sink_path(name) end def update_sink name, destination, filter, unique_writer_identity: nil sink = Google::Cloud::Logging::V2::LogSink.new( { name: name, destination: destination, filter: filter }.compact ) sinks.update_sink sink_name: sink_path(name), sink: sink, unique_writer_identity: unique_writer_identity end def delete_sink name sinks.delete_sink sink_name: sink_path(name) end def list_metrics token: nil, max: nil paged_enum = metrics.list_log_metrics parent: project_path, page_size: max, page_token: token paged_enum.response end def create_metric name, filter, description metric = Google::Cloud::Logging::V2::LogMetric.new( { name: name, description: description, filter: filter }.compact ) metrics.create_log_metric parent: project_path, metric: metric end def get_metric name metrics.get_log_metric metric_name: metric_path(name) end def update_metric name, description, filter metric = Google::Cloud::Logging::V2::LogMetric.new( { name: name, description: description, filter: filter }.compact ) metrics.update_log_metric metric_name: metric_path(name), metric: metric end def delete_metric name metrics.delete_log_metric metric_name: metric_path(name) end def log_path log_name return nil if log_name.nil? return log_name if log_name.empty? return log_name if log_name.to_s.include? "/" "#{project_path}/logs/#{log_name}" end def inspect "#{self.class}(#{@project})" end protected def project_path "projects/#{@project}" end def sink_path sink_name return sink_name if sink_name.to_s.include? "/" "#{project_path}/sinks/#{sink_name}" end def metric_path metric_name return metric_name if metric_name.to_s.include? "/" "#{project_path}/metrics/#{metric_name}" 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 end google-cloud-logging-2.7.0/lib/google/cloud/logging/resource.rb0000644000004100000410000000522415170601174024513 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Google module Cloud module Logging ## # # Resource # # A monitored resource is an abstraction used to characterize many kinds # of objects in your cloud infrastructure, including Google Cloud SQL # databases, Google App Engine apps, Google Compute Engine virtual machine # instances, and so forth. Each of those kinds of objects is described by # an instance of {ResourceDescriptor}. # # For use with {Google::Cloud::Logging::Entry#resource}, # {Google::Cloud::Logging::Project#resource}, and # {Google::Cloud::Logging::Project#write_entries}. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource = logging.resource "gae_app", # "module_id" => "1", # "version_id" => "20150925t173233" # class Resource ## # Create an empty Resource object. def initialize @labels = {} end ## # The type of resource, as represented by a {ResourceDescriptor}. attr_accessor :type ## # A set of labels that can be used to describe instances of this # monitored resource type. attr_accessor :labels ## # @private Determines if the Resource has any data. def empty? type.nil? && (labels.nil? || labels.empty?) end ## # @private Exports the Resource to a Google::Api::MonitoredResource # object. def to_grpc return nil if empty? Google::Api::MonitoredResource.new( type: type, labels: labels.to_h { |k, v| [String(k), String(v)] } ) end ## # @private New Resource from a Google::Api::MonitoredResource object. def self.from_grpc grpc return new if grpc.nil? new.tap do |r| r.type = grpc.type r.labels = Convert.map_to_hash grpc.labels end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/sink/0000755000004100000410000000000015170601174023300 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging/sink/list.rb0000644000004100000410000001262315170601174024604 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "delegate" module Google module Cloud module Logging class Sink ## # Sink::List is a special case Array with additional values. class List < DelegateClass(::Array) ## # If not empty, indicates that there are more records that match # the request and this value should be passed to continue. attr_accessor :token ## # @private Create a new Sink::List with an array of Sink instances. def initialize arr = [] super arr end ## # Whether there is a next page of sinks. # # @return [Boolean] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # sinks = logging.sinks # if sinks.next? # next_sinks = sinks.next # end # def next? !token.nil? end ## # Retrieve the next page of sinks. # # @return [Sink::List] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # sinks = logging.sinks # if sinks.next? # next_sinks = sinks.next # end # def next return nil unless next? ensure_service! list_grpc = @service.list_sinks token: token, max: @max self.class.from_grpc list_grpc, @service, @max end ## # Retrieves remaining results by repeatedly invoking {#next} until # {#next?} returns `false`. Calls the given block once for each # result, which is passed as the argument to the block. # # An Enumerator is returned if no block is given. # # This method will make repeated API calls until all remaining results # are retrieved. (Unlike `#each`, for example, which merely iterates # over the results returned by a single API call.) Use with caution. # # @param [Integer] request_limit The upper limit of API requests to # make to load all sinks. Default is no limit. # @yield [sink] The block for accessing each sink. # @yieldparam [Sink] sink The sink object. # # @return [Enumerator] # # @example Iterating each sink by passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sinks = logging.sinks # # sinks.all do |sink| # puts "#{sink.name}: #{sink.filter} -> #{sink.destination}" # end # # @example Using the enumerator by not passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sinks = logging.sinks # # all_names = sinks.all.map do |sink| # sink.name # end # # @example Limit the number of API calls made: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sinks = logging.sinks # # sinks.all(request_limit: 10) do |sink| # puts "#{sink.name}: #{sink.filter} -> #{sink.destination}" # end # def all request_limit: nil, &block request_limit = request_limit.to_i if request_limit unless block_given? return enum_for :all, request_limit: request_limit end results = self loop do results.each(&block) if request_limit request_limit -= 1 break if request_limit.negative? end break unless results.next? results = results.next end end ## # @private New Sink::List from a # Google::Cloud::Logging::V2::ListSinksResponse object. def self.from_grpc grpc_list, service, max = nil sinks = new(Array(grpc_list.sinks).map do |grpc| Sink.from_grpc grpc, service end) token = grpc_list.next_page_token token = nil if token == "".freeze sinks.instance_variable_set :@token, token sinks.instance_variable_set :@service, service sinks.instance_variable_set :@max, max sinks end protected ## # Raise an error unless an active service is available. def ensure_service! raise "Must have active service" unless @service end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/project.rb0000644000004100000410000010264515170601174024337 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/errors" require "google/cloud/logging/service" require "google/cloud/logging/credentials" require "google/cloud/logging/log/list" require "google/cloud/logging/entry" require "google/cloud/logging/resource_descriptor" require "google/cloud/logging/sink" require "google/cloud/logging/metric" require "google/cloud/logging/async_writer" require "google/cloud/logging/logger" require "google/cloud/logging/middleware" module Google module Cloud module Logging ## # # Project # # Projects are top-level containers in Google Cloud Platform. They store # information about billing and authorized users, and they control access # to Stackdriver Logging resources. Each project has a friendly name and a # unique ID. Projects can be created only in the [Google Developers # Console](https://console.developers.google.com). See # {Google::Cloud#logging}. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries # # See Google::Cloud#logging class Project ## # @private The gRPC Service object. attr_accessor :service ## # @private Creates a new Connection instance. def initialize service @service = service end ## # The ID of the current project. # # @return [String] the Google Cloud project ID # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new( # project_id: "my-project", # credentials: "/path/to/keyfile.json" # ) # # logging.project_id #=> "my-project" # def project_id service.project end alias project project_id ## # Lists log entries. Use this method to retrieve log entries from Cloud # Logging. # # @param [String, Array] resources One or more cloud resources # from which to retrieve log entries. If both `resources` and # `projects` are `nil`, the ID of the receiving project instance will # be used. Examples: `"projects/my-project-1A"`, # `"projects/1234567890"`. # @param [String] filter An [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced_filters). # The filter is compared against all log entries in the projects # specified by `projects`. Only entries that match the filter are # retrieved. An empty filter matches all log entries. # @param [String] order How the results should be sorted. Presently, the # only permitted values are "timestamp" (default) and "timestamp # desc". # @param [String] token A previously-returned page token representing # part of the larger set of results to view. # @param [Integer] max Maximum number of entries to return. # @param [String, Array] projects One or more project IDs or # project numbers from which to retrieve log entries. Each value will # be formatted as a project resource name and added to any values # passed to `resources`. If both `resources` and `projects` are `nil`, # the ID of the receiving project instance will be used. This is # deprecated in favor of `resources`. # # @return [Array] (See # {Google::Cloud::Logging::Entry::List}) # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries # entries.each do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # # @example You can use a filter to narrow results to a single log. # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries filter: "logName:syslog" # entries.each do |e| # puts "[#{e.timestamp}] #{e.payload.inspect}" # end # # @example You can also order the results by timestamp. # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries order: "timestamp desc" # entries.each do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # # @example Retrieve all log entries: (See {Entry::List#all}) # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries # # entries.all do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # def entries resources: nil, filter: nil, order: nil, token: nil, max: nil, projects: nil ensure_service! list_grpc = service.list_entries resources: resources, filter: filter, order: order, token: token, max: max, projects: projects Entry::List.from_grpc list_grpc, service, resources: resources, max: max, filter: filter, order: order, projects: projects end alias find_entries entries ## # Creates an new Entry instance that may be populated and written to the # Stackdriver Logging service. The {Entry#resource} attribute is # pre-populated with a new {Google::Cloud::Logging::Resource} instance. # Equivalent to calling `Google::Cloud::Logging::Entry.new`. # # @param [String] log_name The resource name of the log to which this # log entry belongs. See also {Entry#log_name=}. # @param [Resource] resource The monitored resource associated with this # log entry. See also {Entry#resource}. # @param [Time] timestamp The time the event described by the log entry # occurred. If omitted, Stackdriver Logging will use the time the log # entry is written. See also {Entry#timestamp}. # @param [Symbol] severity The severity level of the log entry. The # default value is `DEFAULT`. See also {Entry#severity}. # @param [String] insert_id A unique ID for the log entry. If you # provide this field, the logging service considers other log entries # in the same log with the same ID as duplicates which can be removed. # If omitted, Stackdriver Logging will generate a unique ID for this # log entry. See also {Entry#insert_id}. # @param [Hash{Symbol,String => String}] labels A hash of user-defined # `key:value` pairs that provide additional information about the log # entry. See also {Entry#labels=}. # @param [String, Hash] payload The log entry payload, represented as # either a string, a hash (JSON), or a hash (protocol buffer). See # also {Entry#payload}. # # @return [Google::Cloud::Logging::Entry] a new Entry instance # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry severity: :INFO, payload: "Job started." # # logging.write_entries entry # # @example Provide a hash to write a JSON payload to the log: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # payload = { "stats" => { "a" => 8, "b" => 12.5} } # entry = logging.entry severity: :INFO, payload: payload # # logging.write_entries entry # def entry log_name: nil, resource: nil, timestamp: nil, severity: nil, insert_id: nil, labels: nil, payload: nil ensure_service! e = Entry.new e.log_name = service.log_path log_name if log_name e.resource = resource if resource e.timestamp = timestamp if timestamp e.severity = severity if severity e.insert_id = insert_id if insert_id e.labels = labels if labels e.payload = payload if payload e end alias new_entry entry ## # Writes log entries to the Stackdriver Logging service. # # If you write a collection of log entries, you can provide the log # name, resource, and/or labels hash to be used for all of the entries, # and omit these values from the individual entries. # # @param [Google::Cloud::Logging::Entry, # Array] entries One or more entry # objects to write. The log entries must have values for all required # fields. # @param [String] log_name A default log ID for those log entries in # `entries` that do not specify their own `log_name`. See also # {Entry#log_name=}. # @param [Resource] resource A default monitored resource for those log # entries in entries that do not specify their own resource. See also # {Entry#resource}. # @param [Hash{Symbol,String => String}] labels User-defined `key:value` # items that are added to the `labels` field of each log entry in # `entries`, except when a log entry specifies its own `key:value` # item with the same key. See also {Entry#labels=}. # @param [Boolean] partial_success Whether valid entries should be # written even if some other entries fail due to `INVALID_ARGUMENT` or # `PERMISSION_DENIED` errors when communicating to the Stackdriver # Logging API. # # @return [Boolean] Returns `true` if the entries were written. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry payload: "Job started.", # log_name: "my_app_log" # entry.resource.type = "gae_app" # entry.resource.labels[:module_id] = "1" # entry.resource.labels[:version_id] = "20150925t173233" # # logging.write_entries entry # # @example Provide a hash to write a JSON payload to the log: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # payload = { "stats" => { "a" => 8, "b" => 12.5} } # # entry = logging.entry payload: payload, # log_name: "my_app_log" # entry.resource.type = "gae_app" # entry.resource.labels[:module_id] = "1" # entry.resource.labels[:version_id] = "20150925t173233" # # logging.write_entries entry # # # @example Optionally pass log name, resource, and labels for entries. # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry1 = logging.entry payload: "Job started." # entry2 = logging.entry payload: "Job completed." # # labels = { job_size: "large", job_code: "red" } # resource = logging.resource "gae_app", # "module_id" => "1", # "version_id" => "20150925t173233" # # logging.write_entries [entry1, entry2], # log_name: "my_app_log", # resource: resource, # labels: labels, # partial_success: true # def write_entries entries, log_name: nil, resource: nil, labels: nil, partial_success: nil ensure_service! service.write_entries Array(entries).map(&:to_grpc), log_name: log_name, resource: resource, labels: labels, partial_success: partial_success true end ## # Creates an object that buffers, batches, and transmits log entries # efficiently. Writing log entries to this object is asynchronous and # will not block. # # Batches that cannot be delivered immediately are queued. When the # queue is full new batch requests will raise errors that can be # consumed using the {AsyncWriter#on_error} callback. This provides back # pressure in case the writer cannot keep up with requests. # # This object is thread-safe; it may accept write requests from # multiple threads simultaneously, and will serialize them when # executing in the background thread. # # @param [Integer] max_batch_count The maximum number of log entries # that may be buffered and sent in a batch. # @param [Integer] max_batch_bytes The maximum byte size of log entries # that may be buffered and sent in a batch. # @param [Integer] max_queue_size The maximum number of pending # write_entries requests that may be queued. # @param [Numeric] interval The number of seconds to buffer log entries # before a batch is written. Default is 5. # @param [Integer] threads The number of threads used to make # batched write_entries requests. Default is 10. # @param [Boolean] partial_success Whether valid entries should be # written even if some other entries fail due to `INVALID_ARGUMENT` or # `PERMISSION_DENIED` errors when communicating to the Stackdriver # Logging API. # # @return [Google::Cloud::Logging::AsyncWriter] an AsyncWriter object # that buffers, batches, and transmits log entries efficiently. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # async = logging.async_writer # # entry1 = logging.entry payload: "Job started." # entry2 = logging.entry payload: "Job completed." # # labels = { job_size: "large", job_code: "red" } # resource = logging.resource "gae_app", # "module_id" => "1", # "version_id" => "20150925t173233" # # async.write_entries [entry1, entry2], # log_name: "my_app_log", # resource: resource, # labels: labels # def async_writer max_batch_count: 10_000, max_batch_bytes: 10_000_000, max_queue_size: 100, interval: 5, threads: 10, partial_success: false AsyncWriter.new self, max_count: max_batch_count, max_bytes: max_batch_bytes, max_queue: max_queue_size, interval: interval, threads: threads, partial_success: partial_success end ## # Returns a shared AsyncWriter for this Project. If this method is # called multiple times, it will return the same object. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # async = logging.shared_async_writer # # entry1 = logging.entry payload: "Job started." # entry2 = logging.entry payload: "Job completed." # # labels = { job_size: "large", job_code: "red" } # resource = logging.resource "gae_app", # "module_id" => "1", # "version_id" => "20150925t173233" # # async.write_entries [entry1, entry2], # log_name: "my_app_log", # resource: resource, # labels: labels # def shared_async_writer @shared_async_writer ||= async_writer end ## # Creates a logger instance that is API-compatible with Ruby's standard # library [Logger](https://ruby-doc.org/current/stdlibs/logger/). # # The logger will create a new AsyncWriter object to transmit log # entries on a background thread. # # @param [String] log_name A log resource name to be associated with the # written log entries. # @param [Google::Cloud::Logging::Resource] resource The monitored # resource to be associated with written log entries. # @param [Hash] labels A set of user-defined data to be associated with # written log entries. Values can be strings or Procs which are # functions of the request environment. # # @return [Google::Cloud::Logging::Logger] a Logger object that can be # used in place of a ruby standard library logger object. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # logger = logging.logger "my_app_log", resource, env: :production # logger.info "Job started." # # @example Provide a hash to write a JSON payload to the log: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # logger = logging.logger "my_app_log", resource, env: :production # # payload = { "stats" => { "a" => 8, "b" => 12.5} } # logger.info payload # def logger log_name, resource, labels = {} Logger.new shared_async_writer, log_name, resource, labels end ## # Lists log names. Use this method to retrieve log names from Cloud # Logging. # # @param [String] resource The cloud resource from which to retrieve log # names. Optional. If `nil`, the ID of the receiving project instance # will be used. Examples: `"projects/my-project-1A"`, # `"projects/1234567890"`. # @param [String] token A previously-returned page token representing # part of the larger set of results to view. # @param [Integer] max Maximum number of log names to return. # # @return [Array] A list of log names. For example, # `projects/my-project/syslog` or # `organizations/123/cloudresourcemanager.googleapis.com%2Factivity`. # (See {Google::Cloud::Logging::Log::List}) # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # logs = logging.logs # logs.each { |l| puts l } # # @example Retrieve all log names: (See {Log::List#all}) # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # logs = logging.logs # # logs.all { |l| puts l } # def logs resource: nil, token: nil, max: nil ensure_service! list_grpc = service.list_logs resource: resource, token: token, max: max Log::List.from_grpc list_grpc, service, resource: resource, max: max end alias find_logs logs alias log_names logs alias find_log_names logs ## # Deletes a log and all its log entries. The log will reappear if it # receives new entries. # # @param [String] name The name of the log, which may be the full path # including the project ID (`projects//logs/`), or # just the short name (``), in which case the beginning of the # path will be automatically prepended, using the ID of the current # project. # # @return [Boolean] Returns `true` if the log and all its log entries # were deleted. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # logging.delete_log "my_app_log" # def delete_log name ensure_service! service.delete_log name true end ## # Retrieves the list of monitored resource descriptors that are used by # Stackdriver Logging. # # @see https://cloud.google.com/logging/docs/api/v2/resource-list # Monitored Resources # # @param [String] token A previously-returned page token representing # part of the larger set of results to view. # @param [Integer] max Maximum number of resource descriptors to return. # # @return [Array] (See # {Google::Cloud::Logging::ResourceDescriptor::List}) # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptors = logging.resource_descriptors # resource_descriptors.each do |rd| # label_keys = rd.labels.map(&:key).join(", ") # puts "#{rd.type} (#{label_keys})" # end # # @example Pagination: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # resource_descriptors = logging.resource_descriptors # # resource_descriptors.all do |rd| # puts rd.type # end # def resource_descriptors token: nil, max: nil ensure_service! list_grpc = service.list_resource_descriptors token: token, max: max ResourceDescriptor::List.from_grpc list_grpc, service, max end alias find_resource_descriptors resource_descriptors ## # Creates a new monitored resource instance. # # @param [String] type The type of resource, as represented by a # {ResourceDescriptor}. # @param [Hash] labels A set of labels that can be used to describe # instances of this monitored resource type. # # @return [Google::Cloud::Logging::Resource] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # "module_id" => "1", # "version_id" => "20150925t173233" # def resource type, labels = {} Resource.new.tap do |r| r.type = type r.labels = labels end end alias new_resource resource ## # Retrieves the list of sinks belonging to the project. # # @param [String] token A previously-returned page token representing # part of the larger set of results to view. # @param [Integer] max Maximum number of sinks to return. # # @return [Array] (See # {Google::Cloud::Logging::Sink::List}) # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sinks = logging.sinks # sinks.each do |s| # puts "#{s.name}: #{s.filter} -> #{s.destination}" # end # # @example Retrieve all sinks: (See {Sink::List#all}) # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sinks = logging.sinks # # sinks.all do |s| # puts "#{s.name}: #{s.filter} -> #{s.destination}" # end # def sinks token: nil, max: nil ensure_service! list_grpc = service.list_sinks token: token, max: max Sink::List.from_grpc list_grpc, service, max end alias find_sinks sinks ## # Creates a new project sink. When you create a sink, only new log # entries that match the sink's filter are exported. Stackdriver Logging # does not send previously-ingested log entries to the sink's # destination. # # Before creating the sink, ensure that you have granted the sink's # _unique writer identity_ permission to write logs to the destination. # See [Destination # permissions](https://cloud.google.com/logging/docs/export/configure_export_v2#dest-auth). # # @see https://cloud.google.com/logging/docs/export # Overview of logs exports # @see https://cloud.google.com/logging/docs/reference/v2/rpc/google.logging.v2#configservicev2 # ConfigService API which includes sink methods # # @overload create_sink(name, destination, filter: nil, unique_writer_identity: nil) # @param [String] name The client-assigned sink identifier. Sink # identifiers are limited to 1000 characters and can include only # the following characters: `A-Z`, `a-z`, `0-9`, and the special # characters `_-.`. # @param [String] destination The resource name of the export # destination. See [About # sinks](https://cloud.google.com/logging/docs/api/tasks/exporting-logs#about_sinks) # for examples. # @param [String, nil] filter An [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced_filters) # that defines the log entries to be exported. The filter must be # 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 [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 # # @example # require "google/cloud/storage" # # storage = Google::Cloud::Storage.new # # bucket = storage.create_bucket "my-logs-bucket" # # # Grant owner permission to Stackdriver Logging service # email = "cloud-logs@google.com" # bucket.acl.add_owner "group-#{email}" # # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # sink = logging.create_sink "my-sink", # "storage.googleapis.com/#{bucket.id}" # def create_sink name, destination, filter: nil, unique_writer_identity: nil, start_at: nil, end_at: nil, version: nil ensure_service! if start_at warn "[DEPRECATION] start_at is deprecated and will be ignored." end if end_at warn "[DEPRECATION] end_at is deprecated and will be ignored." end if version warn "[DEPRECATION] version is deprecated and will be ignored." end grpc = service.create_sink \ name, destination, filter, unique_writer_identity: unique_writer_identity Sink.from_grpc grpc, service end alias new_sink create_sink ## # Retrieves a sink by name. # # @param [String] sink_name Name of a sink. # # @return [Google::Cloud::Logging::Sink, nil] Returns `nil` if the sink # does not exist. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sink = logging.sink "existing-sink" # # @example By default `nil` will be returned if the sink does not exist. # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # sink = logging.sink "non-existing-sink" # nil # def sink sink_name ensure_service! grpc = service.get_sink sink_name Sink.from_grpc grpc, service rescue Google::Cloud::NotFoundError nil end alias get_sink sink alias find_sink sink ## # Retrieves the list of metrics belonging to the project. # # @param [String] token A previously-returned page token representing # part of the larger set of results to view. # @param [Integer] max Maximum number of metrics to return. # # @return [Array] (See # {Google::Cloud::Logging::Metric::List}) # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metrics = logging.metrics # metrics.each do |m| # puts "#{m.name}: #{m.filter}" # end # # @example Retrieve all metrics: (See {Metric::List#all}) # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metrics = logging.metrics # # metrics.all do |m| # puts "#{m.name}: #{m.filter}" # end # def metrics token: nil, max: nil ensure_service! grpc = service.list_metrics token: token, max: max Metric::List.from_grpc grpc, service, max end alias find_metrics metrics ## # Creates a new logs-based metric for Google Cloud Monitoring. # # @see https://cloud.google.com/logging/docs/view/logs_based_metrics # Logs-based Metrics # @see https://cloud.google.com/monitoring/docs Google Cloud Monitoring # # @param [String] name The client-assigned metric identifier. Metric # identifiers are limited to 1000 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. # @param [String] filter An [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced_filters). # @param [String, nil] description A description of this metric, which # is used in documentation. # # @return [Google::Cloud::Logging::Metric] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.create_metric "errors", "severity>=ERROR" # def create_metric name, filter, description: nil ensure_service! grpc = service.create_metric name, filter, description Metric.from_grpc grpc, service end alias new_metric create_metric ## # Retrieves metric by name. # # @param [String] name Name of a metric. # # @return [Google::Cloud::Logging::Metric, nil] Returns `nil` if metric # does not exist. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.metric "existing_metric" # # @example By default `nil` will be returned if metric does not exist. # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.metric "non_existing_metric" # nil # def metric name ensure_service! grpc = service.get_metric name Metric.from_grpc grpc, service rescue Google::Cloud::NotFoundError nil end alias get_metric metric alias find_metric metric protected ## # @private Raise an error unless an active connection to the service is # available. def ensure_service! raise "Must have active connection to service" unless service end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/entry.rb0000644000004100000410000004121015170601174024020 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/logging/convert" require "google/cloud/logging/resource" require "google/cloud/logging/entry/http_request" require "google/cloud/logging/entry/operation" require "google/cloud/logging/entry/source_location" require "google/cloud/logging/entry/list" module Google module Cloud module Logging ## # # Entry # # An individual entry in a log. # # Each log entry is composed of metadata and a payload. The metadata # includes standard information used by Stackdriver Logging, such as when # the entry was created and where it came from. The payload is the event # record. Traditionally this is a message string, but in Stackdriver # Logging it can also be a JSON or protocol buffer object. A single log # can have entries with different payload types. # # A log is a named collection of entries. Logs can be produced by Google # Cloud Platform services, by third-party services, or by your # applications. For example, the log `compute.googleapis.com/activity_log` # is produced by Google Compute Engine. Logs are simply referenced by name # in google-cloud. There is no `Log` type in google-cloud or `Log` # resource in the Stackdriver Logging API. # # @see https://cloud.google.com/logging/docs/view/logs_index List of Log # Types # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry payload: "Job started.", log_name: "my_app_log" # entry.resource.type = "gae_app" # entry.resource.labels[:module_id] = "1" # entry.resource.labels[:version_id] = "20150925t173233" # # logging.write_entries entry # # @example Provide a hash to write a JSON payload to the log: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # payload = { "stats" => { "a" => 8, "b" => 12.5} } # entry = logging.entry payload: payload, log_name: "my_app_log" # entry.resource.type = "gae_app" # entry.resource.labels[:module_id] = "1" # entry.resource.labels[:version_id] = "20150925t173233" # # logging.write_entries entry # class Entry ## # Generate a pseudo-random, 16-character ID suitable for use as the log # entry's {#insert_id}. # # @return [String] # # @example # require "google/cloud/logging" # # insert_id = Google::Cloud::Logging::Entry.insert_id # def self.insert_id rand(36**16).to_s 36 end ## # Create a new Entry instance. The {#resource} attribute is # pre-populated with a new {Google::Cloud::Logging::Resource} instance. # See also {Google::Cloud::Logging::Project#entry}. def initialize @labels = {} @resource = Resource.new @http_request = HttpRequest.new @operation = Operation.new @severity = :DEFAULT @source_location = SourceLocation.new @insert_id = Entry.insert_id end ## # The resource name of the log to which this log entry belongs. The # format of the name is `projects//logs/`. e.g. # `projects/my-projectid/logs/my_app_log` and # `projects/1234567890/logs/library.googleapis.com%2Fbook_log` # # 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. attr_accessor :log_name ## # The monitored resource associated with this log entry. Example: a log # entry that reports a database error would be associated with the # monitored resource designating the particular database that reported # the error. # @return [Google::Cloud::Logging::Resource] attr_accessor :resource ## # The time the event described by the log entry occurred. If omitted, # Stackdriver Logging will use the time the log entry is written. # @return [Time] attr_accessor :timestamp ## # The severity level of the log entry. The default value is `:DEFAULT`. # @return [Symbol] attr_accessor :severity ## # Returns `true` if the severity level is `:DEFAULT`. def default? severity == :DEFAULT end ## # Sets the severity level to `:DEFAULT`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity = :DEBUG # entry.default! # entry.default? #=> true # entry.severity #=> :DEFAULT # def default! self.severity = :DEFAULT end ## # Returns `true` if the severity level is `:DEBUG`. def debug? severity == :DEBUG end ## # Sets the severity level to `:DEBUG`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.debug! # entry.debug? #=> true # entry.severity #=> :DEBUG # def debug! self.severity = :DEBUG end ## # Returns `true` if the severity level is `:INFO`. def info? severity == :INFO end ## # Sets the severity level to `:INFO`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.info! # entry.info? #=> true # entry.severity #=> :INFO # def info! self.severity = :INFO end ## # Returns `true` if the severity level is `:NOTICE`. def notice? severity == :NOTICE end ## # Sets the severity level to `:NOTICE`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.notice! # entry.notice? #=> true # entry.severity #=> :NOTICE # def notice! self.severity = :NOTICE end ## # Returns `true` if the severity level is `:WARNING`. def warning? severity == :WARNING end ## # Sets the severity level to `:WARNING`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.warning! # entry.warning? #=> true # entry.severity #=> :WARNING # def warning! self.severity = :WARNING end ## # Returns `true` if the severity level is `:ERROR`. def error? severity == :ERROR end ## # Sets the severity level to `:ERROR`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.error! # entry.error? #=> true # entry.severity #=> :ERROR # def error! self.severity = :ERROR end ## # Returns `true` if the severity level is `:CRITICAL`. def critical? severity == :CRITICAL end ## # Sets the severity level to `:CRITICAL`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.critical! # entry.critical? #=> true # entry.severity #=> :CRITICAL # def critical! self.severity = :CRITICAL end ## # Returns `true` if the severity level is `:ALERT`. def alert? severity == :ALERT end ## # Sets the severity level to `:ALERT`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.alert! # entry.alert? #=> true # entry.severity #=> :ALERT # def alert! self.severity = :ALERT end ## # Returns `true` if the severity level is `:EMERGENCY`. def emergency? severity == :EMERGENCY end ## # Sets the severity level to `:EMERGENCY`. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entry = logging.entry # entry.severity #=> :DEFAULT # entry.emergency! # entry.emergency? #=> true # entry.severity #=> :EMERGENCY # def emergency! self.severity = :EMERGENCY end ## # A unique ID for the log entry. If you provide this field, the logging # service considers other log entries in the same log with the same ID # as duplicates which can be removed. If omitted, Stackdriver Logging # will generate a unique ID for this log entry. # @return [String] attr_accessor :insert_id ## # A set of user-defined data that provides additional information about # the log entry. # @return [Hash] attr_accessor :labels ## # The log entry payload, represented as either a string, a hash (JSON), # or a hash (protocol buffer). # @return [String, Hash] attr_accessor :payload ## # Information about the HTTP request associated with this log entry, if # applicable. # @return [Google::Cloud::Logging::Entry::HttpRequest] attr_reader :http_request ## # Information about an operation associated with the log entry, if # applicable. # @return [Google::Cloud::Logging::Entry::Operation] attr_reader :operation ## # Resource name of the trace associated with the log entry, if any. If # it contains a relative resource name, the name is assumed to be # relative to `//tracing.googleapis.com`. Example: # `projects/my-projectid/traces/06796866738c859f2f19b7cfb3214824` # Optional. # @return [String] attr_accessor :trace ## # Source code location information associated with the log entry, if # any. # @return [Google::Cloud::Logging::Entry::SourceLocation] attr_reader :source_location ## # The sampling decision of the trace associated with the log entry. # Optional. A `true` value means that the trace resource name in the # `trace` field was sampled for storage in a trace backend. A `false` # means that the trace was not sampled for storage when this log entry # was written, or the sampling decision was unknown at the time. A # non-sampled `trace` value is still useful as a request correlation # identifier. The default is `false`. # @return [Boolean] attr_accessor :trace_sampled ## # @private Determines if the Entry has any data. def empty? log_name.nil? && timestamp.nil? && (labels.nil? || labels.empty?) && payload.nil? && resource.empty? && http_request.empty? && operation.empty? && trace.nil? && source_location.empty? && trace_sampled.nil? end ## # @private Exports the Entry to a Google::Cloud::Logging::V2::LogEntry object. def to_grpc grpc = Google::Cloud::Logging::V2::LogEntry.new( log_name: log_name.to_s, timestamp: timestamp_grpc, # TODO: verify severity is the correct type? severity: severity, insert_id: insert_id.to_s, labels: labels_grpc, resource: resource.to_grpc, http_request: http_request.to_grpc, operation: operation.to_grpc, trace: trace.to_s, source_location: source_location.to_grpc, trace_sampled: !(!trace_sampled) ) # Add payload append_payload grpc grpc end ## # @private New Entry from a Google::Cloud::Logging::V2::LogEntry object. def self.from_grpc grpc return new if grpc.nil? new.tap do |e| e.log_name = grpc.log_name e.timestamp = extract_timestamp grpc e.severity = grpc.severity e.insert_id = grpc.insert_id e.labels = Convert.map_to_hash grpc.labels e.payload = extract_payload grpc e.instance_variable_set :@resource, Resource.from_grpc(grpc.resource) e.instance_variable_set :@http_request, HttpRequest.from_grpc(grpc.http_request) e.instance_variable_set :@operation, Operation.from_grpc(grpc.operation) e.trace = grpc.trace e.instance_variable_set :@source_location, SourceLocation.from_grpc( grpc.source_location ) e.trace_sampled = grpc.trace_sampled end end ## # @private Formats the timestamp as a Google::Protobuf::Timestamp # object. def timestamp_grpc return nil if timestamp.nil? # TODO: ArgumentError if timestamp is not a Time object? Google::Protobuf::Timestamp.new( seconds: timestamp.to_i, nanos: timestamp.nsec ) end ## # @private Formats the labels so they can be saved to a # Google::Cloud::Logging::V2::LogEntry object. def labels_grpc return {} if labels.nil? # Coerce symbols to strings labels.to_h do |k, v| v = String(v) if v.is_a? Symbol [String(k), v] end end ## # @private Adds the payload data to a Google::Cloud::Logging::V2::LogEntry # object. def append_payload grpc grpc.proto_payload = nil grpc.json_payload = nil grpc.text_payload = nil if payload.is_a? Google::Protobuf::Any grpc.proto_payload = payload elsif payload.respond_to? :to_hash grpc.json_payload = Convert.hash_to_struct payload.to_hash else grpc.text_payload = payload.to_s end end ## # @private Extract payload data from Google API Client object. def self.extract_payload grpc grpc.proto_payload || grpc.json_payload || grpc.text_payload end ## # @private Get a Time object from a Google::Protobuf::Timestamp object. def self.extract_timestamp grpc return nil if grpc.timestamp.nil? Time.at grpc.timestamp.seconds, Rational(grpc.timestamp.nanos, 1000) end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/convert.rb0000644000004100000410000000464215170601174024347 0ustar www-datawww-data# Copyright 2017 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Google module Cloud module Logging ## # @private Conversion to/from Logging GRPC objects. module Convert ## # @private Convert a Hash to a Google::Protobuf::Struct. def self.hash_to_struct hash # TODO: ArgumentError if hash is not a Hash Google::Protobuf::Struct.new \ fields: hash.to_h { |k, v| [String(k), object_to_value(v)] } end ## # @private Convert an Array to a Google::Protobuf::ListValue. def self.array_to_list array # TODO: ArgumentError if array is not an Array Google::Protobuf::ListValue.new \ values: array.map { |o| object_to_value o } end ## # @private Convert an Object to a Google::Protobuf::Value. def self.object_to_value obj case obj when NilClass Google::Protobuf::Value.new null_value: :NULL_VALUE when Numeric Google::Protobuf::Value.new number_value: obj when String Google::Protobuf::Value.new string_value: obj when TrueClass Google::Protobuf::Value.new bool_value: true when FalseClass Google::Protobuf::Value.new bool_value: false when Hash Google::Protobuf::Value.new struct_value: hash_to_struct(obj) when Array Google::Protobuf::Value.new list_value: array_to_list(obj) else # TODO: Could raise ArgumentError here, or convert to a string Google::Protobuf::Value.new string_value: obj.to_s end end ## # @private Convert a Google::Protobuf::Map to a Hash def self.map_to_hash map if map.respond_to? :to_h map.to_h else map.to_a.to_h end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/metric/0000755000004100000410000000000015170601174023617 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging/metric/list.rb0000644000004100000410000001302115170601174025114 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "delegate" module Google module Cloud module Logging class Metric ## # Metric::List is a special case Array with additional values. class List < DelegateClass(::Array) ## # If not empty, indicates that there are more records that match # the request and this value should be passed to continue. attr_accessor :token ## # @private Create a new Metric::List with an array of Metric # instances. def initialize arr = [] super arr end ## # Whether there is a next page of metrics. # # @return [Boolean] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # metrics = logging.metrics # if metrics.next? # next_metrics = metrics.next # end # def next? !token.nil? end ## # Retrieve the next page of metrics. # # @return [Sink::List] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # metrics = logging.metrics # if metrics.next? # next_metrics = metrics.next # end # def next return nil unless next? ensure_service! grpc = @service.list_metrics token: token, max: @max self.class.from_grpc grpc, @service, @max end ## # Retrieves remaining results by repeatedly invoking {#next} until # {#next?} returns `false`. Calls the given block once for each # result, which is passed as the argument to the block. # # An Enumerator is returned if no block is given. # # This method will make repeated API calls until all remaining results # are retrieved. (Unlike `#each`, for example, which merely iterates # over the results returned by a single API call.) Use with caution. # # @param [Integer] request_limit The upper limit of API requests to # make to load all metrics. Default is no limit. # @yield [metric] The block for accessing each metric. # @yieldparam [Metric] metric The metric object. # # @return [Enumerator] # # @example Iterating each metric by passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metrics = logging.metrics # # metrics.all do |metric| # puts "#{metric.name}: #{metric.filter}" # end # # @example Using the enumerator by not passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metrics = logging.metrics # # all_names = metrics.all.map do |metric| # metric.name # end # # @example Limit the number of API calls made: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metrics = logging.metrics # # metrics.all(request_limit: 10) do |metric| # puts "#{metric.name}: #{metric.filter}" # end # def all request_limit: nil, &block request_limit = request_limit.to_i if request_limit unless block_given? return enum_for :all, request_limit: request_limit end results = self loop do results.each(&block) if request_limit request_limit -= 1 break if request_limit.negative? end break unless results.next? results = results.next end end ## # @private New Metric::List from a # Google::Cloud::Logging::V2::ListLogMetricsResponse object. def self.from_grpc grpc_list, service, max = nil metrics = new(Array(grpc_list.metrics).map do |grpc_metric| Metric.from_grpc grpc_metric, service end) token = grpc_list.next_page_token token = nil if token == "".freeze metrics.instance_variable_set :@token, token metrics.instance_variable_set :@service, service metrics.instance_variable_set :@max, max metrics end protected ## # @private Raise an error unless an active connection to the service # is available. def ensure_service! raise "Must have active connection to service" unless @service end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/rails.rb0000644000004100000410000002367115170601174024004 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/logging" module Google module Cloud module Logging ## # Default log name to be used for Stackdriver Logging DEFAULT_LOG_NAME = Middleware::DEFAULT_LOG_NAME ## # Railtie # # Adds the {Google::Cloud::Logging::Middleware} to Rack in a Rails # environment. The middleware will set `env['rack.logger']` to a # {Google::Cloud::Logging::Logger} instance to be used by the Rails # application. # # The middleware is loaded only when certain conditions are met. These # conditions are when the configuration # `Google::Cloud.configure.use_logging` (also available as # `Rails.application.config.google_cloud.use_logging` for a Rails # application) is set to `true`, or, if the configuration is left unset # but `Rails.env.production?` is `true`. # # When loaded, the {Google::Cloud::Logging::Middleware} will be inserted # before the `Rails::Rack::Logger Middleware`, which allows it to set the # `env['rack.logger']` in place of Rails's default logger. # See the [Configuration # Guide](https://googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html) # on how to configure the Railtie and Middleware. # class Railtie < ::Rails::Railtie config.google_cloud = ::ActiveSupport::OrderedOptions.new unless config.respond_to? :google_cloud config.google_cloud.logging = ::ActiveSupport::OrderedOptions.new config.google_cloud.logging.monitored_resource = ::ActiveSupport::OrderedOptions.new config.google_cloud.logging.monitored_resource.labels = ::ActiveSupport::OrderedOptions.new initializer "Stackdriver.Logging", before: :initialize_logger do |app| self.class.consolidate_rails_config app.config self.class.init_middleware app if Cloud.configure.use_logging end ## # @private Init Logging integration for Rails. Setup configuration and # insert the Middleware. def self.init_middleware app project_id = Logging.configure.project_id credentials = Logging.configure.credentials resource_type = Logging.configure.monitored_resource.type resource_labels = Logging.configure.monitored_resource.labels log_name = Logging.configure.log_name labels = Logging.configure.labels logging = Google::Cloud::Logging.new project_id: project_id, credentials: credentials resource = Logging::Middleware.build_monitored_resource resource_type, resource_labels Middleware.logger = logging.logger log_name, resource, labels # Set the default Rails logger if Logging.configure.set_default_logger_on_rails_init set_default_logger end init_callback = -> { set_default_logger } app.middleware.insert_before Rails::Rack::Logger, Google::Cloud::Logging::Middleware, logger: Middleware.logger, on_init: init_callback end ## # This should be called once the application determines that it is safe # to start background threads and open gRPC connections. It informs the # middleware system that it is safe to use Google Cloud Logging. This is # called during Rails initialization when the # `set_default_logger_on_rails_init` configuration is set. # # Generally, this matters if the application forks worker processes; # this method should be called only after workers are forked, since # threads and network connections interact badly with fork. For example, # when running Puma in [clustered # mode](https://github.com/puma/puma#clustered-mode), this method should # be called in an `on_worker_boot` block. # # If the application does no forking, this method can be called any time # early in the application initialization process. Or by setting the # `set_default_logger_on_rails_init` configuration. # # If the `set_default_logger_on_rails_init` configuration is not set, # and {Railtie.set_default_logger} is not called in a post-fork hook, # the default Rails logger object will not be set to use the Google # Cloud Logging Logger object. For best results, an application should # call this method at the appropriate time, such as a post-fork hook. # def self.set_default_logger return if Middleware.logger.nil? return if Rails.logger.is_a? Google::Cloud::Logging::Logger # configure the Middleware logger to use the same settings as Rails Middleware.logger.level = Rails.logger.level # TODO: are there more settings to be set here? # Replace the Rails default logger Rails.application.config.logger = Middleware.logger Rails.logger = Middleware.logger end ## # @private Consolidate Rails configuration into Logging instrumentation # configuration. Also consolidate the `use_logging` setting by verifying # credentials and Rails environment. The `use_logging` setting will be # true if credentials are valid, and the setting is manually set to true # or Rails is in production environment. # # @param [Rails::Railtie::Configuration] config The # Rails.application.config # def self.consolidate_rails_config config merge_rails_config config init_default_config # Done if Google::Cloud.configure.use_logging is explicitly false return if Google::Cloud.configure.use_logging == false # Verify credentials and set use_logging to false if # credentials are invalid unless valid_credentials? Logging.configure.project_id, Logging.configure.keyfile Cloud.configure.use_logging = false return end # Otherwise set use_logging to true if Rails is running in production Google::Cloud.configure.use_logging ||= Rails.env.production? end ## # @private Merge Rails configuration into Logging instrumentation # configuration. def self.merge_rails_config rails_config gcp_config = rails_config.google_cloud log_config = gcp_config.logging if Cloud.configure.use_logging.nil? Cloud.configure.use_logging = gcp_config.use_logging end Logging.configure do |config| config.project_id ||= config.project config.project_id ||= log_config.project_id || log_config.project config.project_id ||= gcp_config.project_id || gcp_config.project config.credentials ||= config.keyfile config.credentials ||= log_config.credentials || log_config.keyfile config.credentials ||= gcp_config.credentials || gcp_config.keyfile config.log_name ||= log_config.log_name config.labels ||= log_config.labels config.log_name_map ||= log_config.log_name_map config.monitored_resource.type ||= log_config.monitored_resource.type config.monitored_resource.labels ||= log_config.monitored_resource.labels.to_h if config.set_default_logger_on_rails_init.nil? config.set_default_logger_on_rails_init = log_config.set_default_logger_on_rails_init end end end ## # Fallback to default config values if config parameters not provided. def self.init_default_config Logging.configure.project_id ||= Logging.default_project_id Logging.configure.log_name ||= Middleware::DEFAULT_LOG_NAME end ## # @private Verify credentials def self.valid_credentials? project_id, credentials # Try authenticate authorize client API. Return false if unable to # authorize. begin # if credentials is nil, get default credentials ||= Logging::Credentials.default # only create a new Credentials object if the val isn't one already unless credentials.is_a? Google::Auth::Credentials # if credentials is not a Credentials object, create one Logging::Credentials.new credentials end rescue Exception => e # rubocop:disable Lint/RescueException $stdout.puts "Note: Google::Cloud::Logging is disabled because " \ "it failed to authorize with the service. (#{e.message}) " \ "Falling back to the default Rails logger." return false end if project_id.to_s.empty? $stdout.puts "Note: Google::Cloud::Logging is disabled because " \ "the project ID could not be determined. " \ "Falling back to the default Rails logger." return false end true end private_class_method :merge_rails_config, :init_default_config, :valid_credentials? end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/version.rb0000644000004100000410000000124215170601174024345 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Google module Cloud module Logging VERSION = "2.7.0".freeze end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/entry/0000755000004100000410000000000015170601174023475 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging/entry/operation.rb0000644000004100000410000000544215170601174026027 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Google module Cloud module Logging class Entry ## # # Operation # # Additional information about a potentially long-running operation with # which a log entry is associated. # # See also {Google::Cloud::Logging::Entry#operation}. # class Operation ## # @private Create an empty Operation object. def initialize end ## # An arbitrary operation identifier. Log entries with the same # identifier are assumed to be part of the same operation. attr_accessor :id ## # An arbitrary producer identifier. The combination of `id` and # `producer` must be globally unique. Examples for `producer`: # `"MyDivision.MyBigCompany.com"`, # `"github.com/MyProject/MyApplication"`. attr_accessor :producer ## # Set this to `true` if this is the first log entry in the operation. attr_accessor :first ## # Set this to `true` if this is the last log entry in the operation. attr_accessor :last ## # @private Determines if the Operation has any data. def empty? id.nil? && producer.nil? && first.nil? && last.nil? end ## # @private Exports the Operation to a # Google::Cloud::Logging::V2::LogEntryOperation object. def to_grpc return nil if empty? Google::Cloud::Logging::V2::LogEntryOperation.new( id: id.to_s, producer: producer.to_s, first: !(!first), last: !(!last) ) end ## # @private New Google::Cloud::Logging::Entry::Operation from a # Google::Cloud::Logging::V2::LogEntryOperation object. def self.from_grpc grpc return new if grpc.nil? new.tap do |o| o.id = grpc.id o.producer = grpc.producer o.first = grpc.first o.last = grpc.last end end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/entry/list.rb0000644000004100000410000001441315170601174025000 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "delegate" module Google module Cloud module Logging class Entry ## # Entry::List is a special case Array with additional values. class List < DelegateClass(::Array) ## # If not empty, indicates that there are more records that match # the request and this value should be passed to continue. attr_accessor :token ## # @private Create a new Entry::List with an array of Entry instances. def initialize arr = [] super arr end ## # Whether there is a next page of entries. # # @return [Boolean] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entries = logging.entries # if entries.next? # next_entries = entries.next # end # def next? !token.nil? end ## # Retrieve the next page of entries. # # @return [Sink::List] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # entries = logging.entries # if entries.next? # next_entries = entries.next # end # def next return nil unless next? ensure_service! grpc = @service.list_entries token: token, resources: @resources, filter: @filter, order: @order, max: @max, projects: @projects self.class.from_grpc grpc, @service, resources: @resources, filter: @filter, order: @order, max: @max, projects: @projects end ## # Retrieves remaining results by repeatedly invoking {#next} until # {#next?} returns `false`. Calls the given block once for each # result, which is passed as the argument to the block. # # An Enumerator is returned if no block is given. # # This method will make repeated API calls until all remaining results # are retrieved. (Unlike `#each`, for example, which merely iterates # over the results returned by a single API call.) Use with caution. # # @param [Integer] request_limit The upper limit of API requests to # make to load all log entries. Default is no limit. # @yield [entry] The block for accessing each log entry. # @yieldparam [Entry] entry The log entry object. # # @return [Enumerator] # # @example Iterating each log entry by passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries order: "timestamp desc" # # entries.all do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # # @example Using the enumerator by not passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries order: "timestamp desc" # # all_payloads = entries.all.map do |entry| # entry.payload # end # # @example Limit the number of API calls made: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # entries = logging.entries order: "timestamp desc" # # entries.all(request_limit: 10) do |e| # puts "[#{e.timestamp}] #{e.log_name} #{e.payload.inspect}" # end # def all request_limit: nil, &block request_limit = request_limit.to_i if request_limit unless block_given? return enum_for :all, request_limit: request_limit end results = self loop do results.each(&block) if request_limit request_limit -= 1 break if request_limit.negative? end break unless results.next? results = results.next end end ## # @private New Entry::List from a # Google::Cloud::Logging::V2::ListLogEntryResponse object. def self.from_grpc grpc_list, service, resources: nil, filter: nil, order: nil, max: nil, projects: nil entries = new(Array(grpc_list.entries).map do |grpc_entry| Entry.from_grpc grpc_entry end) token = grpc_list.next_page_token token = nil if token == "".freeze entries.instance_variable_set :@token, token entries.instance_variable_set :@service, service entries.instance_variable_set :@projects, projects entries.instance_variable_set :@resources, resources entries.instance_variable_set :@filter, filter entries.instance_variable_set :@order, order entries.instance_variable_set :@max, max entries end protected ## # @private Raise an error unless an active connection to the service # is available. def ensure_service! raise "Must have active connection to service" unless @service end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/entry/source_location.rb0000644000004100000410000000527415170601174027222 0ustar www-datawww-data# Copyright 2017 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Google module Cloud module Logging class Entry ## # # SourceLocation # # Additional information about the source code location that produced # the log entry. # # See also {Google::Cloud::Logging::Entry#source_location}. # class SourceLocation ## # @private Create an empty SourceLocation object. def initialize end ## # Source file name. Depending on the runtime environment, this might # be a simple name or a fully-qualified name. Optional. attr_accessor :file ## # Line within the source file. 1-based; `0` indicates no line number # available. Optional. attr_accessor :line ## # Human-readable name of the function or method being invoked, with # optional context such as the class or package name. This information # may be used in contexts such as the logs viewer, where a file and # line number are less meaningful. Optional. attr_accessor :function ## # @private Determines if the SourceLocation has any data. def empty? file.nil? && line.nil? && function.nil? end ## # @private Exports the SourceLocation to a # Google::Cloud::Logging::V2::LogEntrySourceLocation object. def to_grpc return nil if empty? Google::Cloud::Logging::V2::LogEntrySourceLocation.new( file: file.to_s, line: line, function: function.to_s ) end ## # @private New Google::Cloud::Logging::Entry::SourceLocation from a # Google::Cloud::Logging::V2::LogEntrySourceLocation object. def self.from_grpc grpc return new if grpc.nil? new.tap do |o| o.file = grpc.file o.line = grpc.line o.function = grpc.function end end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/entry/http_request.rb0000644000004100000410000001334015170601174026552 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Google module Cloud module Logging class Entry ## # # Http Request # # HTTP request data associated with a log entry. # # See also {Google::Cloud::Logging::Entry#http_request}. # class HttpRequest ## # @private Create an empty HttpRequest object. def initialize end ## # The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. # (String) attr_accessor :request_method ## # @overload method() # Deprecated. Use {#request_method} instead. # # The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, # `"POST"`. (String) def method *args # Call Object#method when args are present. return super unless args.empty? request_method end ## # @overload method() # Deprecated. Use {#request_method=} instead. # # The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, # `"POST"`. (String) def method= new_request_method self.request_method = new_request_method end ## # The URL. The scheme (http, https), the host name, the path and the # query portion of the URL that was requested. Example: # `"http://example.com/some/info?color=red"`. (String) attr_accessor :url ## # The size of the HTTP request message in bytes, including the request # headers and the request body. (Integer) attr_accessor :size ## # The response code indicating the status of response. Examples: # `200`, `404`. (Integer) attr_accessor :status ## # The size of the HTTP response message sent back to the client, in # bytes, including the response headers and the response body. # (Integer) attr_accessor :response_size ## # The user agent sent by the client. Example: `"Mozilla/4.0 # (compatible; MSIE 6.0; Windows 98; Q312461; .NET CLR 1.0.3705)"`. # (String) attr_accessor :user_agent ## # The IP address (IPv4 or IPv6) of the client that issued the HTTP # request. Examples: `"192.168.1.1"`, `"FE80::0202:B3FF:FE1E:8329"`. # (String) attr_accessor :remote_ip ## # The referer URL of the request, as defined in [HTTP/1.1 Header Field # Definitions](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). # (String) attr_accessor :referer ## # Whether an entity was served from cache (with or without # validation). (Boolean) attr_accessor :cache_hit ## # Whether the response was validated with the origin server before # being served from cache. This field is only meaningful if # `cache_hit` is `true`. (Boolean) attr_accessor :validated ## # @private Determines if the HttpRequest has any data. def empty? method.nil? && url.nil? && size.nil? && status.nil? && response_size.nil? && user_agent.nil? && remote_ip.nil? && referer.nil? && cache_hit.nil? && validated.nil? end ## # @private Exports the HttpRequest to a # Google::Cloud::Logging::Type::HttpRequest object. def to_grpc return nil if empty? Google::Cloud::Logging::Type::HttpRequest.new( request_method: request_method.to_s, request_url: url.to_s, request_size: size.to_i, status: status.to_i, response_size: response_size.to_i, user_agent: user_agent.to_s, remote_ip: remote_ip.to_s, referer: referer.to_s, cache_hit: !(!cache_hit), cache_validated_with_origin_server: !(!validated) ) end ## # @private New HttpRequest from a Google::Cloud::Logging::Type::HttpRequest # object. def self.from_grpc grpc return new if grpc.nil? new.tap do |h| h.request_method = grpc.request_method h.url = grpc.request_url h.size = grpc.request_size h.status = grpc.status h.response_size = grpc.response_size h.user_agent = grpc.user_agent h.remote_ip = grpc.remote_ip h.referer = grpc.referer h.cache_hit = grpc.cache_hit h.validated = grpc.cache_validated_with_origin_server end end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/middleware.rb0000644000004100000410000002662515170601174025011 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "stackdriver/core" module Google module Cloud module Logging class Middleware ## # The default log name used to instantiate the default logger if one # isn't provided. DEFAULT_LOG_NAME = "ruby_app_log".freeze ## # A default value for the log_name_map argument. Directs health check # logs to a separate log name so they don't spam the main log. DEFAULT_LOG_NAME_MAP = { "/_ah/health" => "ruby_health_check_log", "/healthz" => "ruby_health_check_log" }.freeze ## # The Google::Cloud::Logging::Logger instance attr_reader :logger ## # Create a new AppEngine logging Middleware. # # @param [Rack Application] app Rack application # @param [Google::Cloud::Logging::Logger] logger A logger to be used by # this middleware. The middleware will be interacting with the logger # to track Stackdriver request trace ID. It also properly sets # env["rack.logger"] to this assigned logger for accessing. If not # specified, a default logger with be used. # @param [Proc] on_init A callback to be invoked when the middleware is # initialized. The callback takes no arguments. Optional. # @param [Hash] kwargs Hash of configuration settings. Used for # backward API compatibility. See the [Configuration # Guide](https://googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html) # for the prefered way to set configuration parameters. # # @return [Google::Cloud::Logging::Middleware] A new # Google::Cloud::Logging::Middleware instance # def initialize app, logger: nil, on_init: nil, **kwargs @app = app load_config(**kwargs) logger ||= Middleware.logger logger ||= begin log_name = configuration.log_name logging = Logging.new project_id: configuration.project_id, credentials: configuration.credentials resource = Middleware.build_monitored_resource( configuration.monitored_resource.type, configuration.monitored_resource.labels ) Middleware.logger = logging.logger log_name, resource end on_init&.call @logger = logger end ## # Rack middleware entry point. In most Rack based frameworks, a request # is served by one thread. So entry point, we associate the GCP request # trace_id with the current thread's object_id in logger. All the logs # written by logger beyond this point will carry this request's # trace_id. Untrack the trace_id with this thread upon exiting. # # @param [Hash] env Rack environment hash # # @return [Rack::Response] The response from downstream Rack app # def call env env["rack.logger"] = logger trace_id = get_trace_id env log_name = get_log_name env logger.add_request_info trace_id: trace_id, log_name: log_name, env: env begin @app.call env ensure logger.delete_request_info end end ## # Determine the trace ID for this request. # # @private # @param [Hash] env The Rack environment. # @return [String] The trace ID. # def get_trace_id env trace_context = Stackdriver::Core::TraceContext.parse_rack_env env trace_context.trace_id end ## # Determine the log name override for this request, if any. # # @private # @param [Hash] env The Rack environment. # @return [String, nil] The log name override, or `nil` if there is # no override. # def get_log_name env log_name_map = configuration.log_name_map return nil unless log_name_map path = "#{env['SCRIPT_NAME']}#{env['PATH_INFO']}" path = "/#{path}" unless path.start_with? "/" log_name_map.each do |k, v| return v if k === path end nil end ## # Construct a monitored resource based on the given type and label if # both are provided. Otherwise, construct a default monitored resource # based on the current environment. # # @param [String] type Type of Google::Cloud::Logging::Resource # @param [Hash] labels Metadata lebels of # Google::Cloud::Logging::Resource # # @return [Google::Cloud::Logging::Resource] An Resource object with # type and labels # # @see https://cloud.google.com/logging/docs/api/v2/resource-list # Monitored Resources and Services # # @example If both type and labels are provided, it returns resource: # rc = Google::Cloud::Logging::Middleware.build_monitored_resource( # "aws_ec2_instance", # { # instance_id: "ec2-id", # aws_account: "aws-id" # } # ) # rc.type #=> "aws_ec2_instance" # rc.labels #=> { instance_id: "ec2-id", aws_account: "aws-id" } # # @example If running from GAE, returns default resource: # rc = Google::Cloud::Logging::Middleware.build_monitored_resource # rc.type #=> "gae_app" # rc.labels # { module_id: [GAE module name], # # version_id: [GAE module version] } # # @example If running from GKE, returns default resource: # rc = Google::Cloud::Logging::Middleware.build_monitored_resource # rc.type #=> "container" # rc.labels # { cluster_name: [GKE cluster name], # # namespace_id: [GKE namespace_id] } # # @example If running from GCE, return default resource: # rc = Google::Cloud::Logging::Middleware.build_monitored_resource # rc.type #=> "gce_instance" # rc.labels # { instance_id: [GCE VM instance id], # # zone: [GCE vm group zone] } # # @example Otherwise default to generic "global" type: # rc = Google::Cloud::Logging::Middleware.build_monitored_resource # rc.type #=> "global" # rc.labels #=> {} # def self.build_monitored_resource type = nil, labels = nil if type && labels Google::Cloud::Logging::Resource.new.tap do |r| r.type = type r.labels = labels end else default_monitored_resource end end class << self ## # @private Global logger object attr_accessor :logger end ## # @private Extract information from current environment and construct # the correct monitoring resource types and labels. # # @return [Google::Cloud::Logging::Resource] An Resource object with # correct type and labels # # @see https://cloud.google.com/logging/docs/api/v2/resource-list # Monitored Resources and Services # # @example If running from GAE, returns default resource: # rc = Google::Cloud::Logging::Middleware.send \ # :default_monitored_resource # rc.type #=> "gae_app" # rc.labels # { module_id: [GAE module name], # # version_id: [GAE module version] } # # @example If running from GKE, returns default resource: # rc = Google::Cloud::Logging::Middleware.send \ # :default_monitored_resource # rc.type #=> "container" # rc.labels # { cluster_name: [GKE cluster name], # # namespace_id: [GKE namespace_id] } # # @example If running from GCE, return default resource: # rc = Google::Cloud::Logging::Middleware.send \ # :default_monitored_resource # rc.type #=> "gce_instance" # rc.labels # { instance_id: [GCE VM instance id], # # zone: [GCE vm group zone] } # # @example Otherwise default to generic "global" type: # rc = Google::Cloud::Logging::Middleware.send \ # :default_monitored_resource # rc.type #=> "global" # rc.labels #=> {} # def self.default_monitored_resource type, labels = if Google::Cloud.env.app_engine? ["gae_app", { module_id: Google::Cloud.env.app_engine_service_id, version_id: Google::Cloud.env.app_engine_service_version }] elsif Google::Cloud.env.container_engine? namespace_id = Google::Cloud.env.container_engine_namespace_id namespace_id ||= "default" ["container", { cluster_name: Google::Cloud.env.container_engine_cluster_name, namespace_id: namespace_id }] elsif Google::Cloud.env.compute_engine? ["gce_instance", { instance_id: Google::Cloud.env.instance_name, zone: Google::Cloud.env.instance_zone }] else ["global", {}] end Google::Cloud::Logging::Resource.new.tap do |r| r.type = type r.labels = labels end end private_class_method :default_monitored_resource private ## # Consolidate configurations from various sources. Also set # instrumentation config parameters to default values if not set # already. # def load_config **kwargs project_id = kwargs[:project] || kwargs[:project_id] configuration.project_id = project_id unless project_id.nil? creds = kwargs[:credentials] || kwargs[:keyfile] configuration.credentials = creds unless creds.nil? log_name_map = kwargs[:log_name_map] configuration.log_name_map = log_name_map unless log_name_map.nil? init_default_config end ## # Fallback to default configuration values if not defined already def init_default_config configuration.project_id ||= Cloud.configure.project_id || Logging.default_project_id configuration.credentials ||= Cloud.configure.credentials configuration.log_name ||= DEFAULT_LOG_NAME configuration.log_name_map ||= DEFAULT_LOG_NAME_MAP end ## # @private Get Google::Cloud::Logging.configure def configuration Google::Cloud::Logging.configure end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/credentials.rb0000644000004100000410000000246415170601174025164 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/logging/v2/logging_service/credentials" module Google module Cloud module Logging ## # # Credentials # # Represents the authentication and authorization used to connect to the # Stackdriver Logging API. # # @example # require "google/cloud/logging" # # keyfile = "/path/to/keyfile.json" # creds = Google::Cloud::Logging::Credentials.new keyfile # # logging = Google::Cloud::Logging.new( # project_id: "my-project", # credentials: creds # ) # # logging.project_id #=> "my-project" # class Credentials < Google::Cloud::Logging::V2::LoggingService::Credentials end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/errors.rb0000644000004100000410000000655415170601174024207 0ustar www-datawww-data# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/errors" module Google module Cloud module Logging ## # # AsyncWriterError # # Used to indicate a problem preventing {AsyncWriter} from asynchronously # calling the API. This can occur when the {AsyncWriter} has too few # resources allocated for the amount of usage. # # @example # require "google/cloud/logging" # require "google/cloud/error_reporting" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # async = logging.async_writer # # # Register to be notified when unhandled errors occur. # async.on_error do |error| # # error can be a AsyncWriterError, with entries # Google::Cloud::ErrorReporting.report error # end # # logger = async.logger "my_app_log", resource, env: :production # logger.info "Job started." # class AsyncWriterError < Google::Cloud::Error # @!attribute [r] count # @return [Array] entries The entry # objects that were not written to the API due to the error. attr_reader :entries def initialize message, entries = nil super message @entries = entries if entries end end ## # # AsyncWriteEntriesError # # Used to indicate a problem when {AsyncWriter} writes log entries to the # API. This can occur when the API returns an error. # # @example # require "google/cloud/logging" # require "google/cloud/error_reporting" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # async = logging.async_writer # # # Register to be notified when unhandled errors occur. # async.on_error do |error| # # error can be a AsyncWriteEntriesError, with entries # Google::Cloud::ErrorReporting.report error # end # # logger = async.logger "my_app_log", resource, env: :production # logger.info "Job started." # class AsyncWriteEntriesError < Google::Cloud::Error # @!attribute [r] count # @return [Array] entries The entry # objects that were not written to the API due to the error. attr_reader :entries def initialize message, entries = nil super message @entries = entries if entries end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/async_writer.rb0000644000004100000410000004225415170601174025401 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "monitor" require "concurrent" require "google/cloud/logging/errors" module Google module Cloud module Logging ## # # AsyncWriter # # AsyncWriter buffers, batches, and transmits log entries efficiently. # Writing log entries is asynchronous and will not block. # # Batches that cannot be delivered immediately are queued. When the queue # is full new batch requests will raise errors that can be consumed using # the {#on_error} callback. This provides back pressure in case the writer # cannot keep up with requests. # # This object is thread-safe; it may accept write requests from # multiple threads simultaneously, and will serialize them when # executing in the background thread. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # async = logging.async_writer # # entry1 = logging.entry payload: "Job started." # entry2 = logging.entry payload: "Job completed." # # labels = { job_size: "large", job_code: "red" } # resource = logging.resource "gae_app", # "module_id" => "1", # "version_id" => "20150925t173233" # # async.write_entries [entry1, entry2], # log_name: "my_app_log", # resource: resource, # labels: labels # class AsyncWriter include MonitorMixin ## # @private Implementation accessors attr_reader :logging, :max_bytes, :max_count, :interval, :threads, :max_queue, :partial_success ## # @private Creates a new AsyncWriter instance. def initialize logging, max_count: 10_000, max_bytes: 10_000_000, max_queue: 100, interval: 5, threads: 10, partial_success: false # init MonitorMixin super() @logging = logging @max_count = max_count @max_bytes = max_bytes @max_queue = max_queue @interval = interval @threads = threads @partial_success = partial_success @error_callbacks = [] @cond = new_cond # Make sure all buffered messages are sent when process exits. at_exit { stop } end ## # Asynchronously write one or more log entries to the Stackdriver # Logging service. # # Unlike the main write_entries method, this method usually does not # block. The actual write RPCs will happen in the background, and may # be batched with related calls. However, if the queue is full, this # method will block until enough space has cleared out. # # @param [Google::Cloud::Logging::Entry, # Array] entries One or more entry # objects to write. The log entries must have values for all required # fields. # @param [String] log_name A default log ID for those log entries in # `entries` that do not specify their own `log_name`. See also # {Entry#log_name=}. # @param [Resource] resource A default monitored resource for those log # entries in entries that do not specify their own resource. See also # {Entry#resource}. # @param [Hash{Symbol,String => String}] labels User-defined `key:value` # items that are added to the `labels` field of each log entry in # `entries`, except when a log entry specifies its own `key:value` # item with the same key. See also {Entry#labels=}. # # @return [Google::Cloud::Logging::AsyncWriter] Returns self. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # async = logging.async_writer # # entry = logging.entry payload: "Job started.", # log_name: "my_app_log" # entry.resource.type = "gae_app" # entry.resource.labels[:module_id] = "1" # entry.resource.labels[:version_id] = "20150925t173233" # # async.write_entries entry # def write_entries entries, log_name: nil, resource: nil, labels: nil synchronize do raise "AsyncWriter has been stopped" if @stopped Array(entries).each do |entry| # Update the entry to have all the data directly on it entry.log_name ||= log_name if entry.resource.nil? || entry.resource.empty? entry.resource = resource end entry.labels = labels if entry.labels.nil? || entry.labels.empty? # Add the entry to the batch @batch ||= Batch.new self next if @batch.try_add entry # If we can't add to the batch, publish and create a new batch publish_batch! @batch = Batch.new self @batch.add entry end @thread_pool ||= Concurrent::ThreadPoolExecutor.new \ max_threads: @threads, max_queue: @max_queue @thread ||= Thread.new { run_background } publish_batch! if @batch&.ready? @cond.broadcast end self end ## # Creates a logger instance that is API-compatible with Ruby's standard # library [Logger](https://ruby-doc.org/current/stdlibs/logger/). # # The logger will use AsyncWriter to transmit log entries on a # background thread. # # @param [String] log_name A log resource name to be associated with the # written log entries. # @param [Google::Cloud::Logging::Resource] resource The monitored # resource to be associated with written log entries. # @param [Hash] labels A set of user-defined data to be associated with # written log entries. # # @return [Google::Cloud::Logging::Logger] a Logger object that can be # used in place of a ruby standard library logger object. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # async = logging.async_writer # logger = async.logger "my_app_log", resource, env: :production # logger.info "Job started." # def logger log_name, resource, labels = {} Logger.new self, log_name, resource, labels end ## # Begins the process of stopping the writer. Entries already in the # queue will be published, but no new entries can be added. Use {#wait!} # to block until the writer is fully stopped and all pending entries # have been published. # # @return [AsyncWriter] returns self so calls can be chained. def stop synchronize do break if @stopped @stopped = true publish_batch! @cond.broadcast @thread_pool&.shutdown end self end ## # Blocks until the writer is fully stopped, all pending entries have # been published, and all callbacks have completed. Does not stop the # writer. To stop the writer, first call {#stop} and then call {#wait!} # to block until the writer is stopped. # # @param [Number, nil] timeout The maximum number of seconds to wait for # shutdown to complete. Will wait forever when the value is `nil`. The # default value is `nil`. # # @return [AsyncWriter] returns self so calls can be chained. def wait! timeout = nil synchronize do if @thread_pool @thread_pool.shutdown @thread_pool.wait_for_termination timeout end end self end ## # Stop this asynchronous writer and block until it has been stopped. # # @param [Number, nil] timeout The maximum number of seconds to wait for # shutdown to complete. Will wait forever when the value is `nil`. The # default value is `nil`. # @param [Boolean] force If set to true, and the writer hasn't stopped # within the given timeout, kill it forcibly by terminating the # thread. This should be used with extreme caution, as it can # leave RPCs unfinished. Default is false. # # @return [Symbol] Returns `:new` if {#write_entries} has never been # called on the AsyncWriter, `:stopped` if it was already stopped # at the time of invocation, `:waited` if it stopped during the # timeout period, `:timeout` if it is still running after the # timeout, or `:forced` if it was forcibly killed. # def stop! timeout = nil, force: nil return :new unless @thread_pool return :stopped if stopped? stop wait! timeout if synchronize { @thread_pool.shutdown? } return :waited if timeout elsif force @thread_pool.kill return :forced end :timeout end alias async_stop! stop! ## # Forces all entries in the current batch to be published # immediately. # # @return [AsyncWriter] returns self so calls can be chained. def flush synchronize do publish_batch! @cond.broadcast end self end ## # Whether the writer has been started. # # @return [boolean] `true` when started, `false` otherwise. def started? !stopped? end ## # Whether the writer has been stopped. # # @return [boolean] `true` when stopped, `false` otherwise. def stopped? synchronize { @stopped } end ## # Register to be notified of errors when raised. # # If an unhandled error has occurred the writer will attempt to # recover from the error and resume buffering, batching, and # transmitting log entries # # Multiple error handlers can be added. # # @yield [callback] The block to be called when an error is raised. # @yieldparam [Exception] error The error raised. # # @example # require "google/cloud/logging" # require "google/cloud/error_reporting" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # async = logging.async_writer # # # Register to be notified when unhandled errors occur. # async.on_error do |error| # # error can be a AsyncWriterError or AsyncWriteEntriesError # Google::Cloud::ErrorReporting.report error # end # # logger = async.logger "my_app_log", resource, env: :production # logger.info "Job started." # def on_error &block synchronize do @error_callbacks << block end end ## # The most recent unhandled error to occur while transmitting log # entries. # # If an unhandled error has occurred the subscriber will attempt to # recover from the error and resume buffering, batching, and # transmitting log entries. # # @return [Exception, nil] error The most recent error raised. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # resource = logging.resource "gae_app", # module_id: "1", # version_id: "20150925t173233" # # async = logging.async_writer # # logger = async.logger "my_app_log", resource, env: :production # logger.info "Job started." # # # If an error was raised, it can be retrieved here: # async.last_error #=> nil # def last_error synchronize { @last_error } end alias last_exception last_error protected def run_background synchronize do until @stopped if @batch.nil? @cond.wait next end if @batch.ready? # interval met, publish the batch... publish_batch! @cond.wait else # still waiting for the interval to publish the batch... @cond.wait @batch.publish_wait end end end end def publish_batch! return unless @batch batch_to_be_published = @batch @batch = nil publish_batch_async batch_to_be_published end # Sets the last_error and calls all error callbacks. def error! error error_callbacks = synchronize do @last_error = error @error_callbacks end error_callbacks = default_error_callbacks if error_callbacks.empty? error_callbacks.each { |error_callback| error_callback.call error } end def default_error_callbacks # This is memoized to reduce calls to the configuration. @default_error_callbacks ||= begin error_callback = Google::Cloud::Logging.configure.on_error error_callback ||= Google::Cloud.configure.on_error if error_callback [error_callback] else [] end end end def publish_batch_async batch Concurrent::Promises.future_on( @thread_pool, batch.entries ) do |entries| write_entries_with entries end rescue Concurrent::RejectedExecutionError => e async_error = AsyncWriterError.new( "Error writing entries: #{e.message}", batch.entries ) # Manually set backtrace so we don't have to raise async_error.set_backtrace caller error! async_error end def write_entries_with entries logging.write_entries entries, partial_success: partial_success rescue StandardError => e write_error = AsyncWriteEntriesError.new( "Error writing entries: #{e.message}", entries ) # Manually set backtrace so we don't have to raise write_error.set_backtrace caller error! write_error end ## # @private class Batch attr_reader :created_at attr_reader :entries def initialize writer @writer = writer @entries = [] @entries_bytes = 2 # initial size w/ partial_success @created_at = nil end def add entry, addl_bytes: nil addl_bytes ||= addl_bytes_for entry @entries << entry @entries_bytes += addl_bytes @created_at ||= Time.now nil end def try_add entry addl_bytes = addl_bytes_for entry new_message_count = @entries.count + 1 new_message_bytes = @entries_bytes + addl_bytes if new_message_count > @writer.max_count || new_message_bytes >= @writer.max_bytes return false end add entry, addl_bytes: addl_bytes true end def ready? @entries.count >= @writer.max_count || @entries_bytes >= @writer.max_bytes || (@created_at.nil? || (publish_at < Time.now)) end def publish_at return nil if @created_at.nil? @created_at + @writer.interval end def publish_wait publish_wait = publish_at - Time.now return 0 if publish_wait.negative? publish_wait end def addl_bytes_for entry entry.to_grpc.to_proto.bytesize + 2 end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/log/0000755000004100000410000000000015170601174023115 5ustar www-datawww-datagoogle-cloud-logging-2.7.0/lib/google/cloud/logging/log/list.rb0000644000004100000410000001207615170601174024423 0ustar www-datawww-data# Copyright 2017 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "delegate" module Google module Cloud module Logging class Log ## # Log::List is a special case Array with additional values. class List < DelegateClass(::Array) ## # If not empty, indicates that there are more records that match # the request and this value should be passed to continue. attr_accessor :token ## # @private Create a new Log::List with an array of log names. def initialize arr = [] super arr end ## # Whether there is a next page of logs. # # @return [Boolean] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # logs = logging.logs # if logs.next? # next_logs = logs.next # end # def next? !token.nil? end ## # Retrieve the next page of logs. # # @return [Log::List] # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # # logs = logging.logs # if logs.next? # next_logs = logs.next # end # def next return nil unless next? ensure_service! grpc = @service.list_logs token: token, resource: @resource, max: @max self.class.from_grpc grpc, @service, resource: @resource, max: @max end ## # Retrieves remaining results by repeatedly invoking {#next} until # {#next?} returns `false`. Calls the given block once for each # result, which is passed as the argument to the block. # # An Enumerator is returned if no block is given. # # This method will make repeated API calls until all remaining results # are retrieved. (Unlike `#each`, for example, which merely iterates # over the results returned by a single API call.) Use with caution. # # @param [Integer] request_limit The upper limit of API requests to # make to load all log names. Default is no limit. # @yield [log] The block for accessing each log name. # @yieldparam [String] log The log name. # # @return [Enumerator] # # @example Iterating each log name by passing a block: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # logs = logging.logs # # logs.all { |l| puts l } # # @example Limit the number of API calls made: # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # logs = logging.logs # # logs.all(request_limit: 10) { |l| puts l } # def all request_limit: nil, &block request_limit = request_limit.to_i if request_limit unless block_given? return enum_for :all, request_limit: request_limit end results = self loop do results.each(&block) if request_limit request_limit -= 1 break if request_limit.negative? end break unless results.next? results = results.next end end ## # @private New Log::List from a # Google::Cloud::Logging::V2::ListLogsResponse object. def self.from_grpc grpc_list, service, resource: nil, max: nil logs = new Array(grpc_list.log_names) token = grpc_list.next_page_token token = nil if token == "".freeze logs.instance_variable_set :@token, token logs.instance_variable_set :@service, service logs.instance_variable_set :@resource, resource logs.instance_variable_set :@max, max logs end protected ## # @private Raise an error unless an active connection to the service # is available. def ensure_service! raise "Must have active connection to service" unless @service end end end end end end google-cloud-logging-2.7.0/lib/google/cloud/logging/metric.rb0000644000004100000410000001146715170601174024155 0ustar www-datawww-data# Copyright 2016 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "google/cloud/logging/metric/list" module Google module Cloud module Logging ## # # Metric # # A logs-based [Google Cloud # Monitoring](https://cloud.google.com/monitoring/docs) metric. A metric # is a measured value that can be used to assess a system. The basis of a # logs-based metric is the collection of log entries that match a logs # filter. # # @see https://cloud.google.com/logging/docs/view/logs_based_metrics # Logs-based Metrics # @see https://cloud.google.com/monitoring/docs Google Cloud Monitoring # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.create_metric "errors", "severity>=ERROR" # class Metric ## # @private The gRPC Service object. attr_accessor :service ## # @private The gRPC Google::Cloud::Logging::V2::LogMetric object. attr_accessor :grpc ## # @private Create an empty Metric object. def initialize @service = nil @grpc = Google::Cloud::Logging::V2::LogMetric.new end ## # The client-assigned metric identifier. Metric identifiers are limited # to 1000 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. def name grpc.name end ## # The description of this metric, which is used in documentation. def description grpc.description end ## # Updates the description of this metric, which is used in # documentation. def description= description grpc.description = description end ## # An [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced_filters). def filter grpc.filter end ## # Updates the [advanced logs # filter](https://cloud.google.com/logging/docs/view/advanced_filters). def filter= filter grpc.filter = filter end ## # Updates the logs-based metric. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.metric "severe_errors" # metric.filter = "logName:syslog AND severity>=ERROR" # metric.save # def save ensure_service! @grpc = service.update_metric name, description, filter true end ## # Reloads the logs-based metric with current data from the Logging # service. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.metric "severe_errors" # metric.filter = "Unwanted value" # metric.reload! # metric.filter #=> "logName:syslog" # def reload! ensure_service! @grpc = service.get_metric name true end alias refresh! reload! ## # Permanently deletes the logs-based metric. # # @return [Boolean] Returns `true` if the metric was deleted. # # @example # require "google/cloud/logging" # # logging = Google::Cloud::Logging.new # metric = logging.metric "severe_errors" # metric.delete # def delete ensure_service! service.delete_metric name true end ## # @private New Metric from a gRPC object. def self.from_grpc grpc, service new.tap do |m| m.grpc = grpc m.service = service end end protected ## # @private Raise an error unless an active connection to the service is # available. def ensure_service! raise "Must have active connection to service" unless service end end end end end google-cloud-logging-2.7.0/.yardopts0000644000004100000410000000042515170601174017425 0ustar www-datawww-data--no-private --title=Stackdriver Logging --exclude _pb\.rb$ --markup markdown --markup-provider redcarpet --main OVERVIEW.md ./lib/**/*.rb - OVERVIEW.md AUTHENTICATION.md INSTRUMENTATION.md LOGGING.md CONTRIBUTING.md TROUBLESHOOTING.md CHANGELOG.md CODE_OF_CONDUCT.md LICENSE google-cloud-logging-2.7.0/CODE_OF_CONDUCT.md0000644000004100000410000000367715170601174020372 0ustar www-datawww-data# Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) google-cloud-logging-2.7.0/LICENSE0000644000004100000410000002613715170601174016574 0ustar www-datawww-data Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. google-cloud-logging-2.7.0/TROUBLESHOOTING.md0000644000004100000410000000173715170601174020377 0ustar www-datawww-data# Troubleshooting ## Where can I get more help? ### Ask the Community If you have a question about how to use a Google Cloud client library in your project or are stuck in the Developer's console and don't know where to turn, it's possible your questions have already been addressed by the community. First, check out the appropriate tags on StackOverflow: - [`google-cloud-platform+ruby+logging`][so-ruby] Next, try searching through the issues on GitHub: - [`api:logging` issues][gh-search-ruby] Still nothing? ### Ask the Developers If you're experiencing a bug with the code, or have an idea for how it can be improved, *please* create a new issue on GitHub so we can talk about it. - [New issue][gh-ruby] [so-ruby]: http://stackoverflow.com/questions/tagged/google-cloud-platform+ruby+logging [gh-search-ruby]: https://github.com/googleapis/google-cloud-ruby/issues?q=label%3A%22api%3A+logging%22 [gh-ruby]: https://github.com/googleapis/google-cloud-ruby/issues/new google-cloud-logging-2.7.0/LOGGING.md0000644000004100000410000000171515170601174017172 0ustar www-datawww-data# Enabling gRPC Logging To enable logging for this library, set the logger for the underlying [gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library. The logger that you set may be a Ruby stdlib [`Logger`](https://ruby-doc.org/current/stdlibs/logger/Logger.html) as shown below, or a [`Google::Cloud::Logging::Logger`](https://googleapis.dev/ruby/google-cloud-logging/latest) that will write logs to [Stackdriver Logging](https://cloud.google.com/logging/). See [grpc/logconfig.rb](https://github.com/grpc/grpc/blob/master/src/ruby/lib/grpc/logconfig.rb) and the gRPC [spec_helper.rb](https://github.com/grpc/grpc/blob/master/src/ruby/spec/spec_helper.rb) for additional information. Configuring a Ruby stdlib logger: ```ruby require "logger" module MyLogger LOGGER = Logger.new $stderr, level: Logger::WARN def logger LOGGER end end # Define a gRPC module-level logger method before grpc/logconfig.rb loads. module GRPC extend MyLogger end ``` google-cloud-logging-2.7.0/INSTRUMENTATION.md0000644000004100000410000000553515170601174020413 0ustar www-datawww-data# Stackdriver Logging Instrumentation Then google-cloud-logging gem provides a Rack Middleware class that can easily integrate with Rack based application frameworks, such as Rails and Sinatra. When enabled, it sets an instance of Google::Cloud::Logging::Logger as the default Rack or Rails logger. Then all consequent log entries will be submitted to the Stackdriver Logging service. On top of that, the google-cloud-logging also implements a Railtie class that automatically enables the Rack Middleware in Rails applications when used. ## Configuration The default configuration enables Stackdriver instrumentation features to run on Google Cloud Platform. You can easily configure the instrumentation library if you want to run on a non Google Cloud environment or you want to customize the default behavior. See the [Configuration Guide](https://googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html) for full configuration parameters. ## Using instrumentation with Ruby on Rails To install application instrumentation in your Ruby on Rails app, add this gem, `google-cloud-logging`, to your Gemfile and update your bundle. Then add the following line to your `config/application.rb` file: ```ruby require "google/cloud/logging/rails" ``` This will load a Railtie that automatically integrates with the Rails framework by injecting a Rack middleware. ## Using instrumentation with Sinatra To install application instrumentation in your Sinatra app, add this gem, `google-cloud-logging`, to your Gemfile and update your bundle. Then add the following lines to your main application Ruby file: ```ruby require "google/cloud/logging" use Google::Cloud::Logging::Middleware ``` This will install the logging middleware in your application. ### Using instrumentation with other Rack-based frameworks To install application instrumentation in an app using another Rack-based web framework, add this gem, `google-cloud-logging`, to your Gemfile and update your bundle. Then add install the logging middleware in your middleware stack. In most cases, this means adding these lines to your `config.ru` Rack configuration file: ```ruby require "google/cloud/logging" use Google::Cloud::Logging::Middleware ``` Some web frameworks have an alternate mechanism for modifying the middleware stack. Consult your web framework's documentation for more information. ### The Stackdriver diagnostics suite The google-cloud-logging library is part of the Stackdriver diagnostics suite, which also includes error reporting, tracing analysis, and real-time debugger. If you include the `stackdriver` gem in your Gemfile, this logging library will be included automatically. In addition, if you include the `stackdriver` gem in an application using Ruby On Rails, the Railties will be installed automatically. See the documentation for the "stackdriver" gem for more details. google-cloud-logging-2.7.0/CHANGELOG.md0000644000004100000410000003423215170601174017373 0ustar www-datawww-data# Release History ### 2.7.0 (2026-04-15) #### Features * Update minimum Ruby to v3.2 and support v4.0 ([#33811](https://github.com/googleapis/google-cloud-ruby/issues/33811)) ### 2.6.1 (2025-11-04) #### Documentation * add warning about loading unvalidated credentials ([#32121](https://github.com/googleapis/google-cloud-ruby/issues/32121)) ### 2.6.0 (2025-03-04) #### Features * Update minimum Ruby version to 3.0 ([#29261](https://github.com/googleapis/google-cloud-ruby/issues/29261)) ### 2.5.0 (2024-07-09) #### Features * compatibility with GA releases of underlying versioned clients ([#26361](https://github.com/googleapis/google-cloud-ruby/issues/26361)) ### 2.4.0 (2024-03-07) #### Features * Update minimum supported Ruby version to 2.7 ([#25298](https://github.com/googleapis/google-cloud-ruby/issues/25298)) ### 2.3.3 (2023-05-19) #### Documentation * Fixed broken links in authentication documentation ([#21619](https://github.com/googleapis/google-cloud-ruby/issues/21619)) ### 2.3.2 (2022-10-18) #### Bug Fixes * update list logs response ([#19285](https://github.com/googleapis/google-cloud-ruby/issues/19285)) ### 2.3.1 (2022-07-24) #### Bug Fixes * update resource descriptor to handle paged enum ([#18856](https://github.com/googleapis/google-cloud-ruby/issues/18856)) ### 2.3.0 (2022-06-30) #### Features * Update minimum Ruby version to 2.6 ([#18444](https://github.com/googleapis/google-cloud-ruby/issues/18444)) ### 2.2.2 / 2021-10-21 #### Documentation * Add documentation for quota_project Configuration attribute ### 2.2.1 / 2021-07-08 #### Documentation * Update AUTHENTICATION.md in handwritten packages ### 2.2.0 / 2021-03-10 #### Features * Drop support for Ruby 2.4 and add support for Ruby 3.0 ### 2.1.0 / 2020-09-16 #### Features * quota_project can be set via library configuration ### 2.0.0 / 2020-07-21 This is a major update that removes the "low-level" client interface code, and instead adds the new `google-cloud-logging-v2` gem as a dependency. The new dependency is a rewritten low-level client, produced by a next- generation client code generator, with improved performance and stability. This change should have no effect on the high-level interface that most users will use. The one exception is that the (mostly undocumented) `client_config` argument, for adjusting low-level parameters such as RPC retry settings on client objects, has been removed. If you need to adjust these parameters, use the configuration interface in `google-cloud-logging-v2`. Substantial changes have been made in the low-level interfaces, however. If you are using the low-level classes under the `Google::Cloud::Logging::V2` module, please review the docs for the new `google-cloud-logging-v2` gem. In particular: * Some classes have been renamed, notably the client class itself. * The client constructor takes a configuration block instead of configuration keyword arguments. * All RPC method arguments are now keyword arguments. ### 1.10.9 / 2020-06-17 #### Documentation * Improved field descriptions in the low-level interface. ### 1.10.8 / 2020-06-12 #### Documentation * Provide more details on low-level monitored resource data types ### 1.10.7 / 2020-05-28 #### Documentation * Fix a few broken links ### 1.10.6 / 2020-05-19 #### Bug Fixes * Adjusted some default timeout and retry settings ### 1.10.5 / 2020-05-05 #### Bug Fixes * Prevent error when calling stop! on unused AsyncWriter ### 1.10.4 / 2020-04-20 #### Documentation * Fix some broken links in the Project and Sink docs ### 1.10.3 / 2020-04-06 #### Documentation * Fix some broken links in the low-level interface documentation. ### 1.10.2 / 2020-04-01 #### Bug Fixes * Restore some path helpers in the low-level interface. ### 1.10.1 / 2020-03-19 #### Bug Fixes * Restore billing, folder, and organization path helpers in low-level interface ### 1.10.0 / 2020-03-16 #### Features * support separate project setting for quota/billing #### Low-level interface updates * Add LogBucket * Add ConfigServiceV2Client#list_buckets * Add ConfigServiceV2Client#get_bucket * Add ConfigServiceV2Client#update_bucket * Add LifecycleState enum * Change name to positional param in ConfigServiceV2Client#get_cmek_settings * Change name and cmek_settings to positional params in ConfigServiceV2Client#update_cmek_settings * Remove billing, folder, and organization path helpers from ConfigServiceV2Client * Remove LogEntry#metadata * Remove previously deprecated project_ids from LoggingServiceV2Client#list_log_entries * Remove log_path helpers from LoggingServiceV2Client * Rename ConfigServiceV2Client#billing_path to #billing_account_path * Rename LoggingServiceV2Client#billing_path to #billing_account_path * Rename MetricsServiceV2Client#metric_path to #log_metric_path * Update network configuration settings ### 1.9.5 / 2020-02-24 #### Documentation * Fix doc links to Cmek methods in lower-level client ### 1.9.4 / 2020-01-23 #### Documentation * Update copyright year ### 1.9.3 / 2019-12-20 #### Documentation * Update description of MetricDescriptor#unit in lower-level API ### 1.9.2 / 2019-12-18 #### Bug Fixes * Fix MonitorMixin usage on Ruby 2.7 * Ruby 2.7 will error if new_cond is called before super(). * Make the call to super() be the first call in initialize #### Documentation * Update docs for lower-level API call MetricDescriptorMetadata#unit ### 1.9.1 / 2019-11-06 #### Bug Fixes * Update minimum runtime dependencies ### 1.9.0 / 2019-10-29 This release requires Ruby 2.4 or later. #### Documentation * Clarify which Google Cloud Platform environments support automatic authentication ### 1.8.0 / 2019-10-03 #### Features * Support additional fields of LogSink in the low-level interface * Add LogSink#create_time field * Add LogSink#update_time field * Add LogSink#bigquery_options field * Add BigQueryOptions type * Update documentation ### 1.7.0 / 2019-08-23 #### Features * Support overriding of service endpoint ### 1.6.6 / 2019-07-31 * Fix max threads setting in thread pools * Thread pools once again limit the number of threads allocated. * Update documentation links ### 1.6.5 / 2019-07-08 * Support overriding service host and port in the low-level interface. ### 1.6.4 / 2019-06-11 * Add documentation for MetricDescriptor#launch_stage and MonitoredResourceDescriptor#launch_stage. * Deprecate MetricDescriptor:: MetricDescriptorMetadata#launch_stage * Use VERSION constant in GAPIC client ### 1.6.3 / 2019-04-29 * Add AUTHENTICATION.md guide. * Update generated documentation. * Update generated code examples. * Extract gRPC header values from request. ### 1.6.2 / 2019-02-13 * Fix bug (typo) in retrieving default on_error proc. ### 1.6.1 / 2019-02-07 * Update concurrent-ruby dependency ### 1.6.0 / 2019-01-22 * AsyncWriter buffer entries and make batch API calls * Update AsyncWriter to buffer log entries and batch API calls. * Maintain backwards compatibility with the previous AsyncWriter's public API, although the implementation is changed. * Back pressure is applied by limiting the number of queued API calls. Errors will now be raised when there are not enough resources. * Errors are reported using the AsyncWriter#on_error callback. * Pending log entries are sent before the process closes using at_exit. * Add Logging on_error configuration. * Add default insert_id value for Entry * Add Entry.insert_id * Add default insert_id value for Entry An Entry object is assigned an insert_id when created so that if the Entry object gets persisted multiple times it would know its insert_id value and not attempt to generate a new one for each persist attempt. An Entry object will still be considered empty if the only value it has is the insert_id. * (This change does not use SecureRandom for performance reasons.) * Add Logging trace_sampled * Add Entry#trace_sampled attribute * Add trace_sampled to Logger::RequestInfo * Changes to Rails default Logger * Delay updating the Rails default logger until the first web request. * This will avoid issues with forking processes and gRPC resources. * This is accomplished by adding the on_init argument to middleware. * Add Railtie.set_default_logger * This method can be called post-fork to update the Rails default logger. * Make use of Credentials#project_id * Use Credentials#project_id If a project_id is not provided, use the value on the Credentials object. This value was added in googleauth 0.7.0. * Loosen googleauth dependency Allow for new releases up to 0.10. The googleauth devs have committed to maintaining the current API and will not make backwards compatible changes before 0.10. * Direct logs for "/healthz" requests to the health check log. * Update documentation. ### 1.5.7 / 2018-11-15 * Add Google::Logging::V2::LogEntry#trace_sampled. * Update low-level documentation. ### 1.5.6 / 2018-10-03 * Use concurrent-ruby and ThreadLocalVar in Logger. * Remove Monitor and synchronize blocks. * Logger#thread_ids now only returns the current thread. ### 1.5.5 / 2018-09-20 * Make Logger thread-safe. * Update Logging generated files. * Add Metric's MetricDescriptorMetadata. * Update documentation. * Change documentation URL to googleapis GitHub org. * Fix circular require warning. ### 1.5.4 / 2018-09-12 * Add missing documentation files to package. ### 1.5.3 / 2018-09-10 * Update documentation. ### 1.5.2 / 2018-08-21 * Update documentation. ### 1.5.1 / 2018-07-05 * Fix bug in List classes by propagating arguments needed for pagination calls. * Fix issue when disabling Stackdriver components with Rails.env.production. * Reduce string memory usage. * Add documentation for enabling gRPC logging. ### 1.5.0 / 2018-02-27 * Use Google Cloud Shared Configuration. * Deprecated Logging Sink attributes. ### 1.4.0 / 2017-12-19 * Update google-gax dependency to 1.0. ### 1.3.2 / 2017-11-20 * Refresh GAPIC layer (low-level API) based on updates to Protobuf types. ### 1.3.1 / 2017-11-15 * Fix credentials verification bug in Railtie. ### 1.3.0 / 2017-11-14 * Add `Google::Cloud::Logging::Credentials` class. * Rename constructor arguments to `project_id` and `credentials`. (The previous arguments `project` and `keyfile` are still supported.) * Document `Google::Auth::Credentials` as `credentials` value. * Add `partial_success` optional argument to `Project#write_entries`. * Deprecate `HttpRequest#method`, use `HttpRequest#request_method` instead. * Update generated low level GAPIC code. * Updated `google-gax` (`grpc`, `google-protobuf`), `googleauth` dependencies. ### 1.2.3 / 2017-09-27 * Updated protobuf classes. * Updated README. ### 1.2.2 / 2017-09-08 * Add `labels` configuration option to `Google::Cloud::Logging::Middleware` for Rails and other Rack-based framework integrations. ### 1.2.1 / 2017-07-11 * stackdriver-core 1.2.0 release ### 1.2.0 / 2017-07-11 * Update `labels` parameter in `Google::Cloud::Logging::Logger#initialize` to default to empty hash. * Update `Google::Cloud::Logging::Logger` to support the following `ActiveSupport::Logger` methods: `:local_level`, `:local_level=`, `:silence`, `:silencer`, and `:unknown?`. * Update GAPIC configuration to exclude `UNAVAILABLE` errors from automatic retry. * Update gem spec homepage links. ### 1.1.0 / 2017-05-25 * Introduce new `Google::Cloud::Logging.configure` instrumentation configuration interface. * Google::Cloud::Logger now sends extra trace context information in log entries. ### 1.0.1 / 2017-04-21 * Middleware constructor can be called without an explicit logger. This should make integration in non-Rails applications simpler. * If Rails integration fails due to an auth error, the notice is now printed to STDOUT rather than STDERR, which should make it a bit less scary when displayed in Docker output. ### 1.0.0 / 2017-03-31 * Release 1.0 * Added `#trace` and `#source_location` to Entry * Added listing of logs for the project * Updated documentation * Automatic retry on `UNAVAILABLE` errors ### 0.24.2 / 2017-03-03 * No public API changes. * Update GRPC header value sent to the Logging API. ### 0.24.1 / 2017-03-01 * No public API changes. * Update GRPC header value sent to the Logging API. * Low level API adds new Protobuf types and GAPIC methods. ### 0.24.0 / 2017-02-21 * Fix GRPC retry bug * The client_config data structure has replaced retry_codes/retry_codes_def with retry_codes * Update GRPC/Protobuf/GAX dependencies ### 0.23.2 / 2016-12-27 * `Google::Cloud::Logging::Logger` depended on standard logger but didn't require it. Fixed. ### 0.23.1 / 2016-12-22 * Use the `stackdriver-core` gem to obtain Trace ID, for compatibility with the `google-cloud-trace` gem. * `Google::Cloud::Logging::Logger` now understands all remaining standard Logger methods. * Clean up `AsyncWriter` threads on VM exit, to prevent gRPC from crashing if it's still in the middle of a call. * Support setting log name by path, and direct App Engine health checks to a separate log by default. * Minor improvements to warning messages. ### 0.23.0 / 2016-12-8 * Add `resources` method argument to `Project#entries` * Deprecate `projects` method argument from `Project#entries` * Add `start_at`, `end_at`, and `writer_identity` attributes to `Sink` * Add `start_at`, `end_at`, and `unique_writer_identity` parameters to `Project#create_sink` * Add `unique_writer_identity` parameter to `Sink#save` * Many documentation improvements * Add documentation for Low Level API ### 0.21.2 / 2016-11-15 * Fix issue with uninitialized VERSION (remi) ### 0.21.1 / 2016-11-4 * Upgraded Google::Cloud::Logging::Railtie to use AsyncWriter * Added Rails configuration for custom monitored resource ### 0.21.0 / 2016-10-20 * New service constructor Google::Cloud::Logging.new * New constructor argument client_config * Logger is now asynchronous * AsyncWriter added * Rails and Rack integration added ### 0.20.1 / 2016-09-02 * Fix an issue with the GRPC client and forked sub-processes ### 0.20.0 / 2016-08-26 This gem contains the Stackdriver Logging service implementation for the `google-cloud` gem. The `google-cloud` gem replaces the old `gcloud` gem. Legacy code can continue to use the `gcloud` gem. * Namespace is now `Google::Cloud` * The `google-cloud` gem is now an umbrella package for individual gems