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/server/database/base.py +25 -23
- logdetective/server/database/models/koji.py +29 -22
- logdetective/server/database/models/merge_request_jobs.py +163 -164
- logdetective/server/database/models/metrics.py +61 -46
- logdetective/server/emoji.py +7 -7
- logdetective/server/gitlab.py +6 -6
- logdetective/server/metric.py +9 -9
- logdetective/server/plot.py +12 -10
- logdetective/server/server.py +19 -11
- logdetective/server/utils.py +7 -0
- logdetective/utils.py +36 -29
- {logdetective-2.4.1.dist-info → logdetective-2.5.0.dist-info}/METADATA +4 -3
- {logdetective-2.4.1.dist-info → logdetective-2.5.0.dist-info}/RECORD +16 -16
- {logdetective-2.4.1.dist-info → logdetective-2.5.0.dist-info}/WHEEL +0 -0
- {logdetective-2.4.1.dist-info → logdetective-2.5.0.dist-info}/entry_points.txt +0 -0
- {logdetective-2.4.1.dist-info → logdetective-2.5.0.dist-info}/licenses/LICENSE +0 -0
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
|
|
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
|
|
25
|
-
* is the
|
|
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
|
|
31
|
-
lambda
|
|
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(
|
|
33
|
+
y = c(text)
|
|
37
34
|
if y:
|
|
38
|
-
return
|
|
35
|
+
return False
|
|
39
36
|
|
|
40
|
-
return
|
|
37
|
+
return True
|
|
41
38
|
|
|
42
39
|
|
|
43
40
|
def get_chunks(
|
|
44
|
-
text: str,
|
|
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
|
-
|
|
50
|
-
|
|
46
|
+
lines = text.splitlines()
|
|
47
|
+
|
|
48
|
+
# Chunk we will be yielding
|
|
51
49
|
chunk = ""
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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.
|
|
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=
|
|
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=
|
|
19
|
-
logdetective/server/database/models/merge_request_jobs.py,sha256=
|
|
20
|
-
logdetective/server/database/models/metrics.py,sha256=
|
|
21
|
-
logdetective/server/emoji.py,sha256=
|
|
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=
|
|
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
|
|
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=
|
|
29
|
-
logdetective/server/server.py,sha256=
|
|
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=
|
|
33
|
+
logdetective/server/utils.py,sha256=KiyzzUIVssBc61LhGS0QNC5EY29In3NsG9j58ZRtoNI,4104
|
|
34
34
|
logdetective/skip_snippets.yml,sha256=reGlhPPCo06nNUJWiC2LY-OJOoPdcyOB7QBTSMeh0eg,487
|
|
35
|
-
logdetective/utils.py,sha256=
|
|
36
|
-
logdetective-2.
|
|
37
|
-
logdetective-2.
|
|
38
|
-
logdetective-2.
|
|
39
|
-
logdetective-2.
|
|
40
|
-
logdetective-2.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|