Class: Google::Cloud::Logging::AsyncWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/logging/async_writer.rb

Overview

AsyncWriter

An object that batches and transmits log entries asynchronously.

Use this object to transmit log entries efficiently. It keeps a queue of log entries, and runs a background thread that transmits them to the logging service in batches. Generally, adding to the queue will not block.

This object is thread-safe; it may accept write requests from multiple threads simultaneously, and will serialize them when executing in the background thread.

Examples:

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

Constant Summary collapse

DEFAULT_MAX_QUEUE_SIZE =
10000

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#last_exceptionObject (readonly)

The last exception thrown by the background thread, or nil if nothing has been thrown.



86
87
88
# File 'lib/google/cloud/logging/async_writer.rb', line 86

def last_exception
  @last_exception
end

#stateObject (readonly)

The current state. Either :running, :suspended, :stopping, or :stopped



81
82
83
# File 'lib/google/cloud/logging/async_writer.rb', line 81

def state
  @state
end

Instance Method Details

#logger(log_name, resource, labels = {}) ⇒ Google::Cloud::Logging::Logger

Creates a logger instance that is API-compatible with Ruby's standard library Logger.

The logger will use AsyncWriter to transmit log entries on a background thread.

Examples:

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."

Parameters:

  • log_name (String)

    A log resource name to be associated with the written log entries.

  • resource (Google::Cloud::Logging::Resource)

    The monitored resource to be associated with written log entries.

  • labels (Hash) (defaults to: {})

    A set of user-defined data to be associated with written log entries.

Returns:



186
187
188
# File 'lib/google/cloud/logging/async_writer.rb', line 186

def logger log_name, resource, labels = {}
  Logger.new self, log_name, resource, labels
end

#resumeBoolean

Resumes this suspended asynchronous writer.

After this call succeeds, the state will change to :running, and the writer will resume sending RPCs.

Returns:

  • (Boolean)

    Returns true if the writer had been suspended and is now running, otherwise false.



245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/google/cloud/logging/async_writer.rb', line 245

def resume
  ensure_thread
  @lock.synchronize do
    if state == :suspended
      @state = :running
      @lock_cond.broadcast
      true
    else
      false
    end
  end
end

#running?Boolean

Returns true if this writer is running.

Returns:

  • (Boolean)

    Returns true if the writer is currently running.



263
264
265
266
267
268
# File 'lib/google/cloud/logging/async_writer.rb', line 263

def running?
  ensure_thread
  @lock.synchronize do
    state == :running
  end
end

#stopBoolean

Stops this asynchronous writer.

After this call succeeds, the state will change to :stopping, and you may not issue any additional write_entries calls. Any previously issued writes will complete. Once any existing backlog has been cleared, the state will change to :stopped.

Returns:

  • (Boolean)

    Returns true if the writer was running, or false if the writer had already been stopped.



201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/google/cloud/logging/async_writer.rb', line 201

def stop
  ensure_thread
  @lock.synchronize do
    if state != :stopped
      @state = :stopping
      @lock_cond.broadcast
      true
    else
      false
    end
  end
end

#stopped?Boolean

Returns true if this writer is fully stopped.

Returns:

  • (Boolean)

    Returns true if the writer is fully stopped.



300
301
302
303
304
305
# File 'lib/google/cloud/logging/async_writer.rb', line 300

def stopped?
  ensure_thread
  @lock.synchronize do
    state == :stopped
  end
end

#suspendBoolean

Suspends this asynchronous writer.

After this call succeeds, the state will change to :suspended, and the writer will stop sending RPCs until resumed.

Returns:

  • (Boolean)

    Returns true if the writer had been running and was suspended, otherwise false.



223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/google/cloud/logging/async_writer.rb', line 223

def suspend
  ensure_thread
  @lock.synchronize do
    if state == :running
      @state = :suspended
      @lock_cond.broadcast
      true
    else
      false
    end
  end
end

#suspended?Boolean

Returns true if this writer is suspended.

Returns:

  • (Boolean)

    Returns true if the writer is currently suspended.



275
276
277
278
279
280
# File 'lib/google/cloud/logging/async_writer.rb', line 275

def suspended?
  ensure_thread
  @lock.synchronize do
    state == :suspended
  end
end

#wait_until_stopped(timeout = nil) ⇒ Boolean

Blocks until this asynchronous writer has been stopped, or the given timeout (if present) has elapsed.

Parameters:

  • timeout (Number) (defaults to: nil)

    Timeout in seconds, or nil for no timeout.

Returns:

  • (Boolean)

    Returns true if the writer is stopped, or false if the timeout expired.



316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/google/cloud/logging/async_writer.rb', line 316

def wait_until_stopped timeout = nil
  ensure_thread
  deadline = timeout ? ::Time.new.to_f + timeout : nil
  @lock.synchronize do
    until state == :stopped
      cur_time = ::Time.new.to_f
      return false if deadline && cur_time >= deadline
      @lock_cond.wait(deadline ? deadline - cur_time : nil)
    end
  end
  true
end

#writable?Boolean

Returns true if this writer is still accepting writes. This means it is either running or suspended.

Returns:

  • (Boolean)

    Returns true if the writer is accepting writes.



288
289
290
291
292
293
# File 'lib/google/cloud/logging/async_writer.rb', line 288

def writable?
  ensure_thread
  @lock.synchronize do
    state == :suspended || state == :running
  end
end

#write_entries(entries, log_name: nil, resource: nil, labels: nil) ⇒ Google::Cloud::Logging::AsyncWriter

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.

Examples:

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

Parameters:

  • entries (Google::Cloud::Logging::Entry, Array<Google::Cloud::Logging::Entry>)

    One or more entry objects to write. The log entries must have values for all required fields.

  • log_name (String)

    A default log ID for those log entries in entries that do not specify their own log_name. See also Entry#log_name=.

  • resource (Resource)

    A default monitored resource for those log entries in entries that do not specify their own resource. See also Entry#resource.

  • labels (Hash{Symbol,String => String})

    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=.

Returns:



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/google/cloud/logging/async_writer.rb', line 138

def write_entries entries, log_name: nil, resource: nil, labels: nil
  ensure_thread
  entries = Array(entries)
  @lock.synchronize do
    fail "AsyncWriter has been stopped" unless writable?
    queue_item = QueueItem.new entries, log_name, resource, labels
    if @queue.empty? || !@queue.last.try_combine(queue_item)
      @queue.push queue_item
    end
    @queue_size += entries.size
    @lock_cond.broadcast
    while @max_queue_size && @queue_size > @max_queue_size
      @lock_cond.wait
    end
  end
  self
end