class Google::Logging::Message

A log message that can be formatted either as a normal text log entry or as a structured log entry suitable for Google Cloud Logging.

A log message has a “body” which consists of either a string message, a JSON object (i.e. a Hash whose values are typically strings or numbers but could be nested arrays and hashes), or both. It also includes several additional optional fields used by the Google Cloud Logging backend.

Most log formatters will render the message body as a string and ignore the other attributes. The {StructuredFormatter}, however, will format the full message data in the JSON format understood by the Google logging agent.

Constants

DISALLOWED_FIELDS

@private

Attributes

fields[R]

@return [Hash{String=>Object},nil] The log message as a set of

key-value pairs, or nil if not present.
full_message[R]

@return [String] A full string representation of the message and fields

as rendered in the standard logger formatter.
insert_id[R]

@return [String,nil] The unique ID for this log entry that could be

used on the backend to dedup messages, or nil if not present.
inspect[R]

@return [String] A full string representation of the message and fields

as rendered in the standard logger formatter.
labels[R]

@return [Hash{String=>String},nil] Metadata, or nil if not present.

message[R]

@return [String] The message as a string. This is always present as a

nonempty string, and can be reliably used as the "display" of this
log entry in a list of entries.
source_location[R]

@return [SourceLocation,nil] The source location for the log entry, or

nil if not present.
span_id[R]

@return [String,nil] The trace span containing this entry, or nil if

not present.
timestamp[R]

@return [Time,nil] The timestamp for the log entry, or nil if not

present.
to_s[R]

@return [String] The message as a string. This is always present as a

nonempty string, and can be reliably used as the "display" of this
log entry in a list of entries.
trace[R]

@return [String,nil] The Google Cloud Trace resource name, or nil if

not present.
trace_sampled[R]

@return [true,false,nil] Whether this trace is sampled, or nil if not

present or known.
trace_sampled?[R]

@return [true,false,nil] Whether this trace is sampled, or nil if not

present or known.

Public Class Methods

from(input) click to toggle source

Create a log message from an input object, which can be any of:

  • An existing Message object.

  • A Hash. Symbol keys are used as keyword arguments to the {Message#initialize} constructor. String keys are treated as fields in the JSON payload.

  • Any other object is converted to a string with ‘to_s` and used as a simple text payload.

@param input [Object] A log message input object. @return [Message]

# File lib/google/logging/message.rb, line 50
def self.from input
  case input
  when Hash
    kwargs = {}
    fields = nil
    input.each do |k, v|
      if k.is_a? Symbol
        kwargs[k] = v
      else
        (fields ||= {})[k.to_s] = v
      end
    end
    if kwargs[:fields] && fields
      kwargs[:fields].merge! fields
    else
      kwargs[:fields] ||= fields
    end
    new(**kwargs)
  when Message
    input
  else
    new message: input.to_s
  end
end
new(message: nil, fields: nil, timestamp: nil, source_location: nil, insert_id: nil, trace: nil, span_id: nil, trace_sampled: nil, labels: nil) click to toggle source

Low-level constructor for a logging message. All arguments are optional, with the exception that at least one of ‘:message` and `:fields` must be provided.

@param message [String] The main log message as a string. @param fields [Hash{String=>Object}] The log message as a set of

key-value pairs representing a JSON object.

@param timestamp [Time,Numeric,:now] The timestamp for the log entry.

Can be provided as a Time object, a Numeric indicating the seconds
since epoch, or `:now` to use the current time. Optional.

@param source_location [SourceLocation,Hash,:caller,nil] The source

location for the log entry. Can be provided as a {SourceLocation}
object, a Hash containing exactly the keys `:file`, `:line`, and
`:function`, or `:caller` to use the location of the caller.
Optional.

@param insert_id [String] A unique ID for this log entry that could be

used on the backend to dedup messages. Optional.

@param trace [String] A Google Cloud Trace resource name. Optional. @param span_id [String] The trace span containing this entry. Optional. @param trace_sampled [boolean] Whether this trace is sampled. Optional. @param labels [Hash{String=>String}] Optional metadata.

# File lib/google/logging/message.rb, line 98
def initialize message: nil,
               fields: nil,
               timestamp: nil,
               source_location: nil,
               insert_id: nil,
               trace: nil,
               span_id: nil,
               trace_sampled: nil,
               labels: nil
  @fields = interpret_fields fields
  @message, @full_message = interpret_message message, @fields
  @timestamp = interpret_timestamp timestamp
  @source_location = interpret_source_location source_location
  @insert_id = interpret_string insert_id
  @trace = interpret_string trace
  @span_id = interpret_string span_id
  @trace_sampled = interpret_boolean trace_sampled
  @labels = interpret_labels labels
end

Public Instance Methods

==(other) click to toggle source

@private

# File lib/google/logging/message.rb, line 200
def == other
  return false unless other.is_a? Message
  message == other.message &&
    fields == other.fields &&
    timestamp == other.timestamp &&
    source_location == other.source_location &&
    insert_id == other.insert_id &&
    trace == other.trace &&
    span_id == other.span_id &&
    trace_sampled? == other.trace_sampled? &&
    labels == other.labels
end
Also aliased as: eql?
eql?(other)
Alias for: ==
hash() click to toggle source

@private

# File lib/google/logging/message.rb, line 215
def hash
  [message, fields, timestamp, source_location, insert_id, trace, span_id, trace_sampled, labels].hash
end
to_h() click to toggle source

@return [Hash] A hash of kwargs that can be passed to the constructor

to clone this message.
# File lib/google/logging/message.rb, line 185
def to_h
  {
    message: @message,
    fields: @fields.dup,
    timestamp: @timestamp,
    source_location: @source_location,
    insert_id: @insert_id,
    trace: @trace,
    span_id: @span_id,
    trace_sampled: @trace_sampled,
    labels: @labels.dup
  }
end

Private Instance Methods

interpret_boolean(input) click to toggle source
# File lib/google/logging/message.rb, line 297
def interpret_boolean input
  return nil if input.nil?
  input ? true : false
end
interpret_fields(fields) click to toggle source
# File lib/google/logging/message.rb, line 230
def interpret_fields fields
  return nil if fields.nil?
  fields = normalize_json fields
  fields.each_key do |key|
    if DISALLOWED_FIELDS.include?(key) || key.start_with?("logging.googleapis.com/")
      raise ArgumentError, "Field key not allowed: #{key}"
    end
  end
  fields
end
interpret_labels(input) click to toggle source
# File lib/google/logging/message.rb, line 302
def interpret_labels input
  return nil if input.nil?
  input.to_h do |k, v|
    v_converted =
      case v
      when Array, Hash
        JSON.generate v
      else
        v.to_s
      end
    [k.to_s, v_converted]
  end
end
interpret_message(message, fields) click to toggle source
# File lib/google/logging/message.rb, line 260
def interpret_message message, fields
  if message
    message = message.to_s
    full_message = fields ? "#{message} -- #{JSON.generate fields}" : message
    [message, full_message]
  else
    fields_json = JSON.generate fields
    [fields_json, fields_json]
  end
end
interpret_source_location(source_location) click to toggle source
# File lib/google/logging/message.rb, line 282
def interpret_source_location source_location
  case source_location
  when SourceLocation
    source_location
  when Hash
    SourceLocation.new(**source_location)
  when :caller
    SourceLocation.for_caller omit_files: [__FILE__]
  end
end
interpret_string(input) click to toggle source
# File lib/google/logging/message.rb, line 293
def interpret_string input
  input&.to_s
end
interpret_timestamp(timestamp) click to toggle source
# File lib/google/logging/message.rb, line 271
def interpret_timestamp timestamp
  case timestamp
  when Time
    timestamp
  when Numeric
    Time.at timestamp
  when :now
    Time.now.utc
  end
end
normalize_json(input) click to toggle source
# File lib/google/logging/message.rb, line 241
def normalize_json input
  case input
  when Hash
    input.to_h { |k, v| [k.to_s, normalize_json(v)] }
  when Array
    input.map { |v| normalize_json v }
  when Integer, Float, nil, true, false
    input
  when Rational
    if input.denominator == 1
      input.numerator
    else
      input.to_f
    end
  else
    input.to_s
  end
end