logdetective 2.4.1__py3-none-any.whl → 2.5.0__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.
logdetective/utils.py CHANGED
@@ -16,54 +16,61 @@ from logdetective.remote_log import RemoteLog
16
16
  LOG = logging.getLogger("logdetective")
17
17
 
18
18
 
19
- def chunk_continues(text: str, index: int) -> bool:
19
+ def new_message(text: str) -> bool:
20
20
  """Set of heuristics for determining whether or not
21
21
  does the current chunk of log text continue on next line.
22
22
 
23
23
  Following rules are checked, in order:
24
- * is the next character is whitespace
25
- * is the previous character backslash '\\'
26
- * is the previous character colon ':'
27
-
24
+ * is the first character is whitespace
25
+ * is the first character backslash '|'
28
26
  """
29
27
  conditionals = [
30
- lambda i, string: string[i + 1].isspace(),
31
- lambda i, string: string[i - 1] == "\\",
32
- lambda i, string: string[i - 1] == ":",
28
+ lambda string: string[0].isspace(),
29
+ lambda string: string[0] == "|",
33
30
  ]
34
31
 
35
32
  for c in conditionals:
36
- y = c(index, text)
33
+ y = c(text)
37
34
  if y:
38
- return True
35
+ return False
39
36
 
40
- return False
37
+ return True
41
38
 
42
39
 
43
40
  def get_chunks(
44
- text: str, max_len: int = 2000
41
+ text: str, max_chunk_len: int = 2000
45
42
  ) -> Generator[Tuple[int, str], None, None]:
46
43
  """Split log into chunks according to heuristic
47
44
  based on whitespace and backslash presence.
48
45
  """
49
- text_len = len(text)
50
- i = 0
46
+ lines = text.splitlines()
47
+
48
+ # Chunk we will be yielding
51
49
  chunk = ""
52
- # Keep track of the original and next line number
53
- # every `\n` hit increases the next_line_number by one.
54
- original_line_number = 0
55
- next_line_number = 0
56
- while i < text_len:
57
- chunk += text[i]
58
- if text[i] == "\n":
59
- next_line_number += 1
60
- if i + 1 < text_len and chunk_continues(text, i) and i + 1 < max_len:
61
- i += 1
62
- continue
63
- yield (original_line_number, chunk)
64
- original_line_number = next_line_number + 1
65
- chunk = ""
66
- i += 1
50
+ # Number of line where the message started
51
+ original_line = 0
52
+ for i, line in enumerate(lines):
53
+ if len(line) == 0:
54
+ continue
55
+ if new_message(line):
56
+ # Yield chunk if we have it
57
+ if len(chunk) > 0:
58
+ yield (original_line, chunk)
59
+ original_line = i
60
+ chunk = line
61
+ else:
62
+ chunk += "\n" + line
63
+ if len(chunk) > max_chunk_len:
64
+ # If the chunk is too long, keep splitting into smaller chunks
65
+ # until we reach manageable size
66
+ while len(chunk) > max_chunk_len:
67
+ remainder = chunk[max_chunk_len:]
68
+ chunk = chunk[:max_chunk_len]
69
+ yield (original_line, chunk)
70
+ chunk = remainder
71
+
72
+ # if we still have some text left over
73
+ yield (original_line, chunk)
67
74
 
68
75
 
69
76
  def initialize_model(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logdetective
3
- Version: 2.4.1
3
+ Version: 2.5.0
4
4
  Summary: Log using LLM AI to search for build/test failures and provide ideas for fixing these.
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE
@@ -27,6 +27,8 @@ Requires-Dist: aiohttp (>=3.7.4,<4.0.0)
27
27
  Requires-Dist: aiolimiter (>=1.0.0,<2.0.0) ; extra == "server"
28
28
  Requires-Dist: aioresponses (>=0.7.8,<0.8.0) ; extra == "testing"
29
29
  Requires-Dist: alembic (>=1.13.3,<2.0.0) ; extra == "server" or extra == "server-testing"
30
+ Requires-Dist: asciidoc[testing] (>=10.2.1,<11.0.0) ; extra == "testing"
31
+ Requires-Dist: asyncpg (>=0.30.0,<0.31.0) ; extra == "server" or extra == "server-testing"
30
32
  Requires-Dist: backoff (==2.2.1) ; extra == "server" or extra == "server-testing"
31
33
  Requires-Dist: drain3 (>=0.9.11,<0.10.0)
32
34
  Requires-Dist: fastapi (>=0.111.1,<1.0.0) ; extra == "server" or extra == "server-testing"
@@ -37,11 +39,10 @@ Requires-Dist: llama-cpp-python (>0.2.56,!=0.2.86,<1.0.0)
37
39
  Requires-Dist: matplotlib (>=3.8.4,<4.0.0) ; extra == "server" or extra == "server-testing"
38
40
  Requires-Dist: numpy (>=1.26.0)
39
41
  Requires-Dist: openai (>=1.82.1,<2.0.0) ; extra == "server" or extra == "server-testing"
40
- Requires-Dist: psycopg2 (>=2.9.9,<3.0.0) ; extra == "server"
41
- Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0) ; extra == "server-testing"
42
42
  Requires-Dist: pydantic (>=2.8.2,<3.0.0)
43
43
  Requires-Dist: pytest (>=8.4.1,<9.0.0) ; extra == "testing"
44
44
  Requires-Dist: pytest-asyncio (>=1.1.0,<2.0.0) ; extra == "testing"
45
+ Requires-Dist: pytest-cov[testing] (>=7.0.0,<8.0.0) ; extra == "testing"
45
46
  Requires-Dist: pytest-mock (>=3.14.1,<4.0.0) ; extra == "server-testing"
46
47
  Requires-Dist: python-gitlab (>=4.4.0)
47
48
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
@@ -12,29 +12,29 @@ logdetective/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
12
12
  logdetective/server/compressors.py,sha256=qzrT-BPSksXY6F2L6ger04GGrgdBsGOfK2YuCFRs0Q4,5427
13
13
  logdetective/server/config.py,sha256=cKUmNCJyNyEid0bPTiUjr8CQuBYBab5bC79Axk2h0z8,2525
14
14
  logdetective/server/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- logdetective/server/database/base.py,sha256=1mcjEbhwLl4RalvT3oy6XVctjJoWIW3H9aI_sMWJBK8,1728
15
+ logdetective/server/database/base.py,sha256=UHcEui5LQ8795tzPZUBANmy5k9CprhyyuG2KczJD2LM,2016
16
16
  logdetective/server/database/models/__init__.py,sha256=GQ_4vC_jahwFrqhF4UUKLRo86_ulq1uSBAF3Je31DyA,878
17
17
  logdetective/server/database/models/exceptions.py,sha256=AXQPZRgt-r2vboxP9SGYelngP6YIFpHlwELKcZ1FD3Y,384
18
- logdetective/server/database/models/koji.py,sha256=vZN585FvOHM4z5o3oBBQsxWWJER1_giOMtZZPiU4q3w,5457
19
- logdetective/server/database/models/merge_request_jobs.py,sha256=q4reSC7YnEfWBPpV-qNt5nvuq0drntisHnKkFOlQW0o,18614
20
- logdetective/server/database/models/metrics.py,sha256=_UCaizcl9w4iX54EWvk5VvXeLcg2UfnQgXg4br3OLko,14214
21
- logdetective/server/emoji.py,sha256=hV4O0yfL0l1a3kWLImvBsY4AJQauKs7okYOGBEtYVz0,4795
18
+ logdetective/server/database/models/koji.py,sha256=1qWRuNej_SNXSc55R73Foel0XZLOYniPlj6ASyiQ22E,5908
19
+ logdetective/server/database/models/merge_request_jobs.py,sha256=fSN1sw4o5460RUglbffKJMQXihOTRTg0o8FC5khIS3E,19273
20
+ logdetective/server/database/models/metrics.py,sha256=Zi4X1j4C7ipwA_tLsqqDMfl7HHsYDTrpQms46YcC3X0,14865
21
+ logdetective/server/emoji.py,sha256=CoaAiZA_JgtUJe41YOsQRqd_QpgVeQ8szJt_bQ3d_JM,4837
22
22
  logdetective/server/exceptions.py,sha256=piV7wVKc-rw_pHrThbZbUjtmjuO5qUbjVNFwjdfcP3Q,864
23
- logdetective/server/gitlab.py,sha256=hPQICeYK1B_1BS56GIExQgEhcdS5Y6IgBCkk-eXtnDY,16708
23
+ logdetective/server/gitlab.py,sha256=putpnf8PfGsCZJsqWZA1rMovRGnyagoQmgpKLqtA-aQ,16743
24
24
  logdetective/server/koji.py,sha256=LG1pRiKUFvYFRKzgQoUG3pUHfcEwMoaMNjUSMKw_pBA,5640
25
25
  logdetective/server/llm.py,sha256=bmA6LsV80OdO60q4WLoKuehuVDEYq-HhBAYcZeLfrv8,10150
26
- logdetective/server/metric.py,sha256=QrrX1FmMa7sc57av0P9UFOiCIFYVLs1opOWV3ObYo0s,4086
26
+ logdetective/server/metric.py,sha256=-gqdd6LBUs_K6Sk30TZ7FJYE7Htp8d-uhVY5NwYgD3g,4186
27
27
  logdetective/server/models.py,sha256=BoiiUYI6BcVDOqtIcUgNRsCyjcWNCKyEfVtYOLYgr1Y,20929
28
- logdetective/server/plot.py,sha256=C98U9prGoPkp8_t4v2dovdZuwOhSbxXSeB_K9Q2r3NE,14607
29
- logdetective/server/server.py,sha256=s1QtD6FYsQX7BaVi783v7sqCEk4ccqlBJHFKUQlGgWM,24684
28
+ logdetective/server/plot.py,sha256=lFKOTXlLJ3aZtZGYXceA4OqUt1z18BpLITTI39fOMx4,14685
29
+ logdetective/server/server.py,sha256=Qx8mqkrRq-nlOnmOmICbaXxUWq2J60K4dHKiJtQJuE0,24938
30
30
  logdetective/server/templates/base_response.html.j2,sha256=BJGGV_Xb0Lnue8kq32oG9lI5CQDf9vce7HMYsP-Pvb4,2040
31
31
  logdetective/server/templates/gitlab_full_comment.md.j2,sha256=eNX_ZkAAVV7nNfKe02g_1-GgbiSqim0JH4aF3anzmxE,2186
32
32
  logdetective/server/templates/gitlab_short_comment.md.j2,sha256=UpQxIgOuOO8BBF__kzFl0XlCuYmcyfN2yMz6vd4PQ2Q,2000
33
- logdetective/server/utils.py,sha256=7ub-Nz7LUP_idwi2_nEC4FBuY9otSBUVy9nw86-sjYc,3861
33
+ logdetective/server/utils.py,sha256=KiyzzUIVssBc61LhGS0QNC5EY29In3NsG9j58ZRtoNI,4104
34
34
  logdetective/skip_snippets.yml,sha256=reGlhPPCo06nNUJWiC2LY-OJOoPdcyOB7QBTSMeh0eg,487
35
- logdetective/utils.py,sha256=9EyHKGNxtS1ObSepL-T3M43rKIxQJkFDA5yllLbS5Bs,9178
36
- logdetective-2.4.1.dist-info/METADATA,sha256=wBT_T5szJE3Xnn76UvC4drCacVhgCaBQ0QZkrBbpjnk,21645
37
- logdetective-2.4.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
- logdetective-2.4.1.dist-info/entry_points.txt,sha256=3K_vXja6PmcA8sNdUi63WdImeiNhVZcEGPTaoJmltfA,63
39
- logdetective-2.4.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
40
- logdetective-2.4.1.dist-info/RECORD,,
35
+ logdetective/utils.py,sha256=4B9wwaM4tyxLFtRnnTRDcGULJDonp6VoUS8HvUpIeSI,9388
36
+ logdetective-2.5.0.dist-info/METADATA,sha256=SvPiPxRVsUuxdepBGm7tJEF5tqksHMzrzrLK141MqEI,21745
37
+ logdetective-2.5.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
+ logdetective-2.5.0.dist-info/entry_points.txt,sha256=3K_vXja6PmcA8sNdUi63WdImeiNhVZcEGPTaoJmltfA,63
39
+ logdetective-2.5.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
40
+ logdetective-2.5.0.dist-info/RECORD,,