Skip to content

Commit a7d719a

Browse files
committed
ft-orchestration store jq output directly on target instead of temporary files
1 parent 1983898 commit a7d719a

1 file changed

Lines changed: 32 additions & 25 deletions

File tree

  • tools/ft-orchestration/src/collector

tools/ft-orchestration/src/collector/jq.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import json
22
import logging
3-
from os import path
43
from pathlib import Path
54
import tempfile
65
import time
76
import xml.etree.ElementTree as ET
87

9-
import pandas as pd
8+
import numpy as np
109
from src.collector.interface import (
1110
CollectorOutputReaderException,
1211
CollectorOutputReaderInterface,
@@ -36,6 +35,21 @@
3635
"ipfix:msgLength": "MSG_LENGTH",
3736
}
3837

38+
CSV_DTYPES = {
39+
"BYTES": np.uint64,
40+
"PACKETS": np.uint64,
41+
"PROTOCOL": np.uint8,
42+
"SRC_PORT": np.uint16,
43+
"SRC_IP": str,
44+
"DST_PORT": np.uint16,
45+
"DST_IP": str,
46+
"START_TIME": np.uint64,
47+
"END_TIME": np.uint64,
48+
"EXPORT_TIME": np.uint32,
49+
"SEQ_NUMBER": np.uint32,
50+
"MSG_LENGTH": np.uint64,
51+
}
52+
3953

4054
class JQ(CollectorOutputReaderInterface):
4155
CONFIG_FILE = "config.xml"
@@ -275,36 +289,29 @@ def save_csv(self, csv_file: str):
275289
csv_file: str
276290
Path to CSV file. Local file, CSV will be downloaded when collector running on remote.
277291
"""
292+
header = CSV_HEADER_TO_ANALYZER_HEADER.values()
278293

279-
rsync = Rsync(self._executor)
280-
filename = path.basename(csv_file)
281-
tmp_file = path.join(rsync.get_data_directory(), filename)
282-
header = ",".join(
283-
[f'"{field}"' for field in CSV_HEADER_TO_ANALYZER_HEADER.keys()]
284-
)
294+
batch_size = 100_000
295+
buffer = []
285296

286297
logging.getLogger().info(
287298
"Preparing CSV output by calling ipfixcol2 + jq command..."
288299
)
289300
start = time.time()
290-
Tool(f"echo '{header}' > {tmp_file}", executor=self._executor).run()
291301
# write csv
292-
Tool(f"({self._cmd_csv}) >> {tmp_file}", executor=self._executor).run()
293-
end = time.time()
294-
logging.getLogger().info("CSV output saved in %.2f seconds.", (end - start))
302+
process = AsyncTool(self._cmd_csv, executor=self._executor)
303+
process.run()
295304

296-
start = time.time()
297-
tmp_dir = tempfile.mkdtemp()
298-
flows_file = rsync.pull_path(tmp_file, tmp_dir)
299-
end = time.time()
300-
df = pd.read_csv(flows_file)
301-
# Filter columns
302-
df = df[list(CSV_HEADER_TO_ANALYZER_HEADER.keys())]
303-
# rename columns
304-
df = df.rename(columns=CSV_HEADER_TO_ANALYZER_HEADER)
305+
with open(csv_file, mode="w", buffering=1024**2) as f:
306+
f.write(",".join(header) + "\n")
307+
for line in process.stdout:
308+
buffer.append(line + "\n")
309+
if len(buffer) >= batch_size:
310+
f.writelines(buffer)
311+
buffer = []
305312

306-
df.to_csv(csv_file, index=False)
313+
if buffer:
314+
f.writelines(buffer)
307315

308-
logging.getLogger().info(
309-
"CSV output downloaded in %.2f seconds.", (end - start)
310-
)
316+
end = time.time()
317+
logging.getLogger().info("CSV output saved in %.2f seconds.", (end - start))

0 commit comments

Comments
 (0)