datadog-async-handler 0.1.2__tar.gz → 0.1.3__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.
- datadog_async_handler-0.1.3/CHANGELOG.md +54 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/PKG-INFO +6 -6
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/mkdocs.yml +3 -3
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/pyproject.toml +5 -5
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/src/datadog_http_handler/__init__.py +1 -1
- datadog_async_handler-0.1.3/src/datadog_http_handler/formatter.py +132 -0
- datadog_async_handler-0.1.2/CHANGELOG.md +0 -48
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/.gitignore +0 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/CONTRIBUTING.md +0 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/LICENSE +0 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/README.md +0 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/src/datadog_http_handler/handler.py +0 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/src/datadog_http_handler/py.typed +0 -0
- {datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/uv.lock +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.2] - 2025-08-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- First stable release of datadog-async-handler
|
|
12
|
+
- High-performance async HTTP logging handler for Datadog
|
|
13
|
+
- Asynchronous batching and background processing
|
|
14
|
+
- Automatic retry logic with exponential backoff
|
|
15
|
+
- Configurable batch size and flush intervals
|
|
16
|
+
- Rich metadata support (service, environment, tags)
|
|
17
|
+
- Multi-site Datadog support (US, EU, etc.)
|
|
18
|
+
- Full type hints and mypy compatibility
|
|
19
|
+
- Comprehensive documentation and examples
|
|
20
|
+
- GitHub Actions CI/CD with trusted PyPI publishing
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
- **Performance**: Non-blocking background processing
|
|
24
|
+
- **Reliability**: Comprehensive retry logic and error handling
|
|
25
|
+
- **Efficiency**: Memory-optimized batching reduces API calls
|
|
26
|
+
- **Integration**: Drop-in replacement for standard logging handlers
|
|
27
|
+
- **Framework Support**: Examples for Django, FastAPI, Flask, Celery
|
|
28
|
+
- **Testing**: Comprehensive test suite with >95% coverage
|
|
29
|
+
|
|
30
|
+
### Documentation
|
|
31
|
+
- Complete API reference with mkdocstrings
|
|
32
|
+
- Framework integration examples
|
|
33
|
+
- Configuration guide with all parameters
|
|
34
|
+
- Troubleshooting documentation
|
|
35
|
+
- Installation instructions
|
|
36
|
+
|
|
37
|
+
### Infrastructure
|
|
38
|
+
- Modern Python packaging with pyproject.toml
|
|
39
|
+
- Hatch build system with UV package manager
|
|
40
|
+
- Ruff for formatting and linting
|
|
41
|
+
- MyPy for type checking
|
|
42
|
+
- Pytest for testing
|
|
43
|
+
- MkDocs Material theme for documentation
|
|
44
|
+
- GitHub Actions for CI/CD
|
|
45
|
+
- Trusted publishing to PyPI
|
|
46
|
+
|
|
47
|
+
## [Unreleased]
|
|
48
|
+
|
|
49
|
+
### Planned
|
|
50
|
+
- Async/await support for truly asynchronous logging
|
|
51
|
+
- Metrics and tracing integration
|
|
52
|
+
- Advanced filtering and transformation options
|
|
53
|
+
- Performance optimizations
|
|
54
|
+
- Additional framework integrations
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datadog-async-handler
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: High-performance async HTTP logging handler for Datadog with batching and retry logic
|
|
5
|
-
Project-URL: Homepage, https://github.com/enlyft/datadog-
|
|
6
|
-
Project-URL: Documentation, https://enlyft.github.io/datadog-
|
|
7
|
-
Project-URL: Repository, https://github.com/enlyft/datadog-
|
|
8
|
-
Project-URL: Changelog, https://github.com/enlyft/datadog-
|
|
9
|
-
Project-URL: Bug Tracker, https://github.com/enlyft/datadog-
|
|
5
|
+
Project-URL: Homepage, https://github.com/enlyft/datadog-async-handler
|
|
6
|
+
Project-URL: Documentation, https://enlyft.github.io/datadog-async-handler
|
|
7
|
+
Project-URL: Repository, https://github.com/enlyft/datadog-async-handler.git
|
|
8
|
+
Project-URL: Changelog, https://github.com/enlyft/datadog-async-handler/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/enlyft/datadog-async-handler/issues
|
|
10
10
|
Author-email: Parth <parth@enlyft.com>
|
|
11
11
|
Maintainer-email: Parth <parth@enlyft.com>
|
|
12
12
|
License-Expression: MIT
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
site_name: Datadog Async Handler
|
|
2
2
|
site_description: High-performance async HTTP logging handler for Datadog with batching and retry logic
|
|
3
|
-
site_url: https://enlyft.github.io/datadog-
|
|
4
|
-
repo_url: https://github.com/enlyft/datadog-
|
|
5
|
-
repo_name: enlyft/datadog-
|
|
3
|
+
site_url: https://enlyft.github.io/datadog-async-handler
|
|
4
|
+
repo_url: https://github.com/enlyft/datadog-async-handler
|
|
5
|
+
repo_name: enlyft/datadog-async-handler
|
|
6
6
|
|
|
7
7
|
theme:
|
|
8
8
|
name: material
|
|
@@ -71,11 +71,11 @@ test = [
|
|
|
71
71
|
]
|
|
72
72
|
|
|
73
73
|
[project.urls]
|
|
74
|
-
Homepage = "https://github.com/enlyft/datadog-
|
|
75
|
-
Documentation = "https://enlyft.github.io/datadog-
|
|
76
|
-
Repository = "https://github.com/enlyft/datadog-
|
|
77
|
-
Changelog = "https://github.com/enlyft/datadog-
|
|
78
|
-
"Bug Tracker" = "https://github.com/enlyft/datadog-
|
|
74
|
+
Homepage = "https://github.com/enlyft/datadog-async-handler"
|
|
75
|
+
Documentation = "https://enlyft.github.io/datadog-async-handler"
|
|
76
|
+
Repository = "https://github.com/enlyft/datadog-async-handler.git"
|
|
77
|
+
Changelog = "https://github.com/enlyft/datadog-async-handler/blob/main/CHANGELOG.md"
|
|
78
|
+
"Bug Tracker" = "https://github.com/enlyft/datadog-async-handler/issues"
|
|
79
79
|
|
|
80
80
|
[tool.hatch.version]
|
|
81
81
|
source = "vcs"
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DatadogJsonFormatter(logging.Formatter):
|
|
9
|
+
"""
|
|
10
|
+
JSON formatter optimized for Datadog log ingestion.
|
|
11
|
+
|
|
12
|
+
This formatter creates structured JSON logs with fields that Datadog
|
|
13
|
+
can automatically parse and index for better searchability and analysis.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, service_name: str, version: Optional[str] = None):
|
|
17
|
+
"""
|
|
18
|
+
Initialize the formatter.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
service_name: Name of the service (e.g., 'auth-service', 'embedding-service')
|
|
22
|
+
version: Version of the service (optional)
|
|
23
|
+
"""
|
|
24
|
+
super().__init__()
|
|
25
|
+
self.service_name = service_name
|
|
26
|
+
self.version = version or os.getenv("SERVICE_VERSION", "unknown")
|
|
27
|
+
self.environment = os.getenv("DD_ENV", "development")
|
|
28
|
+
|
|
29
|
+
def format(self, record: logging.LogRecord) -> str:
|
|
30
|
+
"""
|
|
31
|
+
Format a log record as JSON.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
record: The log record to format
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
JSON-formatted log string
|
|
38
|
+
"""
|
|
39
|
+
# Base log structure for Datadog
|
|
40
|
+
log_entry = {
|
|
41
|
+
"timestamp": datetime.fromtimestamp(record.created, tz=timezone.utc).isoformat(),
|
|
42
|
+
"level": record.levelname,
|
|
43
|
+
"logger": record.name,
|
|
44
|
+
"message": record.getMessage(),
|
|
45
|
+
"service": self.service_name,
|
|
46
|
+
"version": self.version,
|
|
47
|
+
"env": self.environment,
|
|
48
|
+
"process_id": record.process,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# --- Datadog correlation IDs (must be at top level) ---
|
|
52
|
+
# First check nested dd fields
|
|
53
|
+
if hasattr(record, "dd"):
|
|
54
|
+
dd_fields = record.dd
|
|
55
|
+
if "trace_id" in dd_fields:
|
|
56
|
+
log_entry["dd.trace_id"] = dd_fields["trace_id"]
|
|
57
|
+
if "span_id" in dd_fields:
|
|
58
|
+
log_entry["dd.span_id"] = dd_fields["span_id"]
|
|
59
|
+
if "service" in dd_fields:
|
|
60
|
+
log_entry["dd.service"] = dd_fields["service"]
|
|
61
|
+
if "version" in dd_fields:
|
|
62
|
+
log_entry["dd.version"] = dd_fields["version"]
|
|
63
|
+
if "env" in dd_fields:
|
|
64
|
+
log_entry["dd.env"] = dd_fields["env"]
|
|
65
|
+
|
|
66
|
+
# Then check for flat Datadog attributes that ddtrace may inject
|
|
67
|
+
dd_flat_keys = ["dd.trace_id", "dd.span_id", "dd.service", "dd.version", "dd.env"]
|
|
68
|
+
for dd_key in dd_flat_keys:
|
|
69
|
+
# Only use flat key if we don't already have this field from record.dd
|
|
70
|
+
if dd_key not in log_entry and hasattr(record, dd_key):
|
|
71
|
+
log_entry[dd_key] = getattr(record, dd_key)
|
|
72
|
+
|
|
73
|
+
# --- Add source info ---
|
|
74
|
+
if record.pathname:
|
|
75
|
+
log_entry["source"] = {
|
|
76
|
+
"file": record.pathname,
|
|
77
|
+
"line": record.lineno,
|
|
78
|
+
"function": record.funcName,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# --- Collect remaining extras, except dd (already flattened) ---
|
|
82
|
+
extra_fields = {
|
|
83
|
+
k: v
|
|
84
|
+
for k, v in record.__dict__.items()
|
|
85
|
+
if k
|
|
86
|
+
not in {
|
|
87
|
+
"name",
|
|
88
|
+
"msg",
|
|
89
|
+
"args",
|
|
90
|
+
"levelname",
|
|
91
|
+
"levelno",
|
|
92
|
+
"pathname",
|
|
93
|
+
"filename",
|
|
94
|
+
"module",
|
|
95
|
+
"lineno",
|
|
96
|
+
"funcName",
|
|
97
|
+
"created",
|
|
98
|
+
"msecs",
|
|
99
|
+
"relativeCreated",
|
|
100
|
+
"thread",
|
|
101
|
+
"threadName",
|
|
102
|
+
"processName",
|
|
103
|
+
"process",
|
|
104
|
+
"getMessage",
|
|
105
|
+
"exc_info",
|
|
106
|
+
"exc_text",
|
|
107
|
+
"stack_info",
|
|
108
|
+
"message",
|
|
109
|
+
"dd", # skip dd because we handled it
|
|
110
|
+
"dd.trace_id", # skip flat dd keys because we handled them
|
|
111
|
+
"dd.span_id",
|
|
112
|
+
"dd.service",
|
|
113
|
+
"dd.version",
|
|
114
|
+
"dd.env",
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if extra_fields:
|
|
118
|
+
log_entry["extra"] = extra_fields
|
|
119
|
+
|
|
120
|
+
# --- Exception handling ---
|
|
121
|
+
if record.exc_info:
|
|
122
|
+
log_entry["exception"] = {
|
|
123
|
+
"class": record.exc_info[0].__name__ if record.exc_info[0] else None,
|
|
124
|
+
"message": str(record.exc_info[1]) if record.exc_info[1] else None,
|
|
125
|
+
"traceback": self.formatException(record.exc_info),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if record.stack_info:
|
|
129
|
+
log_entry["stack_trace"] = record.stack_info
|
|
130
|
+
|
|
131
|
+
return json.dumps(log_entry, default=str, ensure_ascii=False)
|
|
132
|
+
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
|
|
8
|
-
## [Unreleased]
|
|
9
|
-
|
|
10
|
-
### Added
|
|
11
|
-
- Initial release of datadog-http-handler
|
|
12
|
-
- Asynchronous HTTP logging handler for Datadog
|
|
13
|
-
- Batching support with configurable batch size and flush intervals
|
|
14
|
-
- Automatic retry logic with exponential backoff
|
|
15
|
-
- Comprehensive error handling and graceful degradation
|
|
16
|
-
- Type hints and mypy compatibility
|
|
17
|
-
- Support for all Datadog sites (US, EU, Government, etc.)
|
|
18
|
-
- Environment variable configuration support
|
|
19
|
-
- Framework integration examples (Django, FastAPI, Flask)
|
|
20
|
-
- Background worker thread for non-blocking log processing
|
|
21
|
-
- Automatic tag enrichment (environment, service, version)
|
|
22
|
-
- Memory-efficient queue management
|
|
23
|
-
- Graceful shutdown handling
|
|
24
|
-
|
|
25
|
-
### Changed
|
|
26
|
-
- N/A (initial release)
|
|
27
|
-
|
|
28
|
-
### Deprecated
|
|
29
|
-
- N/A (initial release)
|
|
30
|
-
|
|
31
|
-
### Removed
|
|
32
|
-
- N/A (initial release)
|
|
33
|
-
|
|
34
|
-
### Fixed
|
|
35
|
-
- N/A (initial release)
|
|
36
|
-
|
|
37
|
-
### Security
|
|
38
|
-
- N/A (initial release)
|
|
39
|
-
|
|
40
|
-
## [0.1.0] - 2025-08-25
|
|
41
|
-
|
|
42
|
-
### Added
|
|
43
|
-
- Initial development version
|
|
44
|
-
- Core DatadogHTTPHandler implementation
|
|
45
|
-
- Basic test suite
|
|
46
|
-
- Documentation and examples
|
|
47
|
-
- Modern Python packaging with Hatch
|
|
48
|
-
- Comprehensive development tooling (Ruff, mypy, pytest)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/src/datadog_http_handler/handler.py
RENAMED
|
File without changes
|
{datadog_async_handler-0.1.2 → datadog_async_handler-0.1.3}/src/datadog_http_handler/py.typed
RENAMED
|
File without changes
|
|
File without changes
|