errsight / docs

Ship with confidence.

Everything you need to integrate ErrSight into your Rails, Python, Rust, React, or React Native app, plus a REST API if you'd rather skip the SDK.

Up and running in two minutes.

Pick your stack. Each path ends with ErrSight capturing every exception, logger call, and user context for you.

License and warranty. The ErrSight SDKs and client libraries are open source under the MIT License, a copy of which ships inside each published package. They are provided "as is" and without warranty of any kind; you install and run them inside your own application at your own risk. See the Terms of Service for the full warranty disclaimer and limitation of liability.

Rb

Ruby on Rails.

Installation

Add to your Gemfile:

gem "errsight"

Then run:

bundle install

Configuration

Create config/initializers/errsight.rb:

Errsight.configure do |config|
  config.api_key                = ENV["ERRSIGHT_API_KEY"]   # required
  config.environment            = Rails.env                  # "production", "staging", etc.
  config.host                   = ENV.fetch("ERRSIGHT_HOST", "https://errsight.com")
  # Verbose log forwarding in development; quiet in production.
  # In production, attach_to_rails_logger=true on a busy app
  # will burn through your event quota fast.
  config.attach_to_rails_logger = Rails.env.development?
  config.min_level              = Rails.env.development? ? :debug : :warning

  # Optional. Defaults shown:
  # config.batch_size     = 10            # events per HTTP request
  # config.flush_interval = 2             # background flush interval (seconds)
  # config.max_queue_size = 1000          # drop events when queue exceeds this
  # config.timeout        = 5             # HTTP open + read timeout (seconds)
  # config.enabled        = true          # set false to disable per environment
end
What happens automatically (v0.1.3+):
  • Every unhandled Rails controller exception is captured with its full backtrace.
  • Every Rails.logger call is forwarded (respecting min_level).
  • User context โ€” id, email, username are pulled from the current Warden user (Devise, ActiveAdmin, any scope). ip_address comes from request.remote_ip even when no one is signed in.
  • Tags (filterable in the UI) โ€” controller, action, request_method, status, ruby_version, rails_version, hostname.
  • Metadata โ€” path, full_path, format, duration, exception_class, and filtered params (respects Rails' filter_parameters).

Manual logging

Use Errsight.log or Errsight.capture_exception anywhere in your app:

# Log at any level
Errsight.log(level: :info,    message: "User signed up", metadata: { plan: "pro" })
Errsight.log(level: :warning, message: "Slow query detected", metadata: { duration_ms: 850 })
Errsight.log(level: :error,   message: "Payment gateway timeout")

# Capture an exception object directly
begin
  charge_card(user)
rescue Stripe::CardError => e
  Errsight.capture_exception(e, metadata: { user_id: user.id, amount: 4900 })
  raise
end

Environment variables

Variable Description
ERRSIGHT_API_KEY Your project API key (elp_โ€ฆ). Required.
ERRSIGHT_HOST API base URL. Default: https://errsight.com
ERRSIGHT_ENV Environment name. Defaults to Rails.env when set via config block.

Py

Python โ€” any framework.

One SDK, first-class integrations for Django, Flask, FastAPI / Starlette, Celery, RQ, and AWS Lambda. Zero runtime dependencies. ContextVar-isolated scopes so concurrent async requests never share state. Python 3.8+.

Installation

The base SDK has no third-party dependencies:

pip install errsight

Or install with the extras for your framework โ€” they pin the right version range:

pip install 'errsight[django]'
pip install 'errsight[flask]'
pip install 'errsight[fastapi]'
pip install 'errsight[celery]'
pip install 'errsight[rq]'

Configuration

Call errsight.init() once at process boot:

import os
import errsight

errsight.init(
    api_key=os.environ["ERRSIGHT_API_KEY"],   # required
    environment="production",                  # default: $ERRSIGHT_ENV or "production"
    host="https://errsight.com",               # default: $ERRSIGHT_HOST
    release=os.environ.get("GIT_SHA"),         # default: $ERRSIGHT_RELEASE
    min_level="warning",                       # debug|info|warning|error|fatal
    # Optional. Defaults shown:
    # batch_size=10,             # events per HTTP request
    # flush_interval=2.0,        # background flush cadence (seconds)
    # max_queue_size=1_000,      # drop events beyond this
    # timeout=5.0,               # HTTP timeout (seconds)
    # before_send=None,          # callable(event) -> event | None
    # attach_to_logging=False,   # auto-attach logging.Handler
)
What happens automatically:
  • errsight.init() registers an atexit handler that drains the queue before the process exits โ€” no manual errsight.close() required.
  • Background flush thread sends events in batches of batch_size every flush_interval seconds.
  • Fork-safe via os.register_at_fork โ€” queued events are not silently lost under gunicorn / uWSGI cluster mode.
  • Structured stack frames with ยฑ5 lines of source context for in-app frames, plus the full __cause__ / __context__ chain.

Django

Add the middleware (works with both sync and async views):

# settings.py
MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "errsight.django.ErrsightMiddleware",   # after AuthenticationMiddleware
    # ...
]

Then call errsight.init() from wsgi.py, asgi.py, or an AppConfig.ready() method. The middleware pushes a per-request scope tagged with request_method, path, and view; populates user from request.user; and captures view exceptions via process_exception with the request's path, method, query params, and view name.

Flask

from flask import Flask
import errsight
from errsight.flask import ErrsightFlask

errsight.init(api_key=os.environ["ERRSIGHT_API_KEY"])
app = Flask(__name__)
ErrsightFlask(app)   # or: ext = ErrsightFlask(); ext.init_app(app)

Reads user from flask_login.current_user if installed, otherwise from flask.g.user. Register ErrsightFlask after any before_request hook that populates g.user. abort(404) and other HTTPException subclasses are filtered out โ€” they're routine app flow, not errors.

FastAPI / Starlette

from fastapi import FastAPI
from errsight.fastapi import ErrsightMiddleware
import errsight

errsight.init(api_key=os.environ["ERRSIGHT_API_KEY"])
app = FastAPI()
app.add_middleware(ErrsightMiddleware)

Pure ASGI middleware โ€” does not break streaming responses the way BaseHTTPMiddleware can. Per-request scope is contextvars-isolated, so concurrent async requests on a single event-loop thread each see their own user / tags. User is late-bound from scope["user"] at capture time, so Starlette's AuthenticationMiddleware still wins. The same module is importable as errsight.starlette for non-FastAPI Starlette apps.

Celery & RQ

Celery โ€” one call wires up all four lifecycle signals:

import errsight
from errsight.celery import install

errsight.init(api_key=os.environ["ERRSIGHT_API_KEY"])
install()

Tasks enqueued from inside with errsight.with_scope(): carry the publisher's user / tags / breadcrumbs through task.request.headers["errsight"] to the worker, which rehydrates them on task_prerun. Failures captured on task_failure include task name, id, args, kwargs, and retry count.

RQ โ€” drop-in Worker subclass:

from rq import Queue
from errsight.rq import ErrsightWorker
import errsight

errsight.init(api_key=os.environ["ERRSIGHT_API_KEY"])
worker = ErrsightWorker([Queue()])
worker.work()

For cross-process scope, pass it explicitly when enqueueing (RQ has no publisher-side signal):

job = queue.enqueue(
    send_email, user.email,
    meta={"errsight": errsight.hub.current_scope().to_dict()},
)

AWS Lambda

import errsight
from errsight.aws_lambda import errsight_lambda

errsight.init(api_key=os.environ["ERRSIGHT_API_KEY"])

@errsight_lambda
def lambda_handler(event, context):
    ...

Per-invocation scope tagged with lambda_function, lambda_version, and aws_request_id. Captures unhandled exceptions with full context including remaining_time_ms (useful for diagnosing timeouts), then synchronously flushes the transport before returning so events aren't lost when Lambda freezes the process between invocations. Pass @errsight_lambda(include_event=True) to attach a 4KB-truncated form of the event payload.

Manual logging and capture

# Log at any level
errsight.log(level="info",    message="user signed up", metadata={"plan": "pro"})
errsight.log(level="warning", message="slow query",     metadata={"duration_ms": 850})
errsight.log(level="error",   message="gateway timeout")

# Capture an exception with optional metadata, tags, or user override
try:
    charge_card(user)
except StripeCardError as exc:
    errsight.capture_exception(exc, metadata={"user_id": user.id, "amount": 4900})
    raise

# Attach context for a block of work
with errsight.with_scope():
    errsight.set_user({"id": user.id, "email": user.email})
    errsight.set_tag("transaction_id", txn.id)
    errsight.add_breadcrumb(category="ui", message="clicked checkout")
    run_pipeline()

# Forward all logger.error / logger.exception calls automatically
import logging
logging.getLogger().addHandler(errsight.LoggingHandler(level=logging.WARNING))

Environment variables

Variable Description
ERRSIGHT_API_KEY Project API key (elp_โ€ฆ). Required unless passed to init() directly.
ERRSIGHT_ENV Environment tag attached to events. Default production.
ERRSIGHT_HOST API base URL. Default https://errsight.com.
ERRSIGHT_RELEASE Release identifier (commit SHA, semantic version). Attached to every event.

Full source on PyPI.


JS

React / JavaScript.

Installation

Install the errsight npm package:

npm install errsight
# or
yarn add errsight

Initialisation

Call Errsight.init() once at the top of your entry point (main.jsx or index.js), before anything else renders:

import Errsight from "errsight"

Errsight.init({
  apiKey:      "elp_your_api_key_here",          // required
  environment: import.meta.env.MODE,              // "production" | "development"
  minLevel:    "error",                            // "debug" | "info" | "warning" | "error" | "fatal"

  // Optional. Defaults shown:
  // captureGlobalErrors: true,                    // attach window.onerror + unhandledrejection
  // batchSize:           10,                      // flush when queue reaches this size
  // flushInterval:       2000,                    // background flush interval in ms (0 disables timer)
})

React ErrorBoundary

Wrap your component tree to catch render-phase errors:

import { createRoot } from "react-dom/client"
import { ErrorBoundary } from "errsight/react"
import App from "./App"

createRoot(document.getElementById("root")).render(
  <ErrorBoundary
    fallback={({ error, reset }) => (
      <div>
        <p>Something went wrong: {error.message}</p>
        <button onClick={reset}>Try again</button>
      </div>
    )}
  >
    <App />
  </ErrorBoundary>
)

The fallback prop accepts a React element or a render-prop function with { error, reset }. Omitting it silently hides the crashed subtree.

User context

Attach the current user after sign-in so every subsequent event carries their ID and email:

// After sign-in
Errsight.setUser({ id: currentUser.id, email: currentUser.email })

// After sign-out
Errsight.clearUser()

Manual logging

Errsight.debug("Rendering checkout step 2")
Errsight.info("User added item to cart", { metadata: { productId: 99 } })
Errsight.warn("API response slow", { metadata: { duration: 2800 } })
Errsight.error("Payment failed", { metadata: { orderId: 42, code: "card_declined" } })

// Pass an Error object to capture its stack trace automatically
try {
  await submitOrder()
} catch (err) {
  Errsight.captureError(err, { metadata: { orderId: 42 } })
}

Configuration options

Option Default Description
apiKey โ€” Required. Your project API key (elp_โ€ฆ).
environment "production" Environment tag attached to every event.
host "https://errsight.com" API base URL. Override for self-hosting.
minLevel "error" Minimum level to send. Options: debug | info | warning | error | fatal.
captureGlobalErrors true Attach window.onerror and unhandledrejection handlers.
batchSize 10 Flush immediately when queue reaches this size.
flushInterval 2000 Flush interval in milliseconds (0 = timer disabled).

RN

React Native.

Installation

Install the errsight-rn package:

npm install errsight-rn
# or
yarn add errsight-rn

Initialisation

Call init() once at your app entry point (App.tsx):

import { init } from "errsight-rn"

init({
  apiKey:      "elp_your_api_key_here",          // required
  environment: "production",                      // default
  minLevel:    "error",                            // "debug" | "info" | "warning" | "error" | "fatal"

  // Optional. Defaults shown:
  // captureGlobalErrors: true,                    // capture ErrorUtils crashes + unhandled rejections
  // batchSize:           10,                      // flush when queue reaches this size
  // flushInterval:       2000,                    // background flush interval in ms (0 disables timer)
})
What happens automatically:
  • Native crashes are captured via React Native's ErrorUtils (the red screen still appears).
  • Unhandled promise rejections are tracked.
  • Events are flushed when the app moves to background via AppState.
  • Device context (platform, OS, OS version) is attached to every event.

React ErrorBoundary

Wrap your component tree to catch render-phase errors:

import { ErrsightProvider, ErrorBoundary } from "errsight-rn/react"

export default function App() {
  return (
    <ErrsightProvider>
      <ErrorBoundary fallback={<Text>Something went wrong.</Text>}>
        <MainScreen />
      </ErrorBoundary>
    </ErrsightProvider>
  )
}

User context

Attach the current user so every event carries their info:

import { getClient } from "errsight-rn"

const client = getClient()

// After sign-in
client?.setUser({ id: currentUser.id, email: currentUser.email })

// After sign-out
client?.clearUser()

Manual logging

import { getClient } from "errsight-rn"

const client = getClient()

client?.debug("Cache miss", { metadata: { key: "user:42" } })
client?.info("User signed in")
client?.warn("Deprecated API called")
client?.error("Payment failed", { metadata: { orderId: "123" } })

// Capture an Error object with its stack trace
try {
  await riskyOperation()
} catch (err) {
  client?.captureError(err, { metadata: { screen: "checkout" } })
}

Rs

Rust, panics included.

A small client that captures panics, typed errors, and log / tracing events, then ships them to ErrSight from a background thread. Capture is non-blocking, delivery is batched and bounded, and the queue drains on shutdown. Requires Rust 1.85+ (edition 2024).

Installation

Add the crate with Cargo:

cargo add errsight

The optional features pull in adapters for the log and tracing ecosystems and for anyhow errors. Add only what you use:

[dependencies]
errsight = { version = "0.1", features = ["tracing", "log", "anyhow"] }

Configuration

Call errsight::init once at the top of main and keep the returned guard alive. Dropping the guard flushes the queue and shuts the client down, so bind it to a variable that lives for the whole program:

fn main() {
    let _guard = errsight::init(
        errsight::Config::builder()
            .api_key(std::env::var("ERRSIGHT_API_KEY").unwrap_or_default())
            .environment("production")             // default: $ERRSIGHT_ENV or "production"
            .release(env!("CARGO_PKG_VERSION"))     // default: $ERRSIGHT_RELEASE
            .min_level(errsight::Level::Warning)    // debug | info | warning | error | fatal
            .build(),
    );

    // ... your application ...
}

Driving everything from the environment instead? errsight::Config::from_env() reads the ERRSIGHT_* variables below and is equivalent to the builder above.

What happens automatically:
  • init installs a panic hook that captures every panic with its backtrace before the process unwinds. Pass .panic_hook(false) to opt out.
  • Events are sent from a background thread in batches, so capture never blocks the calling thread.
  • The client is a no-op until a non-blank API key is present, so it is safe to leave initialised in tests and local runs.
  • The guard flushes and drains the queue on drop, so nothing is lost at a clean exit. Call errsight::flush(timeout) for an explicit checkpoint.

Capturing errors

Report any std::error::Error directly. The type name, message, source chain, and backtrace are recorded for you:

match charge_card(&user) {
    Ok(_) => {}
    Err(err) => {
        // Records the error at "error" level with its full source chain.
        errsight::capture_error(&err);
        return Err(err);
    }
}

// Capture at an explicit level for a recovered error:
errsight::capture_error_at_level(&err, errsight::Level::Warning);

// Ad-hoc message, no error object required:
errsight::capture_message("payment gateway timeout", errsight::Level::Error);

Using anyhow? Enable the anyhow feature and call errsight::integrations::anyhow::capture_anyhow(&err) to keep the original backtrace from where the error was first raised.

Scope and context

Attach a user and tags so every captured event carries who and what:

// Set context that applies to every event from here on:
errsight::configure_scope(|scope| {
    scope.set_user(
        errsight::User::new()
            .id(user.id.to_string())
            .email(user.email.clone()),
    );
    scope.set_tag("plan", "pro");
});

// Or scope context to a single unit of work:
errsight::with_scope(|| {
    errsight::configure_scope(|scope| scope.set_tag("job", "nightly-import"));
    run_import();
});

log and tracing

With the tracing feature, add the ErrSight layer to your subscriber to forward tracing events at or above your minimum level:

use errsight::integrations::tracing::ErrsightLayer;
use tracing_subscriber::prelude::*;

tracing_subscriber::registry()
    .with(tracing_subscriber::fmt::layer())
    .with(ErrsightLayer::new())
    .init();

Standardised on the log crate instead? Enable the log feature and install the logger:

use errsight::integrations::log::ErrsightLogger;

ErrsightLogger::builder().install();

Environment variables

Variable Description
ERRSIGHT_API_KEY Project API key (elp_โ€ฆ). Required; the client is a no-op without it.
ERRSIGHT_ENV Environment tag attached to events. Default production.
ERRSIGHT_HOST API base URL. Default https://errsight.com.
ERRSIGHT_RELEASE Release identifier (commit SHA, semantic version). Attached to every event.
ERRSIGHT_DEBUG Set to 1 to print the client's own diagnostics to stderr while you wire things up.

Full source on crates.io and API docs on docs.rs.


API

REST reference.

If you're using a language without an official SDK, you can POST events directly. CORS is enabled โ€” browser clients work out of the box.

Ingest events

POST /api/v1/events

Authentication via header:

X-API-Key: elp_your_api_key_here
# or
Authorization: Bearer elp_your_api_key_here

Send a single event:

curl -X POST https://errsight.com/api/v1/events \
  -H "Content-Type: application/json" \
  -H "X-API-Key: elp_your_key" \
  -d '{
    "level":       "error",
    "message":     "Payment gateway timeout",
    "environment": "production",
    "occurred_at": "2026-04-13T08:00:00.000Z",
    "metadata": {
      "user_id": 42,
      "order_id": 1234
    }
  }'

Or send a batch (up to 100 events):

curl -X POST https://errsight.com/api/v1/events \
  -H "Content-Type: application/json" \
  -H "X-API-Key: elp_your_key" \
  -d '[
    { "level": "info",  "message": "User signed in", "occurred_at": "2026-04-13T08:00:00Z" },
    { "level": "error", "message": "Card declined",  "occurred_at": "2026-04-13T08:00:01Z" }
  ]'

Response:

HTTP/1.1 202 Accepted
{ "status": "accepted", "queued": 2 }

Payload schema

Field Type Required Description
level string yes debug | info | warning | error | fatal
message string yes Human-readable log message. Max 10,000 chars.
environment string no Defaults to "production" if omitted.
occurred_at ISO 8601 no Event timestamp. Defaults to server receive time.
backtrace string no Stack trace as a newline-separated string.
metadata object no Arbitrary key-value pairs. Max 50 top-level keys.

Error responses

Status Meaning
401Invalid or missing API key.
400Invalid JSON body.
413Payload too large (max 512 KB).
422Batch exceeds 100 events.
429Rate limit exceeded, monthly event limit reached, or storage limit reached.

Key

Write vs read keys.

Every project ships with a default write key โ€” that's the one on your project's Overview, the one you drop into your app's initializer. You can also create additional keys with a read scope on the Manage keys page. Here's the difference and when you'd need one.

Two doors, not one.
  • Inbound door (write): your app sends errors to ErrSight.
  • Outbound door (read): something pulls errors back out of ErrSight.
You don't want the same key opening both doors โ€” and most projects only ever need the first one.

Write keys

Prefix: elp_โ€ฆ. Used by your app (or any service) to ingest events via POST /api/v1/events. This is the key you put in config/initializers/errsight.rb or Errsight.init({ apiKey }). It can send events โ€” nothing else.

Read keys

Prefix: elr_โ€ฆ. Grants access to the read endpoints: GET /api/v1/events and GET /api/v1/issues/:fingerprint. Use these when something outside ErrSight needs to query your error data.

When do you actually need a read key?

You don't need one by default. Create one only when an external tool needs to read your events. Typical cases:

Scenario Key scope
Rails / JS / React Native SDK ingesting errors in production write
CI job that fails the build if new errors appear after a deploy read
Slack bot posting "top 5 errors today" on a schedule read
Custom Grafana / Metabase dashboard pulling metrics read
Browsing the ErrSight web UI neither โ€” the UI uses your login session
The ErrSight dashboard itself never uses an API key. The web UI reads from its own database through your logged-in session. API keys only matter for traffic between other systems and ErrSight's public API.

Why split the scopes?

Because a leaked key should have the smallest possible blast radius:

  • Leaked write key โ€” an attacker can flood your account with fake errors, burning your monthly quota and hiding real issues in noise. Bad, but they can't read anything you've stored.
  • Leaked read key โ€” an attacker can read every error message, stack trace, and user identifier you've ever logged. Much worse.

Shipping a write-only key with your deployed app means even if the binary, bundle, or committed .env gets out, your stored data isn't exposed. Read keys stay in fewer, more trusted places (a CI secret, a dashboard's server-side config).

Managing keys

From a project's Overview, click Manage keys. You can:

  • Create additional keys with either scope, each with a name for bookkeeping (e.g. staging-backend, ci-deploy-check).
  • Revoke any key you've created. Revoked keys stop working immediately; existing events stay intact.
  • See when each key was last used, so dormant keys are easy to spot.
The default ingestion key is protected. You can't revoke it from Manage keys โ€” rotate it from the project's Overview instead, which issues a new value and invalidates the old one in a single step.

Using a read key

Authentication works the same way as ingestion โ€” just use the elr_โ€ฆ token:

# List recent events
curl https://errsight.com/api/v1/events \
  -H "X-API-Key: elr_your_read_key"

# Fetch a specific issue by fingerprint
curl https://errsight.com/api/v1/issues/abc123def456 \
  -H "X-API-Key: elr_your_read_key"

Sl

Slack notifications.

Get error events posted into a Slack channel โ€” either instantly or as an hourly digest. Available on every plan, including free.

How it works:
  • One Slack incoming webhook per organization โ€” it points to a specific channel you choose in Slack.
  • Each member opts in independently and picks their own severity threshold and frequency.
  • When at least one opted-in member's threshold is met, ErrSight posts once to the channel (no duplicate messages per member).

1. Create a Slack incoming webhook

  1. Go to api.slack.com/apps โ†’ Create New App โ†’ From scratch.
  2. Give it a name (e.g. ErrSight), pick your workspace, click Create App.
  3. In the left sidebar, open Incoming Webhooks and toggle Activate Incoming Webhooks to On.
  4. Scroll down, click Add New Webhook to Workspace, pick the destination channel (e.g. #alerts), then Allow.
  5. Copy the webhook URL. It looks like:
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

2. Connect it to ErrSight

  1. Sign in to ErrSight as an org admin.
  2. From the dashboard, open your organization, then click Alerts in the top-right.
  3. In the Slack Integration card, paste the webhook URL and click Save Webhook.
  4. Click Send Test Message โ€” a confirmation post should appear in Slack within a few seconds.
Keep the webhook URL private. Anyone with it can post to your channel. If it leaks, rotate it from the same Slack app page.

3. Configure alert preferences

Each member configures their own delivery on the same Alerts page:

Setting Options Description
Slack Alerts on / off Opt this member in or out of Slack delivery.
Minimum Severity debug โ†’ fatal Only events at or above this level trigger a post.
Frequency immediate / hourly Post per-event, or batch into an hourly digest.

Per-project overrides

Under Per-Project Overrides, use the Slack / Mute Slack button next to a project to toggle that project independently of your default.

Verify end-to-end

Post a test event from any shell to confirm the full pipeline โ€” ingestion, queue, and Slack delivery:

curl -X POST https://errsight.com/api/v1/events \
  -H "Content-Type: application/json" \
  -H "X-API-Key: elp_your_key" \
  -d '{
    "level":       "error",
    "message":     "Slack integration test",
    "environment": "production"
  }'

The message lands in Slack a few seconds after ErrSight accepts the event.

Troubleshooting

Symptom Likely cause
Test message says "webhook did not respond successfully" URL is wrong, or the Slack app was removed from the channel. Re-copy the URL from Slack and save again.
Events arrive in ErrSight but nothing posts to Slack No member has Slack Alerts enabled at a severity that matches the event level.
Slack toggle is disabled on the Alerts page Your org admin hasn't saved a webhook URL yet.
Hourly digest didn't post Digest posts only when at least one event above your Minimum Severity occurred in that hour.

Ruby SDK config.

Option Default Description
api_key ENV["ERRSIGHT_API_KEY"] Required. Your project API key.
environment "production" Environment tag on every event.
host "https://errsight.com" API base URL.
min_level :warning Minimum level to forward. :debug sends everything.
batch_size 10 Number of events per HTTP request.
flush_interval 2 Background flush interval in seconds.
max_queue_size 1000 Drop events when the queue exceeds this size.
timeout 5 HTTP open + read timeout in seconds.
shutdown_timeout 5 Seconds to wait for the flush thread to drain on process shutdown.
attach_to_rails_logger false Broadcast all Rails.logger calls to Errsight (also respects min_level). Off by default to avoid quota burn โ€” opt in for development.
before_send nil Optional callable; receives the event hash, returns it (possibly modified) to send, or nil to drop. PII scrubbing hook.
breadcrumbs_active_record true Auto-collect SQL queries as DB-category breadcrumbs (Rails only).
breadcrumbs_active_record_capture_binds false Include bind values in SQL breadcrumbs. Off by default โ€” bind values often carry PII.
enabled true Set to false to disable in specific environments.

Log levels.

Level Ruby JavaScript When to use
debug :debug "debug" Fine-grained diagnostic info.
info :info "info" Normal application events.
warning:warning"warning"Recoverable issues worth watching.
error:error "error" Errors that affect functionality.
fatal:fatal "fatal" Critical failures. App may be unusable.