Skip to main content

OpenBioNews

CI License: MIT Python 3.9+ Zero dependencies

A free, self-hosted news digest you run on your own computer.

OpenBioNews gathers stories from the sources you choose, groups the same story reported by different outlets into one entry, ranks them by importance, and writes a clean daily digest — as Markdown, a web page, or plain text, and optionally straight to your inbox. It ships tuned for biotech and life sciences, but you can point it at any topic.

  • 🆓 Free and open (MIT). No account, no subscription, no server to rent.
  • 🔬 Primary sources, cited to the sentence. Track ClinicalTrials.gov, FDA (recalls, approvals, shortages) and SEC EDGAR by company, drug or condition — and every sentence of every brief carries a numbered citation back to the exact source record. It's deterministic (verbatim from the record), so there's nothing to hallucinate — no LLM required. Plus any RSS/Atom feed.
  • 🔔 Tells you what changed. Remembers each trial/filing/record between runs and surfaces the diff — a trial gone to Terminated, results posted, a recall reclassified — so you read the change, not the same snapshot twice.
  • 🎯 Watch by theme, not just disease. One-tap groups seed your watch list: therapeutic areas and thematic cohorts like AI in drug discovery, NAM, gene/cell therapy, CRISPR, mRNA, ADCs, radiopharma, GLP-1/obesity. Stack several.
  • 🖥️ Runs everywhere. Windows, macOS, and Linux — pure Python, no build step.
  • 🔌 Bring your own LLM — or none. The cited facts are always deterministic; an optional local model (Ollama) or OpenAI-compatible API only adds a clearly labelled "Why it matters" interpretation on top — so the AI never touches the record, and there's nothing to hallucinate into it. Runs fully offline.
  • 🧩 Zero dependencies. The core runs on the Python standard library. If you have Python, you can run it.
  • 🥇 Curated, not a firehose. Stories are de-duplicated across outlets and ranked by importance, with a read-time estimate.
  • 📬 Optional email delivery. Have it mail you the digest every morning via any SMTP server.
  • 🔒 Private. Your feeds and reading habits stay on your machine. With the local or no-LLM modes, nothing is sent anywhere.
  • 🪄 One-minute onboarding. openbionews setup walks you through it and writes a config customized to you.

Gathering news into a post is deterministic — grouping and de-duplicating stories needs no AI. An LLM is optional and only used to polish the one-line summaries, so even a small local model is plenty.


Quick start

You need Python 3.9 or newer. Check with python3 --version (on Windows, py --version).

Install from PyPI:

pip install openbionews            # core — pure standard library, no deps
pipx install "openbionews[mcp]"    # optional: + MCP server for AI assistants (Python 3.10+)

openbionews run --demo             # try it offline with bundled sample data
openbionews setup                  # personalize (interactive, ~1 minute)
openbionews run                    # build today's digest

That's it — your digest is written to the digest/ folder as digest-YYYY-MM-DD.md (plus a latest.md you can always point to).

Prefer to run from source (or hack on it)? Clone and skip the install:

git clone https://github.com/fedor-i/OpenBioNews.git
cd OpenBioNews
python3 -m openbionews run --demo

Works on Windows, macOS, and Linux

The tool is pure Python and platform-independent. Command names differ slightly:

macOS / Linux Windows
Run a module python3 -m openbionews … py -m openbionews …
Set an env var (this shell) export KEY=value set KEY=value (cmd) · $env:KEY="value" (PowerShell)
Schedule it cron Task Scheduler

After pip install ., the openbionews command works the same on every platform. Output is written as UTF-8 everywhere.

Optional: install it as a command

pip install .
openbionews setup      # now available as a plain command
openbionews run

Onboarding: openbionews setup

The setup wizard is the heart of OpenBioNews. It asks a handful of questions — each with a sensible default you can accept by pressing Enter — and writes a config file customized to you:

  1. Name your digest (e.g. "My Morning Bio Brief").
  2. Pick topics. Choose from built-in bundles (Biotech & Pharma, Regulatory (FDA/EMA), Preprints (bioRxiv/medRxiv), Life Science & Research, Health, Science, Tech, World) or add your own RSS URLs.
  3. Track primary sources. Optionally watch ClinicalTrials.gov, FDA recalls/approvals, and SEC filings by company, condition, or drug — official developments, cited to their source record. Start from a therapeutic-area preset (oncology, cardiometabolic, rare disease, neurology, immunology, infectious disease) to seed the watch list, then tweak (see below).
  4. Focus it. Optionally keep only stories mentioning certain keywords, or always drop others.
  5. Choose how summaries are written — no LLM, local Ollama, or an OpenAI-compatible API.
  6. Pick an output format — Markdown, HTML, text, or an RSS feed you can subscribe to in any reader.

The result is openbionews.config.json in the current folder. Re-run setup any time to change it, or edit the file directly (see config.example.json).


Choosing an LLM (or not)

OpenBioNews works three ways. You choose during setup; you can switch any time.

1. No LLM (default) — free, instant, offline

Summaries are the article's own opening sentences. No model, no network, no setup. Great for a fast, private digest.

2. Local model via Ollama — free and private

Install Ollama, pull a small model, and OpenBioNews talks to it on your machine. Nothing leaves your computer.

ollama pull llama3.2        # or qwen2.5, phi3, gemma2 — small models are fine
# choose "Local model via Ollama" in `openbionews setup`

3. Any OpenAI-compatible API

Works with OpenAI, OpenRouter, Groq, Together, LM Studio, llama.cpp's server, vLLM, and more. During setup, give the base URL, model name, and the name of an environment variable that holds your API key. The key is read from the environment and is never written to the config file.

export OPENAI_API_KEY=sk-...      # or whatever variable you named
openbionews run

If a summary call ever fails (rate limit, network blip), that story quietly falls back to the no-LLM summary — the run never aborts.


Primary sources — traced to the document

Beyond RSS (which is secondary trade press), OpenBioNews can read official primary records and trace every development back to its source document.

Nine connectors are built in. You keep one watch list (companies, conditions, drugs, terms) and switch on whichever official sources you want:

  • ClinicalTrials.gov — trial developments (registration, status, phase), cited to the NCT record.
  • openFDA drug recalls — enforcement reports (reason, Class I/II/III, status), cited to the FDA record.
  • openFDA drug approvals — Drugs@FDA approvals, original and supplemental (new indication), cited to the Drugs@FDA page.
  • openFDA drug shortages — current/resolved shortages (reason, status, category), cited to the FDA Drug Shortages database.
  • openFDA drug adverse events (FAERS) — most-reported reactions per drug (spontaneous report counts, not incidence), cited to the openFDA query.
  • openFDA drug labeling — current FDA label: indications and whether a drug carries a boxed warning, cited to the openFDA label record.
  • Federal Register — FDA guidances, advisory-committee notices and rules, cited to the Federal Register document.
  • PubMed — recent biomedical literature (NCBI E-utilities), cited to the PubMed record (and DOI when present).
  • SEC EDGAR — filings (8-K, 10-K, S-1, 424B, 13D/G, DEF 14A, Form 4…), cited to the filing document. SEC asks for a contact User-Agent — set your email in connectors.edgar.user_agent.
"watchlist": {
  "sponsors": ["Moderna", "Vertex Pharmaceuticals"],
  "conditions": ["cystic fibrosis"],
  "interventions": ["mRNA-1345"],
  "terms": []
},
"connectors": {
  "clinicaltrials":    { "enabled": true, "recent_days": 30 },
  "openfda":           { "enabled": true, "recent_days": 30 },
  "openfda_approvals": { "enabled": true, "recent_days": 90 },
  "openfda_shortages": { "enabled": true, "recent_days": 60, "statuses": ["Current"] },
  "edgar":             { "enabled": true, "recent_days": 30, "forms": ["8-K"],
                         "user_agent": "Your Name your@email.com" }
}

The setup wizard builds this for you, and openbionews doctor verifies each source. Every story renders with a tag and a source line:

### Study of DrugX in Advanced Solid Tumors
*Recruiting · Phase 2 · Acme Bio · ClinicalTrials.gov · 20 Sep*
A phase 2 study evaluating DrugX…
↳ Source: ClinicalTrials.gov NCT01234567

No API keys are required. Because the connectors run on your machine, they can set the User-Agent SEC requires and are not subject to the browser CORS limits that constrain the hosted web page — this is the reliable path for SEC data.


Hosted web version — filter in your browser, no install

For people who just want to click and filter, there's a single-page web app in docs/index.html with a tab for each source, plus a cross-agency Insights digest:

  • Clinical trials — filter ClinicalTrials.gov by company, condition, drug, status, phase, recency ("updated within N days"), and industry-sponsored only.
  • FDA drug recalls — filter openFDA enforcement reports by firm, product, reason, classification (Class I/II/III), status, report-date recency, and voluntary vs. FDA-mandated.
  • FDA drug approvals — Drugs@FDA approvals (original + supplemental) by company or drug, within a chosen window.
  • FDA drug shortages — current/resolved shortages by drug or company.
  • SEC filings — full-text search SEC EDGAR by company/ticker/keyword, filing type (8-K, 10-K, S-1, 424B, 13D/G, DEF 14A, Form 4…), and filed-within recency; each result links to the filing document. (SEC does not reliably allow in-browser cross-origin requests, so when a visitor's browser is blocked, this tab falls back to opening the same search on SEC's official EDGAR site with the filters applied.)
  • FDA adverse events (FAERS) — most-reported reactions for a drug (signal, not incidence), cited to the openFDA query.
  • FDA labels — current label indications and boxed-warning status per drug.
  • Federal Register — FDA guidances, advisory-committee notices and rules.
  • Insights (beta) — a deterministic, no-LLM cross-agency digest over a time window: key stats, emergent themes, a word cloud, rising terms and a BM25-ranked source list, every figure counted from the cited records beneath it.

Both query the source live in the browser, show a link to each source record, and support shareable links (copy a link that reproduces the exact filtered view). No server, no backend, no tracking.

Host it free on GitHub Pages:

  1. Repo → Settings → Pages → Build and deployment.
  2. Source: GitHub Actions (the included workflow deploys docs/), or Deploy from a branch → main / /docs.
  3. Your page goes live at https://fedor-i.github.io/OpenBioNews/.

Point a custom domain at it in the same settings page if you like. Because it's static and calls the public APIs directly, it costs nothing to run and scales to any number of visitors.


Use it from an AI assistant (MCP)

The core has no LLM and invents nothing — but any assistant that speaks the Model Context Protocol (Claude Desktop, Claude Code, …) can call OpenBioNews as a tool to pull primary-source records, each returned with the exact URL it traces to. The AI gets grounded, citable facts; it never sees our prose.

The MCP server needs Python 3.10+ (the mcp SDK requires it; the core pipeline still runs on 3.9). Install it with an isolated installer so the openbionews command lands on your PATH — which the MCP config below relies on:

pipx install "openbionews[mcp]"              # recommended: isolated, command on PATH
# or
uv tool install "openbionews[mcp]"           # same idea, via uv
# or, into an environment you manage yourself:
python3 -m pip install "openbionews[mcp]"    # use python3.10+; see the note below

openbionews mcp                              # speaks MCP over stdio

On Python 3.9 pip install "openbionews[mcp]" can't install the mcp SDK, so the extra resolves to nothing and you get the core without the server. Use Python 3.10+ (pipx install "openbionews[mcp]" --python python3.12). A plain pip install --user also warns that its script directory isn't on PATH, which breaks the "command": "openbionews" config below — prefer pipx/uv, or point "command" at python3 with "args": ["-m", "openbionews", "mcp"].

Ten tools exposed: search_clinical_trials, search_fda_recalls, search_fda_approvals, search_fda_shortages, search_fda_adverse_events, search_fda_labeling, search_federal_register, search_pubmed, search_sec_filings, and watchlist_digest (every source at once).

The output is shaped for LLM callers:

  • Lean by default — the citation never drops. Each record keeps one source: {id, name, url, kind} object: source.url is the citation link, always present, alongside the record id and date. Lean only collapses the three repeated copies of that link into one — the "every record cited" guarantee holds in lean exactly as in verbose. Pass verbose=true for the full citations[] array and raw meta (e.g. a PubMed DOI also rides in source.also).

  • The numbers travel in facts — enrollment, start/primary-completion dates and primary endpoints for trials; reaction counts for FAERS; form/filer/accession for SEC; and so on. A model should cite these rather than infer figures. (SEC returns the filing pointer, not extracted financials — read the cited document for those.)

  • A trustworthy negative — a successful-but-empty search returns status: "no_current_results" with the query_used and as_of date, so "not in shortage as of 2026-10-20" is a citable fact, not an inference from a bare 0.

  • Provenance on every block — endpoint, retrieved_at, as_of.

  • A relevance signal, and a filter — each result carries match: {terms, where} showing which query terms actually hit and where. search_clinical_trials and search_pubmed go further and drop strays by default (require_match=true): a study the registry returns for a different drug, where the query term appears in no field, is removed. Set require_match=false to see everything and filter yourself via match.

  • SEC entity scoping — search_sec_filings has two modes. Give company (a name, ticker, or raw CIK; query optional) and it resolves the subject to its CIK and returns only that registrant's own filings — so a fund's 13F or an NPORT-P that merely lists the ticker is excluded (unresolvable names come back as entity_not_found). Give only query for a document full-text search; own_filer_only=true applies the same entity scoping to a bare query.

  • Monitoring + paging — since (YYYY-MM-DD) filters to new records and flags each is_new; limit/offset page through results with a truncated flag; watchlist_digest takes sources=[...] to query only the agencies you need.

  • Relevance ranking — every search tool attaches a deterministic score (0–1) to each result, reports ranked_by, and takes rank_by to pick the intent:

    • recency (default) — what's new, most recently updated first.
    • relevance — lexical keyword match, over a wider recent candidate pool. Use it to find records containing your terms; use salience when you want the important ones.
    • salience — what matters: for trials, an equal blend of enrollment, phase, results-posted and maturity (completed/with-results > just-recruiting), with recency and keyword match dropped — validated against landmark-trial recall, so a pivotal Phase-3/outcomes trial isn't crowded out by a fresher Phase-4. (Recalls weight severity; approvals priority; shortages current-vs-resolved.) It searches a wide window and pool, so a landmark older study can surface instead of being cut by the recency window. Sources without a salience signal fall back to relevance with a ranking_note.

    The per-signal breakdown is in relevance_components under verbose, and watchlist_digest applies the chosen mode within each source block. This is classical scoring — it only orders records that already cite themselves, and invents nothing.

  • Semantic ranking (optional [ml] extra) — rank_by="semantic" ranks by meaning rather than keywords, using TF-IDF + LSA (pip install "openbionews[ml]"; classical, local, deterministic — no LLM). It surfaces an on-topic record whose wording differs from the query. Without the extra it falls back to lexical relevance and says so in a ranking_note. Results report ranked_by.

Register it with Claude Desktop (or Claude Code) — add to your MCP config (claude_desktop_config.json).

Use an absolute path for command. The desktop app does not inherit your shell's PATH, so a bare "command": "openbionews" (or "uvx") usually fails to launch. Find the installed binary with which openbionews (after pipx/uv tool install) and paste that full path. On macOS it's typically ~/.local/bin/openbionews (pipx) or ~/.local/bin/openbionews / the uv tools dir.

{
  "mcpServers": {
    "openbionews": {
      "command": "/Users/you/.local/bin/openbionews",
      "args": ["mcp"],
      "env": { "OPENBIONEWS_EDGAR_UA": "Your Name your@email.com" }
    }
  }
}

If you'd rather not hard-code a path, point command at the Python that has the package and run it as a module — more portable across machines:

{
  "mcpServers": {
    "openbionews": {
      "command": "/usr/bin/python3",
      "args": ["-m", "openbionews", "mcp"],
      "env": { "OPENBIONEWS_EDGAR_UA": "Your Name your@email.com" }
    }
  }
}

Set OPENBIONEWS_EDGAR_UA if you'll use search_sec_filings — SEC rejects EDGAR requests without a descriptive User-Agent, so skipping it returns a 403 (the tool now says exactly this and names the variable, rather than surfacing raw 403 HTML). Set it to "Your Name your@email.com". The other sources don't need it.

Then ask your assistant things like "any Class I drug recalls for Moderna in the last 90 days?" and it will call the tool and answer from the cited records.


Commands

Command What it does
openbionews setup Interactive onboarding; writes your config.
openbionews mcp Run the MCP server so an AI can call the primary-source connectors.
openbionews run Build today's digest and write it to digest/.
openbionews run --demo Build a digest offline from bundled sample data.
openbionews run --stdout Print the digest instead of writing a file.
openbionews run --format html Override the output format for one run.
openbionews run --no-summaries Headlines and links only.
openbionews run --email Also email the digest (uses your email config).
openbionews doctor Check your config, feeds, LLM, and email.
openbionews sources List the built-in topic bundles and their feeds.

Use -c path/to/config.json to use a config file somewhere other than the current directory (or set OPENBIONEWS_CONFIG).


Run it every morning (automation)

OpenBioNews is a plain command, so any scheduler works.

macOS / Linux (cron) — build a digest every weekday at 7am:

0 7 * * 1-5  cd /path/to/OpenBioNews && /usr/bin/python3 -m openbionews run

Windows (Task Scheduler) — create a Basic Task that runs python -m openbionews run in the project folder on your schedule.

Point your reader, a static-site folder, or an email script at digest/latest.<ext>. With format: rss (or openbionews run --format rss), that's digest/latest.xml — a standard RSS feed you can subscribe to in any feed reader, so a scheduled run keeps your reader up to date automatically.


Email delivery (optional)

Have OpenBioNews mail you the digest every morning. Enable it during openbionews setup, or set the email block in your config. It works with any SMTP server (your own, Gmail with an app password, Fastmail, a work relay…).

"email": {
  "enabled": true,
  "smtp_host": "smtp.gmail.com",
  "smtp_port": 587,
  "use_tls": true,
  "username": "you@gmail.com",
  "password_env": "OPENBIONEWS_SMTP_PASSWORD",  // password read from this env var
  "from_addr": "you@gmail.com",
  "to_addrs": ["you@gmail.com"]
}

Set the password in your environment (never in the file) and run:

export OPENBIONEWS_SMTP_PASSWORD=your-app-password   # Windows: set / $env:
openbionews run --email

The email is sent as both a formatted HTML version and a plain-text fallback.


Curation & "why it matters"

OpenBioNews doesn't just dump every headline. Stories are:

  1. De-duplicated across outlets (the same story from five sites becomes one entry that lists all five).
  2. Ranked by importance — a transparent, deterministic score combining how many outlets carried a story, how fresh it is, and whether the headline contains high-signal words (approval, acquires, phase, recall…).
  3. Capped to the top max_items (and max_per_topic), so you get a focused read with a read-time estimate in the header.

If you use an LLM backend, turn on "why it matters" in setup to add a short significance note under each summary, generated locally or with your own key. It is always rendered as a clearly labelled "Why it matters (AI analysis)" line, kept separate from the deterministic, cited facts above it — so interpretation is never mistaken for a sourced claim.

Pick a capable model for this note. The cited facts never touch an LLM, but the optional note does, and a small local model will confabulate — in our testing a 9B model invented a precise, fake net-loss figure when the numbers weren't in front of it. Prefer a strong model (a frontier API, or a larger local model with good instruction-following) for "why it matters"; treat a tiny model's note as throwaway. If a note ever states a number, trust the cited record, not the note.


How it works

feeds ─▶ fetch ─▶ filter ─▶ cluster ─▶ rank ─▶ summarize ─▶ render ─▶ digest
        (RSS/Atom) (age &   (group the  (biggest  (LLM or   (md/html/
                    keywords) same story  first)   no-LLM)   text)
                              across
                              outlets)

Everything except the optional summary step is deterministic: stories are grouped by how much their headlines overlap (Jaccard similarity of title tokens), so results are reproducible and need no AI. See ARCHITECTURE.md for a module-by-module tour.


Customizing sources

Run openbionews sources to see the built-in bundles. To add your own, either choose "Add your own RSS feed" during setup, or edit the feeds list in your config:

{
  "feeds": [
    { "name": "My Favorite Blog", "url": "https://example.com/feed.xml", "topic": "biotech" }
  ]
}

Any RSS 2.0 or Atom feed works. Run openbionews doctor to confirm a new feed is reachable.


Privacy

  • No-LLM and Ollama modes send nothing off your machine. OpenBioNews only fetches the feeds you list.
  • API mode sends article titles and feed-provided descriptions to the endpoint you configured, only to write summaries. Your API key stays in your environment, never in the config file.
  • No telemetry, ever.

Requirements

  • Python 3.9+ (standard library only for the core).
  • Optional: feedparser for wider feed compatibility (pip install .[feeds]).
  • Optional: Ollama for a free local model.

Contributing

Contributions of every size are welcome — a typo fix, a new feed, or a whole new primary-source connector. Start with CONTRIBUTING.md, see where things are headed in ROADMAP.md, and check the good first issues.

The test suite runs with no dependencies (each file prints ok/FAIL per test):

python3 tests/test_pipeline.py      # core pipeline
python3 tests/test_web_insights.py  # hosted Insights analytics (structure guards)
python3 tests/test_mcp.py           # MCP tool logic
python3 tests/test_mcp_server.py    # MCP server wiring (skips without the mcp extra)

CI runs these on Linux, macOS and Windows across Python 3.9–3.12 on every pull request. Releases publish to PyPI automatically (RELEASING.md).

License

MIT. Free to use, modify, and redistribute. This is an independent, community-oriented, open-source tool.

Metadata

Release files for openbionews 0.8.5

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

Source distribution (sdist)

Source distribution for openbionews 0.8.5
File Size Uploaded Provenance
openbionews-0.8.5.tar.gz 144.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for openbionews 0.8.5
File Interpreter ABI Platform
openbionews-0.8.5-py3-none-any.whl Python 3 none any Details

Total release size: 249.4 kB

Release files / openbionews-0.8.5.tar.gz

Download URL openbionews-0.8.5.tar.gz
Size 144.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3a6b0abf4a0c141122e32eaaf2c89991c2853dafe90e8c5e021fd967da57f923
BLAKE2b-256 checksum
How to use checksums
2bbcaea8f5fa1c42a5792f2da0df8b2e24bb5775318a3dc6571c590c2b732358
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / openbionews-0.8.5-py3-none-any.whl

Download URL openbionews-0.8.5-py3-none-any.whl
Size 105.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d19380d16305e743b20a1766aee911e326607bcbed5ef760fc699443fb4c554f
BLAKE2b-256 checksum
How to use checksums
afb77d13d36c977ea87ed950d341253e8b3c2e66d124b76925e4ebccf7a9fcdc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for openbionews 0.8.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for openbionews-0.8.5.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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