openinfra-logger 0.1.0__tar.gz

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,38 @@
1
+ # Changelog
2
+
3
+ All notable changes to OpenInfra Logger will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] — 2026-05-15
11
+
12
+ ### Added
13
+ - **Node.js implementation** (`src/index.js`) — console / file / remote transports, structured JSON output, log levels (`debug` / `info` / `warn` / `error`), default metadata merging.
14
+ - **Python implementation** (`python/openinfra_logger/`) — feature parity with Node.
15
+ - **Go implementation** (`go/logger.go`) — feature parity with Node and Python.
16
+ - **Rust implementation** (`rust/src/lib.rs`) — zero-dependency JSON builder, file + console transports.
17
+ - **Auto-redaction** — sensitive keys (`password`, `token`, `secret`, `api_key`, `credit_card`) recursively replaced with `[REDACTED]` before any transport sees the entry. Case-insensitive on keys; configurable via `redactKeys` / `redact_keys`.
18
+ - **Remote batching transport** — Node and Python ship logs in batches (default 100 entries or 2 s, whichever first) instead of HTTP-per-log; survives endpoint failures without crashing the host process.
19
+ - **OpenTelemetry context injection** — when an active span is present, `trace_id` and `span_id` are extracted automatically (no extra `import`).
20
+ - **Datadog formatter** — renames `level` → `status`, `trace_id` → `dd.trace_id`, `span_id` → `dd.span_id`.
21
+ - **Elastic / ECS formatter** — renames `timestamp` → `@timestamp`, `level` → `log.level`.
22
+ - **Log analyzer CLI** (`tools/ai-analyzer.js`) — runs entirely on the host by default. Seven layers of analysis without a single network call: (1) clustering by normalized message shape, (2) six built-in heuristics (timeout cascades, OOM, database failures, 5xx, rate-limit, auth), (3) stack-trace dedup on the top-3 frames, (4) temporal cascade detection (bursts of ≥3 errors / 1 s), (5) per-minute anomaly windows via z-score over the baseline rate, (6) service-interaction graph derived from `trace_id` co-occurrence, (7) service breakdown and observed time window. The optional `--llm=<provider>` flag sends the clustered prompt to one of three providers for an LLM-deepened narrative: `anthropic` (cloud, needs `ANTHROPIC_API_KEY`), `ollama` (fully local — keeps the host-only guarantee), or `openai` (OpenAI-compatible endpoint such as LM Studio or vLLM). `--prompt-only` prints the prompt for manual paste.
23
+ - **Test matrix** — 69 tests across the four runtimes (Node 32, Python 22, Go 8, Rust 7) covering redaction, levels, transports, formatters, batching triggers, and JSON escaping.
24
+ - **Examples** — Express integration, security logging, Datadog integration, OpenTelemetry tracing, basic usage in Node / Python / Go / Rust.
25
+ - **Documentation** — installation, architecture, integration, advanced configuration under `docs/`.
26
+ - **CI workflow** and release automation under `.github/workflows/`.
27
+
28
+ ### Fixed
29
+ - **Node** — invalid log levels were being emitted verbatim in the JSON because the fallback to `'info'` updated the wrong variable. The emitted entry now correctly contains `"level":"info"` when the caller passes an unsupported level.
30
+ - **Node** — concurrent `fs.appendFile` calls could interleave lines under bursty writes. Writes are now serialized through an internal promise chain, preserving emission order.
31
+ - **Python** — replaced 5 occurrences of the deprecated `datetime.datetime.utcnow()` with a forward-compatible helper that emits ISO-8601 UTC with a trailing `Z`. No more `DeprecationWarning` on Python 3.12+.
32
+ - **Rust** — the manual JSON builder did not escape `"`, `\`, control characters or newlines in messages or metadata, producing invalid JSON whenever user input contained any of them. Introduced `escape_json_string()` and a pure `build_json_line()` function (RFC 8259-compliant). Crate remains dependency-free.
33
+
34
+ ### Security
35
+ - **LGPD / GDPR** — auto-redaction is on by default; disabling it requires an explicit `redactKeys: []` in the configuration.
36
+
37
+ [Unreleased]: https://github.com/jonathascordeiro20/openinfra-logger/compare/v0.1.0...HEAD
38
+ [0.1.0]: https://github.com/jonathascordeiro20/openinfra-logger/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jonathas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ recursive-exclude tests *
5
+ recursive-exclude * __pycache__
6
+ recursive-exclude * *.py[cod]
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: openinfra-logger
3
+ Version: 0.1.0
4
+ Summary: Universal structured logging and observability for Node, Python, Go and Rust — built from the standard library only. Native batching, auto-redaction, OpenTelemetry-aware, with native Datadog and Elastic (ECS) formatters.
5
+ Home-page: https://github.com/jonathascordeiro20/openinfra-logger
6
+ Author: Jonathas
7
+ Author-email: Jonathas Cordeiro <jonathas.cordeiro2023@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://openinfralogger.fun
10
+ Project-URL: Repository, https://github.com/jonathascordeiro20/openinfra-logger
11
+ Project-URL: Documentation, https://github.com/jonathascordeiro20/openinfra-logger#readme
12
+ Project-URL: Changelog, https://github.com/jonathascordeiro20/openinfra-logger/blob/main/CHANGELOG.md
13
+ Project-URL: Bug Tracker, https://github.com/jonathascordeiro20/openinfra-logger/issues
14
+ Keywords: logging,logger,structured-logging,observability,telemetry,opentelemetry,datadog,elasticsearch,ecs,loki,zero-dependency,lgpd,gdpr,redaction
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: System Administrators
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Programming Language :: Python :: 3.13
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Topic :: System :: Logging
29
+ Classifier: Typing :: Typed
30
+ Requires-Python: >=3.6
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Provides-Extra: opentelemetry
34
+ Requires-Dist: opentelemetry-api>=1.20; extra == "opentelemetry"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # OpenInfra Logger — Python
41
+
42
+ [![PyPI](https://img.shields.io/pypi/v/openinfra-logger?style=flat-square)](https://pypi.org/project/openinfra-logger/)
43
+ [![License](https://img.shields.io/pypi/l/openinfra-logger?style=flat-square)](https://github.com/jonathascordeiro20/openinfra-logger/blob/main/LICENSE)
44
+ [![Python Versions](https://img.shields.io/pypi/pyversions/openinfra-logger?style=flat-square)](https://pypi.org/project/openinfra-logger/)
45
+
46
+ **OpenInfra Logger** is a zero-dependency, structured logging library — built from the Python standard library only — with native batching, auto-redaction, OpenTelemetry trace injection, and Datadog/Elastic formatters.
47
+
48
+ The same JSON shape is emitted by sibling implementations for **Node.js, Go and Rust**, making polyglot stacks observable with a single log format.
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install openinfra-logger
54
+ ```
55
+
56
+ ## Quickstart
57
+
58
+ ```python
59
+ from openinfra_logger import log, configure
60
+
61
+ log("System initialized", "info")
62
+ log("Failed to parse payload", "error", {"request_id": "abc-123"})
63
+ ```
64
+
65
+ ## File + remote with batching
66
+
67
+ ```python
68
+ from openinfra_logger import log, configure
69
+
70
+ configure(
71
+ transports=["console", "file", "remote"],
72
+ file_path="./production.log",
73
+ remote_url="https://logs.my-infrastructure.com/ingest",
74
+ default_metadata={"service": "payment-gateway", "env": "production"},
75
+ batch_size=100,
76
+ flush_interval_ms=2000,
77
+ )
78
+
79
+ log("Payment processed", "info", {"transaction_id": "abc-456"})
80
+ ```
81
+
82
+ ## Datadog / Elastic formatters
83
+
84
+ ```python
85
+ configure(formatter="datadog") # renames level → status, trace_id → dd.trace_id
86
+ # configure(formatter="elastic") # renames timestamp → @timestamp, level → log.level
87
+ ```
88
+
89
+ ## Auto-redaction (LGPD / GDPR)
90
+
91
+ Sensitive keys (`password`, `token`, `secret`, `api_key`, `credit_card`) are recursively replaced with `[REDACTED]` before any transport sees the entry. Case-insensitive on key names. Override via `redact_keys=[...]` in `configure(...)`.
92
+
93
+ ```python
94
+ log("Login", "info", {"user": "alice", "password": "p@ss"})
95
+ # → "...","user":"alice","password":"[REDACTED]"
96
+ ```
97
+
98
+ ## OpenTelemetry tracing
99
+
100
+ If an OTel span is active in the current context, `trace_id` and `span_id` are picked up automatically. Install the optional extra to enable detection:
101
+
102
+ ```bash
103
+ pip install "openinfra-logger[opentelemetry]"
104
+ ```
105
+
106
+ ## Links
107
+
108
+ - **Source** — <https://github.com/jonathascordeiro20/openinfra-logger>
109
+ - **Issues** — <https://github.com/jonathascordeiro20/openinfra-logger/issues>
110
+ - **Changelog** — <https://github.com/jonathascordeiro20/openinfra-logger/blob/main/CHANGELOG.md>
111
+ - **Project site** — <https://openinfralogger.fun>
112
+
113
+ ## License
114
+
115
+ MIT — see [LICENSE](https://github.com/jonathascordeiro20/openinfra-logger/blob/main/LICENSE).
@@ -0,0 +1,76 @@
1
+ # OpenInfra Logger — Python
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/openinfra-logger?style=flat-square)](https://pypi.org/project/openinfra-logger/)
4
+ [![License](https://img.shields.io/pypi/l/openinfra-logger?style=flat-square)](https://github.com/jonathascordeiro20/openinfra-logger/blob/main/LICENSE)
5
+ [![Python Versions](https://img.shields.io/pypi/pyversions/openinfra-logger?style=flat-square)](https://pypi.org/project/openinfra-logger/)
6
+
7
+ **OpenInfra Logger** is a zero-dependency, structured logging library — built from the Python standard library only — with native batching, auto-redaction, OpenTelemetry trace injection, and Datadog/Elastic formatters.
8
+
9
+ The same JSON shape is emitted by sibling implementations for **Node.js, Go and Rust**, making polyglot stacks observable with a single log format.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install openinfra-logger
15
+ ```
16
+
17
+ ## Quickstart
18
+
19
+ ```python
20
+ from openinfra_logger import log, configure
21
+
22
+ log("System initialized", "info")
23
+ log("Failed to parse payload", "error", {"request_id": "abc-123"})
24
+ ```
25
+
26
+ ## File + remote with batching
27
+
28
+ ```python
29
+ from openinfra_logger import log, configure
30
+
31
+ configure(
32
+ transports=["console", "file", "remote"],
33
+ file_path="./production.log",
34
+ remote_url="https://logs.my-infrastructure.com/ingest",
35
+ default_metadata={"service": "payment-gateway", "env": "production"},
36
+ batch_size=100,
37
+ flush_interval_ms=2000,
38
+ )
39
+
40
+ log("Payment processed", "info", {"transaction_id": "abc-456"})
41
+ ```
42
+
43
+ ## Datadog / Elastic formatters
44
+
45
+ ```python
46
+ configure(formatter="datadog") # renames level → status, trace_id → dd.trace_id
47
+ # configure(formatter="elastic") # renames timestamp → @timestamp, level → log.level
48
+ ```
49
+
50
+ ## Auto-redaction (LGPD / GDPR)
51
+
52
+ Sensitive keys (`password`, `token`, `secret`, `api_key`, `credit_card`) are recursively replaced with `[REDACTED]` before any transport sees the entry. Case-insensitive on key names. Override via `redact_keys=[...]` in `configure(...)`.
53
+
54
+ ```python
55
+ log("Login", "info", {"user": "alice", "password": "p@ss"})
56
+ # → "...","user":"alice","password":"[REDACTED]"
57
+ ```
58
+
59
+ ## OpenTelemetry tracing
60
+
61
+ If an OTel span is active in the current context, `trace_id` and `span_id` are picked up automatically. Install the optional extra to enable detection:
62
+
63
+ ```bash
64
+ pip install "openinfra-logger[opentelemetry]"
65
+ ```
66
+
67
+ ## Links
68
+
69
+ - **Source** — <https://github.com/jonathascordeiro20/openinfra-logger>
70
+ - **Issues** — <https://github.com/jonathascordeiro20/openinfra-logger/issues>
71
+ - **Changelog** — <https://github.com/jonathascordeiro20/openinfra-logger/blob/main/CHANGELOG.md>
72
+ - **Project site** — <https://openinfralogger.fun>
73
+
74
+ ## License
75
+
76
+ MIT — see [LICENSE](https://github.com/jonathascordeiro20/openinfra-logger/blob/main/LICENSE).
@@ -0,0 +1,192 @@
1
+ """
2
+ OpenInfra Logger
3
+ Critical infrastructure library for structured observability.
4
+
5
+ @author Jonathas Cordeiro (@jonathascordeiro20)
6
+ @license MIT
7
+ @copyright (c) 2026 Jonathas Cordeiro
8
+ """
9
+ import json
10
+ import logging
11
+ import datetime
12
+ import urllib.request
13
+ import urllib.error
14
+
15
+
16
+ def _utc_now_iso():
17
+ """ISO-8601 UTC timestamp with trailing 'Z', forward-compatible with Python 3.12+."""
18
+ return datetime.datetime.now(datetime.timezone.utc).isoformat().replace('+00:00', 'Z')
19
+
20
+ # Internal configuration
21
+ _config = {
22
+ 'transports': ['console'], # console, file, remote
23
+ 'file_path': './app.log',
24
+ 'remote_url': None,
25
+ 'remote_headers': {'Content-Type': 'application/json'},
26
+ 'default_metadata': {},
27
+ 'formatter': 'default', # 'default', 'datadog', 'elastic'
28
+ 'redact_keys': ['password', 'token', 'secret', 'api_key', 'credit_card'],
29
+ 'batch_size': 100,
30
+ 'flush_interval_ms': 2000
31
+ }
32
+
33
+ _logger = logging.getLogger("openinfra_logger")
34
+ _logger.setLevel(logging.DEBUG)
35
+ # Disable default propagation so we can handle outputs cleanly
36
+ _logger.propagate = False
37
+
38
+ # Ensure we have a stream handler for console transport
39
+ if not _logger.handlers:
40
+ _console_handler = logging.StreamHandler()
41
+ _console_handler.setFormatter(logging.Formatter('%(message)s'))
42
+ _logger.addHandler(_console_handler)
43
+
44
+ def configure(**kwargs):
45
+ """
46
+ Configure the logger transports and defaults.
47
+ """
48
+ _config.update(kwargs)
49
+
50
+ def redact_object(obj, keys_to_redact):
51
+ if isinstance(obj, dict):
52
+ result = {}
53
+ for k, v in obj.items():
54
+ if k.lower() in keys_to_redact:
55
+ result[k] = '[REDACTED]'
56
+ else:
57
+ result[k] = redact_object(v, keys_to_redact)
58
+ return result
59
+ elif isinstance(obj, list):
60
+ return [redact_object(item, keys_to_redact) for item in obj]
61
+ return obj
62
+
63
+ import threading
64
+ _remote_buffer = []
65
+ _flush_timer = None
66
+
67
+ def _flush_remote():
68
+ global _remote_buffer, _flush_timer
69
+ if not _remote_buffer:
70
+ return
71
+
72
+ payload = json.dumps(_remote_buffer)
73
+ _remote_buffer = []
74
+
75
+ if _flush_timer:
76
+ _flush_timer.cancel()
77
+ _flush_timer = None
78
+
79
+ try:
80
+ req = urllib.request.Request(
81
+ _config['remote_url'],
82
+ data=payload.encode('utf-8'),
83
+ headers=_config['remote_headers'],
84
+ method='POST'
85
+ )
86
+ urllib.request.urlopen(req, timeout=2.0)
87
+ except Exception as e:
88
+ _logger.error(json.dumps({
89
+ "level": "error",
90
+ "message": f"OpenInfra Logger: Failed to send remote logs batch: {str(e)}",
91
+ "timestamp": _utc_now_iso()
92
+ }))
93
+
94
+ def extract_trace_context():
95
+ """
96
+ Attempt to extract trace context if OpenTelemetry is active.
97
+ Zero-dependency check.
98
+ """
99
+ try:
100
+ import opentelemetry.trace
101
+ span = opentelemetry.trace.get_current_span()
102
+ if span and span.is_recording():
103
+ ctx = span.get_span_context()
104
+ if ctx.is_valid:
105
+ return {
106
+ 'trace_id': format(ctx.trace_id, "032x"),
107
+ 'span_id': format(ctx.span_id, "016x")
108
+ }
109
+ except ImportError:
110
+ pass
111
+ return {}
112
+
113
+ def _dispatch(log_entry, original_level):
114
+ redacted_entry = redact_object(log_entry, _config['redact_keys'])
115
+ output = json.dumps(redacted_entry)
116
+
117
+ # 1. Console transport
118
+ if 'console' in _config['transports']:
119
+ if original_level == 'error':
120
+ _logger.error(output)
121
+ elif original_level == 'warn':
122
+ _logger.warning(output)
123
+ elif original_level == 'debug':
124
+ _logger.debug(output)
125
+ else:
126
+ _logger.info(output)
127
+
128
+ # 2. File transport
129
+ if 'file' in _config['transports'] and _config.get('file_path'):
130
+ try:
131
+ with open(_config['file_path'], 'a') as f:
132
+ f.write(output + '\n')
133
+ except Exception as e:
134
+ _logger.error(json.dumps({
135
+ "level": "error",
136
+ "message": f"OpenInfra Logger: Failed to write to log file: {str(e)}",
137
+ "timestamp": _utc_now_iso()
138
+ }))
139
+
140
+ # 3. Remote transport
141
+ global _flush_timer
142
+ if 'remote' in _config['transports'] and _config.get('remote_url'):
143
+ _remote_buffer.append(redacted_entry)
144
+ if len(_remote_buffer) >= _config['batch_size']:
145
+ _flush_remote()
146
+ elif _flush_timer is None:
147
+ _flush_timer = threading.Timer(_config['flush_interval_ms'] / 1000.0, _flush_remote)
148
+ _flush_timer.daemon = True
149
+ _flush_timer.start()
150
+
151
+ def log(message: str, level: str = 'info', metadata: dict = None):
152
+ """
153
+ Emits a structured JSON log.
154
+ """
155
+ if metadata is None:
156
+ metadata = {}
157
+
158
+ normalized_level = level.lower()
159
+ valid_levels = {'debug', 'info', 'warn', 'error'}
160
+
161
+ if normalized_level not in valid_levels:
162
+ _logger.warning(json.dumps({
163
+ "level": "warn",
164
+ "message": f"Invalid log level '{level}' provided, falling back to 'info'",
165
+ "timestamp": _utc_now_iso()
166
+ }))
167
+ normalized_level = 'info'
168
+
169
+ log_entry = {
170
+ "timestamp": _utc_now_iso(),
171
+ "level": normalized_level,
172
+ "message": message,
173
+ }
174
+
175
+ trace_context = extract_trace_context()
176
+
177
+ # Merge default metadata, trace context, and specific metadata
178
+ log_entry.update(_config['default_metadata'])
179
+ log_entry.update(trace_context)
180
+ log_entry.update(metadata)
181
+
182
+ if _config['formatter'] == 'datadog':
183
+ log_entry['status'] = log_entry.pop('level', 'info')
184
+ if 'trace_id' in log_entry:
185
+ log_entry['dd.trace_id'] = log_entry.pop('trace_id')
186
+ if 'span_id' in log_entry:
187
+ log_entry['dd.span_id'] = log_entry.pop('span_id')
188
+ elif _config['formatter'] == 'elastic':
189
+ log_entry['@timestamp'] = log_entry.pop('timestamp')
190
+ log_entry['log.level'] = log_entry.pop('level', 'info')
191
+
192
+ _dispatch(log_entry, normalized_level)
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: openinfra-logger
3
+ Version: 0.1.0
4
+ Summary: Universal structured logging and observability for Node, Python, Go and Rust — built from the standard library only. Native batching, auto-redaction, OpenTelemetry-aware, with native Datadog and Elastic (ECS) formatters.
5
+ Home-page: https://github.com/jonathascordeiro20/openinfra-logger
6
+ Author: Jonathas
7
+ Author-email: Jonathas Cordeiro <jonathas.cordeiro2023@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://openinfralogger.fun
10
+ Project-URL: Repository, https://github.com/jonathascordeiro20/openinfra-logger
11
+ Project-URL: Documentation, https://github.com/jonathascordeiro20/openinfra-logger#readme
12
+ Project-URL: Changelog, https://github.com/jonathascordeiro20/openinfra-logger/blob/main/CHANGELOG.md
13
+ Project-URL: Bug Tracker, https://github.com/jonathascordeiro20/openinfra-logger/issues
14
+ Keywords: logging,logger,structured-logging,observability,telemetry,opentelemetry,datadog,elasticsearch,ecs,loki,zero-dependency,lgpd,gdpr,redaction
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: System Administrators
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Programming Language :: Python :: 3.13
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Topic :: System :: Logging
29
+ Classifier: Typing :: Typed
30
+ Requires-Python: >=3.6
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Provides-Extra: opentelemetry
34
+ Requires-Dist: opentelemetry-api>=1.20; extra == "opentelemetry"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # OpenInfra Logger — Python
41
+
42
+ [![PyPI](https://img.shields.io/pypi/v/openinfra-logger?style=flat-square)](https://pypi.org/project/openinfra-logger/)
43
+ [![License](https://img.shields.io/pypi/l/openinfra-logger?style=flat-square)](https://github.com/jonathascordeiro20/openinfra-logger/blob/main/LICENSE)
44
+ [![Python Versions](https://img.shields.io/pypi/pyversions/openinfra-logger?style=flat-square)](https://pypi.org/project/openinfra-logger/)
45
+
46
+ **OpenInfra Logger** is a zero-dependency, structured logging library — built from the Python standard library only — with native batching, auto-redaction, OpenTelemetry trace injection, and Datadog/Elastic formatters.
47
+
48
+ The same JSON shape is emitted by sibling implementations for **Node.js, Go and Rust**, making polyglot stacks observable with a single log format.
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install openinfra-logger
54
+ ```
55
+
56
+ ## Quickstart
57
+
58
+ ```python
59
+ from openinfra_logger import log, configure
60
+
61
+ log("System initialized", "info")
62
+ log("Failed to parse payload", "error", {"request_id": "abc-123"})
63
+ ```
64
+
65
+ ## File + remote with batching
66
+
67
+ ```python
68
+ from openinfra_logger import log, configure
69
+
70
+ configure(
71
+ transports=["console", "file", "remote"],
72
+ file_path="./production.log",
73
+ remote_url="https://logs.my-infrastructure.com/ingest",
74
+ default_metadata={"service": "payment-gateway", "env": "production"},
75
+ batch_size=100,
76
+ flush_interval_ms=2000,
77
+ )
78
+
79
+ log("Payment processed", "info", {"transaction_id": "abc-456"})
80
+ ```
81
+
82
+ ## Datadog / Elastic formatters
83
+
84
+ ```python
85
+ configure(formatter="datadog") # renames level → status, trace_id → dd.trace_id
86
+ # configure(formatter="elastic") # renames timestamp → @timestamp, level → log.level
87
+ ```
88
+
89
+ ## Auto-redaction (LGPD / GDPR)
90
+
91
+ Sensitive keys (`password`, `token`, `secret`, `api_key`, `credit_card`) are recursively replaced with `[REDACTED]` before any transport sees the entry. Case-insensitive on key names. Override via `redact_keys=[...]` in `configure(...)`.
92
+
93
+ ```python
94
+ log("Login", "info", {"user": "alice", "password": "p@ss"})
95
+ # → "...","user":"alice","password":"[REDACTED]"
96
+ ```
97
+
98
+ ## OpenTelemetry tracing
99
+
100
+ If an OTel span is active in the current context, `trace_id` and `span_id` are picked up automatically. Install the optional extra to enable detection:
101
+
102
+ ```bash
103
+ pip install "openinfra-logger[opentelemetry]"
104
+ ```
105
+
106
+ ## Links
107
+
108
+ - **Source** — <https://github.com/jonathascordeiro20/openinfra-logger>
109
+ - **Issues** — <https://github.com/jonathascordeiro20/openinfra-logger/issues>
110
+ - **Changelog** — <https://github.com/jonathascordeiro20/openinfra-logger/blob/main/CHANGELOG.md>
111
+ - **Project site** — <https://openinfralogger.fun>
112
+
113
+ ## License
114
+
115
+ MIT — see [LICENSE](https://github.com/jonathascordeiro20/openinfra-logger/blob/main/LICENSE).
@@ -0,0 +1,12 @@
1
+ CHANGELOG.md
2
+ LICENSE
3
+ MANIFEST.in
4
+ README.md
5
+ pyproject.toml
6
+ setup.py
7
+ openinfra_logger/__init__.py
8
+ openinfra_logger.egg-info/PKG-INFO
9
+ openinfra_logger.egg-info/SOURCES.txt
10
+ openinfra_logger.egg-info/dependency_links.txt
11
+ openinfra_logger.egg-info/requires.txt
12
+ openinfra_logger.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+
2
+ [opentelemetry]
3
+ opentelemetry-api>=1.20
@@ -0,0 +1 @@
1
+ openinfra_logger
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "openinfra-logger"
7
+ version = "0.1.0"
8
+ description = "Universal structured logging and observability for Node, Python, Go and Rust — built from the standard library only. Native batching, auto-redaction, OpenTelemetry-aware, with native Datadog and Elastic (ECS) formatters."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Jonathas Cordeiro", email = "jonathas.cordeiro2023@gmail.com" }
14
+ ]
15
+ keywords = [
16
+ "logging", "logger", "structured-logging", "observability",
17
+ "telemetry", "opentelemetry", "datadog", "elasticsearch",
18
+ "ecs", "loki", "zero-dependency", "lgpd", "gdpr", "redaction"
19
+ ]
20
+ classifiers = [
21
+ "Development Status :: 4 - Beta",
22
+ "Intended Audience :: Developers",
23
+ "Intended Audience :: System Administrators",
24
+ "License :: OSI Approved :: MIT License",
25
+ "Operating System :: OS Independent",
26
+ "Programming Language :: Python :: 3",
27
+ "Programming Language :: Python :: 3.8",
28
+ "Programming Language :: Python :: 3.9",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Programming Language :: Python :: 3.13",
33
+ "Topic :: Software Development :: Libraries :: Python Modules",
34
+ "Topic :: System :: Logging",
35
+ "Typing :: Typed"
36
+ ]
37
+ # No runtime dependencies. The package is built from the standard library only.
38
+ dependencies = []
39
+
40
+ [project.urls]
41
+ Homepage = "https://openinfralogger.fun"
42
+ Repository = "https://github.com/jonathascordeiro20/openinfra-logger"
43
+ Documentation = "https://github.com/jonathascordeiro20/openinfra-logger#readme"
44
+ Changelog = "https://github.com/jonathascordeiro20/openinfra-logger/blob/main/CHANGELOG.md"
45
+ "Bug Tracker" = "https://github.com/jonathascordeiro20/openinfra-logger/issues"
46
+
47
+ [project.optional-dependencies]
48
+ opentelemetry = ["opentelemetry-api>=1.20"]
49
+
50
+ [tool.setuptools.packages.find]
51
+ include = ["openinfra_logger*"]
52
+ exclude = ["tests*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,17 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="openinfra-logger",
5
+ version="0.1.0",
6
+ description="Critical structured logging and observability library for modern infrastructure",
7
+ author="Jonathas",
8
+ url="https://github.com/jonathascordeiro20/openinfra-logger",
9
+ packages=find_packages(),
10
+ install_requires=[],
11
+ classifiers=[
12
+ "Programming Language :: Python :: 3",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Operating System :: OS Independent",
15
+ ],
16
+ python_requires='>=3.6',
17
+ )