Skip to main content

An extremely fast Python linter and code formatter, written in Rust.

Project description

Ruff

Ruff image image image Actions status Discord

Docs | Playground

An extremely fast Python linter and code formatter, written in Rust.

Shows a bar chart with benchmark results.

Linting the CPython codebase from scratch.

  • ⚡️ 10-100x faster than existing linters (like Flake8) and formatters (like Black)
  • 🐍 Installable via pip
  • 🛠️ pyproject.toml support
  • 🤝 Python 3.13 compatibility
  • ⚖️ Drop-in parity with Flake8, isort, and Black
  • 📦 Built-in caching, to avoid re-analyzing unchanged files
  • 🔧 Fix support, for automatic error correction (e.g., automatically remove unused imports)
  • 📏 Over 800 built-in rules, with native re-implementations of popular Flake8 plugins, like flake8-bugbear
  • ⌨️ First-party editor integrations for VS Code and more
  • 🌎 Monorepo-friendly, with hierarchical and cascading configuration

Ruff aims to be orders of magnitude faster than alternative tools while integrating more functionality behind a single, common interface.

Ruff can be used to replace Flake8 (plus dozens of plugins), Black, isort, pydocstyle, pyupgrade, autoflake, and more, all while executing tens or hundreds of times faster than any individual tool.

Ruff is extremely actively developed and used in major open-source projects like:

...and many more.

Ruff is backed by Astral. Read the launch post, or the original project announcement.

Testimonials

Sebastián Ramírez, creator of FastAPI:

Ruff is so fast that sometimes I add an intentional bug in the code just to confirm it's actually running and checking the code.

Nick Schrock, founder of Elementl, co-creator of GraphQL:

Why is Ruff a gamechanger? Primarily because it is nearly 1000x faster. Literally. Not a typo. On our largest module (dagster itself, 250k LOC) pylint takes about 2.5 minutes, parallelized across 4 cores on my M1. Running ruff against our entire codebase takes .4 seconds.

Bryan Van de Ven, co-creator of Bokeh, original author of Conda:

Ruff is ~150-200x faster than flake8 on my machine, scanning the whole repo takes ~0.2s instead of ~20s. This is an enormous quality of life improvement for local dev. It's fast enough that I added it as an actual commit hook, which is terrific.

Timothy Crosley, creator of isort:

Just switched my first project to Ruff. Only one downside so far: it's so fast I couldn't believe it was working till I intentionally introduced some errors.

Tim Abbott, lead developer of Zulip:

This is just ridiculously fast... ruff is amazing.

Table of Contents

For more, see the documentation.

  1. Getting Started
  2. Configuration
  3. Rules
  4. Contributing
  5. Support
  6. Acknowledgements
  7. Who's Using Ruff?
  8. License

Getting Started

For more, see the documentation.

Installation

Ruff is available as ruff on PyPI.

Invoke Ruff directly with uvx:

uvx ruff check   # Lint all files in the current directory.
uvx ruff format  # Format all files in the current directory.

Or install Ruff with uv (recommended), pip, or pipx:

# With uv.
uv tool install ruff@latest  # Install Ruff globally.
uv add --dev ruff            # Or add Ruff to your project.

# With pip.
pip install ruff

# With pipx.
pipx install ruff

Starting with version 0.5.0, Ruff can be installed with our standalone installers:

# On macOS and Linux.
curl -LsSf https://astral.sh/ruff/install.sh | sh

# On Windows.
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"

# For a specific version.
curl -LsSf https://astral.sh/ruff/0.9.1/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.9.1/install.ps1 | iex"

You can also install Ruff via Homebrew, Conda, and with a variety of other package managers.

Usage

To run Ruff as a linter, try any of the following:

ruff check                          # Lint all files in the current directory (and any subdirectories).
ruff check path/to/code/            # Lint all files in `/path/to/code` (and any subdirectories).
ruff check path/to/code/*.py        # Lint all `.py` files in `/path/to/code`.
ruff check path/to/code/to/file.py  # Lint `file.py`.
ruff check @arguments.txt           # Lint using an input file, treating its contents as newline-delimited command-line arguments.

Or, to run Ruff as a formatter:

ruff format                          # Format all files in the current directory (and any subdirectories).
ruff format path/to/code/            # Format all files in `/path/to/code` (and any subdirectories).
ruff format path/to/code/*.py        # Format all `.py` files in `/path/to/code`.
ruff format path/to/code/to/file.py  # Format `file.py`.
ruff format @arguments.txt           # Format using an input file, treating its contents as newline-delimited command-line arguments.

Ruff can also be used as a pre-commit hook via ruff-pre-commit:

- repo: https://github.com/astral-sh/ruff-pre-commit
  # Ruff version.
  rev: v0.9.1
  hooks:
    # Run the linter.
    - id: ruff
      args: [ --fix ]
    # Run the formatter.
    - id: ruff-format

Ruff can also be used as a VS Code extension or with various other editors.

Ruff can also be used as a GitHub Action via ruff-action:

name: Ruff
on: [ push, pull_request ]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/ruff-action@v3

Configuration

Ruff can be configured through a pyproject.toml, ruff.toml, or .ruff.toml file (see: Configuration, or Settings for a complete list of all configuration options).

If left unspecified, Ruff's default configuration is equivalent to the following ruff.toml file:

# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]

# Same as Black.
line-length = 88
indent-width = 4

# Assume Python 3.9
target-version = "py39"

[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`)  codes by default.
select = ["E4", "E7", "E9", "F"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

Note that, in a pyproject.toml, each section header should be prefixed with tool.ruff. For example, [lint] should be replaced with [tool.ruff.lint].

Some configuration options can be provided via dedicated command-line arguments, such as those related to rule enablement and disablement, file discovery, and logging level:

ruff check --select F401 --select F403 --quiet

The remaining configuration options can be provided through a catch-all --config argument:

ruff check --config "lint.per-file-ignores = {'some_file.py' = ['F841']}"

To opt in to the latest lint rules, formatter style changes, interface updates, and more, enable preview mode by setting preview = true in your configuration file or passing --preview on the command line. Preview mode enables a collection of unstable features that may change prior to stabilization.

See ruff help for more on Ruff's top-level commands, or ruff help check and ruff help format for more on the linting and formatting commands, respectively.

Rules

Ruff supports over 800 lint rules, many of which are inspired by popular tools like Flake8, isort, pyupgrade, and others. Regardless of the rule's origin, Ruff re-implements every rule in Rust as a first-party feature.

By default, Ruff enables Flake8's F rules, along with a subset of the E rules, omitting any stylistic rules that overlap with the use of a formatter, like ruff format or Black.

If you're just getting started with Ruff, the default rule set is a great place to start: it catches a wide variety of common errors (like unused imports) with zero configuration.

Beyond the defaults, Ruff re-implements some of the most popular Flake8 plugins and related code quality tools, including:

For a complete enumeration of the supported rules, see Rules.

Contributing

Contributions are welcome and highly appreciated. To get started, check out the contributing guidelines.

You can also join us on Discord.

Support

Having trouble? Check out the existing issues on GitHub, or feel free to open a new one.

You can also ask for help on Discord.

Acknowledgements

Ruff's linter draws on both the APIs and implementation details of many other tools in the Python ecosystem, especially Flake8, Pyflakes, pycodestyle, pydocstyle, pyupgrade, and isort.

In some cases, Ruff includes a "direct" Rust port of the corresponding tool. We're grateful to the maintainers of these tools for their work, and for all the value they've provided to the Python community.

Ruff's formatter is built on a fork of Rome's rome_formatter, and again draws on both API and implementation details from Rome, Prettier, and Black.

Ruff's import resolver is based on the import resolution algorithm from Pyright.

Ruff is also influenced by a number of tools outside the Python ecosystem, like Clippy and ESLint.

Ruff is the beneficiary of a large number of contributors.

Ruff is released under the MIT license.

Who's Using Ruff?

Ruff is used by a number of major open-source projects and companies, including:

Show Your Support

If you're using Ruff, consider adding the Ruff badge to your project's README.md:

[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

...or README.rst:

.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
    :target: https://github.com/astral-sh/ruff
    :alt: Ruff

...or, as HTML:

<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" style="max-width:100%;"></a>

License

This repository is licensed under the MIT License

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ruff-0.9.1.tar.gz (3.5 MB view details)

Uploaded Source

Built Distributions

ruff-0.9.1-py3-none-win_arm64.whl (9.1 MB view details)

Uploaded Python 3 Windows ARM64

ruff-0.9.1-py3-none-win_amd64.whl (9.7 MB view details)

Uploaded Python 3 Windows x86-64

ruff-0.9.1-py3-none-win32.whl (8.8 MB view details)

Uploaded Python 3 Windows x86

ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl (11.3 MB view details)

Uploaded Python 3 musllinux: musl 1.2+ x86-64

ruff-0.9.1-py3-none-musllinux_1_2_i686.whl (11.0 MB view details)

Uploaded Python 3 musllinux: musl 1.2+ i686

ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl (10.5 MB view details)

Uploaded Python 3 musllinux: musl 1.2+ ARMv7l

ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl (10.9 MB view details)

Uploaded Python 3 musllinux: musl 1.2+ ARM64

ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.3 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ x86-64

ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (13.1 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ s390x

ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (11.7 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ ppc64le

ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl (12.2 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ ppc64

ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (11.5 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ i686

ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (10.4 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ ARMv7l

ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.9 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ ARM64

ruff-0.9.1-py3-none-macosx_11_0_arm64.whl (10.0 MB view details)

Uploaded Python 3 macOS 11.0+ ARM64

ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl (10.4 MB view details)

Uploaded Python 3 macOS 10.12+ x86-64

ruff-0.9.1-py3-none-linux_armv6l.whl (10.6 MB view details)

Uploaded Python 3

File details

Details for the file ruff-0.9.1.tar.gz.

File metadata

  • Download URL: ruff-0.9.1.tar.gz
  • Upload date:
  • Size: 3.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.5.16

File hashes

Hashes for ruff-0.9.1.tar.gz
Algorithm Hash digest
SHA256 fd2b25ecaf907d6458fa842675382c8597b3c746a2dde6717fe3415425df0c17
MD5 5b748f6f4a6c597f52e9b3d585bd2649
BLAKE2b-256 673ee89f736f01aa9517a97e2e7e0ce8d34a4d8207087b3cfdec95133fee13b5

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-win_arm64.whl.

File metadata

  • Download URL: ruff-0.9.1-py3-none-win_arm64.whl
  • Upload date:
  • Size: 9.1 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.5.16

File hashes

Hashes for ruff-0.9.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 1cd76c7f9c679e6e8f2af8f778367dca82b95009bc7b1a85a47f1521ae524fa7
MD5 06b7365565898d8d37a5f411dcf39eb0
BLAKE2b-256 b2940498cdb7316ed67a1928300dd87d659c933479f44dec51b4f62bfd1f8028

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: ruff-0.9.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 9.7 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.5.16

File hashes

Hashes for ruff-0.9.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 342a824b46ddbcdddd3abfbb332fa7fcaac5488bf18073e841236aadf4ad5c19
MD5 061dd958170558d2ea62d594b6a4c438
BLAKE2b-256 388d580db77c3b9d5c3d9479e55b0b832d279c30c8f00ab0190d4cd8fc67831c

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-win32.whl.

File metadata

  • Download URL: ruff-0.9.1-py3-none-win32.whl
  • Upload date:
  • Size: 8.8 MB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.5.16

File hashes

Hashes for ruff-0.9.1-py3-none-win32.whl
Algorithm Hash digest
SHA256 46ebf5cc106cf7e7378ca3c28ce4293b61b449cd121b98699be727d40b79ba72
MD5 eab4998d640c7fac9d1b32ad12b3dc90
BLAKE2b-256 39c6fe45f3eb27e3948b41a305d8b768e949bf6a39310e9df73f6c576d7f1d9f

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 5dc40a378a0e21b4cfe2b8a0f1812a6572fc7b230ef12cd9fac9161aa91d807f
MD5 862a91dabd8aff55deafaa2e7fbfd85c
BLAKE2b-256 0042afedcaa089116d81447347f76041ff46025849fedb0ed2b187d24cf70fca

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 ae017c3a29bee341ba584f3823f805abbe5fe9cd97f87ed07ecbf533c4c88366
MD5 a1e8234b7215352610d44f2510aa4d00
BLAKE2b-256 7885de4aa057e2532db0f9761e2c2c13834991e087787b93e4aeb5f1cb10d2df

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 2f312c86fb40c5c02b44a29a750ee3b21002bd813b5233facdaf63a51d9a85e1
MD5 7560f78ad4bd83542ad5f17d68453841
BLAKE2b-256 2a665599d23257c61cf038137f82999ca8f9d0080d9d5134440a461bef85b461

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 728d791b769cc28c05f12c280f99e8896932e9833fef1dd8756a6af2261fd1ab
MD5 bfe4765dda95c9c4dfa2fdcc6693a0e2
BLAKE2b-256 e43b7235bbeff00c95dc2d073cfdbf2b871b5bbf476754c5d277815d286b4328

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3f94942a3bb767675d9a051867c036655fe9f6c8a491539156a6f7e6b5f31831
MD5 ad118d5641b92113b1c061a2d354ff0e
BLAKE2b-256 f9d6fcb78e0531e863d0a952c4c5600cc5cd317437f0e5f031cd2288b117bb37

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 186c2313de946f2c22bdf5954b8dd083e124bcfb685732cfb0beae0c47233d9b
MD5 bca113b366dcea3a8a5f67c09948d916
BLAKE2b-256 a6a44e77cf6065c700d5593b25fca6cf725b1ab6d70674904f876254d0112ed0

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 937267afce0c9170d6d29f01fcd1f4378172dec6760a9f4dface48cdabf9610a
MD5 029dac81a2fec8f6a020dd965b07ab8a
BLAKE2b-256 84974a524027518525c7cf6931e9fd3b2382be5e4b75b2b61bec02681a7685a5

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Algorithm Hash digest
SHA256 69572926c0f0c9912288915214ca9b2809525ea263603370b9e00bed2ba56dbd
MD5 2977d3e04d35dc5b3e0f603f58a21430
BLAKE2b-256 ebc61ccfcc209bee465ced4874dcfeaadc88aafcc1ea9c9f31ef66f063c187f0

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 39d0174ccc45c439093971cc06ed3ac4dc545f5e8bdacf9f067adf879544d969
MD5 9bf99ee393d09e2e73a68a40b79fd65a
BLAKE2b-256 f0a2057a3cb7999513cb78d6cb33a7d1cc6401c82d7332583786e4dad9e38e44

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 beb3298604540c884d8b282fe7625651378e1986c25df51dec5b2f60cafc31ce
MD5 da4ee9cf2a247bcc9ef777470e762370
BLAKE2b-256 12f4dac4361afbfe520afa7186439e8094e4884ae3b15c8fc75fb2e759c1f267

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f0c8b149e9c7353cace7d698e1656ffcf1e36e50f8ea3b5d5f7f87ff9986a7ca
MD5 156e40b03cc6aad0a62b31cee34dc0d7
BLAKE2b-256 6f9b780aa5d4bdca8dcea4309264b8faa304bac30e1ce0bcc910422bfcadd203

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 50c647ff96f4ba288db0ad87048257753733763b409b2faf2ea78b45c8bb7fcb
MD5 7be5a30054bcb7c84c5608a0b8ace4a6
BLAKE2b-256 b7fe85e1c1acf0ba04a3f2d54ae61073da030f7a5dc386194f96f3c6ca444a78

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3cae39ba5d137054b0e5b472aee3b78a7c884e61591b100aeb544bcd1fc38d4f
MD5 4b1f9b105a2011ead1d924144691fa91
BLAKE2b-256 ddda59f0a40e5f88ee5c054ad175caaa2319fc96571e1d29ab4730728f2aad4f

See more details on using hashes here.

File details

Details for the file ruff-0.9.1-py3-none-linux_armv6l.whl.

File metadata

File hashes

Hashes for ruff-0.9.1-py3-none-linux_armv6l.whl
Algorithm Hash digest
SHA256 84330dda7abcc270e6055551aca93fdde1b0685fc4fd358f26410f9349cf1743
MD5 6bd0d3503b911b6b86e8ddddb2762cee
BLAKE2b-256 dc05c3a2e0feb3d5d394cdfd552de01df9d3ec8a3a3771bbff247fab7e668653

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page