1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
# frozen_string_literal: true
module Sentry
# The StructuredLogger class implements Sentry's SDK telemetry logs protocol.
# It provides methods for logging messages at different severity levels and
# sending them to Sentry with structured data.
#
# This class follows the Sentry Logs Protocol as defined in:
# https://develop.sentry.dev/sdk/telemetry/logs/
#
# @example Basic usage
# Sentry.logger.info("User logged in", user_id: 123)
#
# @example With structured data
# Sentry.logger.warn("API request failed",
# status_code: 404,
# endpoint: "/api/users",
# request_id: "abc-123"
# )
#
# @example With a message template
# # Using positional parameters
# Sentry.logger.info("User %s logged in", ["Jane Doe"])
#
# # Using hash parameters
# Sentry.logger.info("User %{name} logged in", name: "Jane Doe")
#
# # Using hash parameters and extra attributes
# Sentry.logger.info("User %{name} logged in", name: "Jane Doe", user_id: 312)
#
# @see https://develop.sentry.dev/sdk/telemetry/logs/ Sentry SDK Telemetry Logs Protocol
class StructuredLogger
# Severity number mapping for log levels according to the Sentry Logs Protocol
# @see https://develop.sentry.dev/sdk/telemetry/logs/#log-severity-number
LEVELS = {
trace: 1,
debug: 5,
info: 9,
warn: 13,
error: 17,
fatal: 21
}.freeze
# @return [Configuration] The Sentry configuration
# @!visibility private
attr_reader :config
# Initializes a new StructuredLogger instance
#
# @param config [Configuration] The Sentry configuration
def initialize(config)
@config = config
end
# Logs a message at TRACE level
#
# @param message [String] The log message
# @param parameters [Array] Array of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def trace(message, parameters = [], **attributes)
log(__method__, message, parameters: parameters, **attributes)
end
# Logs a message at DEBUG level
#
# @param message [String] The log message
# @param parameters [Array] Array of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def debug(message, parameters = [], **attributes)
log(__method__, message, parameters: parameters, **attributes)
end
# Logs a message at INFO level
#
# @param message [String] The log message
# @param parameters [Array] Array of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def info(message, parameters = [], **attributes)
log(__method__, message, parameters: parameters, **attributes)
end
# Logs a message at WARN level
#
# @param message [String] The log message
# @param parameters [Array] Array of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def warn(message, parameters = [], **attributes)
log(__method__, message, parameters: parameters, **attributes)
end
# Logs a message at ERROR level
#
# @param message [String] The log message
# @param parameters [Array] Array of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def error(message, parameters = [], **attributes)
log(__method__, message, parameters: parameters, **attributes)
end
# Logs a message at FATAL level
#
# @param message [String] The log message
# @param parameters [Array] Array of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def fatal(message, parameters = [], **attributes)
log(__method__, message, parameters: parameters, **attributes)
end
# Logs a message at the specified level
#
# @param level [Symbol] The log level (:trace, :debug, :info, :warn, :error, :fatal)
# @param message [String] The log message
# @param parameters [Array, Hash] Array or Hash of values to replace template parameters in the message
# @param attributes [Hash] Additional attributes to include with the log
#
# @return [LogEvent, nil] The created log event or nil if logging is disabled
def log(level, message, parameters:, **attributes)
case parameters
when Array then
Sentry.capture_log(message, level: level, severity: LEVELS[level], parameters: parameters, **attributes)
else
Sentry.capture_log(message, level: level, severity: LEVELS[level], **parameters)
end
end
end
end
|