hydra-structlog 0.1.0__tar.gz → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hydra-structlog
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: An opinionated hydra plugin to configure logging with structlog
5
5
  Keywords: hydra,structlog,plugin,hydra-zen
6
6
  Author: Sören Zapp
@@ -27,6 +27,11 @@ Description-Content-Type: text/markdown
27
27
 
28
28
  # Hydra-Structlog
29
29
 
30
+ [![CI](https://github.com/szapp/hydra-structlog/actions/workflows/ci.yml/badge.svg)](https://github.com/szapp/hydra-structlog/actions/workflows/ci.yml)
31
+ [![PyPI](https://img.shields.io/pypi/v/hydra-structlog)](https://pypi.python.org/pypi/hydra-structlog)
32
+ [![Python Versions](https://img.shields.io/pypi/pyversions/hydra-structlog)](https://github.com/szapp/hydra-structlog)
33
+ [![Support on Ko-fi](https://img.shields.io/badge/ko--fi-support-ff586e?logo=kofi&logoColor=white)](https://ko-fi.com/szapp)
34
+
30
35
  An opinionated hydra plugin to configure logging with structlog.
31
36
 
32
37
  ## Usage
@@ -1,5 +1,10 @@
1
1
  # Hydra-Structlog
2
2
 
3
+ [![CI](https://github.com/szapp/hydra-structlog/actions/workflows/ci.yml/badge.svg)](https://github.com/szapp/hydra-structlog/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/hydra-structlog)](https://pypi.python.org/pypi/hydra-structlog)
5
+ [![Python Versions](https://img.shields.io/pypi/pyversions/hydra-structlog)](https://github.com/szapp/hydra-structlog)
6
+ [![Support on Ko-fi](https://img.shields.io/badge/ko--fi-support-ff586e?logo=kofi&logoColor=white)](https://ko-fi.com/szapp)
7
+
3
8
  An opinionated hydra plugin to configure logging with structlog.
4
9
 
5
10
  ## Usage
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hydra-structlog"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  description = "An opinionated hydra plugin to configure logging with structlog"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -0,0 +1 @@
1
+ __version__ = "0.2.0"
@@ -40,12 +40,13 @@ formatters:
40
40
  remove_processors_meta:
41
41
  _target_: structlog.stdlib.ProcessorFormatter.remove_processors_meta
42
42
  _partial_: true
43
- static_field_adder:
44
- _target_: hydra_structlog.processors.StaticFieldAdder
45
- service: ${oc.env:SERVICE,null}
46
- version: ${oc.env:VERSION,null}
47
- env: ${oc.env:ENV,dev}
43
+ static_key_adder:
44
+ _target_: hydra_structlog.processors.StaticKeyAdder
45
+ service: ${oc.select:hydra.job.env_set.SERVICE,${oc.env:SERVICE,null}}
46
+ version: ${oc.select:hydra.job.env_set.VERSION,${oc.env:VERSION,null}}
47
+ env: ${oc.select:hydra.job.env_set.ENV,${oc.env:ENV,dev}}
48
48
  task: ${hydra.job.name}
49
+ runtime_version: ${python_version:micro}
49
50
  callsite_parameter_adder:
50
51
  _target_: structlog.processors.CallsiteParameterAdder
51
52
  parameters:
@@ -61,16 +62,25 @@ formatters:
61
62
  time_stamper:
62
63
  _target_: structlog.processors.TimeStamper
63
64
  fmt: iso
64
- field_renamer:
65
- _target_: hydra_structlog.processors.FieldRenamer
65
+ key_renamer:
66
+ _target_: hydra_structlog.processors.KeyRenamer
66
67
  level: status
67
68
  event: message
68
69
  format_exc_info:
69
70
  _target_: structlog.processors.format_exc_info
70
71
  _partial_: true
72
+ key_sorter:
73
+ _target_: hydra_structlog.processors.KeySorter
74
+ key_order:
75
+ - timestamp
76
+ - status
77
+ - message
78
+ - logger
79
+ - func_name
80
+ - lineno
81
+ drop_missing: true
71
82
  json_renderer:
72
83
  _target_: structlog.processors.JSONRenderer
73
- sort_keys: true
74
84
  handlers:
75
85
  console:
76
86
  class: hydra_structlog.handlers.TqdmStreamHandler
@@ -0,0 +1,92 @@
1
+ from collections.abc import Callable, MutableMapping, Sequence
2
+ from typing import Any
3
+
4
+ from structlog.typing import EventDict, WrappedLogger
5
+
6
+
7
+ class StaticKeyAdder:
8
+ """Structlog processor to add static keys to all logs."""
9
+
10
+ def __init__(self, **keys: str):
11
+ self.keys = keys
12
+
13
+ def __call__(
14
+ self, logger: WrappedLogger, name: str, event_dict: EventDict
15
+ ) -> EventDict:
16
+ for key, value in self.keys.items():
17
+ if value is not None and value != "":
18
+ event_dict.setdefault(key, value)
19
+ return event_dict
20
+
21
+
22
+ class KeyRenamer:
23
+ """Structlog processor to rename keys. Existing keys of new name are overwritten."""
24
+
25
+ def __init__(self, **mapping: str):
26
+ self.mapping = mapping
27
+
28
+ def __call__(
29
+ self, logger: WrappedLogger, name: str, event_dict: EventDict
30
+ ) -> EventDict:
31
+ for key, replace in self.mapping.items():
32
+ if key in event_dict:
33
+ event_dict[replace] = event_dict.pop(key)
34
+ return event_dict
35
+
36
+
37
+ class KeySorter:
38
+ """Sort keys in events.
39
+
40
+ Args:
41
+ key_order: List of keys that should be rendered in this exact order. Missing
42
+ keys will be added as None.
43
+ drop_missing: When True, extra keys in key_order will be dropped rather than
44
+ added as None.
45
+ """
46
+
47
+ def __init__(
48
+ self, key_order: Sequence[str] | None = None, drop_missing: bool = False
49
+ ):
50
+ self._ordered_items = self._items_sorter(key_order, drop_missing)
51
+
52
+ @staticmethod
53
+ def _items_sorter(
54
+ key_order: Sequence[str] | None, drop_missing: bool
55
+ ) -> Callable[[EventDict], dict[str, object]]:
56
+ """Return a function to sort items from an `event_dict`.
57
+
58
+ Modified from `structlog.processors._items_sorter`.
59
+ """
60
+ # Use an optimized version for each case.
61
+ if key_order:
62
+
63
+ def ordered_items(event_dict: EventDict) -> dict[str, Any]:
64
+ items = []
65
+ for key in key_order:
66
+ value = event_dict.pop(key, None)
67
+ if value is not None or not drop_missing:
68
+ items.append((key, value))
69
+
70
+ items += sorted(event_dict.items())
71
+
72
+ return dict(items)
73
+
74
+ else:
75
+
76
+ def ordered_items(event_dict: EventDict) -> dict[str, Any]:
77
+ return dict(sorted(event_dict.items()))
78
+
79
+ return ordered_items
80
+
81
+ def __call__(
82
+ self, logger: WrappedLogger, name: str, event_dict: EventDict
83
+ ) -> EventDict:
84
+ return self._ordered_items(event_dict)
85
+
86
+
87
+ Processor = Callable[[Any, str, MutableMapping], MutableMapping]
88
+
89
+
90
+ def named_processor_chain(**processors: Processor) -> list[Processor]:
91
+ """Convert a mapping of named processors into list. Skip None"""
92
+ return [p for p in processors.values() if p is not None]
@@ -1 +0,0 @@
1
- __version__ = "0.1.0"
@@ -1,43 +0,0 @@
1
- from collections.abc import Callable, MutableMapping
2
- from typing import Any
3
-
4
- from structlog.typing import EventDict, WrappedLogger
5
-
6
-
7
- class StaticFieldAdder:
8
- """Structlog processor to add static fields to all logs."""
9
-
10
- def __init__(self, **fields: str):
11
- self.fields = fields
12
-
13
- def __call__(
14
- self, logger: WrappedLogger, name: str, event_dict: EventDict
15
- ) -> EventDict:
16
- for field, value in self.fields.items():
17
- event_dict.setdefault(field, value)
18
- return event_dict
19
-
20
-
21
- class FieldRenamer:
22
- """Structlog processor to rename fields. Existing fields of the new name are
23
- overwritten.
24
- """
25
-
26
- def __init__(self, **mapping: str):
27
- self.mapping = mapping
28
-
29
- def __call__(
30
- self, logger: WrappedLogger, name: str, event_dict: EventDict
31
- ) -> EventDict:
32
- for field, replace in self.mapping.items():
33
- if field in event_dict:
34
- event_dict[replace] = event_dict.pop(field)
35
- return event_dict
36
-
37
-
38
- Processor = Callable[[Any, str, MutableMapping], MutableMapping]
39
-
40
-
41
- def named_processor_chain(**processors: Processor) -> list[Processor]:
42
- """Convert a mapping of named processors into list. Skip None"""
43
- return [p for p in processors.values() if p is not None]
File without changes