### Install Project Dependencies Source: https://github.com/logtail/logtail-ruby/blob/main/spec/README.md Run this command to install all required Ruby gems for the project. Ensure you have Bundler installed. ```shell bundle install ``` -------------------------------- ### Run Example Project Source: https://github.com/logtail/logtail-ruby/blob/main/example-project/README.md Execute this command to run the example application. Remember to replace placeholders with your actual source token and ingesting host. ```bash bundle exec ruby main.rb ``` -------------------------------- ### Rails Initializer Configuration Example Source: https://context7.com/logtail/logtail-ruby/llms.txt Example configuration for Logtail within a Rails initializer file. ```ruby # config/initializers/logtail.rb # config.logtail.debug_to_stdout! # config.logtail.filter_sent_to_better_stack { |e| e.level == :debug } ``` -------------------------------- ### Async HTTP Log Delivery Device Setup Source: https://context7.com/logtail/logtail-ruby/llms.txt Configure Logtail::LogDevices::HTTP for buffered, asynchronous log delivery over HTTPS. It batches, encodes (MessagePack), compresses (zlib), and sends logs without blocking application threads. ```ruby require "logtail" # Basic setup http_device = Logtail::LogDevices::HTTP.new("YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com" ) ``` -------------------------------- ### Millisecond Duration Tracking with Logtail::Timer Source: https://context7.com/logtail/logtail-ruby/llms.txt Use `Logtail.start_timer` or `Logtail::Timer.start` to begin timing, and `Logtail::Timer.duration_ms` to get the elapsed time in milliseconds. Useful for logging query or API call durations. ```ruby require "logtail" logger = Logtail::Logger.new(STDOUT) # Time a database query timer = Logtail.start_timer # equivalent to Logtail::Timer.start result = User.where(active: true).count logger.info("Users counted", db_query: { sql: "SELECT COUNT(*) FROM users WHERE active = true", time_ms: Logtail::Timer.duration_ms(timer).round(2), result: result } ) # Time an external HTTP call timer = Logtail::Timer.start response = Net::HTTP.get(URI("https://api.example.com/health")) logger.info("Health check", http: { url: "https://api.example.com/health", time_ms: Logtail::Timer.duration_ms(timer).round(2), status: 200 }) ``` -------------------------------- ### Rails Integration with Devise Source: https://github.com/logtail/logtail-ruby/blob/main/example-project/README.md Automatically add user context to logs in Rails applications using Devise. This example shows how to implement an `around_action` to wrap requests with logtail context. ```ruby class ApplicationController < ActionController::Base around_action :with_logtail_context private def with_logtail_context if user_signed_in? Logtail.with_context(user_context) { yield } else yield end end def user_context Logtail::Contexts::User.new( id: current_user.id, name: current_user.name, email: current_user.email ) end end ``` -------------------------------- ### Create Logtail Logger Instance Source: https://context7.com/logtail/logtail-ruby/llms.txt Instantiate Logtail::Logger for different environments. Use STDOUT for development (message only), HTTP for production (structured JSON/MessagePack to Better Stack), or combine multiple devices. ```ruby require "logtail" # 1. Log to STDOUT (development — message only, no metadata) logger = Logtail::Logger.new(STDOUT) logger.info("Server started") # => "Server started\n" ``` ```ruby # 2. Log to Better Stack over HTTPS (production — structured JSON) http_device = Logtail::LogDevices::HTTP.new( "YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com" ) logger = Logtail::Logger.new(http_device) logger.info("Payment processed", payment: { amount: 49.99, currency: "USD", customer_id: 42 }) # Delivered as MessagePack batch to Better Stack: # { "level": "info", "dt": "2024-03-15T10:22:01.123456Z", # "message": "Payment processed", # "payment": { "amount": 49.99, "currency": "USD", "customer_id": 42 }, # "context": { "system": { "hostname": "web-1", "pid": 12345 }, # "runtime": { "thread_id": 70123, "file": "app/jobs/payment_job.rb", "line": 28 } } } ``` ```ruby # 3. Log to both a file and Better Stack simultaneously file_device = ::Logger::LogDevice.new("log/production.log") file_logger = ::Logger.new(file_device) logger = Logtail::Logger.new(http_device, file_logger) logger.error("Disk quota exceeded") # Written to log/production.log AND sent to Better Stack ``` -------------------------------- ### Run Project Tests Source: https://github.com/logtail/logtail-ruby/blob/main/spec/README.md Execute this command to run the test suite using RSpec. This verifies the functionality of the project. ```shell bundle exec rspec ``` -------------------------------- ### Release/Deployment Context from Environment Variables Source: https://context7.com/logtail/logtail-ruby/llms.txt Automatically associates log entries with the deployed code version by reading environment variables like `RELEASE_COMMIT`, `RELEASE_VERSION`, and `RELEASE_CREATED_AT`. No code change is needed if environment variables are set. ```ruby # Set env vars before process start (e.g. in Dockerfile or Heroku config): # RELEASE_COMMIT=abc123def456 # RELEASE_VERSION=v2.4.1 # RELEASE_CREATED_AT=2024-03-15T09:00:00Z # Logtail picks these up automatically — no code change needed. # Every log line will include: # "context": { "release": { "commit_hash": "abc123def456", # "version": "v2.4.1", # "created_at": "2024-03-15T09:00:00Z" }, ... } ``` ```ruby # On Heroku, enable dyno metadata instead: # heroku labs:enable runtime-dyno-metadata -a my-app # This sets HEROKU_SLUG_COMMIT, HEROKU_RELEASE_VERSION, HEROKU_RELEASE_CREATED_AT automatically. ``` ```ruby # Manually build a release context if needed release = Logtail::Contexts::Release.from_env puts release.to_hash # => { release: { commit_hash: "abc123def456", version: "v2.4.1", # created_at: "2024-03-15T09:00:00Z" } } ``` -------------------------------- ### Custom HTTP Device Tuning for High-Volume Services Source: https://context7.com/logtail/logtail-ruby/llms.txt Configure the HTTP log device with custom batch size, flush interval, and requests per connection for high-volume services. Alternatively, use a SizedQueue for request queuing to apply back-pressure under heavy load. ```ruby http_device = Logtail::LogDevices::HTTP.new("YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com", batch_size: 500, # flush every 500 messages (default: 1000) flush_interval: 1, # flush every 1 second (default: 2) requests_per_conn: 1_000 # reconnect after 1000 requests (default: 2500) ) # Apply back-pressure instead of dropping logs under heavy load http_device = Logtail::LogDevices::HTTP.new("YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com", request_queue: SizedQueue.new(25) # blocks caller instead of dropping ) logger = Logtail::Logger.new(http_device) logger.info("Application booted") # Force synchronous flush (e.g. before process exit or in scripts) http_device.flush # Verify delivery in CLI scripts / one-off jobs http_device.verify_delivery! ``` -------------------------------- ### Send Debug and Info Logs Source: https://github.com/logtail/logtail-ruby/blob/main/example-project/README.md Use the `debug()` and `info()` methods to send log messages. The `debug()` method is for debugging information, and `info()` is for general application progress. ```ruby # Send debug logs messages using the debug() method logger.debug("Logtail is ready!") # Send informative messages about interesting events using the info() method logger.info("I am using Logtail!") ``` -------------------------------- ### Logtail::LogDevices::HTTP.new Source: https://context7.com/logtail/logtail-ruby/llms.txt Instantiates a buffered, asynchronous HTTPS log delivery device for sending logs to Better Stack. It batches, encodes, compresses, and delivers logs over persistent connections without blocking application threads. ```APIDOC ## Logtail::LogDevices::HTTP.new — Async HTTP log delivery device Instantiates a buffered, asynchronous HTTPS log delivery device. Logs are batched (up to 1 000 entries or 2-second intervals), msgpack-encoded, zlib-compressed, and delivered over persistent keep-alive connections. The device is designed to never block application threads. ```ruby require "logtail" # Basic setup http_device = Logtail::LogDevices::HTTP.new("YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com" ) ``` ``` -------------------------------- ### Global Configuration with Logtail::Config Source: https://context7.com/logtail/logtail-ruby/llms.txt Access the singleton `Logtail::Config` instance to set the global logger, explicitly define the environment, or enable debug logging. This configuration affects all Logtail instances. ```ruby require "logtail" config = Logtail::Config.instance # Set the global logger (non-Rails) config.logger = Logtail::Logger.new( Logtail::LogDevices::HTTP.new("YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com") ) # Set environment explicitly (defaults to RACK_ENV / RAILS_ENV) config.environment = "staging" ``` -------------------------------- ### Implement Custom Logtail Integrator Source: https://context7.com/logtail/logtail-ruby/llms.txt Define a custom integrator by inheriting from `Logtail::Integrator` and implementing the `integrate!` method. Raise `RequirementNotMetError` if necessary dependencies are not met. Call `integrate!` to activate the custom integration. ```ruby class MyIntegrator < Logtail::Integrator def integrate! # Hook into a library here. # Raise RequirementNotMetError if the target library is unavailable. raise RequirementNotMetError, "MyLib not loaded" unless defined?(MyLib) MyLib.on_event { |e| Logtail::Config.instance.logger.info(e.to_s) } end end MyIntegrator.integrate! # => true (or false if disabled / requirement not met) ``` -------------------------------- ### Logtail::Logger.new Source: https://context7.com/logtail/logtail-ruby/llms.txt Creates a new structured logger instance. It can log to various devices like STDOUT, files, or directly to Better Stack via HTTP. ```APIDOC ## Logtail::Logger.new — Create a logger instance Creates a new structured logger bound to one or more IO devices or loggers. When given a `Logtail::LogDevices::HTTP` device the formatter is automatically set to `PassThroughFormatter`; in development/test environments `MessageOnlyFormatter` is used; all other environments default to `JSONFormatter`. ```ruby require "logtail" # 1. Log to STDOUT (development — message only, no metadata) logger = Logtail::Logger.new(STDOUT) logger.info("Server started") # => "Server started\n" # 2. Log to Better Stack over HTTPS (production — structured JSON) http_device = Logtail::LogDevices::HTTP.new( "YOUR_SOURCE_TOKEN", ingesting_host: "in.logs.betterstack.com" ) logger = Logtail::Logger.new(http_device) logger.info("Payment processed", payment: { amount: 49.99, currency: "USD", customer_id: 42 }) # Delivered as MessagePack batch to Better Stack: # { "level": "info", "dt": "2024-03-15T10:22:01.123456Z", # "message": "Payment processed", # "payment": { "amount": 49.99, "currency": "USD", "customer_id": 42 }, # "context": { "system": { "hostname": "web-1", "pid": 12345 }, # "runtime": { "thread_id": 70123, "file": "app/jobs/payment_job.rb", "line": 28 } } } # 3. Log to both a file and Better Stack simultaneously file_device = ::Logger::LogDevice.new("log/production.log") file_logger = ::Logger.new(file_device) logger = Logtail::Logger.new(http_device, file_logger) logger.error("Disk quota exceeded") # Written to log/production.log AND sent to Better Stack ``` ``` -------------------------------- ### Scoped Context Injection with Logtail.with_context Source: https://context7.com/logtail/logtail-ruby/llms.txt Temporarily merge structured data into log lines within a block. Context is thread-local and automatically removed upon block exit. Useful for request-scoped or nested context. ```ruby require "logtail" logger = Logtail::Logger.new(STDOUT) # Add user context for the duration of a request Logtail.with_context(user: { id: 99, email: "alice@example.com", role: "admin" }) do logger.info("Dashboard accessed") logger.warn("Suspicious export attempt", export: { rows: 50_000 }) end # Nest multiple contexts (e.g. inside a Rails around_action) Logtail.with_context(request: { id: "req-abc123", path: "/api/orders" }) do Logtail.with_context(user: { id: 7 }) do logger.info("Order list fetched") # context includes both :request and :user keys end end # Equivalent via logger instance shorthand logger.with_context(job: { id: "job-42", queue: "default" }) do logger.info("Job started") sleep 0.1 logger.info("Job finished") end # Rails around_action pattern class ApplicationController < ActionController::Base around_action :with_logtail_context private def with_logtail_context Logtail.with_context( user: { id: current_user&.id, email: current_user&.email } ) { yield } end end ``` -------------------------------- ### Persistent Context Management with Logtail::CurrentContext Source: https://context7.com/logtail/logtail-ruby/llms.txt Manage context that persists across log calls without a block scope. Use `add` to set context, `remove` to delete specific keys, and `reset` to clear all context. Useful for long-lived processes. ```ruby require "logtail" logger = Logtail::Logger.new(STDOUT) # Add context that stays for all subsequent logs in this thread Logtail::CurrentContext.add( worker: { id: "worker-3", queue: "critical", concurrency: 5 } ) logger.info("Worker started") # includes worker context logger.debug("Polling queue") # includes worker context # Remove specific context key Logtail::CurrentContext.remove(:worker) # Or reset everything (careful: removes auto-added system/runtime context too) Logtail::CurrentContext.reset # Fetch a specific context value hostname = Logtail::CurrentContext.fetch(:system)[:hostname] puts hostname # => "web-1" ``` -------------------------------- ### Add Custom Context to Logs Source: https://github.com/logtail/logtail-ruby/blob/main/example-project/README.md Customize all logged items by adding a custom context, such as a user ID, to the logger instance. ```ruby # Add custom context to all logged items logger.custom_context = { user_id: "user-123" } ``` -------------------------------- ### Configure Logtail Debug Output Source: https://context7.com/logtail/logtail-ruby/llms.txt Enable internal Logtail debug output to STDOUT, a file, or a custom logger. ```ruby config.debug_to_stdout! # or to a file config.debug_to_file!("log/logtail_debug.log") # or with a custom logger config.debug_logger = ::Logger.new(STDERR) ``` -------------------------------- ### Add Context to Logs in Ruby Source: https://github.com/logtail/logtail-ruby/blob/main/example-project/README.md Use `Logtail.with_context` to add key-value pairs to all logs within the block. This is useful for tracking user sessions or request-specific data. ```ruby Logtail.with_context(user: { id: 123 }) do logger.info('new subscription') end ``` -------------------------------- ### Logtail JSONFormatter for Production Source: https://context7.com/logtail/logtail-ruby/llms.txt Configures the logger to use `JSONFormatter` for outputting full structured JSON per log line. This is auto-selected in production environments with non-HTTP devices. ```ruby require "logtail" # JSONFormatter — full structured JSON per line (auto-selected in production with non-HTTP device) logger.formatter = Logtail::Logger::JSONFormatter.new logger.info("User logged in", user: { id: 7 }) # => {"level":"info","dt":"2024-03-15T10:22:01.123456Z","message":"User logged in", # "user":{"id":7},"context":{...}}\n ``` -------------------------------- ### Log Structured Data with Warn Message Source: https://github.com/logtail/logtail-ruby/blob/main/example-project/README.md Send warning messages with additional structured data as the second argument. This is useful for providing context to non-critical issues. ```ruby # Send messages about worrying events using the warn() method # You can also log additional structured data logger.warn( "log structured data", item: { url: "https://fictional-store.com/item-123", price: 100.00 } ) ``` -------------------------------- ### Structured Message Logging with Logtail::Logger Source: https://context7.com/logtail/logtail-ruby/llms.txt Use standard log-level methods with an optional hash argument for structured data. The hash keys become payload fields, with ':message' for the human-readable string and ':tag'/:tags' for filtering. ```ruby logger = Logtail::Logger.new(STDOUT) # Plain message logger.debug("Cache miss for key user:42") # Structured data as second argument (key becomes the event namespace) logger.info("Order shipped", order: { id: "ORD-9981", items: 3, weight_kg: 1.2 }) # Using :message key inside the hash logger.warn(message: "Retry attempt", attempt: { count: 2, max: 5, job: "EmailWorker" }) # Tagged log lines logger.error("Auth failure", message: "Invalid token", tags: ["security", "auth"], auth: { ip: "203.0.113.45", user_agent: "curl/7.88" }) # Logging exceptions begin Integer("not_a_number") rescue => e logger.error("Conversion failed", error: { class: e.class.name, message: e.message, backtrace: e.backtrace&.first(5) }) end # Output (JSONFormatter, production): # {"level":"error","dt":"2024-03-15T10:22:01.123456Z","message":"Conversion failed", # "error":{"class":"ArgumentError","message":"invalid value for Integer(): \"not_a_number\"", # "backtrace":["(irb):2:in `Integer'"], # "context":{"system":{"hostname":"web-1","pid":12345},"runtime":{"thread_id":70123}}} ``` -------------------------------- ### Logtail PassThroughFormatter for HTTP Device Source: https://context7.com/logtail/logtail-ruby/llms.txt The `PassThroughFormatter` is automatically selected for HTTP log devices and returns the `LogEntry` object directly. The formatter cannot be changed after initialization when using an HTTP device. ```ruby require "logtail" # PassThroughFormatter — returns LogEntry object (auto-selected for HTTP device, not user-facing) # Note: formatter cannot be changed after initialization when using HTTP device http_device = Logtail::LogDevices::HTTP.new("token", ingesting_host: "in.logs.betterstack.com") logger = Logtail::Logger.new(http_device) # logger.formatter is automatically PassThroughFormatter; changing it raises ArgumentError ``` -------------------------------- ### Logtail AugmentedFormatter for Log Shippers Source: https://context7.com/logtail/logtail-ruby/llms.txt Configures the logger to use `AugmentedFormatter`, which outputs a human-readable message followed by appended `@metadata` JSON. This is useful for log shippers that can parse this format. ```ruby require "logtail" # AugmentedFormatter — human message + appended @metadata JSON (useful for log shippers) logger.formatter = Logtail::Logger::AugmentedFormatter.new logger.info("User logged in") # => "User logged in @metadata {"level":"info","dt":"...","context":{...}}\n" ``` -------------------------------- ### Logtail::Logger log-level methods Source: https://context7.com/logtail/logtail-ruby/llms.txt Uses standard log-level methods (`debug`, `info`, `warn`, `error`, `fatal`) to log messages. An optional second argument hash allows merging structured data into the log payload. ```APIDOC ## Logtail::Logger log-level methods — Structured message logging All five standard log-level methods (`debug`, `info`, `warn`, `error`, `fatal`) accept an optional second argument. When that argument is a `Hash`, its keys are merged into the structured payload; the `:message` key becomes the human-readable message, and `:tag`/`:tags` keys populate the tags array. ```ruby logger = Logtail::Logger.new(STDOUT) # Plain message logger.debug("Cache miss for key user:42") # Structured data as second argument (key becomes the event namespace) logger.info("Order shipped", order: { id: "ORD-9981", items: 3, weight_kg: 1.2 }) # Using :message key inside the hash logger.warn(message: "Retry attempt", attempt: { count: 2, max: 5, job: "EmailWorker" }) # Tagged log lines logger.error("Auth failure", message: "Invalid token", tags: ["security", "auth"], auth: { ip: "203.0.113.45", user_agent: "curl/7.88" }) # Logging exceptions begin Integer("not_a_number") rescue => e logger.error("Conversion failed", error: { class: e.class.name, message: e.message, backtrace: e.backtrace&.first(5) }) end # Output (JSONFormatter, production): # {"level":"error","dt":"2024-03-15T10:22:01.123456Z","message":"Conversion failed", # "error":{"class":"ArgumentError","message":"invalid value for Integer(): \"not_a_number\"", # "backtrace":["(irb):2:in `Integer'"]}, # "context":{"system":{"hostname":"web-1","pid":12345},"runtime":{"thread_id":70123}}} ``` ``` -------------------------------- ### Add User Context to Logs Source: https://context7.com/logtail/logtail-ruby/llms.txt Attaches authenticated user information to log lines using `Logtail::Contexts::User`. This context is automatically removed after the block when using `Logtail.with_context`. ```ruby require "logtail" logger = Logtail::Logger.new(STDOUT) user_ctx = Logtail::Contexts::User.new(id: 42, name: "Alice Smith", email: "alice@example.com") Logtail::CurrentContext.add(user_ctx) logger.info("Profile updated") # context includes: "user": {"id": 42, "name": "Alice Smith", "email": "alice@example.com"} ``` ```ruby # More commonly via with_context shorthand (auto-removed after block) Logtail.with_context(user: { id: 42, name: "Alice Smith", email: "alice@example.com" }) do logger.info("Checkout completed") logger.warn("Coupon not found", coupon: { code: "SAVE20" }) end ``` -------------------------------- ### Disable Logtail Integrations Source: https://context7.com/logtail/logtail-ruby/llms.txt Control framework integrations by silencing or disabling specific library integrations or low-level subscribers. Integration status can also be checked. ```ruby require "logtail" # Disable an entire library integration Logtail::Config.instance.integrations.active_record.silence = true # Disable a specific low-level integrator # Logtail::Integrations::ActiveRecord::LogSubscriber.enabled = false # Silence Rails ActionController logs (don't generate them at all) # Logtail::Integrations::ActionController.silence = true # Check integration status # puts Logtail::Config.instance.integrations.active_record.silence? # => true ``` -------------------------------- ### Filter Logs Sent to Better Stack Source: https://context7.com/logtail/logtail-ruby/llms.txt Define filters to exclude specific log entries from being sent to Better Stack. The block should return true if the log should NOT be sent. ```ruby config.filter_sent_to_better_stack { |entry| entry.message.include?("DO_NOT_SEND") } ``` ```ruby config.filter_sent_to_better_stack { |entry| entry.context_snapshot.dig(:http, :path)&.start_with?("/_health") } ``` -------------------------------- ### Logtail MessageOnlyFormatter for Development Source: https://context7.com/logtail/logtail-ruby/llms.txt Configures the logger to use `MessageOnlyFormatter` for plain text output without metadata. This is auto-selected in development and test environments. ```ruby require "logtail" # MessageOnlyFormatter — plain text, no metadata (auto-selected in development/test) logger = Logtail::Logger.new(STDOUT) logger.formatter = Logtail::Logger::MessageOnlyFormatter.new logger.info("User logged in") # => "User logged in\n" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.