apache-airflow-providers-elasticsearch 6.3.1__py3-none-any.whl → 6.3.2__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.
Potentially problematic release.
This version of apache-airflow-providers-elasticsearch might be problematic. Click here for more details.
- airflow/providers/elasticsearch/__init__.py +1 -1
- airflow/providers/elasticsearch/hooks/elasticsearch.py +1 -5
- airflow/providers/elasticsearch/log/es_task_handler.py +25 -14
- airflow/providers/elasticsearch/version_compat.py +9 -1
- {apache_airflow_providers_elasticsearch-6.3.1.dist-info → apache_airflow_providers_elasticsearch-6.3.2.dist-info}/METADATA +10 -8
- {apache_airflow_providers_elasticsearch-6.3.1.dist-info → apache_airflow_providers_elasticsearch-6.3.2.dist-info}/RECORD +8 -8
- {apache_airflow_providers_elasticsearch-6.3.1.dist-info → apache_airflow_providers_elasticsearch-6.3.2.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_elasticsearch-6.3.1.dist-info → apache_airflow_providers_elasticsearch-6.3.2.dist-info}/entry_points.txt +0 -0
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
|
29
29
|
|
|
30
30
|
__all__ = ["__version__"]
|
|
31
31
|
|
|
32
|
-
__version__ = "6.3.
|
|
32
|
+
__version__ = "6.3.2"
|
|
33
33
|
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
|
35
35
|
"2.10.0"
|
|
@@ -26,11 +26,7 @@ from urllib import parse
|
|
|
26
26
|
from elasticsearch import Elasticsearch
|
|
27
27
|
|
|
28
28
|
from airflow.providers.common.sql.hooks.sql import DbApiHook
|
|
29
|
-
|
|
30
|
-
try:
|
|
31
|
-
from airflow.sdk import BaseHook
|
|
32
|
-
except ImportError:
|
|
33
|
-
from airflow.hooks.base import BaseHook # type: ignore[attr-defined,no-redef]
|
|
29
|
+
from airflow.providers.elasticsearch.version_compat import BaseHook
|
|
34
30
|
|
|
35
31
|
if TYPE_CHECKING:
|
|
36
32
|
from elastic_transport import ObjectApiResponse
|
|
@@ -29,7 +29,7 @@ import time
|
|
|
29
29
|
from collections import defaultdict
|
|
30
30
|
from collections.abc import Callable
|
|
31
31
|
from operator import attrgetter
|
|
32
|
-
from typing import TYPE_CHECKING, Any, Literal
|
|
32
|
+
from typing import TYPE_CHECKING, Any, Literal, cast
|
|
33
33
|
from urllib.parse import quote, urlparse
|
|
34
34
|
|
|
35
35
|
# Using `from elasticsearch import *` would break elasticsearch mocking used in unit test.
|
|
@@ -56,6 +56,7 @@ if TYPE_CHECKING:
|
|
|
56
56
|
from datetime import datetime
|
|
57
57
|
|
|
58
58
|
from airflow.models.taskinstance import TaskInstance, TaskInstanceKey
|
|
59
|
+
from airflow.utils.log.file_task_handler import LogMetadata
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
LOG_LINE_DEFAULTS = {"exc_text": "", "stack_info": ""}
|
|
@@ -66,6 +67,7 @@ LOG_LINE_DEFAULTS = {"exc_text": "", "stack_info": ""}
|
|
|
66
67
|
# not exist, the task handler should use the log_id_template attribute instead.
|
|
67
68
|
USE_PER_RUN_LOG_ID = hasattr(DagRun, "get_log_template")
|
|
68
69
|
|
|
70
|
+
TASK_LOG_FIELDS = ["timestamp", "event", "level", "chan", "logger"]
|
|
69
71
|
|
|
70
72
|
VALID_ES_CONFIG_KEYS = set(inspect.signature(elasticsearch.Elasticsearch.__init__).parameters.keys())
|
|
71
73
|
# Remove `self` from the valid set of kwargs
|
|
@@ -159,11 +161,11 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
159
161
|
es_kwargs = es_kwargs or {}
|
|
160
162
|
if es_kwargs == "default_es_kwargs":
|
|
161
163
|
es_kwargs = get_es_kwargs_from_config()
|
|
162
|
-
host = self.format_url(host)
|
|
164
|
+
self.host = self.format_url(host)
|
|
163
165
|
super().__init__(base_log_folder)
|
|
164
166
|
self.closed = False
|
|
165
167
|
|
|
166
|
-
self.client = elasticsearch.Elasticsearch(host, **es_kwargs)
|
|
168
|
+
self.client = elasticsearch.Elasticsearch(self.host, **es_kwargs)
|
|
167
169
|
# in airflow.cfg, host of elasticsearch has to be http://dockerhostXxxx:9200
|
|
168
170
|
|
|
169
171
|
self.frontend = frontend
|
|
@@ -184,7 +186,7 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
184
186
|
)
|
|
185
187
|
|
|
186
188
|
self.formatter: logging.Formatter
|
|
187
|
-
self.handler: logging.FileHandler | logging.StreamHandler
|
|
189
|
+
self.handler: logging.FileHandler | logging.StreamHandler | None = None
|
|
188
190
|
self._doc_type_map: dict[Any, Any] = {}
|
|
189
191
|
self._doc_type: list[Any] = []
|
|
190
192
|
|
|
@@ -286,7 +288,7 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
286
288
|
def _group_logs_by_host(self, response: ElasticSearchResponse) -> dict[str, list[Hit]]:
|
|
287
289
|
grouped_logs = defaultdict(list)
|
|
288
290
|
for hit in response:
|
|
289
|
-
key = getattr_nested(hit, self.host_field, None) or
|
|
291
|
+
key = getattr_nested(hit, self.host_field, None) or self.host
|
|
290
292
|
grouped_logs[key].append(hit)
|
|
291
293
|
return grouped_logs
|
|
292
294
|
|
|
@@ -294,8 +296,8 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
294
296
|
return True
|
|
295
297
|
|
|
296
298
|
def _read(
|
|
297
|
-
self, ti: TaskInstance, try_number: int, metadata:
|
|
298
|
-
) -> tuple[EsLogMsgType,
|
|
299
|
+
self, ti: TaskInstance, try_number: int, metadata: LogMetadata | None = None
|
|
300
|
+
) -> tuple[EsLogMsgType, LogMetadata]:
|
|
299
301
|
"""
|
|
300
302
|
Endpoint for streaming log.
|
|
301
303
|
|
|
@@ -306,7 +308,9 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
306
308
|
:return: a list of tuple with host and log documents, metadata.
|
|
307
309
|
"""
|
|
308
310
|
if not metadata:
|
|
309
|
-
|
|
311
|
+
# LogMetadata(TypedDict) is used as type annotation for log_reader; added ignore to suppress mypy error
|
|
312
|
+
metadata = {"offset": 0} # type: ignore[assignment]
|
|
313
|
+
metadata = cast("LogMetadata", metadata)
|
|
310
314
|
if "offset" not in metadata:
|
|
311
315
|
metadata["offset"] = 0
|
|
312
316
|
|
|
@@ -346,7 +350,9 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
346
350
|
"Otherwise, the logs for this task instance may have been removed."
|
|
347
351
|
)
|
|
348
352
|
if AIRFLOW_V_3_0_PLUS:
|
|
349
|
-
|
|
353
|
+
from airflow.utils.log.file_task_handler import StructuredLogMessage
|
|
354
|
+
|
|
355
|
+
return [StructuredLogMessage(event=missing_log_message)], metadata
|
|
350
356
|
return [("", missing_log_message)], metadata # type: ignore[list-item]
|
|
351
357
|
if (
|
|
352
358
|
# Assume end of log after not receiving new log for N min,
|
|
@@ -375,11 +381,16 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
375
381
|
sources=[host for host in logs_by_host.keys()],
|
|
376
382
|
), # type: ignore[call-arg]
|
|
377
383
|
StructuredLogMessage(event="::endgroup::"),
|
|
378
|
-
]
|
|
384
|
+
]
|
|
379
385
|
|
|
386
|
+
# Flatten all hits, filter to only desired fields, and construct StructuredLogMessage objects
|
|
380
387
|
message = header + [
|
|
381
|
-
StructuredLogMessage(
|
|
382
|
-
|
|
388
|
+
StructuredLogMessage(
|
|
389
|
+
**{k: v for k, v in hit.to_dict().items() if k.lower() in TASK_LOG_FIELDS}
|
|
390
|
+
)
|
|
391
|
+
for hits in logs_by_host.values()
|
|
392
|
+
for hit in hits
|
|
393
|
+
]
|
|
383
394
|
else:
|
|
384
395
|
message = [
|
|
385
396
|
(host, concat_logs(hits)) # type: ignore[misc]
|
|
@@ -421,7 +432,7 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
421
432
|
|
|
422
433
|
index_patterns = self._get_index_patterns(ti)
|
|
423
434
|
try:
|
|
424
|
-
max_log_line = self.client.count(index=index_patterns, query=query)["count"]
|
|
435
|
+
max_log_line = self.client.count(index=index_patterns, query=query)["count"]
|
|
425
436
|
except NotFoundError as e:
|
|
426
437
|
self.log.exception("The target index pattern %s does not exist", index_patterns)
|
|
427
438
|
raise e
|
|
@@ -508,7 +519,7 @@ class ElasticsearchTaskHandler(FileTaskHandler, ExternalLoggingMixin, LoggingMix
|
|
|
508
519
|
|
|
509
520
|
# Reopen the file stream, because FileHandler.close() would be called
|
|
510
521
|
# first in logging.shutdown() and the stream in it would be set to None.
|
|
511
|
-
if self.handler.stream is None or self.handler.stream.closed:
|
|
522
|
+
if self.handler.stream is None or self.handler.stream.closed:
|
|
512
523
|
self.handler.stream = self.handler._open() # type: ignore[union-attr]
|
|
513
524
|
|
|
514
525
|
# Mark the end of file using end of log mark,
|
|
@@ -33,10 +33,18 @@ def get_base_airflow_version_tuple() -> tuple[int, int, int]:
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
AIRFLOW_V_3_0_PLUS = get_base_airflow_version_tuple() >= (3, 0, 0)
|
|
36
|
+
AIRFLOW_V_3_1_PLUS: bool = get_base_airflow_version_tuple() >= (3, 1, 0)
|
|
37
|
+
|
|
38
|
+
if AIRFLOW_V_3_1_PLUS:
|
|
39
|
+
from airflow.sdk import BaseHook
|
|
40
|
+
else:
|
|
41
|
+
from airflow.hooks.base import BaseHook # type: ignore[attr-defined,no-redef]
|
|
36
42
|
|
|
37
43
|
if AIRFLOW_V_3_0_PLUS:
|
|
38
44
|
from airflow.utils.log.file_task_handler import StructuredLogMessage
|
|
39
45
|
|
|
40
46
|
EsLogMsgType = list[StructuredLogMessage] | str
|
|
41
47
|
else:
|
|
42
|
-
EsLogMsgType = list[tuple[str, str]] # type: ignore[misc]
|
|
48
|
+
EsLogMsgType = list[tuple[str, str]] # type: ignore[assignment,misc]
|
|
49
|
+
|
|
50
|
+
__all__ = ["AIRFLOW_V_3_0_PLUS", "AIRFLOW_V_3_1_PLUS", "BaseHook", "EsLogMsgType"]
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apache-airflow-providers-elasticsearch
|
|
3
|
-
Version: 6.3.
|
|
3
|
+
Version: 6.3.2
|
|
4
4
|
Summary: Provider package apache-airflow-providers-elasticsearch for Apache Airflow
|
|
5
5
|
Keywords: airflow-provider,elasticsearch,airflow,integration
|
|
6
6
|
Author-email: Apache Software Foundation <dev@airflow.apache.org>
|
|
7
7
|
Maintainer-email: Apache Software Foundation <dev@airflow.apache.org>
|
|
8
|
-
Requires-Python:
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/x-rst
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Environment :: Console
|
|
@@ -18,13 +18,14 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Classifier: Topic :: System :: Monitoring
|
|
22
23
|
Requires-Dist: apache-airflow>=2.10.0
|
|
23
24
|
Requires-Dist: apache-airflow-providers-common-sql>=1.27.0
|
|
24
25
|
Requires-Dist: elasticsearch>=8.10,<9
|
|
25
26
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
|
26
|
-
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.
|
|
27
|
-
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.
|
|
27
|
+
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.2/changelog.html
|
|
28
|
+
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.2
|
|
28
29
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
|
29
30
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
|
30
31
|
Project-URL: Source Code, https://github.com/apache/airflow
|
|
@@ -55,8 +56,9 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
|
|
|
55
56
|
|
|
56
57
|
Package ``apache-airflow-providers-elasticsearch``
|
|
57
58
|
|
|
58
|
-
Release: ``6.3.
|
|
59
|
+
Release: ``6.3.2``
|
|
59
60
|
|
|
61
|
+
Release Date: ``|PypiReleaseDate|``
|
|
60
62
|
|
|
61
63
|
`Elasticsearch <https://www.elastic.co/elasticsearch>`__
|
|
62
64
|
|
|
@@ -68,7 +70,7 @@ This is a provider package for ``elasticsearch`` provider. All classes for this
|
|
|
68
70
|
are in ``airflow.providers.elasticsearch`` python package.
|
|
69
71
|
|
|
70
72
|
You can find package information and changelog for the provider
|
|
71
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.
|
|
73
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.2/>`_.
|
|
72
74
|
|
|
73
75
|
Installation
|
|
74
76
|
------------
|
|
@@ -77,7 +79,7 @@ You can install this package on top of an existing Airflow 2 installation (see `
|
|
|
77
79
|
for the minimum Airflow version supported) via
|
|
78
80
|
``pip install apache-airflow-providers-elasticsearch``
|
|
79
81
|
|
|
80
|
-
The package supports the following python versions: 3.10,3.11,3.12
|
|
82
|
+
The package supports the following python versions: 3.10,3.11,3.12,3.13
|
|
81
83
|
|
|
82
84
|
Requirements
|
|
83
85
|
------------
|
|
@@ -110,5 +112,5 @@ Dependent package
|
|
|
110
112
|
============================================================================================================ ==============
|
|
111
113
|
|
|
112
114
|
The changelog for the provider package can be found in the
|
|
113
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.
|
|
115
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/6.3.2/changelog.html>`_.
|
|
114
116
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
airflow/providers/elasticsearch/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
|
|
2
|
-
airflow/providers/elasticsearch/__init__.py,sha256=
|
|
2
|
+
airflow/providers/elasticsearch/__init__.py,sha256=QyVuquS4SFu8rW3mF_Z6J8B-_xBf749nRxohrJ4Fp7Y,1502
|
|
3
3
|
airflow/providers/elasticsearch/get_provider_info.py,sha256=473iBNJ4Kiy-DvbOa6CqDOS3pPEs6x7WBwkhR1QTuiw,8106
|
|
4
|
-
airflow/providers/elasticsearch/version_compat.py,sha256=
|
|
4
|
+
airflow/providers/elasticsearch/version_compat.py,sha256=VoYY99deuWiC8ya1zauXtFNSb6MBplEtBvc6zAgb6oM,2073
|
|
5
5
|
airflow/providers/elasticsearch/hooks/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
|
|
6
|
-
airflow/providers/elasticsearch/hooks/elasticsearch.py,sha256=
|
|
6
|
+
airflow/providers/elasticsearch/hooks/elasticsearch.py,sha256=hHbNKnsy8bNHjV-ufZYBXSOw2dj5JmicOub7VTohy7A,8583
|
|
7
7
|
airflow/providers/elasticsearch/log/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
8
8
|
airflow/providers/elasticsearch/log/es_json_formatter.py,sha256=DwWPDJtZLr_6Mdae1-XVEgmE1XErFIanSzxWovs50ig,1796
|
|
9
9
|
airflow/providers/elasticsearch/log/es_response.py,sha256=LdMBuVBTydaC42HooYSttAjTK-CpPA4r_KHl38msMnk,6046
|
|
10
|
-
airflow/providers/elasticsearch/log/es_task_handler.py,sha256=
|
|
11
|
-
apache_airflow_providers_elasticsearch-6.3.
|
|
12
|
-
apache_airflow_providers_elasticsearch-6.3.
|
|
13
|
-
apache_airflow_providers_elasticsearch-6.3.
|
|
14
|
-
apache_airflow_providers_elasticsearch-6.3.
|
|
10
|
+
airflow/providers/elasticsearch/log/es_task_handler.py,sha256=nqjmWbHkXNfroDeQn611jMOODpLKNuCA-SUkJ1QwLM8,28928
|
|
11
|
+
apache_airflow_providers_elasticsearch-6.3.2.dist-info/entry_points.txt,sha256=jpgAUVmTsdtWQ4nru2FJQKP9JBN4OPHK-ybfYc3_BOs,109
|
|
12
|
+
apache_airflow_providers_elasticsearch-6.3.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
13
|
+
apache_airflow_providers_elasticsearch-6.3.2.dist-info/METADATA,sha256=kx20yrITa4jQD7i3y0EDS6_zSsDDNyR5DhYrmGp3ESU,5255
|
|
14
|
+
apache_airflow_providers_elasticsearch-6.3.2.dist-info/RECORD,,
|
|
File without changes
|