Metadata-Version: 2.5
Name: logsite
Version: 0.7.1
Summary: See production log volume and log-quality issues inline, next to the log calls in your code.
Project-URL: Homepage, https://github.com/rajpaynaik/logsite
Project-URL: Issues, https://github.com/rajpaynaik/logsite/issues
Author-email: Raj Paynaik <rajpaynaik18@gmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: cloudwatch,elasticsearch,go,java,linter,logging,loguru,loki,lsp,mcp,observability,opensearch,slf4j,slog,structlog,vscode,zap
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: System :: Logging
Requires-Python: >=3.10
Requires-Dist: tomli>=2.0; python_version < '3.11'
Requires-Dist: tree-sitter-go>=0.23
Requires-Dist: tree-sitter-java>=0.23
Requires-Dist: tree-sitter-typescript>=0.23
Requires-Dist: tree-sitter>=0.23
Provides-Extra: bigquery
Requires-Dist: google-cloud-bigquery>=3.0; extra == 'bigquery'
Provides-Extra: clickhouse
Requires-Dist: clickhouse-connect>=0.7; extra == 'clickhouse'
Provides-Extra: cloudwatch
Requires-Dist: boto3>=1.34; extra == 'cloudwatch'
Provides-Extra: dev
Requires-Dist: loguru>=0.7; extra == 'dev'
Requires-Dist: mcp<3,>=2.3; extra == 'dev'
Requires-Dist: pygls<3,>=2.0; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: structlog>=24; extra == 'dev'
Provides-Extra: lsp
Requires-Dist: pygls<3,>=2.0; extra == 'lsp'
Provides-Extra: mcp
Requires-Dist: mcp<3,>=2.3; extra == 'mcp'
Provides-Extra: mssql
Requires-Dist: pyodbc>=5.0; extra == 'mssql'
Provides-Extra: mysql
Requires-Dist: pymysql>=1.1; extra == 'mysql'
Provides-Extra: postgres
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
Provides-Extra: snowflake
Requires-Dist: snowflake-connector-python>=3.0; extra == 'snowflake'
Description-Content-Type: text/markdown

# logsite

[![PyPI](https://img.shields.io/pypi/v/logsite?label=PyPI&cacheSeconds=3600)](https://pypi.org/project/logsite/)
[![Python](https://img.shields.io/pypi/pyversions/logsite?cacheSeconds=86400)](https://pypi.org/project/logsite/)
[![CI](https://github.com/rajpaynaik/logsite/actions/workflows/ci.yml/badge.svg)](https://github.com/rajpaynaik/logsite/actions/workflows/ci.yml)
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue)](https://github.com/rajpaynaik/logsite/blob/main/LICENSE)

**Your logs say something broke. logsite tells you which line of your code, and writes a test that proves it.**

It reads the logs you already have (a file, Loki, OpenSearch, CloudWatch, Sentry or
OpenTelemetry), groups thousands of stack traces into a few causes, and points each one at
your line of code. No SDK, nothing to add to your services. Works with Python, Java, Go,
TypeScript and JavaScript.

```bash
pip install logsite
```

## Try it

The repo has a small demo shop with a planted bug and its production log.

```bash
pip install logsite pytest
git clone https://github.com/rajpaynaik/logsite && cd logsite/examples/bookstore
```

**1. What's failing?**

```
$ logsite errors --from ../../bench/repro/scenarios/supplier-timeout/incident.log
28 errors in incident.log · 2 group(s)

  #  TREND  COUNT  ERROR                                      RAISED AT       LOGGED AT
  1            25  TimeoutError: timed out                    supplier.py:31  api.py:36
  2             3  ConnectionRefusedError: cache unavailable  cache.py:15     api.py:23
```

**2. Write a test that reproduces it.**

```
$ logsite repro --from ../../bench/repro/scenarios/supplier-timeout/incident.log --write-test
wrote tests/test_repro_346fa937.py
```

**3. Check it fails the way production did.**

```
$ logsite agent --expect 346fa937 -- python -m pytest tests/test_repro_346fa937.py
✓ 346fa937 reproduced: TimeoutError through bookstore/supplier.py:31, as in production
```

Fix `supplier.py` until the test passes.

## Use it on your service

```bash
cd your-service
logsite errors --from app.log        # errors grouped by cause
logsite lint                         # logging mistakes in your code
```

To read from your log store, add a `logsite.toml`:

```toml
[backend]
type = "loki"                        # or "opensearch", "cloudwatch", "sentry", "file"
url = "http://localhost:3100"
selector = '{service_name="checkout"}'
```

## Watch production

`logsite watch` checks your logs every 5 minutes, stores every error in your own database,
and posts to Slack when an error is **new**, **back after a fix**, or **spiking**. No SDK:
it reads the log store you already have.

**Guided setup:** `logsite init` asks for your log store, Slack and database in the terminal,
testing each one; `logsite app` does the same in your browser.

**Or with a config file:**

```toml
[backend]
type = "loki"
url = "http://loki:3100"
selector = '{service_name="checkout"}'

[alerts]
slack_webhook_env = "SLACK_WEBHOOK_URL"   # a Slack incoming webhook

[store]                                   # leave out to use SQLite
url_env = "LOGSITE_DATABASE_URL"          # Postgres, MySQL, SQL Server or ClickHouse
```

```bash
pip install "logsite[postgres]"
logsite watch --dry-run                   # print the Slack messages first
logsite watch
```

Tables are created on first use. The first check loads the last 24 hours without posting;
`logsite db backfill --since 30d` loads more.

**Where to run it:** anywhere that can reach your log store: a server, Docker, or
Kubernetes. On Kubernetes (EKS included) it's one Deployment with one replica, config in a
ConfigMap, secrets in a Secret, and an IAM role for CloudWatch.
See [Run on Kubernetes](https://github.com/rajpaynaik/logsite/blob/main/docs/kubernetes.md).

## More

| Command | What it does |
|---|---|
| `logsite app` | Set everything up and browse errors in your browser, no terminal needed |
| `logsite db backfill --since 30d` | Store errors in your own database (SQLite, Postgres, MySQL, SQL Server, ClickHouse) for instant date-range queries |
| `logsite errors -i` | Browse the stored errors in the terminal: search, any time range, open one, copy it as an AI prompt |
| `logsite prompt <id> --copy` | Everything about one stored error (code, when it started, the commits before, what failing requests share) as a prompt for your AI assistant |
| `logsite investigate` | Find the deploy and commit behind an incident |
| `logsite grafana --store postgres` | A Grafana dashboard on your stored errors |

Also: a [GitHub Action](https://github.com/rajpaynaik/logsite/blob/main/docs/github-action.md),
a [VS Code extension](https://marketplace.visualstudio.com/items?itemName=rajpaynaik.logsite),
and a [Claude connector](https://github.com/rajpaynaik/logsite/blob/main/docs/mcp.md) (MCP) so you can
ask "what failed in checkout yesterday after 3pm?" in plain English.

## Docs

[Commands](https://github.com/rajpaynaik/logsite/blob/main/docs/commands.md) ·
[Configuration](https://github.com/rajpaynaik/logsite/blob/main/docs/configuration.md) ·
[logsite app](https://github.com/rajpaynaik/logsite/blob/main/docs/app.md) ·
[Watch production](https://github.com/rajpaynaik/logsite/blob/main/docs/watch.md) ·
[Kubernetes](https://github.com/rajpaynaik/logsite/blob/main/docs/kubernetes.md) ·
[Reproduce an error](https://github.com/rajpaynaik/logsite/blob/main/docs/repro.md) ·
[AI prompt](https://github.com/rajpaynaik/logsite/blob/main/docs/prompt.md) ·
[Security](https://github.com/rajpaynaik/logsite/blob/main/docs/security.md) ·
[Changelog](https://github.com/rajpaynaik/logsite/blob/main/CHANGELOG.md)

Questions and ideas: [Discussions](https://github.com/rajpaynaik/logsite/discussions).
Contributions welcome, see [CONTRIBUTING.md](https://github.com/rajpaynaik/logsite/blob/main/CONTRIBUTING.md).

## License

Apache 2.0
