bufferlog 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,219 @@
1
+ Metadata-Version: 2.4
2
+ Name: bufferlog
3
+ Version: 0.1.0
4
+ Summary: BufferLog — Buffer logs in memory, flush only on errors. Save 90%+ on APM costs.
5
+ Author: BufferLog.io
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/lehan0328/bufferlog
8
+ Project-URL: Repository, https://github.com/lehan0328/bufferlog
9
+ Project-URL: Issues, https://github.com/lehan0328/bufferlog/issues
10
+ Keywords: logging,apm,buffer,datadog,splunk,observability,cost-reduction
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: System :: Logging
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ Provides-Extra: flask
23
+ Requires-Dist: flask>=2.0; extra == "flask"
24
+ Provides-Extra: fastapi
25
+ Requires-Dist: fastapi>=0.100; extra == "fastapi"
26
+ Requires-Dist: starlette>=0.27; extra == "fastapi"
27
+ Provides-Extra: django
28
+ Requires-Dist: django>=4.0; extra == "django"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
32
+ Requires-Dist: flask>=2.0; extra == "dev"
33
+ Requires-Dist: fastapi>=0.100; extra == "dev"
34
+ Requires-Dist: starlette>=0.27; extra == "dev"
35
+ Requires-Dist: httpx>=0.24; extra == "dev"
36
+ Requires-Dist: uvicorn>=0.20; extra == "dev"
37
+
38
+ # bufferlog
39
+
40
+ Buffer logs in memory per-request. Flush only on errors. Save 90%+ on APM costs.
41
+
42
+ ## Table of Contents
43
+
44
+ - [Install](#install)
45
+ - [Usage](#usage)
46
+ - [Flask](#flask)
47
+ - [FastAPI](#fastapi)
48
+ - [Django](#django)
49
+ - [Configuration](#configuration)
50
+ - [Control Plane](#control-plane)
51
+ - [Metrics](#metrics)
52
+ - [Shutdown](#shutdown)
53
+ - [License](#license)
54
+
55
+ ## Install
56
+
57
+ ```bash
58
+ pip install bufferlog
59
+ ```
60
+
61
+ With framework extras:
62
+
63
+ ```bash
64
+ pip install bufferlog[flask]
65
+ pip install bufferlog[fastapi]
66
+ pip install bufferlog[django]
67
+ ```
68
+
69
+ ## Usage
70
+
71
+ ### Flask
72
+
73
+ ```python
74
+ import logging
75
+ from flask import Flask
76
+ from bufferlog import BufferLog
77
+ from bufferlog.adapters import StdOutAdapter
78
+
79
+ app = Flask(__name__)
80
+ bl = BufferLog(adapters=[StdOutAdapter(pretty=True)])
81
+ bl.init_flask(app)
82
+
83
+ logger = logging.getLogger("myapp")
84
+ logger.addHandler(bl.logging_handler())
85
+ logger.setLevel(logging.DEBUG)
86
+
87
+ @app.route("/")
88
+ def index():
89
+ logger.info("Processing request") # Buffered (discarded on 200)
90
+ logger.debug("SQL: SELECT * ...") # Buffered (discarded on 200)
91
+ return "OK" # 200 → logs discarded ($0)
92
+
93
+ @app.route("/fail")
94
+ def fail():
95
+ logger.info("Starting transaction")
96
+ logger.error("Connection lost") # Triggers flush
97
+ return "Error", 500 # 500 → context sent to APM
98
+ ```
99
+
100
+ ### FastAPI
101
+
102
+ ```python
103
+ import logging
104
+ from fastapi import FastAPI
105
+ from bufferlog import BufferLog
106
+ from bufferlog.adapters import StdOutAdapter
107
+ from bufferlog.middleware.fastapi_mw import BufferLogMiddleware
108
+
109
+ app = FastAPI()
110
+ bl = BufferLog(adapters=[StdOutAdapter()])
111
+ app.add_middleware(BufferLogMiddleware, **bl.asgi_kwargs())
112
+
113
+ logger = logging.getLogger("myapp")
114
+ logger.addHandler(bl.logging_handler())
115
+ logger.setLevel(logging.DEBUG)
116
+
117
+ @app.get("/")
118
+ async def index():
119
+ logger.info("Handling request")
120
+ return {"ok": True}
121
+ ```
122
+
123
+ ### Django
124
+
125
+ ```python
126
+ # settings.py
127
+ MIDDLEWARE = [
128
+ "bufferlog.middleware.django_mw.BufferLogDjangoMiddleware",
129
+ # ... other middleware
130
+ ]
131
+
132
+ # apps.py or wsgi.py
133
+ from bufferlog import BufferLog
134
+ from bufferlog.adapters import StdOutAdapter
135
+
136
+ bl = BufferLog(adapters=[StdOutAdapter()])
137
+ bl.init_django()
138
+ ```
139
+
140
+ ## Configuration
141
+
142
+ ```python
143
+ from bufferlog import BufferLog, BufferLogConfig
144
+ from bufferlog.adapters import DatadogAdapter, SplunkAdapter, StdOutAdapter
145
+
146
+ bl = BufferLog(config=BufferLogConfig(
147
+ # Max logs per request buffer. Oldest overwritten when full.
148
+ buffer_capacity=100,
149
+
150
+ # Log levels that trigger immediate flush.
151
+ flush_on_levels=["error", "critical"],
152
+
153
+ # HTTP status codes that trigger flush.
154
+ flush_on_status_codes=[500, 501, 502, 503, 504],
155
+
156
+ # Downstream targets for flushed logs.
157
+ adapters=[
158
+ DatadogAdapter(api_key="your-key"),
159
+ SplunkAdapter(token="your-token", url="https://splunk.example.com"),
160
+ StdOutAdapter(),
161
+ ],
162
+
163
+ # Enable/disable buffering.
164
+ enabled=True,
165
+
166
+ # If True, logs fall through to stderr on adapter failure.
167
+ fail_open=True,
168
+
169
+ # Scrub PII before logs enter the buffer.
170
+ scrubber=lambda msg, meta: (msg.replace("password", "***"), meta),
171
+ ))
172
+ ```
173
+
174
+ ## Control Plane
175
+
176
+ Connect to the BufferLog Control Plane for remote policy management and usage tracking.
177
+
178
+ ```python
179
+ from bufferlog import BufferLog, ControlPlaneConfig
180
+
181
+ bl = BufferLog(
182
+ control_plane=ControlPlaneConfig(
183
+ url="https://control.bufferlog.io",
184
+ api_key="bl_sk_your_key",
185
+ poll_interval_s=60,
186
+ telemetry_interval_s=60,
187
+ )
188
+ )
189
+ ```
190
+
191
+ When connected:
192
+ - **Poll for policy updates** — buffer capacity, sampling rate, flush triggers, and bypass rules can all be changed remotely.
193
+ - **Push usage metrics** — counters (never log data) are sent to power the ROI dashboard.
194
+
195
+ If the control plane is unreachable, the SDK continues with its last known configuration.
196
+
197
+ ## Metrics
198
+
199
+ ```python
200
+ metrics = bl.get_metrics()
201
+ # {
202
+ # "buffers": {"created": 1000, "discarded": 995, "flushed": 5, "active": 0},
203
+ # "flash": {"flush_count": 5, "events_flushed": 45, "adapter_errors": 0}
204
+ # }
205
+ ```
206
+
207
+ ## Shutdown
208
+
209
+ Stop background threads and send a final telemetry report.
210
+
211
+ ```python
212
+ import atexit
213
+
214
+ atexit.register(bl.shutdown)
215
+ ```
216
+
217
+ ## License
218
+
219
+ [MIT](LICENSE)
@@ -0,0 +1,24 @@
1
+ bufferlog/__init__.py,sha256=vxExPhcvEmVVdql1FS5cuYsJMvp9GBu4dcxoE6_hspQ,5643
2
+ bufferlog/buffer_manager.py,sha256=IGo1jkJFqrf2zT3EspzGXZIMY6OsETUg0LZfUY2HviA,2738
3
+ bufferlog/config.py,sha256=V0ah8pDRA-KPEfUwgyC3ZhxTjBPo_6euqtLpXrvlus8,1288
4
+ bufferlog/context.py,sha256=kfXTsLG6xILIJpUcg31k0ulrAP4jQyIUe8lbRvjaCuk,1361
5
+ bufferlog/flash_controller.py,sha256=FerOwB-4qKlPNa1lXJtBB07yhVRoFjk47OppKITE0pw,2180
6
+ bufferlog/log_event.py,sha256=JG7l_DKxn7iepTrBUI2FBTypUkUL_TgLsbojai59tPI,1206
7
+ bufferlog/ring_buffer.py,sha256=hMfyLtlYmPfrioBbWjKaElQ3Lx2S9UwPEQFkL8TIsSM,2849
8
+ bufferlog/adapters/__init__.py,sha256=HEPhucFuimbNPZe3sDvZevuh-KmbmfoPGRZawK_DC_U,195
9
+ bufferlog/adapters/base.py,sha256=XOXI4k-O7PBjLyMVWzaRifv4OufKyEUsZdlQhBJqwjk,438
10
+ bufferlog/adapters/datadog.py,sha256=k7TlvbfTjFlGqRIJrGe26Ye7sawB8QZIV8MyKPQKFoo,1681
11
+ bufferlog/adapters/splunk.py,sha256=iujBjgF4nqv1iYuytJCFJUBVIQObWnRfzOsczrjqm1o,1587
12
+ bufferlog/adapters/stdout.py,sha256=jKwPIJx9CbPKiRfoA9ZQgSoRUxpqpusoptpW17VHdi8,714
13
+ bufferlog/control_plane/__init__.py,sha256=_ievQvidVIdygvZRSFwm_5pb2KAdKzbDTaH5pV1yAkU,39
14
+ bufferlog/control_plane/policy_fetcher.py,sha256=VapZQBkPCn0DsYyzHxEbxjvfBmKU8YPrrVDUy5E_63I,3185
15
+ bufferlog/control_plane/telemetry_reporter.py,sha256=Vcneilcficiqb0gEe8ef_QPfTRwDb9P70ZN3wPCR_EY,3256
16
+ bufferlog/integrations/__init__.py,sha256=oKywGBNAEoPiSVRGBxCoq76BEVRf1q1eHqQ2-ZPlTZo,2394
17
+ bufferlog/middleware/__init__.py,sha256=jKaAZI9aHMEFD-6CW0fMJOC70MFXeUCUfGp4J5Cp9cw,36
18
+ bufferlog/middleware/django_mw.py,sha256=q_eYEffK8iWb2rMSCqHw1SUXy0Y-Ymlu_0dnQ_JbwZM,2924
19
+ bufferlog/middleware/fastapi_mw.py,sha256=MRFdb0cWj9khAEESI-qmK3Tk1ejDZUhFFa6S-m0p2mg,3090
20
+ bufferlog/middleware/flask_mw.py,sha256=IYkBjM-2Y6j8f5MEaAUUN9gVXxC28GKGfqjRvKj7cA8,2253
21
+ bufferlog-0.1.0.dist-info/METADATA,sha256=tN5yJ0_WQWZH-FpyEA7axqgrzeScsS_9zA2Kigb7wtk,5751
22
+ bufferlog-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
23
+ bufferlog-0.1.0.dist-info/top_level.txt,sha256=gzYBsdusu9nk0_u7pIGk4EXW-akvM1BAi6BQKDH9m78,10
24
+ bufferlog-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ bufferlog