Configuration
LogStruct is designed to be highly configurable while working with sensible defaults. You can customize how and where logs are generated, which integrations are enabled, and how errors are handled.
Create a file at config/initializers/logstruct.rb
with your desired configuration.
LogStruct.configure do |config|
# your configuration here
end
Enabling LogStruct
LogStruct can be enabled or disabled in the following ways:
- LogStruct will be enabled if the
LOGSTRUCT_ENABLED
environment variable is set to"true"
. - LogStruct will be disabled if
LOGSTRUCT_ENABLED
is set to any other value. - If
LOGSTRUCT_ENABLED
is undefined, LogStruct will be enabled if the current Rails environment is listed inconfig.enabled_environments
. - Finally, you can manually set
config.enabled
in an initializer. This will override all other configuration methods.
First, we check if config.enabled_environments
includes the current Rails environment. If it does, we use that value. Otherwise, we check the LOGSTRUCT_ENABLED
environment variable. If that is not set, we fall back to config.enabled
.
Environment Configuration
LogStruct supports different environments and handles them appropriately:
LogStruct.configure do |config|
config.enabled_environments = [:test, :production]
# LogStruct will raise errors in local environments,
# and log or report errors in production.
# (This can be configured with config.error_handling_modes)
config.local_environments = [:development, :test]
end
Integration Configuration
LogStruct integrates with many popular gems. You can enable or disable specific integrations:
LogStruct.configure do |config|
# Enable/disable specific integrations
config.integrations.enable_lograge = true
config.integrations.enable_actionmailer = true
config.integrations.enable_activejob = true
config.integrations.enable_activestorage = true
config.integrations.enable_carrierwave = true
config.integrations.enable_host_authorization = true
config.integrations.enable_rack_error_handler = true
config.integrations.enable_shrine = true
config.integrations.enable_sidekiq = true
config.integrations.enable_sorbet_error_handlers = true
# Configure custom options for Lograge
config.integrations.lograge_custom_options = ->(event, _) {
{
# Add custom fields to your Lograge output
user_id: event.payload[:user_id],
correlation_id: event.payload[:correlation_id]
}
}
end
Filtering Sensitive Data
LogStruct includes robust filtering for sensitive data to ensure privacy and security:
LogStruct.configure do |config|
# Configure which params should be filtered
config.filters.filter_keys = [
:password, :password_confirmation, :token, :secret,
:credit_card, :ssn, :social_security
]
# Configure which params should include hashes for values
config.filters.filter_keys_with_hashes = [
:email, :email_address
]
# Configure sensitive data filtering for all strings
config.filters.email_addresses = true # Filter email addresses
config.filters.url_passwords = true # Filter passwords in URLs
config.filters.credit_card_numbers = true # Filter credit card numbers
config.filters.phone_numbers = true # Filter phone numbers
config.filters.ssns = true # Filter social security numbers
config.filters.ip_addresses = false # Filter IP addresses (off by default)
config.filters.mac_addresses = false # Filter MAC addresses (off by default)
# Configure the salt used for hashing filtered email addresses
config.filters.hash_salt = ENV.fetch("EMAIL_HASH_SALT", "test_salt")
# Configure the length of hash output for filtered emails (default: 12)
config.filters.hash_length = 12
end
Error Handling Configuration
LogStruct provides customizable error handling modes to control how errors are processed. You probably don't want type-checking errors or internal logging-related errors to crash your application, so our default behavior is to log and report those errors without crashing. We automatically detect which error reporting service you use (Sentry, Bugsnag, Rollbar, etc.). If you use a service that we don't support yet, you can configure a custom error handler. (Or you can send a PR!)
LogStruct.configure do |config|
# Configure error handling modes
modes = config.error_handling_modes
modes.type_checking_errors = LogStruct::ErrorHandlingMode::ReportProduction
modes.logstruct_errors = LogStruct::ErrorHandlingMode::ReportProduction
modes.security_errors = LogStruct::ErrorHandlingMode::Report
modes.standard_errors = LogStruct::ErrorHandlingMode::Raise
end
Custom Lograge Options
You can extend Lograge request logging with custom fields:
# Provide a custom proc to extend Lograge options
LogStruct.configure do |config|
config.integrations.lograge_custom_options = T.let(->(event, options) do
# Add custom fields to the options hash
options[:user_id] = event.payload[:user_id] if event.payload[:user_id]
options[:account_id] = event.payload[:account_id] if event.payload[:account_id]
options
end,
LogStruct::Handlers::LogrageCustomOptions)
end
Custom String Scrubbing
You can implement custom string scrubbers to filter out sensitive data that isn't caught by the built-in filters:
# Set a custom string scrubbing handler that will be called
# after the built-in scrubbers run
LogStruct.configure do |config|
config.string_scrubbing_handler = T.let(->(value) {
# Custom string scrubbing logic here
# Example: Remove all bank account numbers that match the pattern
value.gsub(/\b\d{10,12}\b/, "[BANK_ACCOUNT]")
},
LogStruct::Handlers::StringScrubber)
end
Custom Error Reporting
If LogStruct doesn't support your error reporting service, you can register a custom error reporting handler. (Or submit a PR!)
LogStruct.configure do |config|
config.error_reporting_handler = T.let(->(error, context, source) {
# Custom error reporting logic here
# You could send errors to a custom service, log them specially, etc.
# This is just a simple example:
# Extract info from the error
error_class = error.class.name
error_message = error.message
# Log to a custom target
puts "[CUSTOM ERROR REPORTER] #{error_class}: #{error_message}"
puts "Context: #{context.inspect}"
puts "Backtrace: #{error.backtrace&.first(5)&.join("\n ")}"
},
LogStruct::Handlers::ErrorReporter)
end
Sorbet Integration
LogStruct integrates with Sorbet to handle type checking errors based on the environment. We raise type errors or logging-related errors in test/development so you can catch them early, but we only log or report them in production. You can configure a different error handling mode to change this behavior.
config.integrations.enable_sorbet_error_handlers = true
# This configures the following error handlers for Sorbet:
# - T::Configuration.inline_type_error_handler
# - T::Configuration.call_validation_error_handler
# - T::Configuration.sig_builder_error_handler
# - T::Configuration.sig_validation_error_handler