ZipLogger accepts what Sentry SDKs send: errors, tracing, structured logs and cron check-ins.
Swap the DSN for a ZipLogger one and your captureException calls, your
tracesSampleRate and your tags keep working as written. The errors then sit next to
your logs, traces, metrics and on-call instead of in a separate tool.
One line of config · Same SDK, same calls · Move one service at a time
ZipLogger reads the Sentry envelope format that current SDKs send to
/api/<project>/envelope/, and the older /store/ endpoint too. Each
kind of item goes to the place in ZipLogger that already handles that signal.
| What the Sentry SDK sends | Where it lands in ZipLogger |
|---|---|
| Errors and captured messages | A log line at the event's level: errors at error, captured messages at info unless you pass a level. The stack trace is written the way your language prints it (a Python traceback, a .NET or Java trace, a V8 trace), with the trace id, release and commit attached. An error with an exception is also grouped into an Issue. |
| Transactions and spans (tracing) | Traces: one waterfall per request, with span names, durations, status and HTTP fields named the way OpenTelemetry names them. |
Structured logs (Sentry.logger) |
Log lines, grouped by their message template. |
| Cron check-ins | A log line per check-in. A check-in whose monitor_slug matches a heartbeat also
reports that heartbeat’s run, so a missed or failed run opens an incident. |
release: "checkout@3f9a2c1" |
Service checkout, commit 3f9a2c1. That commit is what the git
regression engine blames from. |
| Tags, user, environment | Searchable fields: tag.customer_tier, userId, environment. The ZipLogger environment the data lands in comes from the key; the SDK's environment is kept only as a field. |
The key is read wherever the SDK puts it: the X-Sentry-Auth header, the
sentry_key query parameter browser SDKs use, or the DSN inside a tunnelled
envelope. Compressed bodies (gzip, brotli, deflate) are read too.
Same ingest keys, same plan allowance, same durable queue. Rate limits come back in the headers Sentry SDKs obey, and an event re-sent from an SDK's offline cache is stored once.
An error carries its trace id, so it links straight to the request that produced it. Its stack frames and commit feed the same regression engine as your other logs. Errors that carry an exception are grouped into Issues you can assign and resolve, with links to the trace, the logs and the release.
Sentry.init in place of the old one. Nothing else changes.Set release to <service>@<git sha> if you do not already.
ZipLogger has no separate project per service, so it reads the service name and the commit from
the release.
The DSN carries your key hex-encoded, because Sentry's JavaScript SDK only
accepts letters, digits and underscores in that part of the URL. The project number at the end
is always 1.
// JavaScript: @sentry/browser, @sentry/node, @sentry/react ...
Sentry.init({
dsn: "https://[email protected]/1",
release: `checkout@${GIT_SHA}`,
environment: "production",
tracesSampleRate: 0.2,
})
# Python: sentry-sdk
sentry_sdk.init(
dsn="https://[email protected]/1",
release=f"checkout-api@{GIT_SHA}",
traces_sample_rate=0.2,
)
// .NET: Sentry.AspNetCore
builder.WebHost.UseSentry(o => {
o.Dsn = "https://[email protected]/1";
o.Release = $"orders-api@{gitSha}";
});
Each official SDK was run end to end against ZipLogger: the same error twice, an unhandled crash, a transaction with child spans, structured logs, a cron check-in pair and a profile, each read back through ZipLogger. Each page lists what arrived and what did not.
| Language | SDK tested | What differs |
|---|---|---|
| Python | sentry-sdk 2.72.0 | Everything in the table above, plus source lines and trace-linked profiles. |
| Node.js | @sentry/node 11.8.0 | Source lines. Profiles are continuous: flame graphs per service, not linked to one trace. |
| Go | sentry-go 0.50.0 | No source lines and no profiler in the SDK; panics are reported with a deferred recover. |
| Java | sentry 8.61.0 | No source lines (source bundles are not accepted). Profiles are continuous, not linked to one trace. |
| Ruby | sentry-ruby 7.1.0 | Source lines and trace-linked profiles (stackprof). Unhandled errors come from the Rack, Rails or Sidekiq integrations. |
| PHP | sentry/sentry 4.34.0 | Source lines and trace-linked profiles (excimer). |
| .NET | Sentry 6.12.1 | No source lines (the SDK sends none). Trace-linked profiles with Sentry.Profiling. |
Better to read this before you switch than after.
The SDK gets a normal success response for these, so nothing errors or retries. The response lists what was left out.
fingerprint is honored.
Ownership rules, merges and splits you made in Sentry, and your Sentry tracker links do not
carry over. An Issue can create or link a
GitHub, Jira Cloud or Linear issue, without two-way status sync, and takes comments and bulk
resolve, ignore, assign and merge. Issue trackerssentry-cli. Those uploads are not accepted.
ZipLogger has its own upload (a curl call from CI, or the Source maps page), keyed
by the same release; see Source maps. Debug
IDs are not used for matching. Mapped frames are shown on the Issue page; commit blame still
reads the frames as received.monitor_config and the heartbeat is created for you. Sentry’s
failure_issue_threshold and recovery_threshold are not used: the first
missed or failed run opens an incident. As in Sentry, every check_in_id is a run of
its own, and a run that never reports back fails after its max_runtime (30 minutes
when the SDK sends none).Sentry is a very good error tracker, and it attributes errors to suspect commits too. The honest split:
A Sentry SDK sends to one DSN, so the easy way to compare is by service: move one service to ZipLogger, keep the rest on Sentry for a week, then decide.
No. Replace the DSN in Sentry.init with the one ZipLogger shows when you create an ingest key. Your captureException calls, tracing and tags stay as they are. Setting release to service@git-sha is recommended, because ZipLogger reads the service name and the commit from it.
The official server SDKs for Python, Node.js, Go, Java, Ruby, PHP and .NET were each run end to end against ZipLogger on 2026-10-21 (sentry-sdk 2.72.0, @sentry/node 11.8.0, sentry-go 0.50.0, sentry-java 8.61.0, sentry-ruby 7.1.0, sentry/sentry 4.34.0, Sentry for .NET 6.12.1), and every request they sent is replayed by ZipLogger's test suite. Errors, Issues, tracing, structured logs and cron check-ins work with all seven; source lines and profiles depend on the SDK, and each language page says which. Other current Sentry SDKs send the same envelope format; mobile and native SDKs were not tested.
Sessions are stored and feed release health: crash-free sessions and users per release under Issues, Releases. Profiles are stored for continuous profiling, as wall-time flame graphs. Client reports, attachments, replays and user feedback are acknowledged with a normal success response, so the SDK does not retry or log errors; they are not stored, billed or imported. The response lists which item types were left out.
Yes, in a different way. Sentry attributes the exceptions its SDK captured. ZipLogger blames from an Issue or from a log pattern, so it works for errors from a Sentry SDK and for error lines from anything else, reading your repository over the GitHub or GitLab API. It needs the commit, which it takes from a release such as api@3f9a2c1, and frames that name your source files: minified browser frames cannot be blamed.
A Sentry SDK sends to one DSN, so the simple way is service by service: point one service at ZipLogger, keep the others on Sentry, and compare. Nothing on the ZipLogger side stops you running both for as long as you like.