Class: LogStruct::Log::SQL
- Inherits:
-
T::Struct
- Object
- T::Struct
- LogStruct::Log::SQL
- Extended by:
- T::Sig
- Includes:
- Interfaces::AdditionalDataField, Interfaces::CommonFields, MergeAdditionalDataFields, SerializeCommon
- Defined in:
- lib/log_struct/log/sql.rb
Overview
SQL Query Log Structure
Captures detailed information about SQL queries executed through ActiveRecord. This provides structured logging for database operations, including:
- Query text and operation name
- Execution timing and performance metrics
- Row counts and connection information
- Safely filtered bind parameters
Use Cases:
- Development debugging of N+1 queries
- Production performance monitoring
- Database query analysis and optimization
- Audit trails for data access patterns
Security:
- SQL queries are safe (always parameterized with ?)
- Bind parameters are filtered through LogStruct's param filters
- Sensitive data like passwords, tokens are automatically scrubbed
Example Usage:
# Automatically captured when SQL query integration is enabled
LogStruct.config.integrations.enable_sql_logging = true
# Manual logging (rare)
sql_log = LogStruct::Log::SQL.new(
message: "User lookup query",
sql: "SELECT * FROM users WHERE id = ?",
name: "User Load",
duration: 2.3,
row_count: 1,
bind_params: [123]
)
LogStruct.info(sql_log)
Constant Summary collapse
Instance Attribute Summary collapse
-
#active_connections ⇒ Integer?
readonly
Active connection count (for monitoring).
-
#additional_data ⇒ Hash{Symbol => T.untyped}
readonly
Allow additional custom data.
-
#bind_params ⇒ Array<T.untyped>?
readonly
Filtered bind parameters (sensitive data removed).
-
#connection_adapter ⇒ String?
readonly
Database connection information (adapter name).
-
#connection_pool_size ⇒ Integer?
readonly
Connection pool size information (for monitoring).
-
#database_name ⇒ String?
readonly
Database name (if available).
-
#duration ⇒ Float
readonly
Duration of the query execution in milliseconds.
-
#event ⇒ SQLEvent
readonly
Returns the value of prop
event
. -
#level ⇒ Level
readonly
Returns the value of prop
level
. -
#message ⇒ String
readonly
Returns the value of prop
message
. -
#name ⇒ String
readonly
The name of the database operation (e.g., "User Load", "Post Create").
-
#operation_type ⇒ String?
readonly
SQL operation type (SELECT, INSERT, UPDATE, DELETE, etc.).
-
#row_count ⇒ Integer?
readonly
Number of rows affected or returned by the query.
-
#source ⇒ Source
readonly
Common fields.
-
#sql ⇒ String
readonly
The SQL query that was executed (parameterized, safe to log).
-
#table_names ⇒ Array<String>?
readonly
Table names involved in the query (extracted from SQL).
-
#timestamp ⇒ Time
readonly
Returns the value of prop
timestamp
.
Instance Method Summary collapse
- #initialize(source: T.let(Source::App, Source), event: T.let(Event::Database, SQLEvent), level: T.let(Level::Info, Level), timestamp:, message:, sql:, name:, duration:, row_count: nil, connection_adapter: nil, bind_params: nil, database_name: nil, connection_pool_size: nil, active_connections: nil, operation_type: nil, table_names: nil, additional_data: {}) ⇒ void constructor
-
#serialize(strict = true) ⇒ Hash{Symbol => T.untyped}
Convert the log entry to a hash for serialization.
Methods included from MergeAdditionalDataFields
Methods included from SerializeCommon
Constructor Details
#initialize(source: T.let(Source::App, Source), event: T.let(Event::Database, SQLEvent), level: T.let(Level::Info, Level), timestamp:, message:, sql:, name:, duration:, row_count: nil, connection_adapter: nil, bind_params: nil, database_name: nil, connection_pool_size: nil, active_connections: nil, operation_type: nil, table_names: nil, additional_data: {}) ⇒ void
|
# File '' const :source, Source, default: T.let(Source::App, Source) const :event, SQLEvent, default: T.let(Event::Database, SQLEvent) const :level, Level, default: T.let(Level::Info, Level) const :timestamp, Time, factory: -> { Time.now } const :message, String const :sql, String const :name, String const :duration, Float const :row_count, T.nilable(Integer) const :connection_adapter, T.nilable(String) const :bind_params, T.nilable(T::Array[T.untyped]) const :database_name, T.nilable(String) const :connection_pool_size, T.nilable(Integer) const :active_connections, T.nilable(Integer) const :operation_type, T.nilable(String) const :table_names, T.nilable(T::Array[String]) const :additional_data, T::Hash[Symbol, T.untyped], default: {} |
Instance Attribute Details
#active_connections ⇒ Integer? (readonly)
Active connection count (for monitoring)
|
# File '' const :active_connections, T.nilable(Integer) |
#additional_data ⇒ Hash{Symbol => T.untyped} (readonly)
Allow additional custom data
|
# File '' const :additional_data, T::Hash[Symbol, T.untyped], default: {} |
#bind_params ⇒ Array<T.untyped>? (readonly)
Filtered bind parameters (sensitive data removed)
|
# File '' const :bind_params, T.nilable(T::Array[T.untyped]) |
#connection_adapter ⇒ String? (readonly)
Database connection information (adapter name)
|
# File '' const :connection_adapter, T.nilable(String) |
#connection_pool_size ⇒ Integer? (readonly)
Connection pool size information (for monitoring)
|
# File '' const :connection_pool_size, T.nilable(Integer) |
#database_name ⇒ String? (readonly)
Database name (if available)
|
# File '' const :database_name, T.nilable(String) |
#duration ⇒ Float (readonly)
Duration of the query execution in milliseconds
|
# File '' const :duration, Float |
#event ⇒ SQLEvent (readonly)
Returns the value of prop event
.
|
# File '' const :event, SQLEvent, default: T.let(Event::Database, SQLEvent) |
#level ⇒ Level (readonly)
Returns the value of prop level
.
|
# File '' const :level, Level, default: T.let(Level::Info, Level) |
#message ⇒ String (readonly)
Returns the value of prop message
.
|
# File '' const :message, String |
#name ⇒ String (readonly)
The name of the database operation (e.g., "User Load", "Post Create")
|
# File '' const :name, String |
#operation_type ⇒ String? (readonly)
SQL operation type (SELECT, INSERT, UPDATE, DELETE, etc.)
|
# File '' const :operation_type, T.nilable(String) |
#row_count ⇒ Integer? (readonly)
Number of rows affected or returned by the query
|
# File '' const :row_count, T.nilable(Integer) |
#source ⇒ Source (readonly)
Common fields
|
# File '' const :source, Source, default: T.let(Source::App, Source) |
#sql ⇒ String (readonly)
The SQL query that was executed (parameterized, safe to log)
|
# File '' const :sql, String |
#table_names ⇒ Array<String>? (readonly)
Table names involved in the query (extracted from SQL)
|
# File '' const :table_names, T.nilable(T::Array[String]) |
#timestamp ⇒ Time (readonly)
Returns the value of prop timestamp
.
|
# File '' const :timestamp, Time, factory: -> { Time.now } |
Instance Method Details
#serialize(strict = true) ⇒ Hash{Symbol => T.untyped}
Convert the log entry to a hash for serialization
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/log_struct/log/sql.rb', line 104 def serialize(strict = true) hash = serialize_common(strict) merge_additional_data_fields(hash) # Add SQL-specific fields using LOG_KEYS mapping for consistency hash[LOG_KEYS.fetch(:message)] = hash[LOG_KEYS.fetch(:sql)] = sql hash[LOG_KEYS.fetch(:name)] = name hash[LOG_KEYS.fetch(:duration)] = duration hash[LOG_KEYS.fetch(:row_count)] = row_count hash[LOG_KEYS.fetch(:connection_adapter)] = connection_adapter hash[LOG_KEYS.fetch(:bind_params)] = bind_params hash[LOG_KEYS.fetch(:database_name)] = database_name hash[LOG_KEYS.fetch(:connection_pool_size)] = connection_pool_size hash[LOG_KEYS.fetch(:active_connections)] = active_connections hash[LOG_KEYS.fetch(:operation_type)] = operation_type hash[LOG_KEYS.fetch(:table_names)] = table_names hash end |