flow.record 3.18.dev1__tar.gz → 3.19.dev1__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.
- {flow_record-3.18.dev1/flow.record.egg-info → flow_record-3.19.dev1}/PKG-INFO +1 -1
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/elastic.py +30 -13
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/tools/rdump.py +6 -1
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/version.py +2 -2
- {flow_record-3.18.dev1 → flow_record-3.19.dev1/flow.record.egg-info}/PKG-INFO +1 -1
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/COPYRIGHT +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/LICENSE +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/MANIFEST.in +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/README.md +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/examples/filesystem.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/examples/passivedns.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/examples/records.json +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/examples/tcpconn.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/__init__.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/__init__.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/archive.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/avro.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/broker.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/csvfile.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/duckdb.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/jsonfile.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/line.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/mongo.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/split.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/splunk.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/sqlite.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/stream.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/text.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/adapter/xlsx.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/base.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/exceptions.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/__init__.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/credential.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/net/__init__.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/net/ip.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/net/ipv4.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/net/tcp.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/fieldtypes/net/udp.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/jsonpacker.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/packer.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/selector.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/stream.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/tools/__init__.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/tools/geoip.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/utils.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow/record/whitelist.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow.record.egg-info/SOURCES.txt +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow.record.egg-info/dependency_links.txt +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow.record.egg-info/entry_points.txt +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow.record.egg-info/requires.txt +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/flow.record.egg-info/top_level.txt +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/pyproject.toml +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/setup.cfg +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/__init__.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/_utils.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/docs/Makefile +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/docs/conf.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/docs/index.rst +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/selector_explain_example.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/standalone_test.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_adapter_line.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_adapter_text.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_avro.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_avro_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_compiled_selector.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_csv_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_deprecations.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_elastic_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_fieldtype_ip.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_fieldtypes.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_json_packer.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_json_record_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_multi_timestamp.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_packer.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_rdump.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_record.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_record_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_record_descriptor.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_regression.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_selector.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_splunk_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_sqlite_duckdb_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tests/test_xlsx_adapter.py +0 -0
- {flow_record-3.18.dev1 → flow_record-3.19.dev1}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.19.dev1
|
|
4
4
|
Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import hashlib
|
|
2
4
|
import logging
|
|
3
5
|
import queue
|
|
4
6
|
import threading
|
|
5
|
-
from typing import Iterator
|
|
7
|
+
from typing import Iterator
|
|
6
8
|
|
|
7
9
|
import elasticsearch
|
|
8
10
|
import elasticsearch.helpers
|
|
@@ -37,10 +39,10 @@ class ElasticWriter(AbstractWriter):
|
|
|
37
39
|
self,
|
|
38
40
|
uri: str,
|
|
39
41
|
index: str = "records",
|
|
40
|
-
verify_certs:
|
|
41
|
-
http_compress:
|
|
42
|
-
hash_record:
|
|
43
|
-
api_key:
|
|
42
|
+
verify_certs: str | bool = True,
|
|
43
|
+
http_compress: str | bool = True,
|
|
44
|
+
hash_record: str | bool = False,
|
|
45
|
+
api_key: str | None = None,
|
|
44
46
|
**kwargs,
|
|
45
47
|
) -> None:
|
|
46
48
|
self.index = index
|
|
@@ -52,6 +54,9 @@ class ElasticWriter(AbstractWriter):
|
|
|
52
54
|
if not uri.lower().startswith(("http://", "https://")):
|
|
53
55
|
uri = "http://" + uri
|
|
54
56
|
|
|
57
|
+
self.queue: queue.Queue[Record | StopIteration] = queue.Queue()
|
|
58
|
+
self.event = threading.Event()
|
|
59
|
+
|
|
55
60
|
self.es = elasticsearch.Elasticsearch(
|
|
56
61
|
uri,
|
|
57
62
|
verify_certs=verify_certs,
|
|
@@ -60,10 +65,11 @@ class ElasticWriter(AbstractWriter):
|
|
|
60
65
|
)
|
|
61
66
|
|
|
62
67
|
self.json_packer = JsonRecordPacker()
|
|
63
|
-
|
|
64
|
-
self.event = threading.Event()
|
|
68
|
+
|
|
65
69
|
self.thread = threading.Thread(target=self.streaming_bulk_thread)
|
|
66
70
|
self.thread.start()
|
|
71
|
+
self.exception: Exception | None = None
|
|
72
|
+
threading.excepthook = self.excepthook
|
|
67
73
|
|
|
68
74
|
if not verify_certs:
|
|
69
75
|
# Disable InsecureRequestWarning of urllib3, caused by the verify_certs flag.
|
|
@@ -76,6 +82,12 @@ class ElasticWriter(AbstractWriter):
|
|
|
76
82
|
if arg_key.startswith("_meta_"):
|
|
77
83
|
self.metadata_fields[arg_key[6:]] = arg_val
|
|
78
84
|
|
|
85
|
+
def excepthook(self, exc: threading.ExceptHookArgs, *args, **kwargs) -> None:
|
|
86
|
+
log.error("Exception in thread: %s", exc)
|
|
87
|
+
self.exception = getattr(exc, "exc_value", exc)
|
|
88
|
+
self.event.set()
|
|
89
|
+
self.close()
|
|
90
|
+
|
|
79
91
|
def record_to_document(self, record: Record, index: str) -> dict:
|
|
80
92
|
"""Convert a record to a Elasticsearch compatible document dictionary"""
|
|
81
93
|
rdict = record._asdict()
|
|
@@ -120,6 +132,7 @@ class ElasticWriter(AbstractWriter):
|
|
|
120
132
|
|
|
121
133
|
def streaming_bulk_thread(self) -> None:
|
|
122
134
|
"""Thread that streams the documents to ES via the bulk api"""
|
|
135
|
+
|
|
123
136
|
for ok, item in elasticsearch.helpers.streaming_bulk(
|
|
124
137
|
self.es,
|
|
125
138
|
self.document_stream(),
|
|
@@ -138,21 +151,25 @@ class ElasticWriter(AbstractWriter):
|
|
|
138
151
|
pass
|
|
139
152
|
|
|
140
153
|
def close(self) -> None:
|
|
154
|
+
self.queue.put(StopIteration)
|
|
155
|
+
self.event.wait()
|
|
156
|
+
|
|
141
157
|
if hasattr(self, "es"):
|
|
142
|
-
self.queue.put(StopIteration)
|
|
143
|
-
self.event.wait()
|
|
144
158
|
self.es.close()
|
|
145
159
|
|
|
160
|
+
if self.exception:
|
|
161
|
+
raise self.exception
|
|
162
|
+
|
|
146
163
|
|
|
147
164
|
class ElasticReader(AbstractReader):
|
|
148
165
|
def __init__(
|
|
149
166
|
self,
|
|
150
167
|
uri: str,
|
|
151
168
|
index: str = "records",
|
|
152
|
-
verify_certs:
|
|
153
|
-
http_compress:
|
|
154
|
-
selector:
|
|
155
|
-
api_key:
|
|
169
|
+
verify_certs: str | bool = True,
|
|
170
|
+
http_compress: str | bool = True,
|
|
171
|
+
selector: None | Selector | CompiledSelector = None,
|
|
172
|
+
api_key: str | None = None,
|
|
156
173
|
**kwargs,
|
|
157
174
|
) -> None:
|
|
158
175
|
self.index = index
|
|
@@ -218,7 +218,9 @@ def main(argv=None):
|
|
|
218
218
|
islice_stop = (args.count + args.skip) if args.count else None
|
|
219
219
|
record_iterator = islice(record_stream(args.src, selector), args.skip, islice_stop)
|
|
220
220
|
count = 0
|
|
221
|
-
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
record_writer = RecordWriter(uri)
|
|
222
224
|
for count, rec in enumerate(record_iterator, start=1):
|
|
223
225
|
if args.record_source is not None:
|
|
224
226
|
rec._source = args.record_source
|
|
@@ -243,6 +245,9 @@ def main(argv=None):
|
|
|
243
245
|
else:
|
|
244
246
|
record_writer.write(rec)
|
|
245
247
|
|
|
248
|
+
finally:
|
|
249
|
+
record_writer.__exit__()
|
|
250
|
+
|
|
246
251
|
if args.list:
|
|
247
252
|
print("Processed {} records".format(count))
|
|
248
253
|
|
|
@@ -12,5 +12,5 @@ __version__: str
|
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
|
13
13
|
version_tuple: VERSION_TUPLE
|
|
14
14
|
|
|
15
|
-
__version__ = version = '3.
|
|
16
|
-
__version_tuple__ = version_tuple = (3,
|
|
15
|
+
__version__ = version = '3.19.dev1'
|
|
16
|
+
__version_tuple__ = version_tuple = (3, 19, 'dev1')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.19.dev1
|
|
4
4
|
Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|