Sentry

repository·master·Indexed 13 days ago

https://github.com/getsentry/sentry

A comprehensive debugging and error-tracking platform that helps developers detect, trace, and resolve software issues. Sentry provides visibility into code failures through issue details, traces, replays, logs, and uptime monitoring, with official SDKs available for a wide range of programming languages and frameworks.

Tokens
117K
Snippets
393
Records
536
Agent score
99%

What's inside Sentry

  1. Overview of Sentry

    master
    Sentry is a debugging platform designed to help developers detect, trace, and fix issues in their applications. It provides visibility into code failures through features like issue details, traces, replays, logs, and uptime monitoring.
  2. Locate Auth V2 frontend and backend code

    master

    The Auth V2 implementation is split between the frontend and backend. If you are working on authentication features:

    • Frontend code: Located in static/app/views/authV2/.
    • Backend code: Located in src/sentry/auth_v2/.

    For legacy or related authentication logic, refer to the existing code in static/app/views/auth/.

  3. Understand apigw package structure

    master

    The apigw package is organized as follows:

    • __init__.py: Initializes the app instance and extensions (Prometheus, Sentry, AsyncPG).
    • config.py: Handles environment-based configuration and Django bootstrap.
    • db.py: Manages the asyncpg pool and provides the adapter to convert Django-SQL to asyncpg placeholders.
    • dsl.py: Handles cell resolution, including organization mapping lookups and DSN parsing.
    • circuitbreaker.py: Implements per-target concurrency caps and failure-window breakers.
    • proxy.py: The core proxy engine using a streaming httpx client.
    • utils.py: General utilities.
    • web.py: The module exposing the app entrypoint.
    • views/proxy.py: The central routing table containing cell and control routes.
    • views/_internal.py: Internal endpoints, such as health checks.
  4. What is Node Storage and when to use it

    master

    Node Storage is a multiple-backend-compatible engine used to store the raw body of an Event.

    Because Sentry Events can be several megabytes in size, storing them directly in relational databases like PostgreSQL or MySQL can cause performance issues with wide rows during CRUD operations. Node Storage solves this by offloading the large event content to a key/value database, which is better suited for large payloads.

  5. What is apigw and how does it route traffic?

    master

    Overview

    apigw is a silo-aware routing proxy that sits in front of sentry.io. Its primary purpose is to terminate incoming customer traffic and forward requests to the correct destination: the control silo, the specific cell owning an organization, or a default cell.

    Routing Logic

    Routing decisions are based on the SiloMode of the Django view registered for a specific path.

    • Control Silo: Handles control-bound traffic.
    • Org-scoped Cells: Handles requests belonging to a specific organization's cell.
    • Default Cell: Handles legacy paths pinned to a specific cell (e.g., the US cell).

    Key Differences from ApiGatewayMiddleware

    Unlike the Django-based ApiGatewayMiddleware, apigw is a thin async service built on emmett55. This provides several advantages:

    • Performance: It avoids the full Django request cycle for proxied requests, meaning the control silo only sees traffic explicitly meant for it.
    • Concurrency: It uses an async httpx client to stream requests and responses in both directions, allowing it to handle thousands of concurrent long-lived requests (like file uploads) without being bound by worker counts.
    • Routing: Uses a Rust-based router for high-performance matching.
    • Database: Performs cell lookups using asyncpg with a dedicated pool, rather than the synchronous Django ORM.
  6. How the Billing Platform architecture works

    master

    The Billing Platform uses a service-oriented architecture designed for strict boundaries and observability. Key architectural principles include:

    • Service Boundaries: Services are isolated with no cross-service imports allowed.
    • Protobuf Interfaces: All service methods are defined using Protobuf to ensure consistent data contracts.
    • Uniform Construction: Services are constructed uniformly without requiring arguments in __init__.
    • Observability: Built-in support for metrics and logging is provided at the platform level.

    As the platform evolves, these service implementations will transition to external services, where the existing interfaces will delegate calls to RPC endpoints.

  7. How to consume design tokens

    master

    Tokens are the smallest unit of the Sentry Design System, representing discrete design decisions.

    Developers should not consume tokens directly as a primary integration surface. Instead, consume tokens by composing component primitives (e.g. <Container />, <Text />) with the correct props. This allows the components to handle the underlying token wiring.

    Direct token access is reserved for low-level core components maintained by the Design Engineering team when abstraction is impractical.

    /* ✅ Prefer using component primitives with props instead of raw tokens */
    <Text variant="danger">Error message</Text>
    
    /* ❌ Avoid direct token wiring in feature code unless building core components */
    const Component = styled('span')`
      background-color: ${p => p.theme.tokens.background.danger.vibrant}
    `;
  8. Choose between InlineCode, CodeBlock, and monospace Text

    master

    Select the appropriate component based on the type and length of the code snippet:

    ComponentUse Case
    <InlineCode>Short snippets (variables, function names, single commands) within a sentence.
    <CodeBlock>Multi-line code snippets that require syntax highlighting.
    <Text monospace>Non-code monospace content, such as user IDs (e.g., usr_12345).

    Note: When documenting API endpoints, use <InlineCode> for the endpoint string (e.g., POST /api/events), but use a CodeBlock (or CodeSnippet) for full request/response examples.

  9. Validate forms with Zod schemas

    master

    Validation is schema-driven using Zod. Pass your schema to the validators: {onDynamic: schema} option in useScrapsForm for form-wide validation, or use the validators prop on an AppField for field-specific validation.

    Cross-Field Validation: Use Zod's .refine() method to validate dependencies between multiple fields (e.g., confirming a password).

    Per-Field Validation: To apply validation logic to a single field only, pass a validators object to the AppField component.

    // Cross-field validation example
    const schema = z
      .object({
        password: z.string(),
        confirmPassword: z.string(),
      })
      .refine(data => data.password === data.confirmPassword, {
        message: 'Passwords do not match',
        path: ['confirmPassword'],
      });
    
    // Per-field validation example
    <form.AppField
      name="secret"
      validators={{
        onDynamic: z.string().min(1, 'Secret is required'),
      }}
    >
      {field => (
        <field.Layout.Row label="Secret" required>
          <field.Input value={field.state.value ?? ''} onChange={field.handleChange} />
        </field.Layout.Row>
      )}
    </form.AppField>
  10. Communicate between billing services using service methods

    master

    Billing services in the platform have strict boundaries. You must never perform direct imports across service directories (e.g., importing a model from sentry.billing.platform.services.contract.models). Instead, use the public service methods provided by the service's entry point to ensure proper encapsulation and communication.

    # ❌ WRONG: Direct import
    from sentry.billing.platform.services.contract.models import Contract
    
    # ✅ CORRECT: Service method
    from sentry.billing.platform.services.contract import ContractService
    contract = ContractService().get_contract(GetContractRequest(organization_id=1))
  11. How Sentry Contexts work

    master

    Contexts are supplemental data added to an event payload (stored in the contexts field) to aid in debugging. They are rendered in the Contexts section of the Sentry issue details page.

    There are three types of contexts:

    1. Raw: Unformatted user data (not handled by UI formatting logic).
    2. Known: Common contexts shared across SDKs where keys are displayed in user-friendly language (e.g., browser, device, os).
    3. Platform: Contexts specific to a particular platform (e.g., laravel, react, unity).

    To add data to an event, you must configure it in the SDK. This document specifically covers how to implement the UI rendering logic for these contexts within the Sentry platform.

  12. How Notification Actions are composed

    master

    A Notification Action is composed of four primary components:

    1. Triggers: The source event (e.g., what happened in Sentry that caused the notification).
    2. Services: The delivery mechanism (e.g., Slack, PagerDuty, MSTeams, or Sentry Notifications).
    3. Targets: The recipient type (e.g., a user, a team, or a specific integration).
    4. Registrations: The ActionRegistration subclass that defines the logic for the specific combination of trigger, service, and target.