provide-foundation 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev3__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.
- provide/foundation/__init__.py +36 -10
- provide/foundation/archive/__init__.py +1 -1
- provide/foundation/archive/base.py +15 -14
- provide/foundation/archive/bzip2.py +40 -40
- provide/foundation/archive/gzip.py +42 -42
- provide/foundation/archive/operations.py +93 -96
- provide/foundation/archive/tar.py +33 -31
- provide/foundation/archive/zip.py +52 -50
- provide/foundation/asynctools/__init__.py +20 -0
- provide/foundation/asynctools/core.py +126 -0
- provide/foundation/cli/__init__.py +2 -2
- provide/foundation/cli/commands/deps.py +15 -9
- provide/foundation/cli/commands/logs/__init__.py +3 -3
- provide/foundation/cli/commands/logs/generate.py +2 -2
- provide/foundation/cli/commands/logs/query.py +4 -4
- provide/foundation/cli/commands/logs/send.py +3 -3
- provide/foundation/cli/commands/logs/tail.py +3 -3
- provide/foundation/cli/decorators.py +11 -11
- provide/foundation/cli/main.py +1 -1
- provide/foundation/cli/testing.py +2 -40
- provide/foundation/cli/utils.py +21 -18
- provide/foundation/config/__init__.py +35 -2
- provide/foundation/config/base.py +2 -2
- provide/foundation/config/converters.py +477 -0
- provide/foundation/config/defaults.py +67 -0
- provide/foundation/config/env.py +6 -20
- provide/foundation/config/loader.py +10 -4
- provide/foundation/config/sync.py +8 -6
- provide/foundation/config/types.py +5 -5
- provide/foundation/config/validators.py +4 -4
- provide/foundation/console/input.py +5 -5
- provide/foundation/console/output.py +36 -14
- provide/foundation/context/__init__.py +8 -4
- provide/foundation/context/core.py +88 -110
- provide/foundation/crypto/certificates/__init__.py +9 -5
- provide/foundation/crypto/certificates/base.py +2 -2
- provide/foundation/crypto/certificates/certificate.py +48 -19
- provide/foundation/crypto/certificates/factory.py +26 -18
- provide/foundation/crypto/certificates/generator.py +24 -23
- provide/foundation/crypto/certificates/loader.py +24 -16
- provide/foundation/crypto/certificates/operations.py +17 -10
- provide/foundation/crypto/certificates/trust.py +21 -21
- provide/foundation/env/__init__.py +28 -0
- provide/foundation/env/core.py +218 -0
- provide/foundation/errors/__init__.py +3 -3
- provide/foundation/errors/decorators.py +0 -234
- provide/foundation/errors/types.py +0 -98
- provide/foundation/eventsets/display.py +13 -14
- provide/foundation/eventsets/registry.py +61 -31
- provide/foundation/eventsets/resolver.py +50 -46
- provide/foundation/eventsets/sets/das.py +8 -8
- provide/foundation/eventsets/sets/database.py +14 -14
- provide/foundation/eventsets/sets/http.py +21 -21
- provide/foundation/eventsets/sets/llm.py +16 -16
- provide/foundation/eventsets/sets/task_queue.py +13 -13
- provide/foundation/eventsets/types.py +7 -7
- provide/foundation/file/directory.py +14 -23
- provide/foundation/file/lock.py +4 -3
- provide/foundation/hub/components.py +75 -389
- provide/foundation/hub/config.py +157 -0
- provide/foundation/hub/discovery.py +63 -0
- provide/foundation/hub/handlers.py +89 -0
- provide/foundation/hub/lifecycle.py +195 -0
- provide/foundation/hub/manager.py +7 -4
- provide/foundation/hub/processors.py +49 -0
- provide/foundation/integrations/__init__.py +11 -0
- provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
- provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
- provide/foundation/{observability → integrations}/openobserve/client.py +14 -14
- provide/foundation/{observability → integrations}/openobserve/commands.py +12 -12
- provide/foundation/integrations/openobserve/config.py +37 -0
- provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
- provide/foundation/{observability → integrations}/openobserve/otlp.py +2 -2
- provide/foundation/{observability → integrations}/openobserve/search.py +2 -3
- provide/foundation/{observability → integrations}/openobserve/streaming.py +5 -5
- provide/foundation/logger/__init__.py +0 -1
- provide/foundation/logger/config/base.py +1 -1
- provide/foundation/logger/config/logging.py +69 -299
- provide/foundation/logger/config/telemetry.py +39 -121
- provide/foundation/logger/factories.py +2 -2
- provide/foundation/logger/processors/main.py +12 -10
- provide/foundation/logger/ratelimit/limiters.py +4 -4
- provide/foundation/logger/ratelimit/processor.py +1 -1
- provide/foundation/logger/setup/coordinator.py +39 -25
- provide/foundation/logger/setup/processors.py +3 -3
- provide/foundation/logger/setup/testing.py +14 -0
- provide/foundation/logger/trace.py +5 -5
- provide/foundation/metrics/__init__.py +1 -1
- provide/foundation/metrics/otel.py +3 -1
- provide/foundation/observability/__init__.py +3 -3
- provide/foundation/process/__init__.py +9 -0
- provide/foundation/process/exit.py +48 -0
- provide/foundation/process/lifecycle.py +69 -46
- provide/foundation/resilience/__init__.py +36 -0
- provide/foundation/resilience/circuit.py +166 -0
- provide/foundation/resilience/decorators.py +236 -0
- provide/foundation/resilience/fallback.py +208 -0
- provide/foundation/resilience/retry.py +327 -0
- provide/foundation/serialization/__init__.py +16 -0
- provide/foundation/serialization/core.py +70 -0
- provide/foundation/streams/config.py +78 -0
- provide/foundation/streams/console.py +4 -5
- provide/foundation/streams/core.py +5 -2
- provide/foundation/streams/file.py +12 -2
- provide/foundation/testing/__init__.py +29 -9
- provide/foundation/testing/archive/__init__.py +7 -7
- provide/foundation/testing/archive/fixtures.py +58 -54
- provide/foundation/testing/cli.py +30 -20
- provide/foundation/testing/common/__init__.py +13 -15
- provide/foundation/testing/common/fixtures.py +27 -57
- provide/foundation/testing/file/__init__.py +15 -15
- provide/foundation/testing/file/content_fixtures.py +289 -0
- provide/foundation/testing/file/directory_fixtures.py +107 -0
- provide/foundation/testing/file/fixtures.py +42 -516
- provide/foundation/testing/file/special_fixtures.py +145 -0
- provide/foundation/testing/logger.py +89 -8
- provide/foundation/testing/mocking/__init__.py +21 -21
- provide/foundation/testing/mocking/fixtures.py +80 -67
- provide/foundation/testing/process/__init__.py +23 -23
- provide/foundation/testing/process/async_fixtures.py +414 -0
- provide/foundation/testing/process/fixtures.py +48 -571
- provide/foundation/testing/process/subprocess_fixtures.py +210 -0
- provide/foundation/testing/threading/__init__.py +17 -17
- provide/foundation/testing/threading/basic_fixtures.py +105 -0
- provide/foundation/testing/threading/data_fixtures.py +101 -0
- provide/foundation/testing/threading/execution_fixtures.py +278 -0
- provide/foundation/testing/threading/fixtures.py +32 -502
- provide/foundation/testing/threading/sync_fixtures.py +100 -0
- provide/foundation/testing/time/__init__.py +11 -11
- provide/foundation/testing/time/fixtures.py +95 -83
- provide/foundation/testing/transport/__init__.py +9 -9
- provide/foundation/testing/transport/fixtures.py +54 -54
- provide/foundation/time/__init__.py +18 -0
- provide/foundation/time/core.py +63 -0
- provide/foundation/tools/__init__.py +2 -2
- provide/foundation/tools/base.py +68 -67
- provide/foundation/tools/cache.py +69 -74
- provide/foundation/tools/downloader.py +68 -62
- provide/foundation/tools/installer.py +51 -57
- provide/foundation/tools/registry.py +38 -45
- provide/foundation/tools/resolver.py +70 -68
- provide/foundation/tools/verifier.py +39 -50
- provide/foundation/tracer/spans.py +2 -14
- provide/foundation/transport/__init__.py +26 -33
- provide/foundation/transport/base.py +32 -30
- provide/foundation/transport/client.py +44 -49
- provide/foundation/transport/config.py +36 -107
- provide/foundation/transport/errors.py +13 -27
- provide/foundation/transport/http.py +69 -55
- provide/foundation/transport/middleware.py +113 -114
- provide/foundation/transport/registry.py +29 -27
- provide/foundation/transport/types.py +6 -6
- provide/foundation/utils/deps.py +17 -14
- provide/foundation/utils/parsing.py +49 -4
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/METADATA +2 -2
- provide_foundation-0.0.0.dev3.dist-info/RECORD +233 -0
- provide_foundation-0.0.0.dev1.dist-info/RECORD +0 -200
- /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
- /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/WHEEL +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/entry_points.txt +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/top_level.txt +0 -0
@@ -3,14 +3,15 @@ Event set registry and discovery.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import importlib
|
6
|
-
import pkgutil
|
7
6
|
from pathlib import Path
|
7
|
+
import pkgutil
|
8
8
|
|
9
9
|
from provide.foundation.errors.resources import AlreadyExistsError, NotFoundError
|
10
|
-
from provide.foundation.hub.registry import Registry
|
11
|
-
from provide.foundation.logger.setup.coordinator import create_foundation_internal_logger
|
12
|
-
|
13
10
|
from provide.foundation.eventsets.types import EventSet
|
11
|
+
from provide.foundation.hub.registry import Registry
|
12
|
+
from provide.foundation.logger.setup.coordinator import (
|
13
|
+
create_foundation_internal_logger,
|
14
|
+
)
|
14
15
|
|
15
16
|
# Bootstrap logger that doesn't trigger full logger setup
|
16
17
|
logger = create_foundation_internal_logger()
|
@@ -19,44 +20,49 @@ logger = create_foundation_internal_logger()
|
|
19
20
|
class EventSetRegistry(Registry):
|
20
21
|
"""
|
21
22
|
Registry for event set definitions using foundation Registry.
|
22
|
-
|
23
|
+
|
23
24
|
Extends the foundation Registry to provide specialized
|
24
25
|
methods for event set registration and discovery.
|
25
26
|
"""
|
26
|
-
|
27
|
+
|
27
28
|
def register_event_set(self, event_set: EventSet) -> None:
|
28
29
|
"""
|
29
30
|
Register an event set definition.
|
30
|
-
|
31
|
+
|
31
32
|
Args:
|
32
33
|
event_set: The EventSet to register
|
33
|
-
|
34
|
+
|
34
35
|
Raises:
|
35
36
|
AlreadyExistsError: If an event set with this name already exists
|
36
37
|
"""
|
37
38
|
try:
|
38
|
-
self.register(
|
39
|
+
self.register(
|
40
|
+
event_set.name,
|
41
|
+
event_set,
|
42
|
+
"eventset",
|
43
|
+
metadata={"priority": event_set.priority},
|
44
|
+
)
|
39
45
|
logger.debug(
|
40
46
|
"Registered event set",
|
41
47
|
name=event_set.name,
|
42
48
|
priority=event_set.priority,
|
43
49
|
field_count=len(event_set.field_mappings),
|
44
|
-
mapping_count=len(event_set.mappings)
|
50
|
+
mapping_count=len(event_set.mappings),
|
45
51
|
)
|
46
52
|
except AlreadyExistsError:
|
47
|
-
logger.
|
53
|
+
logger.trace("Event set already registered", name=event_set.name)
|
48
54
|
raise
|
49
|
-
|
55
|
+
|
50
56
|
def get_event_set(self, name: str) -> EventSet:
|
51
57
|
"""
|
52
58
|
Retrieve an event set by name.
|
53
|
-
|
59
|
+
|
54
60
|
Args:
|
55
61
|
name: The name of the event set
|
56
|
-
|
62
|
+
|
57
63
|
Returns:
|
58
64
|
The EventSet
|
59
|
-
|
65
|
+
|
60
66
|
Raises:
|
61
67
|
NotFoundError: If no event set with this name exists
|
62
68
|
"""
|
@@ -64,11 +70,11 @@ class EventSetRegistry(Registry):
|
|
64
70
|
if event_set is None:
|
65
71
|
raise NotFoundError(f"Event set '{name}' not found")
|
66
72
|
return event_set
|
67
|
-
|
73
|
+
|
68
74
|
def list_event_sets(self) -> list[EventSet]:
|
69
75
|
"""
|
70
76
|
List all registered event sets sorted by priority.
|
71
|
-
|
77
|
+
|
72
78
|
Returns:
|
73
79
|
List of EventSet objects sorted by descending priority
|
74
80
|
"""
|
@@ -77,11 +83,11 @@ class EventSetRegistry(Registry):
|
|
77
83
|
entries = [entry for entry in entries if entry is not None]
|
78
84
|
entries.sort(key=lambda e: e.metadata.get("priority", 0), reverse=True)
|
79
85
|
return [entry.value for entry in entries]
|
80
|
-
|
86
|
+
|
81
87
|
def discover_sets(self) -> None:
|
82
88
|
"""
|
83
89
|
Auto-discover and register event sets from the sets/ directory.
|
84
|
-
|
90
|
+
|
85
91
|
Imports all modules in the sets/ subdirectory and registers
|
86
92
|
any EVENT_SET constants found.
|
87
93
|
"""
|
@@ -89,15 +95,15 @@ class EventSetRegistry(Registry):
|
|
89
95
|
if not sets_path.exists():
|
90
96
|
logger.debug("No sets directory found for auto-discovery")
|
91
97
|
return
|
92
|
-
|
98
|
+
|
93
99
|
for module_info in pkgutil.iter_modules([str(sets_path)]):
|
94
100
|
if module_info.ispkg:
|
95
101
|
continue
|
96
|
-
|
102
|
+
|
97
103
|
module_name = f"provide.foundation.eventsets.sets.{module_info.name}"
|
98
104
|
try:
|
99
105
|
module = importlib.import_module(module_name)
|
100
|
-
|
106
|
+
|
101
107
|
if hasattr(module, "EVENT_SET"):
|
102
108
|
event_set = getattr(module, "EVENT_SET")
|
103
109
|
if isinstance(event_set, EventSet):
|
@@ -106,38 +112,39 @@ class EventSetRegistry(Registry):
|
|
106
112
|
logger.debug(
|
107
113
|
"Auto-discovered event set",
|
108
114
|
module=module_name,
|
109
|
-
name=event_set.name
|
115
|
+
name=event_set.name,
|
110
116
|
)
|
111
117
|
except AlreadyExistsError:
|
112
|
-
logger.
|
118
|
+
logger.trace(
|
113
119
|
"Event set already registered during discovery",
|
114
120
|
module=module_name,
|
115
|
-
name=event_set.name
|
121
|
+
name=event_set.name,
|
116
122
|
)
|
117
123
|
else:
|
118
124
|
logger.warning(
|
119
125
|
"EVENT_SET is not an EventSet",
|
120
126
|
module=module_name,
|
121
|
-
type=type(event_set).__name__
|
127
|
+
type=type(event_set).__name__,
|
122
128
|
)
|
123
|
-
|
129
|
+
|
124
130
|
except ImportError as e:
|
125
131
|
logger.debug(
|
126
132
|
"Failed to import event set module",
|
127
133
|
module=module_name,
|
128
|
-
error=str(e)
|
134
|
+
error=str(e),
|
129
135
|
)
|
130
136
|
except Exception as e:
|
131
137
|
logger.warning(
|
132
138
|
"Error during event set discovery",
|
133
139
|
module=module_name,
|
134
140
|
error=str(e),
|
135
|
-
error_type=type(e).__name__
|
141
|
+
error_type=type(e).__name__,
|
136
142
|
)
|
137
143
|
|
138
144
|
|
139
145
|
# Global registry instance
|
140
146
|
_registry = EventSetRegistry()
|
147
|
+
_discovery_completed = False
|
141
148
|
|
142
149
|
|
143
150
|
def get_registry() -> EventSetRegistry:
|
@@ -148,7 +155,7 @@ def get_registry() -> EventSetRegistry:
|
|
148
155
|
def register_event_set(event_set: EventSet) -> None:
|
149
156
|
"""
|
150
157
|
Register an event set in the global registry.
|
151
|
-
|
158
|
+
|
152
159
|
Args:
|
153
160
|
event_set: The EventSet to register
|
154
161
|
"""
|
@@ -157,4 +164,27 @@ def register_event_set(event_set: EventSet) -> None:
|
|
157
164
|
|
158
165
|
def discover_event_sets() -> None:
|
159
166
|
"""Auto-discover and register all event sets."""
|
160
|
-
|
167
|
+
global _discovery_completed
|
168
|
+
if _discovery_completed:
|
169
|
+
logger.trace("Event set discovery already completed, skipping")
|
170
|
+
return
|
171
|
+
|
172
|
+
logger.debug("Starting event set discovery")
|
173
|
+
_registry.discover_sets()
|
174
|
+
_discovery_completed = True
|
175
|
+
logger.debug("Event set discovery completed")
|
176
|
+
|
177
|
+
|
178
|
+
def reset_discovery_state() -> None:
|
179
|
+
"""Reset discovery state for testing."""
|
180
|
+
global _discovery_completed
|
181
|
+
_discovery_completed = False
|
182
|
+
logger.trace("Event set discovery state reset")
|
183
|
+
|
184
|
+
|
185
|
+
def clear_registry() -> None:
|
186
|
+
"""Clear the registry for testing."""
|
187
|
+
global _registry, _discovery_completed
|
188
|
+
_registry = EventSetRegistry()
|
189
|
+
_discovery_completed = False
|
190
|
+
logger.trace("Event set registry cleared")
|
@@ -5,168 +5,172 @@ Event set resolution and enrichment logic.
|
|
5
5
|
from typing import Any
|
6
6
|
|
7
7
|
from provide.foundation.eventsets.registry import get_registry
|
8
|
-
from provide.foundation.eventsets.types import EventMapping,
|
8
|
+
from provide.foundation.eventsets.types import EventMapping, FieldMapping
|
9
9
|
|
10
10
|
|
11
11
|
class EventSetResolver:
|
12
12
|
"""
|
13
13
|
Resolves and applies event set enrichments to log events.
|
14
14
|
"""
|
15
|
-
|
15
|
+
|
16
16
|
def __init__(self) -> None:
|
17
17
|
"""Initialize the resolver with cached configurations."""
|
18
18
|
self._field_mappings: list[FieldMapping] = []
|
19
19
|
self._event_mappings_by_set: dict[str, list[EventMapping]] = {}
|
20
20
|
self._resolved = False
|
21
|
-
|
21
|
+
|
22
22
|
def resolve(self) -> None:
|
23
23
|
"""
|
24
24
|
Resolve all registered event sets into a unified configuration.
|
25
|
-
|
25
|
+
|
26
26
|
This merges all registered event sets by priority, building
|
27
27
|
the field mapping and event mapping lookup tables.
|
28
28
|
"""
|
29
29
|
registry = get_registry()
|
30
30
|
event_sets = registry.list_event_sets() # Already sorted by priority
|
31
|
-
|
31
|
+
|
32
32
|
# Clear existing state
|
33
33
|
self._field_mappings.clear()
|
34
34
|
self._event_mappings_by_set.clear()
|
35
|
-
|
35
|
+
|
36
36
|
# Process each event set in priority order
|
37
37
|
for event_set in event_sets:
|
38
38
|
# Store event mappings by event set name
|
39
39
|
self._event_mappings_by_set[event_set.name] = event_set.mappings
|
40
|
-
|
40
|
+
|
41
41
|
# Add field mappings
|
42
42
|
self._field_mappings.extend(event_set.field_mappings)
|
43
|
-
|
43
|
+
|
44
44
|
self._resolved = True
|
45
|
-
|
45
|
+
|
46
46
|
def enrich_event(self, event_dict: dict[str, Any]) -> dict[str, Any]:
|
47
47
|
"""
|
48
48
|
Enrich a log event with event set data.
|
49
|
-
|
49
|
+
|
50
50
|
Args:
|
51
51
|
event_dict: The event dictionary to enrich
|
52
|
-
|
52
|
+
|
53
53
|
Returns:
|
54
54
|
The enriched event dictionary
|
55
55
|
"""
|
56
56
|
if not self._resolved:
|
57
57
|
self.resolve()
|
58
|
-
|
58
|
+
|
59
59
|
enrichments = []
|
60
|
-
|
60
|
+
|
61
61
|
# Process each field in the event
|
62
62
|
for field_key, field_value in list(event_dict.items()):
|
63
63
|
if field_key == "event" or field_value is None:
|
64
64
|
continue
|
65
|
-
|
65
|
+
|
66
66
|
# Find appropriate event mapping for this field
|
67
67
|
event_mapping = self._find_event_mapping_for_field(field_key, field_value)
|
68
68
|
if not event_mapping:
|
69
69
|
continue
|
70
|
-
|
70
|
+
|
71
71
|
value_str = str(field_value).lower()
|
72
|
-
|
72
|
+
|
73
73
|
# Apply transformations
|
74
74
|
if value_str in event_mapping.transformations:
|
75
75
|
field_value = event_mapping.transformations[value_str](field_value)
|
76
76
|
value_str = str(field_value).lower()
|
77
|
-
|
77
|
+
|
78
78
|
# Get visual marker
|
79
79
|
visual_marker = event_mapping.visual_markers.get(
|
80
80
|
value_str,
|
81
|
-
event_mapping.visual_markers.get(event_mapping.default_key, "")
|
81
|
+
event_mapping.visual_markers.get(event_mapping.default_key, ""),
|
82
82
|
)
|
83
|
-
|
83
|
+
|
84
84
|
if visual_marker:
|
85
85
|
enrichments.append(visual_marker)
|
86
|
-
|
86
|
+
|
87
87
|
# Apply metadata fields
|
88
88
|
if value_str in event_mapping.metadata_fields:
|
89
|
-
for meta_key, meta_value in event_mapping.metadata_fields[
|
89
|
+
for meta_key, meta_value in event_mapping.metadata_fields[
|
90
|
+
value_str
|
91
|
+
].items():
|
90
92
|
if meta_key not in event_dict:
|
91
93
|
event_dict[meta_key] = meta_value
|
92
|
-
|
94
|
+
|
93
95
|
# Add visual enrichments to event message
|
94
96
|
if enrichments:
|
95
97
|
prefix = "".join(f"[{e}]" for e in enrichments)
|
96
98
|
event_msg = event_dict.get("event", "")
|
97
99
|
event_dict["event"] = f"{prefix} {event_msg}" if event_msg else prefix
|
98
|
-
|
100
|
+
|
99
101
|
return event_dict
|
100
|
-
|
101
|
-
def _find_event_mapping_for_field(
|
102
|
+
|
103
|
+
def _find_event_mapping_for_field(
|
104
|
+
self, field_key: str, field_value: Any
|
105
|
+
) -> EventMapping | None:
|
102
106
|
"""
|
103
107
|
Find the appropriate EventMapping for a given field.
|
104
|
-
|
108
|
+
|
105
109
|
This method uses a heuristic approach to match field keys to EventMappings:
|
106
110
|
1. Direct field name mapping (e.g., "domain" -> "domain" mapping)
|
107
111
|
2. Field prefix mapping (e.g., "http.method" -> "http_method" mapping)
|
108
112
|
3. Field pattern matching
|
109
113
|
"""
|
110
114
|
# First check for direct field name matches
|
111
|
-
simple_key = field_key.split(
|
112
|
-
|
115
|
+
simple_key = field_key.split(".")[-1] # Get last part of dotted key
|
116
|
+
|
113
117
|
for event_set_name, mappings in self._event_mappings_by_set.items():
|
114
118
|
for mapping in mappings:
|
115
119
|
# Direct name match
|
116
120
|
if mapping.name == simple_key or mapping.name == field_key:
|
117
121
|
return mapping
|
118
|
-
|
122
|
+
|
119
123
|
# Pattern matching for common cases
|
120
124
|
if field_key.startswith("http.") and mapping.name.startswith("http_"):
|
121
125
|
if field_key.replace(".", "_") == mapping.name:
|
122
126
|
return mapping
|
123
|
-
|
127
|
+
|
124
128
|
if field_key.startswith("llm.") and mapping.name.startswith("llm_"):
|
125
129
|
if field_key.replace(".", "_") == mapping.name:
|
126
130
|
return mapping
|
127
|
-
|
131
|
+
|
128
132
|
if field_key.startswith("db.") and mapping.name.startswith("db_"):
|
129
133
|
if field_key.replace(".", "_") == mapping.name:
|
130
134
|
return mapping
|
131
|
-
|
135
|
+
|
132
136
|
if field_key.startswith("task.") and mapping.name.startswith("task_"):
|
133
137
|
if field_key.replace(".", "_") == mapping.name:
|
134
138
|
return mapping
|
135
|
-
|
139
|
+
|
136
140
|
return None
|
137
|
-
|
141
|
+
|
138
142
|
def get_visual_markers(self, event_dict: dict[str, Any]) -> list[str]:
|
139
143
|
"""
|
140
144
|
Extract visual markers for an event without modifying it.
|
141
|
-
|
145
|
+
|
142
146
|
Args:
|
143
147
|
event_dict: The event dictionary to analyze
|
144
|
-
|
148
|
+
|
145
149
|
Returns:
|
146
150
|
List of visual markers that would be applied
|
147
151
|
"""
|
148
152
|
if not self._resolved:
|
149
153
|
self.resolve()
|
150
|
-
|
154
|
+
|
151
155
|
markers = []
|
152
|
-
|
156
|
+
|
153
157
|
for field_key, field_value in event_dict.items():
|
154
158
|
if field_key == "event" or field_value is None:
|
155
159
|
continue
|
156
|
-
|
160
|
+
|
157
161
|
event_mapping = self._find_event_mapping_for_field(field_key, field_value)
|
158
162
|
if not event_mapping:
|
159
163
|
continue
|
160
|
-
|
164
|
+
|
161
165
|
value_str = str(field_value).lower()
|
162
166
|
marker = event_mapping.visual_markers.get(
|
163
167
|
value_str,
|
164
|
-
event_mapping.visual_markers.get(event_mapping.default_key, "")
|
168
|
+
event_mapping.visual_markers.get(event_mapping.default_key, ""),
|
165
169
|
)
|
166
|
-
|
170
|
+
|
167
171
|
if marker:
|
168
172
|
markers.append(marker)
|
169
|
-
|
173
|
+
|
170
174
|
return markers
|
171
175
|
|
172
176
|
|
@@ -182,11 +186,11 @@ def get_resolver() -> EventSetResolver:
|
|
182
186
|
def enrich_event(event_dict: dict[str, Any]) -> dict[str, Any]:
|
183
187
|
"""
|
184
188
|
Enrich a log event with event set data.
|
185
|
-
|
189
|
+
|
186
190
|
Args:
|
187
191
|
event_dict: The event dictionary to enrich
|
188
|
-
|
192
|
+
|
189
193
|
Returns:
|
190
194
|
The enriched event dictionary
|
191
195
|
"""
|
192
|
-
return _resolver.enrich_event(event_dict)
|
196
|
+
return _resolver.enrich_event(event_dict)
|
@@ -35,7 +35,7 @@ EVENT_SET = EventSet(
|
|
35
35
|
"payment": "💳",
|
36
36
|
"default": "❓",
|
37
37
|
},
|
38
|
-
default_key="default"
|
38
|
+
default_key="default",
|
39
39
|
),
|
40
40
|
EventMapping(
|
41
41
|
name="action",
|
@@ -74,7 +74,7 @@ EVENT_SET = EventSet(
|
|
74
74
|
"register": "⚙️",
|
75
75
|
"default": "❓",
|
76
76
|
},
|
77
|
-
default_key="default"
|
77
|
+
default_key="default",
|
78
78
|
),
|
79
79
|
EventMapping(
|
80
80
|
name="status",
|
@@ -100,29 +100,29 @@ EVENT_SET = EventSet(
|
|
100
100
|
"ready": "👍",
|
101
101
|
"default": "➡️",
|
102
102
|
},
|
103
|
-
default_key="default"
|
103
|
+
default_key="default",
|
104
104
|
),
|
105
105
|
],
|
106
106
|
field_mappings=[
|
107
107
|
FieldMapping(
|
108
108
|
log_key="domain",
|
109
109
|
event_set_name="default",
|
110
|
-
description="System domain or component"
|
110
|
+
description="System domain or component",
|
111
111
|
),
|
112
112
|
FieldMapping(
|
113
113
|
log_key="action",
|
114
114
|
event_set_name="default",
|
115
|
-
description="Action being performed"
|
115
|
+
description="Action being performed",
|
116
116
|
),
|
117
117
|
FieldMapping(
|
118
118
|
log_key="status",
|
119
119
|
event_set_name="default",
|
120
|
-
description="Status or outcome of the action"
|
120
|
+
description="Status or outcome of the action",
|
121
121
|
),
|
122
122
|
],
|
123
|
-
priority=0
|
123
|
+
priority=0,
|
124
124
|
)
|
125
125
|
|
126
126
|
# Alias for backward compatibility
|
127
127
|
das_event_set = EVENT_SET
|
128
|
-
default_event_set = EVENT_SET
|
128
|
+
default_event_set = EVENT_SET
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Database operations event set for Foundation.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from provide.foundation.eventsets.types import
|
5
|
+
from provide.foundation.eventsets.types import EventMapping, EventSet, FieldMapping
|
6
6
|
|
7
7
|
EVENT_SET = EventSet(
|
8
8
|
name="database",
|
@@ -27,7 +27,7 @@ EVENT_SET = EventSet(
|
|
27
27
|
"redis": {"db.type": "cache", "db.vendor": "redis"},
|
28
28
|
"elasticsearch": {"db.type": "search", "db.vendor": "elastic"},
|
29
29
|
},
|
30
|
-
default_key="default"
|
30
|
+
default_key="default",
|
31
31
|
),
|
32
32
|
EventMapping(
|
33
33
|
name="db_operation",
|
@@ -51,7 +51,7 @@ EVENT_SET = EventSet(
|
|
51
51
|
"update": {"db.write": True},
|
52
52
|
"delete": {"db.write": True},
|
53
53
|
},
|
54
|
-
default_key="default"
|
54
|
+
default_key="default",
|
55
55
|
),
|
56
56
|
EventMapping(
|
57
57
|
name="db_outcome",
|
@@ -67,7 +67,7 @@ EVENT_SET = EventSet(
|
|
67
67
|
"error": {"db.error": True},
|
68
68
|
"timeout": {"db.timeout": True},
|
69
69
|
},
|
70
|
-
default_key="default"
|
70
|
+
default_key="default",
|
71
71
|
),
|
72
72
|
],
|
73
73
|
field_mappings=[
|
@@ -75,51 +75,51 @@ EVENT_SET = EventSet(
|
|
75
75
|
log_key="db.system",
|
76
76
|
event_set_name="database",
|
77
77
|
description="Database system type",
|
78
|
-
value_type="string"
|
78
|
+
value_type="string",
|
79
79
|
),
|
80
80
|
FieldMapping(
|
81
81
|
log_key="db.operation",
|
82
82
|
event_set_name="database",
|
83
83
|
description="Database operation performed",
|
84
|
-
value_type="string"
|
84
|
+
value_type="string",
|
85
85
|
),
|
86
86
|
FieldMapping(
|
87
87
|
log_key="db.outcome",
|
88
88
|
event_set_name="database",
|
89
89
|
description="Operation outcome",
|
90
|
-
value_type="string"
|
90
|
+
value_type="string",
|
91
91
|
),
|
92
92
|
FieldMapping(
|
93
93
|
log_key="db.statement",
|
94
94
|
event_set_name="database",
|
95
95
|
description="SQL or query statement",
|
96
|
-
value_type="string"
|
96
|
+
value_type="string",
|
97
97
|
),
|
98
98
|
FieldMapping(
|
99
99
|
log_key="db.table",
|
100
100
|
event_set_name="database",
|
101
101
|
description="Table name",
|
102
102
|
value_type="string",
|
103
|
-
default_override_key="default"
|
103
|
+
default_override_key="default",
|
104
104
|
),
|
105
105
|
FieldMapping(
|
106
106
|
log_key="db.rows_affected",
|
107
107
|
event_set_name="database",
|
108
108
|
description="Number of rows affected",
|
109
|
-
value_type="integer"
|
109
|
+
value_type="integer",
|
110
110
|
),
|
111
111
|
FieldMapping(
|
112
112
|
log_key="duration_ms",
|
113
113
|
event_set_name="database",
|
114
114
|
description="Query duration in milliseconds",
|
115
|
-
value_type="integer"
|
115
|
+
value_type="integer",
|
116
116
|
),
|
117
117
|
FieldMapping(
|
118
118
|
log_key="trace_id",
|
119
119
|
event_set_name="database",
|
120
120
|
description="Distributed trace ID",
|
121
|
-
value_type="string"
|
121
|
+
value_type="string",
|
122
122
|
),
|
123
123
|
],
|
124
|
-
priority=90
|
125
|
-
)
|
124
|
+
priority=90,
|
125
|
+
)
|