log-foundry 0.10.2.dev127__tar.gz → 0.10.2.dev128__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.
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/PKG-INFO +6 -3
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/README.md +5 -2
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/pyproject.toml +1 -1
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/decorator.py +76 -4
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/LICENSE +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/__init__.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/_diag.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/_fork.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/_lifecycle.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/api.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/config.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/console.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/context.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/ids.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/model.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/py.typed +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/results.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sanitize.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/__init__.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/_batch.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/_chunk.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/_retry.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/_socket.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/_time.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/base.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/callback.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/clickhouse.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/datadog.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/elasticsearch.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/eventhubs.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/file.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/filtering.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/firehose.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/honeycomb.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/http.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/kafka.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/kinesis.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/logging_sink.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/logstash.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/loki.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/memory.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/mongodb.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/multi.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/nats.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/newrelic.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/null.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/postgres.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/pubsub.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/rabbitmq.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/redis.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/sentry.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/sns.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/splunk.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/sqlite.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/sqs.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/stdout.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/syslog.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/transform.py +0 -0
- {log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/worker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: log-foundry
|
|
3
|
-
Version: 0.10.2.
|
|
3
|
+
Version: 0.10.2.dev128
|
|
4
4
|
Summary: Generate logs for your console and JSON events for downstream consumption.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -347,7 +347,7 @@ lands can arrive at a sink whose close has already run, and nothing owes that si
|
|
|
347
347
|
|
|
348
348
|
### `@trace`
|
|
349
349
|
|
|
350
|
-
Decorate
|
|
350
|
+
Decorate a function, sync or async. Usable bare or with arguments:
|
|
351
351
|
|
|
352
352
|
```python
|
|
353
353
|
@lf.trace # span name = func.__qualname__
|
|
@@ -363,7 +363,10 @@ def process(): ...
|
|
|
363
363
|
|
|
364
364
|
`@trace` refuses at decoration what it cannot trace, with a `TypeError` naming the function:
|
|
365
365
|
a `@classmethod` or `@staticmethod` written *below* it (put them above), a bare string
|
|
366
|
-
(`@trace("checkout")` meant `@trace(name="checkout")`),
|
|
366
|
+
(`@trace("checkout")` meant `@trace(name="checkout")`), anything not callable, and a
|
|
367
|
+
**generator function** (sync or async, including one behind `@contextmanager`, `@lru_cache` or
|
|
368
|
+
any `functools.wraps` wrapper) — its body runs after the wrapper has returned, so the span would
|
|
369
|
+
close before it started. Trace the consumer instead: the function that iterates it.
|
|
367
370
|
|
|
368
371
|
The **outermost** decorated call starts a new trace; every nested decorated call becomes a
|
|
369
372
|
child span within it. On an exception, the decorator records `status="error"` plus an `error`
|
|
@@ -296,7 +296,7 @@ lands can arrive at a sink whose close has already run, and nothing owes that si
|
|
|
296
296
|
|
|
297
297
|
### `@trace`
|
|
298
298
|
|
|
299
|
-
Decorate
|
|
299
|
+
Decorate a function, sync or async. Usable bare or with arguments:
|
|
300
300
|
|
|
301
301
|
```python
|
|
302
302
|
@lf.trace # span name = func.__qualname__
|
|
@@ -312,7 +312,10 @@ def process(): ...
|
|
|
312
312
|
|
|
313
313
|
`@trace` refuses at decoration what it cannot trace, with a `TypeError` naming the function:
|
|
314
314
|
a `@classmethod` or `@staticmethod` written *below* it (put them above), a bare string
|
|
315
|
-
(`@trace("checkout")` meant `@trace(name="checkout")`),
|
|
315
|
+
(`@trace("checkout")` meant `@trace(name="checkout")`), anything not callable, and a
|
|
316
|
+
**generator function** (sync or async, including one behind `@contextmanager`, `@lru_cache` or
|
|
317
|
+
any `functools.wraps` wrapper) — its body runs after the wrapper has returned, so the span would
|
|
318
|
+
close before it started. Trace the consumer instead: the function that iterates it.
|
|
316
319
|
|
|
317
320
|
The **outermost** decorated call starts a new trace; every nested decorated call becomes a
|
|
318
321
|
child span within it. On an exception, the decorator records `status="error"` plus an `error`
|
|
@@ -74,7 +74,7 @@ keywords = [
|
|
|
74
74
|
# vulnerability-reporting channel. The repository is still named `log-forge` — the ORIGINAL name,
|
|
75
75
|
# which PyPI rejected for the distribution — so these URLs deliberately do not match the package
|
|
76
76
|
# name. See the note on `name` above before "correcting" them.
|
|
77
|
-
version = "0.10.2.
|
|
77
|
+
version = "0.10.2.dev128"
|
|
78
78
|
|
|
79
79
|
[project.urls]
|
|
80
80
|
Homepage = "https://github.com/agriffi10/log-forge"
|
|
@@ -639,6 +639,21 @@ def _refuse_unusable(fn: object) -> None:
|
|
|
639
639
|
``self`` to a function declared without one. A ``str`` is the slip ``@trace("checkout")``,
|
|
640
640
|
which meant ``name=``. Anything else that is not callable is refused by type.
|
|
641
641
|
|
|
642
|
+
A generator function or an async generator function is refused too (SPEC-055 FR-003): its
|
|
643
|
+
body runs after the wrapper has returned the generator object, so the span would open and
|
|
644
|
+
close before a single line of it ran, and every event the body logged would be an orphan on
|
|
645
|
+
a fresh trace — measured, ``['span.start', 'span.end']`` before the first ``next()``. The
|
|
646
|
+
check is the code flags, on ``fn``, on whatever ``fn`` advertises through ``__wrapped__``
|
|
647
|
+
— so ``@trace`` above ``@contextmanager``, ``@lru_cache`` or any ``functools.wraps`` wrapper
|
|
648
|
+
of a generator is refused too, each measured recording the same orphaned ``inside`` event —
|
|
649
|
+
and on the type's ``__call__`` for a callable instance; all of them see through a
|
|
650
|
+
``functools.partial``. A plain function that merely *returns* a generator object without
|
|
651
|
+
advertising it is indistinguishable here and is not detected, which is a stated limit
|
|
652
|
+
rather than a gap to close at call time, where invariant 13 does not refuse. Wrapping the
|
|
653
|
+
iteration instead — a span per generator, pushed around every resumption — was considered
|
|
654
|
+
and deferred: a refusal can be lifted into a wrap later without breaking anyone, while a
|
|
655
|
+
wrap shipped first freezes its semantics at 1.0.
|
|
656
|
+
|
|
642
657
|
Args:
|
|
643
658
|
fn: Whatever was handed to the decorator.
|
|
644
659
|
|
|
@@ -646,8 +661,8 @@ def _refuse_unusable(fn: object) -> None:
|
|
|
646
661
|
None.
|
|
647
662
|
|
|
648
663
|
Raises:
|
|
649
|
-
TypeError: If ``fn`` is a ``classmethod`` or ``staticmethod`` object, a ``str``,
|
|
650
|
-
callable at all.
|
|
664
|
+
TypeError: If ``fn`` is a ``classmethod`` or ``staticmethod`` object, a ``str``, not
|
|
665
|
+
callable at all, or a generator function or async generator function.
|
|
651
666
|
Exception: Whatever the callable's own attribute access raises — a ``__class__`` property,
|
|
652
667
|
say — at decoration, in the caller's frame, which is invariant 13's moment.
|
|
653
668
|
"""
|
|
@@ -664,6 +679,61 @@ def _refuse_unusable(fn: object) -> None:
|
|
|
664
679
|
)
|
|
665
680
|
if not callable(fn):
|
|
666
681
|
raise TypeError(f"@trace needs a callable, got {type(fn).__name__}")
|
|
682
|
+
if _is_generator_function(fn):
|
|
683
|
+
raise TypeError(
|
|
684
|
+
f"@trace cannot trace the iteration of the generator function {_span_name(fn)}: its "
|
|
685
|
+
f"body runs after the wrapper has returned, so the span would close before it "
|
|
686
|
+
f"starts. Trace the consumer instead: the function that iterates it"
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
def _is_generator_function(fn: object) -> bool:
|
|
691
|
+
"""Reports whether a callable's body is a generator or async generator (SPEC-055 FR-003).
|
|
692
|
+
|
|
693
|
+
The same shape as :func:`_is_async`: the code flags of ``fn`` itself, which see through a
|
|
694
|
+
``functools.partial``; then of whatever ``fn`` advertises through ``__wrapped__``, which is
|
|
695
|
+
how ``@contextmanager``, ``@lru_cache`` and every ``functools.wraps`` wrapper point back at
|
|
696
|
+
the generator they wrap; and for anything that is not a plain function the type's
|
|
697
|
+
``__call__`` as well, so a callable instance whose ``__call__`` yields is caught too. The
|
|
698
|
+
unwrap is guarded because :func:`inspect.unwrap` raises ``ValueError`` on a ``__wrapped__``
|
|
699
|
+
cycle, and a cycle is not a generator.
|
|
700
|
+
|
|
701
|
+
Args:
|
|
702
|
+
fn: The callable being decorated.
|
|
703
|
+
|
|
704
|
+
Returns:
|
|
705
|
+
Whether ``fn`` would return a generator or async generator object when called.
|
|
706
|
+
|
|
707
|
+
Raises:
|
|
708
|
+
Exception: Whatever the callable's own ``__class__``, ``__call__`` or ``__wrapped__``
|
|
709
|
+
lookup raises, at decoration, in the caller's frame.
|
|
710
|
+
"""
|
|
711
|
+
if _yields(fn):
|
|
712
|
+
return True
|
|
713
|
+
try:
|
|
714
|
+
target = inspect.unwrap(cast("Callable[..., Any]", fn))
|
|
715
|
+
except ValueError:
|
|
716
|
+
target = fn
|
|
717
|
+
if target is not fn and _yields(target):
|
|
718
|
+
return True
|
|
719
|
+
if inspect.isfunction(fn):
|
|
720
|
+
return False
|
|
721
|
+
return _yields(type(fn).__call__)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
def _yields(fn: object) -> bool:
|
|
725
|
+
"""Reads a callable's code flags for a generator or async generator body.
|
|
726
|
+
|
|
727
|
+
Args:
|
|
728
|
+
fn: The callable to inspect.
|
|
729
|
+
|
|
730
|
+
Returns:
|
|
731
|
+
Whether its body is a generator or an async generator.
|
|
732
|
+
|
|
733
|
+
Raises:
|
|
734
|
+
None.
|
|
735
|
+
"""
|
|
736
|
+
return inspect.isgeneratorfunction(fn) or inspect.isasyncgenfunction(fn)
|
|
667
737
|
|
|
668
738
|
|
|
669
739
|
def _span_name(fn: object) -> str:
|
|
@@ -749,8 +819,10 @@ def trace(
|
|
|
749
819
|
|
|
750
820
|
Raises:
|
|
751
821
|
TypeError: At decoration, for a ``classmethod`` or ``staticmethod`` object (the decorators
|
|
752
|
-
are in the wrong order), a ``str`` (``name=`` was meant), anything not callable,
|
|
753
|
-
``name=`` that is not a ``str`` (SPEC-055 FR-002,
|
|
822
|
+
are in the wrong order), a ``str`` (``name=`` was meant), anything not callable, a
|
|
823
|
+
``name=`` that is not a ``str`` (SPEC-055 FR-002), or a generator function, whose
|
|
824
|
+
iteration cannot be traced by a wrapper around the call (SPEC-055 FR-003) — invariant
|
|
825
|
+
13.
|
|
754
826
|
"""
|
|
755
827
|
span_defaults = None if defaults is None else dict(defaults)
|
|
756
828
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/elasticsearch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{log_foundry-0.10.2.dev127 → log_foundry-0.10.2.dev128}/src/log_foundry/sinks/logging_sink.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|