Skip to main content

Actions Status PyPI Bytewax User Guide

Bytewax

Python Stateful Stream Processing Framework

Bytewax is a Python framework that simplifies event and stream processing. Because Bytewax couples the stream and event processing capabilities of Flink, Spark, and Kafka Streams with the friendly and familiar interface of Python, you can re-use the Python libraries you already know and love. Connect data sources, run stateful transformations and write to various different downstream systems with built-in connectors or existing Python libraries.

Screen Shot 2022-10-07 at 2 22 49 PM

How it all works

Bytewax is a Python framework and Rust distributed processing engine that uses a dataflow computational model to provide parallelizable stream processing and event processing capabilities similar to Flink, Spark, and Kafka Streams. You can use Bytewax for a variety of workloads from moving data à la Kafka Connect style all the way to advanced online machine learning workloads. Bytewax is not limited to streaming applications but excels anywhere that data can be distributed at the input and output.

Bytewax has an accompanying command line interface, waxctl, which supports the deployment of dataflows on cloud vms or kuberentes. You can download it here.


Getting Started with Bytewax

pip install bytewax

Install waxctl

A Bytewax dataflow is Python code that will represent an input, a series of processing steps, and an output. The inputs could range from a Kafka stream to a WebSocket and the outputs could vary from a data lake to a key-value store.

from bytewax.dataflow import Dataflow
from bytewax.connectors.kafka import KafkaInput

# Bytewax has input and output helpers for common input and output data sources
# but you can also create your own with the ManualOutputConfig.

At a high-level, the dataflow compute model is one in which a program execution is conceptualized as data flowing through a series of operator-based steps. Operators like map and filter are the processing primitives of Bytewax. Each of them gives you a “shape” of data transformation, and you give them regular Python functions to customize them to a specific task you need. See the documentation for a list of the available operators

import json

def deserialize(key_bytes__payload_bytes):
    _, payload_bytes = key_bytes__payload_bytes
    event_data = json.loads(payload_bytes) if payload_bytes else None
    return event_data["user_id"], event_data


def anonymize_email(user_id__event_data):
    user_id, event_data = user_id__event_data
    event_data["email"] = "@".join(["******", event_data["email"].split("@")[-1]])
    return user_id, event_data


def remove_bytewax(user_id__event_data):
    user_id, event_data = user_id__event_data
    return "bytewax" not in event_data["email"]

flow = Dataflow()
flow.input("inp", KafkaInput(brokers=["localhost:9092"], topic="web_events"))
flow.map(deserialize)
flow.map(anonymize_email)
flow.filter(remove_bytewax)

Bytewax is a stateful stream processing framework, which means that some operations remember information across multiple events. Windows and aggregations are also stateful, and can be reconstructed in the event of failure. Bytewax can be configured with different state recovery mechanisms to durably persist state in order to recover from failure.

There are multiple stateful operators available like reduce, stateful_map and fold_window. The complete list can be found in the API documentation for all operators. Below we use the fold_window operator with a tumbling window based on system time to gather events and calculate the number of times events have occurred on a per-user basis.

from datetime import datetime, timedelta, timezone
from collections import defaultdict

from bytewax.window import TumblingWindow, SystemClockConfig

def build():
    return defaultdict(lambda: 0)


def count_events(results, event):
    results[event["type"]] += 1
    return results


cc = SystemClockConfig()
align_to = datetime(2023, 1, 1, tzinfo=timezone.utc)
wc = TumblingWindow(length=timedelta(seconds=5), align_to=align_to)

flow.fold_window("session_state_recovery", cc, wc, build, count_events)

Output mechanisms in Bytewax are managed in the output operator. There are a number of helpers that allow you to easily connect and write to other systems (output docs). If there isn’t a helper built, it is easy to build a custom version, which we will do below. Similar the input, Bytewax output can be parallelized and the client connection will occur on the worker.

import json

import psycopg2

from bytewax.outputs import PartitionedOutput, StatefulSink


class PsqlSink(StatefulSink):
    def __init__(self):
        self.conn = psycopg2.connect("dbname=website user=bytewax")
        self.conn.set_session(autocommit=True)
        self.cur = self.conn.cursor()

    def write(self, user_id__user_data):
        user_id, user_data = user_id__user_data
        query_string = """
            INSERT INTO events (user_id, data)
            VALUES (%s, %s)
            ON CONFLICT (user_id)
            DO UPDATE SET data = %s;
        """
        self.cur.execute(
            query_string, (user_id, json.dumps(user_data), json.dumps(user_data))
        )

    def snapshot(self):
        pass

    def close(self):
        self.conn.close()


class PsqlOutput(PartitionedOutput):
    def list_parts(self):
        return {"single"}

    def assign_part(self, item_key):
        return "single"

    def build_part(for_part, resume_state):
        return PsqlSink()


flow.output("out", PsqlOutput())

Bytewax dataflows can be executed on a single host with multiple Python processes, or on multiple hosts. When processing data in a distributed fashion, Bytewax will ensure that all items with the same key are routed to the same host.

python -m bytewax.run my_dataflow:flow

It can also be run in a Docker container as described further in the documentation.

Kubernetes

The recommended way to run dataflows at scale is to leverage the kubernetes ecosystem. To help manage deployment, we built waxctl, which allows you to easily deploy dataflows that will run at huge scale across multiple compute nodes.

waxctl df deploy my_dataflow.py --name my-dataflow

Why Bytewax?

At a high level, Bytewax provides a few major benefits:

  • The operators in Bytewax are largely “data-parallel”, meaning they can operate on independent parts of the data concurrently.
  • Bytewax offers the ability to express higher-level control constructs, like iteration.
  • Bytewax allows you to develop and run your code locally, and then easily scale that code to multiple workers or processes without changes.
  • Bytewax can be used in both a streaming and batch context
  • Ability to leverage the Python ecosystem directly

Community

Slack Is the main forum for communication and discussion.

GitHub Issues is reserved only for actual issues. Please use the slack community for discussions.

Code of Conduct

Usage

Install the latest release with pip:

pip install bytewax

Building From Source

To build a specific branch, you will need to use Maturin and have Rust installed on your machine. Once those have been installed run

maturin develop -E dev

Important: If you are testing with a maturin built version from source, you should use maturin build --release since maturin develop will be slower.

More Examples

For a more complete example, and documentation on the available operators, check out the User Guide and the /examples folder.

License

Bytewax is licensed under the Apache-2.0 license.

Contributing

Contributions are welcome! This community and project would not be what it is without the contributors. All contributions, from bug reports to new features, are welcome and encouraged. Please view the contribution guidelines before getting started.



With ❤️ Bytewax

Metadata

Release files for bytewax 0.16.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for bytewax 0.16.1
File
bytewax-0.16.1-cp311-cp311-manylinux_2_31_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.31+ x86-64 Details
bytewax-0.16.1-cp311-cp311-manylinux_2_27_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64 Details
bytewax-0.16.1-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
bytewax-0.16.1-cp311-cp311-macosx_10_7_x86_64.whl CPython 3.11 CPython 3.11 macOS 10.7+ x86-64 Details
bytewax-0.16.1-cp310-cp310-manylinux_2_31_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.31+ x86-64 Details
bytewax-0.16.1-cp310-cp310-manylinux_2_27_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ x86-64 Details
bytewax-0.16.1-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details
bytewax-0.16.1-cp310-cp310-macosx_10_7_x86_64.whl CPython 3.10 CPython 3.10 macOS 10.7+ x86-64 Details
bytewax-0.16.1-cp39-cp39-manylinux_2_31_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.31+ x86-64 Details
bytewax-0.16.1-cp39-cp39-manylinux_2_27_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.27+ x86-64 Details
bytewax-0.16.1-cp39-cp39-macosx_11_0_arm64.whl CPython 3.9 CPython 3.9 macOS 11.0+ ARM64 Details
bytewax-0.16.1-cp39-cp39-macosx_10_7_x86_64.whl CPython 3.9 CPython 3.9 macOS 10.7+ x86-64 Details
bytewax-0.16.1-cp38-cp38-manylinux_2_31_x86_64.whl CPython 3.8 CPython 3.8 Linux glibc 2.31+ x86-64 Details
bytewax-0.16.1-cp38-cp38-manylinux_2_27_x86_64.whl CPython 3.8 CPython 3.8 Linux glibc 2.27+ x86-64 Details
bytewax-0.16.1-cp38-cp38-macosx_11_0_arm64.whl CPython 3.8 CPython 3.8 macOS 11.0+ ARM64 Details
bytewax-0.16.1-cp38-cp38-macosx_10_7_x86_64.whl CPython 3.8 CPython 3.8 macOS 10.7+ x86-64 Details
bytewax-0.16.1-cp37-cp37m-manylinux_2_31_x86_64.whl CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.31+ x86-64 Details
bytewax-0.16.1-cp37-cp37m-manylinux_2_27_x86_64.whl CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.27+ x86-64 Details
bytewax-0.16.1-cp37-cp37m-macosx_11_0_arm64.whl CPython 3.7 CPython 3.7 pymalloc macOS 11.0+ ARM64 Details
bytewax-0.16.1-cp37-cp37m-macosx_10_7_x86_64.whl CPython 3.7 CPython 3.7 pymalloc macOS 10.7+ x86-64 Details

Total release size: 162.9 MB

Release files / bytewax-0.16.1-cp311-cp311-manylinux_2_31_x86_64.whl

Download URL bytewax-0.16.1-cp311-cp311-manylinux_2_31_x86_64.whl
Size 9.3 MB
Tags CPython 3.11 Linux glibc 2.31+ x86-64
SHA-256 checksum
How to use checksums
48414c3df819e5bf57e71dfeae72611f6a3c74d86f159b69c897d5625512313c
BLAKE2b-256 checksum
How to use checksums
df2e9069273426c63096aaa84a8d29105003eff37f0c510004948f815ad29de8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp311-cp311-manylinux_2_27_x86_64.whl

Download URL bytewax-0.16.1-cp311-cp311-manylinux_2_27_x86_64.whl
Size 9.1 MB
Tags CPython 3.11 Linux glibc 2.27+ x86-64
SHA-256 checksum
How to use checksums
ae0435a25246ca7a898ecb44a9140263b6194685fb0ee5a4e6ba77a28ea80462
BLAKE2b-256 checksum
How to use checksums
e2d11a454d8e64ae7bea05addf3d20bea4bf35c6d5b6196a09cfd9dda87c35be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp311-cp311-macosx_11_0_arm64.whl

Download URL bytewax-0.16.1-cp311-cp311-macosx_11_0_arm64.whl
Size 6.9 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b61fef2311b61c6db825471b58cdc75dc268d0a5a23ddecc1ac529e8fe2ebdbe
BLAKE2b-256 checksum
How to use checksums
d8126c9148ed3f7afff65b5b8bfb0fcbbe04c20df93bae9a2b5c83863c7f6d32
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp311-cp311-macosx_10_7_x86_64.whl

Download URL bytewax-0.16.1-cp311-cp311-macosx_10_7_x86_64.whl
Size 7.2 MB
Tags CPython 3.11 macOS 10.7+ x86-64
SHA-256 checksum
How to use checksums
5653510e7432948d916758c5bdc108031c71533b958b82c792ecf74ab96a9b32
BLAKE2b-256 checksum
How to use checksums
fa8d875b90ec20d1fb3dfc2a762b5816c0d90a62a4dc8d45da553ba647c94ac4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp310-cp310-manylinux_2_31_x86_64.whl

Download URL bytewax-0.16.1-cp310-cp310-manylinux_2_31_x86_64.whl
Size 9.3 MB
Tags CPython 3.10 Linux glibc 2.31+ x86-64
SHA-256 checksum
How to use checksums
d44089a8a496c845611dff3739b204e205fd6d4abe6e42a2f01852053d863e5a
BLAKE2b-256 checksum
How to use checksums
cee2345cbcbf49264e8f2f3ae6793de05119a665dc25281db4579676c7637965
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp310-cp310-manylinux_2_27_x86_64.whl

Download URL bytewax-0.16.1-cp310-cp310-manylinux_2_27_x86_64.whl
Size 9.1 MB
Tags CPython 3.10 Linux glibc 2.27+ x86-64
SHA-256 checksum
How to use checksums
d30d4ac1c7f904c8dc60943cf37a47e0805e037d2f2903331b68bd2d747a304b
BLAKE2b-256 checksum
How to use checksums
21c6f34c8baa503e1d093a7df2d74ea71931a0f823eff0bf0790f256d8abe32c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp310-cp310-macosx_11_0_arm64.whl

Download URL bytewax-0.16.1-cp310-cp310-macosx_11_0_arm64.whl
Size 6.9 MB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f942dd648f4b1cea7a17bde44ee803b4812fdf9153f13ca877db4700a20266c5
BLAKE2b-256 checksum
How to use checksums
237e01a3774349d310e824c786c9459eef0faefc41779f7e2fcef4779fe6dd1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp310-cp310-macosx_10_7_x86_64.whl

Download URL bytewax-0.16.1-cp310-cp310-macosx_10_7_x86_64.whl
Size 7.2 MB
Tags CPython 3.10 macOS 10.7+ x86-64
SHA-256 checksum
How to use checksums
d230f5a0076aed10e884f10fb2651571def669ca258daf6a60404b1a630ca691
BLAKE2b-256 checksum
How to use checksums
f3e98a5dbef2106cca14ed90adcd81ae4a30eff352afdc1e94c8bf1463d2575d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp39-cp39-manylinux_2_31_x86_64.whl

Download URL bytewax-0.16.1-cp39-cp39-manylinux_2_31_x86_64.whl
Size 9.3 MB
Tags CPython 3.9 Linux glibc 2.31+ x86-64
SHA-256 checksum
How to use checksums
0c77d3be9db1e0d3465989954e7078262ad76ef9169b119dfda42e29b71c648f
BLAKE2b-256 checksum
How to use checksums
1db1703b56edb31a96644cf0607bc02e37841d322cb5ea86bb583df32a34a801
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp39-cp39-manylinux_2_27_x86_64.whl

Download URL bytewax-0.16.1-cp39-cp39-manylinux_2_27_x86_64.whl
Size 9.1 MB
Tags CPython 3.9 Linux glibc 2.27+ x86-64
SHA-256 checksum
How to use checksums
9db906c0399141213a88b05b2eace99f689d799511f900893043a5866503fa0b
BLAKE2b-256 checksum
How to use checksums
32e291829876f865fd2e1919ccae30f4b843247c76bcf870e9d159beb5c40410
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp39-cp39-macosx_11_0_arm64.whl

Download URL bytewax-0.16.1-cp39-cp39-macosx_11_0_arm64.whl
Size 6.9 MB
Tags CPython 3.9 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
39f7e455ac540fd0bae4f98490d5049202fdd92e9ae80c5ee4a7005724241fad
BLAKE2b-256 checksum
How to use checksums
68b8d9f2a943453cbeb05d1eadc151fcf5526bf906a5591301753a3045c171b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp39-cp39-macosx_10_7_x86_64.whl

Download URL bytewax-0.16.1-cp39-cp39-macosx_10_7_x86_64.whl
Size 7.2 MB
Tags CPython 3.9 macOS 10.7+ x86-64
SHA-256 checksum
How to use checksums
63a137d54f42f3c6258a7e307b456614c093b8a27986cb5444327b05458a821c
BLAKE2b-256 checksum
How to use checksums
6afbdff16ac7c53833bda35f57cdf61d88fd71fbd261f48501307d41abebfb46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp38-cp38-manylinux_2_31_x86_64.whl

Download URL bytewax-0.16.1-cp38-cp38-manylinux_2_31_x86_64.whl
Size 9.3 MB
Tags CPython 3.8 Linux glibc 2.31+ x86-64
SHA-256 checksum
How to use checksums
441722b96d0b93ff35e4c44e4bf26b9f3644fce287096018aea3266b61134ddd
BLAKE2b-256 checksum
How to use checksums
1d7b50e8082db8ce1480eca1db0f535398d2b4f733fd1f1b3eb7d422c0b03b71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp38-cp38-manylinux_2_27_x86_64.whl

Download URL bytewax-0.16.1-cp38-cp38-manylinux_2_27_x86_64.whl
Size 9.1 MB
Tags CPython 3.8 Linux glibc 2.27+ x86-64
SHA-256 checksum
How to use checksums
194a6d13acc7ba7ac52549a8d166140c62aa59ebffe14dd3ca1cf3b95953e829
BLAKE2b-256 checksum
How to use checksums
1a5fdee9ef2d5998906e0e7e39a9994f454451aff3499fb67751664355aaf3ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp38-cp38-macosx_11_0_arm64.whl

Download URL bytewax-0.16.1-cp38-cp38-macosx_11_0_arm64.whl
Size 6.9 MB
Tags CPython 3.8 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
09b3e05f6cbc271b9927e59019222ea6c2b4c839cd623c93d00718d42063d623
BLAKE2b-256 checksum
How to use checksums
63774c6e51379e438da42a738066a7fad130ca8ecc8b7997365ab5eb7a8ec929
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp38-cp38-macosx_10_7_x86_64.whl

Download URL bytewax-0.16.1-cp38-cp38-macosx_10_7_x86_64.whl
Size 7.2 MB
Tags CPython 3.8 macOS 10.7+ x86-64
SHA-256 checksum
How to use checksums
3c7483c30de6c372ace14baa0fdc24482160a2f90590dcf7d825f4d08f06d9b7
BLAKE2b-256 checksum
How to use checksums
9fe55fa1322ddd6026829b629a9503e3754a1b06ef8d9092bfa1d3e7d9baf4cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp37-cp37m-manylinux_2_31_x86_64.whl

Download URL bytewax-0.16.1-cp37-cp37m-manylinux_2_31_x86_64.whl
Size 9.3 MB
Tags CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.31+ x86-64
SHA-256 checksum
How to use checksums
b7b2eeeb45f68793ea6ddf56f9b1bf7946d70a090c85efa3b45a1c41055e6809
BLAKE2b-256 checksum
How to use checksums
328d2a0bbb304c8b017c696d50407daae6391e41e295558d3f2fa5e83cd04f07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp37-cp37m-manylinux_2_27_x86_64.whl

Download URL bytewax-0.16.1-cp37-cp37m-manylinux_2_27_x86_64.whl
Size 9.1 MB
Tags CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.27+ x86-64
SHA-256 checksum
How to use checksums
ebc95aae8ea52a2dbe7a3523c0cadce0598d8e83113032787dfd5ff69e9a6881
BLAKE2b-256 checksum
How to use checksums
94c45e65be5b8cf2b8ad5f0870c756b2ea4d838fbd36b77de8839da681300267
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp37-cp37m-macosx_11_0_arm64.whl

Download URL bytewax-0.16.1-cp37-cp37m-macosx_11_0_arm64.whl
Size 6.9 MB
Tags CPython 3.7 CPython 3.7 pymalloc macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
51eaed93fd1b809715cadb1360c24bb1f73f7e63ce057510ea87c600afe61b39
BLAKE2b-256 checksum
How to use checksums
bad11dd80839ea027939c333aae858cd8b112fbac384de5d73b0bf7ccd8ae01c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / bytewax-0.16.1-cp37-cp37m-macosx_10_7_x86_64.whl

Download URL bytewax-0.16.1-cp37-cp37m-macosx_10_7_x86_64.whl
Size 7.2 MB
Tags CPython 3.7 CPython 3.7 pymalloc macOS 10.7+ x86-64
SHA-256 checksum
How to use checksums
30fe825365f958431d679299915516046236ec1efe123f6eb429c3a87f841314
BLAKE2b-256 checksum
How to use checksums
f0fcbab12edf379b1c2609bb226d8eff29298fe771269861ed7bdd65349395cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page