Skip to main content

A ctypes-based wrapper for GLFW3.

Project description

This module provides Python bindings for GLFW (on GitHub: glfw/glfw). It is a ctypes wrapper which keeps very close to the original GLFW API, except for:

  • function names use the pythonic words_with_underscores notation instead of camelCase

  • GLFW_ and glfw prefixes have been removed, as their function is replaced by the module namespace (you can use from glfw.GLFW import * if you prefer the naming convention used by the GLFW C API)

  • structs have been replaced with Python sequences and namedtuples

  • functions like glfwGetMonitors return a list instead of a pointer and an object count

  • Gamma ramps use floats between 0.0 and 1.0 instead of unsigned shorts (use glfw.NORMALIZE_GAMMA_RAMPS=False to disable this)

  • GLFW errors are reported as glfw.GLFWError warnings if no error callback is set (use glfw.ERROR_REPORTING=False to disable this, set it to ‘warn’ instead to issue warnings, set it to ‘log’ to log it using the ‘glfw’ logger or set it to a dict to define the behavior for specific error codes)

  • instead of a sequence for GLFWimage structs, PIL/pillow Image objects can be used

Installation

pyGLFW can be installed using pip:

pip install glfw

Windows

The GLFW shared library and Visual C++ runtime are included in the Python wheels.

To use a different GLFW library, you can set PYGLFW_LIBRARY to its location.

macOS

The GLFW shared library for 64-bit is included in the Python wheels for macOS.

If you are using a 32-bit Python installation or otherwise cannot use the library downloaded with the wheel, you can build and install it yourself by compiling GLFW from source (use -DBUILD_SHARED_LIBS=ON).

pyGLFW will search for the library in a list of search paths (including those in DYLD_LIBRARY_PATH). If you want to use a specific library, you can set the PYGLFW_LIBRARY environment variable to its path.

Linux

The GLFW shared library is included in the Python wheels for Linux. Although pyGLFW will try to detect whether the GLFW library for Wayland or X11 should be used, you can set the PYGLFW_LIBRARY_VARIANT variable to wayland or x11 to select either variant of the library.

If you cannot use these on your system, you can install the GLFW shared library using a package management system (e.g. apt install libglfw3 on Debian or Ubuntu) or you can build and install it yourself by compiling GLFW from source (use -DBUILD_SHARED_LIBS=ON).

pyGLFW will search for the library in a list of search paths (including those in LD_LIBRARY_PATH). If you want to use a specific library, you can set the PYGLFW_LIBRARY environment variable to its path.

cx_Freeze / PyInstaller

pyGLFW will search for the GLFW library in the current working directory, the directory of the executable and in the package on non-Windows platforms if running in an executable frozen with cx_Freeze or PyInstaller, unless the PYGLFW_LIBRARY environment variable is set.

Development Version

If you are using the development version of GLFW and would like to use wrappers for currently unreleased macros and functions, you can instead install:

pip install glfw[preview]

or set the PYGLFW_PREVIEW environment variable.

Note, however, that there will be a slight delay between the development version of GLFW and the wrappers provided by this package.

Example Code

The example from the GLFW documentation ported to pyGLFW:

import glfw

def main():
    # Initialize the library
    if not glfw.init():
        return
    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(640, 480, "Hello World", None, None)
    if not window:
        glfw.terminate()
        return

    # Make the window's context current
    glfw.make_context_current(window)

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Render here, e.g. using pyOpenGL

        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

    glfw.terminate()

if __name__ == "__main__":
    main()

Project details


Download files

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

Source Distribution

glfw-2.10.0.tar.gz (31.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-win_amd64.whl (559.5 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9Windows x86-64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-win32.whl (552.7 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9Windows x86

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux_2_28_x86_64.whl (243.5 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9manylinux: glibc 2.28+ x86-64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux_2_28_aarch64.whl (231.1 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9manylinux: glibc 2.28+ ARM64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux2014_x86_64.whl (242.0 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux2014_aarch64.whl (230.0 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-macosx_11_0_arm64.whl (102.2 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9macOS 11.0+ ARM64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-macosx_10_6_intel.whl (105.3 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.10Python 3.11Python 3.12Python 3.13Python 3.14Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Python 3.9macOS 10.6+ Intel (x86-64, i386)

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-win_amd64.whl (559.5 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Windows x86-64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-win32.whl (552.7 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8Windows x86

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux_2_28_x86_64.whl (243.5 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8manylinux: glibc 2.28+ x86-64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux_2_28_aarch64.whl (231.1 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8manylinux: glibc 2.28+ ARM64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux2014_x86_64.whl (242.0 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux2014_aarch64.whl (230.0 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-macosx_11_0_arm64.whl (102.2 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8macOS 11.0+ ARM64

glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-macosx_10_6_intel.whl (105.3 kB view details)

Uploaded Python 2Python 2.7Python 3Python 3.0Python 3.1Python 3.2Python 3.3Python 3.4Python 3.5Python 3.6Python 3.7Python 3.8macOS 10.6+ Intel (x86-64, i386)

File details

Details for the file glfw-2.10.0.tar.gz.

File metadata

  • Download URL: glfw-2.10.0.tar.gz
  • Upload date:
  • Size: 31.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for glfw-2.10.0.tar.gz
Algorithm Hash digest
SHA256 801e55d8581b34df9aa2cfea43feb06ff617576e2a8cc5dac23ee75b26d10abe
MD5 a25b6bf166ea1a5307b8645e67858902
BLAKE2b-256 9672642d4f12f61816ac96777f7360d413e3977a7dd08237d196f02da681b186

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-win_amd64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-win_amd64.whl
Algorithm Hash digest
SHA256 823c0bd7770977d4b10e0ed0aef2f3682276b7c88b8b65cfc540afce5951392f
MD5 a991fdd69151fd743a0d66c8f11e40e3
BLAKE2b-256 bde16d6816b296a529ac9b897ad228b1e084eb1f92319e96371880eebdc874a6

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-win32.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-win32.whl
Algorithm Hash digest
SHA256 fca724a21a372731edb290841edd28a9fb1ee490f833392752844ac807c0086a
MD5 315f2fc19b54f98b9a49120d83174508
BLAKE2b-256 cfb9b04c3aa0aad2870cfe799f32f8b59789c98e1816bbce9e83f4823c5b840b

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ce6724bb7cb3d0543dcba17206dce909f94176e68220b8eafee72e9f92bcf542
MD5 ebe242ec0f716521fd18876f5f11befe
BLAKE2b-256 5a3fefeb7c6801c46e11bd666a5180f0d615f74f72264212f74f39586c6fda9d

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 27c9e9a2d5e1dc3c9e3996171d844d9df9a5a101e797cb94cce217b7afcf8fd9
MD5 61526f0511f2cf4885029a24c9941585
BLAKE2b-256 ffb4f7b6cc022dd7c68b6c702d19da5d591f978f89c958b9bd3090615db0c739

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 91d36b3582a766512eff8e3b5dcc2d3ffcbf10b7cf448551085a08a10f1b8244
MD5 f1d8ae390dfcf53043715f493205064d
BLAKE2b-256 e2fab035636cd82198b97b51a93efe9cfc4343d6b15cefbd336a3f2be871d848

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7be06d0838f61df67bd54cb6266a6193d54083acb3624ff3c3812a6358406fa4
MD5 24a01b3e2f5f05fed168a0feaa1e0a84
BLAKE2b-256 5819d81b19e8261b9cb51b81d1402167791fef81088dfe91f0c4e9d136fdc5ca

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 23936202a107039b5372f0b88ae1d11080746aa1c78910a45d4a0c4cf408cfaa
MD5 404294423856d09ba20aa362cb51badd
BLAKE2b-256 b6a66ea2f73ad4474896d9e38b3ffbe6ffd5a802c738392269e99e8c6621a461

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-macosx_10_6_intel.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.py39.py310.py311.py312.py313.py314-none-macosx_10_6_intel.whl
Algorithm Hash digest
SHA256 2aab89d2d9535635ba011fc7303390685169a1aa6731ad580d08d043524b8899
MD5 517691e72547fbcda5deb842d640f7df
BLAKE2b-256 b387de0b33f6f00687499ca1371f22aa73396341b85bf88f1a284f9da8842493

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-win_amd64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-win_amd64.whl
Algorithm Hash digest
SHA256 6292d5d6634d668cd23d337e6089491d3945a9aa4ac6e1667b0003520d7caa51
MD5 2fdc3c11c33006e07df6eedd3b614abf
BLAKE2b-256 862700c9c96af18ac0a5eac2ff61cbe306551a2d770d7173f396d0792ee1a59e

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-win32.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-win32.whl
Algorithm Hash digest
SHA256 6c9549da71b93e367b4d71438798daae1da2592039fd14204a80a1a2348ae127
MD5 7e6ab5ae9515d22e424100a09831fe54
BLAKE2b-256 8406cb588ca65561defe0fc48d1df4c2ac12569b81231ae4f2b52ab37007d0bd

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7916034efa867927892635733a3b6af8cd95ceb10566fd7f1e0d2763c2ee8b12
MD5 84711a3c688fb0faa2eb6ccf928e01ae
BLAKE2b-256 f7026e639e90f181dc9127046e00d0528f9f7ad12d428972e3a5378b9aefdb0b

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c6f292fdaf3f9a99e598ede6582d21c523a6f51f8f5e66213849101a6bcdc699
MD5 7783508a78756ca07750323d181fd3c8
BLAKE2b-256 ac2dbfe39a42cad8e80b02bf5f7cae19ba67832c1810bbd3624a8e83153d74a4

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 59c53387dc08c62e8bed86bbe3a8d53ab1b27161281ffa0e7f27b64284e2627c
MD5 bba8a5985c1af97bf158bd9d01ba69ce
BLAKE2b-256 80aa3b503c448609dee6cb4e7138b4109338f0e65b97be107ab85562269d378d

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 312c4c1dd5509613ed6bc1e95a8dbb75a36b6dcc4120f50dc3892b40172e9053
MD5 8c559f8e5754929957f0b9e1f22ec90c
BLAKE2b-256 9d41a5bd1d9e1808f400102bd7d328c4ac17b65fb2fc8014014ec6f23d02f662

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5328db1a92d07abd988730517ec02aa8390d3e6ef7ce98c8b57ecba2f43a39ba
MD5 cd2bee727f78351a195327dc0b0849dc
BLAKE2b-256 7c965a2220abcbd027eebcf8bedd28207a2de168899e51be13ba01ebdd4147a1

See more details on using hashes here.

File details

Details for the file glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-macosx_10_6_intel.whl.

File metadata

File hashes

Hashes for glfw-2.10.0-py2.py27.py3.py30.py31.py32.py33.py34.py35.py36.py37.py38.p39.p310.p311.p312.p313-none-macosx_10_6_intel.whl
Algorithm Hash digest
SHA256 5f365a8c94bcea71ec91327e7c16e7cf739128479a18b8c1241b004b40acc412
MD5 faf9d500ecf83575242558e9e396c0d7
BLAKE2b-256 3d1fa9ce08b1173b0ab625ee92f0c47a5278b3e76fd367699880d8ee7d56c338

See more details on using hashes here.

Supported by

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