logdetective 0.5.10__py3-none-any.whl → 0.6.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/constants.py +8 -0
- logdetective/logdetective.py +25 -9
- logdetective/prompts.yml +6 -0
- logdetective/server/database/models.py +216 -12
- logdetective/server/metric.py +4 -6
- logdetective/server/models.py +11 -3
- logdetective/server/plot.py +114 -39
- logdetective/server/server.py +227 -91
- logdetective/server/templates/{gitlab_comment.md.j2 → gitlab_full_comment.md.j2} +1 -3
- logdetective/server/templates/gitlab_short_comment.md.j2 +53 -0
- logdetective/server/utils.py +3 -1
- logdetective/utils.py +28 -6
- {logdetective-0.5.10.dist-info → logdetective-0.6.0.dist-info}/METADATA +29 -5
- logdetective-0.6.0.dist-info/RECORD +24 -0
- logdetective-0.5.10.dist-info/RECORD +0 -23
- {logdetective-0.5.10.dist-info → logdetective-0.6.0.dist-info}/LICENSE +0 -0
- {logdetective-0.5.10.dist-info → logdetective-0.6.0.dist-info}/WHEEL +0 -0
- {logdetective-0.5.10.dist-info → logdetective-0.6.0.dist-info}/entry_points.txt +0 -0
logdetective/server/utils.py
CHANGED
|
@@ -37,7 +37,7 @@ def get_log(config: Config):
|
|
|
37
37
|
if getattr(log, "initialized", False):
|
|
38
38
|
return log
|
|
39
39
|
|
|
40
|
-
log.setLevel(
|
|
40
|
+
log.setLevel("DEBUG")
|
|
41
41
|
|
|
42
42
|
# Drop the default handler, we will create it ourselves
|
|
43
43
|
log.handlers = []
|
|
@@ -45,12 +45,14 @@ def get_log(config: Config):
|
|
|
45
45
|
# STDOUT
|
|
46
46
|
stream_handler = logging.StreamHandler()
|
|
47
47
|
stream_handler.setFormatter(logging.Formatter(config.log.format))
|
|
48
|
+
stream_handler.setLevel(config.log.level_stream)
|
|
48
49
|
log.addHandler(stream_handler)
|
|
49
50
|
|
|
50
51
|
# Log to file
|
|
51
52
|
if config.log.path:
|
|
52
53
|
file_handler = logging.FileHandler(config.log.path)
|
|
53
54
|
file_handler.setFormatter(logging.Formatter(config.log.format))
|
|
55
|
+
file_handler.setLevel(config.log.level_file)
|
|
54
56
|
log.addHandler(file_handler)
|
|
55
57
|
|
|
56
58
|
log.initialized = True
|
logdetective/utils.py
CHANGED
|
@@ -2,8 +2,9 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from typing import Iterator, List, Dict, Tuple, Generator
|
|
4
4
|
from urllib.parse import urlparse
|
|
5
|
+
|
|
6
|
+
import aiohttp
|
|
5
7
|
import numpy as np
|
|
6
|
-
import requests
|
|
7
8
|
import yaml
|
|
8
9
|
|
|
9
10
|
from llama_cpp import Llama, CreateCompletionResponse, CreateCompletionStreamResponse
|
|
@@ -111,25 +112,46 @@ def compute_certainty(probs: List[Dict]) -> float:
|
|
|
111
112
|
|
|
112
113
|
|
|
113
114
|
def process_log(
|
|
114
|
-
log: str, model: Llama, stream: bool, prompt_template: str
|
|
115
|
+
log: str, model: Llama, stream: bool, prompt_template: str,
|
|
116
|
+
temperature: float
|
|
115
117
|
) -> CreateCompletionResponse | Iterator[CreateCompletionStreamResponse]:
|
|
116
118
|
"""Processes a given log using the provided language model and returns its summary.
|
|
117
119
|
|
|
118
120
|
Args:
|
|
119
121
|
log (str): The input log to be processed.
|
|
120
122
|
model (Llama): The language model used for processing the log.
|
|
121
|
-
|
|
123
|
+
stream (bool): Return output as Iterator.
|
|
124
|
+
prompt_template (str): Which prompt template to use.
|
|
125
|
+
temperature (float): Temperature parameter for model runtime.
|
|
122
126
|
Returns:
|
|
123
127
|
str: The summary of the given log generated by the language model.
|
|
124
128
|
"""
|
|
125
129
|
response = model(
|
|
126
|
-
prompt=prompt_template.format(log), stream=stream, max_tokens=0, logprobs=1
|
|
130
|
+
prompt=prompt_template.format(log), stream=stream, max_tokens=0, logprobs=1,
|
|
131
|
+
temperature=temperature
|
|
127
132
|
)
|
|
128
133
|
|
|
129
134
|
return response
|
|
130
135
|
|
|
131
136
|
|
|
132
|
-
def
|
|
137
|
+
async def get_url_content(http: aiohttp.ClientSession, url: str, timeout: int) -> str:
|
|
138
|
+
"""validate log url and return log text."""
|
|
139
|
+
if validate_url(url=url):
|
|
140
|
+
LOG.debug("process url %s", url)
|
|
141
|
+
try:
|
|
142
|
+
response = await http.get(
|
|
143
|
+
url,
|
|
144
|
+
timeout=timeout,
|
|
145
|
+
raise_for_status=True
|
|
146
|
+
)
|
|
147
|
+
except aiohttp.ClientResponseError as ex:
|
|
148
|
+
raise RuntimeError(f"We couldn't obtain the logs: {ex}") from ex
|
|
149
|
+
return await response.text()
|
|
150
|
+
LOG.error("Invalid URL received ")
|
|
151
|
+
raise RuntimeError(f"Invalid log URL: {url}")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
async def retrieve_log_content(http: aiohttp.ClientSession, log_path: str) -> str:
|
|
133
155
|
"""Get content of the file on the log_path path.
|
|
134
156
|
Path is assumed to be valid URL if it has a scheme.
|
|
135
157
|
Otherwise it attempts to pull it from local filesystem."""
|
|
@@ -144,7 +166,7 @@ def retrieve_log_content(log_path: str) -> str:
|
|
|
144
166
|
log = f.read()
|
|
145
167
|
|
|
146
168
|
else:
|
|
147
|
-
log =
|
|
169
|
+
log = await get_url_content(http, log_path, timeout=60)
|
|
148
170
|
|
|
149
171
|
return log
|
|
150
172
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: logdetective
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.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
|
Author: Jiri Podivin
|
|
@@ -20,6 +20,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
20
20
|
Classifier: Topic :: Software Development :: Debuggers
|
|
21
21
|
Provides-Extra: server
|
|
22
22
|
Provides-Extra: server-testing
|
|
23
|
+
Requires-Dist: aiohttp (>=3.7.4)
|
|
23
24
|
Requires-Dist: alembic (>=1.13.3,<2.0.0) ; extra == "server" or extra == "server-testing"
|
|
24
25
|
Requires-Dist: drain3 (>=0.9.11,<0.10.0)
|
|
25
26
|
Requires-Dist: fastapi (>=0.111.1) ; extra == "server" or extra == "server-testing"
|
|
@@ -32,7 +33,6 @@ Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0) ; extra == "server-testing"
|
|
|
32
33
|
Requires-Dist: pydantic (>=2.8.2,<3.0.0)
|
|
33
34
|
Requires-Dist: python-gitlab (>=4.4.0)
|
|
34
35
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
35
|
-
Requires-Dist: requests (>0.2.31)
|
|
36
36
|
Requires-Dist: sqlalchemy (>=2.0.36,<3.0.0) ; extra == "server" or extra == "server-testing"
|
|
37
37
|
Project-URL: homepage, https://github.com/fedora-copr/logdetective
|
|
38
38
|
Project-URL: issues, https://github.com/fedora-copr/logdetective/issues
|
|
@@ -47,6 +47,8 @@ Log Detective
|
|
|
47
47
|
|
|
48
48
|
A Python tool to analyze logs using a Language Model (LLM) and Drain template miner.
|
|
49
49
|
|
|
50
|
+
Note: if you are looking for code of website logdetective.com it is in [github.com/fedora-copr/logdetective-website](https://github.com/fedora-copr/logdetective-website).
|
|
51
|
+
|
|
50
52
|
Installation
|
|
51
53
|
------------
|
|
52
54
|
|
|
@@ -95,6 +97,17 @@ Example you want to use a different model:
|
|
|
95
97
|
logdetective https://example.com/logs.txt --model https://huggingface.co/QuantFactory/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct.Q5_K_S.gguf?download=true
|
|
96
98
|
logdetective https://example.com/logs.txt --model QuantFactory/Meta-Llama-3-8B-Instruct-GGUF
|
|
97
99
|
|
|
100
|
+
Example of different suffix (useful for models that were quantized)
|
|
101
|
+
|
|
102
|
+
logdetective https://kojipkgs.fedoraproject.org//work/tasks/3367/131313367/build.log --model 'fedora-copr/granite-3.2-8b-instruct-GGUF' -F Q4_K.gguf
|
|
103
|
+
|
|
104
|
+
Example of altered prompts:
|
|
105
|
+
|
|
106
|
+
cp ~/.local/lib/python3.13/site-packages/logdetective/prompts.yml ~/my-prompts.yml
|
|
107
|
+
vi ~/my-prompts.yml # edit the prompts there to better fit your needs
|
|
108
|
+
logdetective https://kojipkgs.fedoraproject.org//work/tasks/3367/131313367/build.log --prompts ~/my-prompts.yml
|
|
109
|
+
|
|
110
|
+
|
|
98
111
|
Note that streaming with some models (notably Meta-Llama-3 is broken) is broken and can be workarounded by `no-stream` option:
|
|
99
112
|
|
|
100
113
|
logdetective https://example.com/logs.txt --model QuantFactory/Meta-Llama-3-8B-Instruct-GGUF --no-stream
|
|
@@ -337,11 +350,23 @@ certbot certonly --standalone -d logdetective01.fedorainfracloud.org
|
|
|
337
350
|
Querying statistics
|
|
338
351
|
-------------------
|
|
339
352
|
|
|
340
|
-
You can retrieve statistics about server requests over a specified time period
|
|
341
|
-
using either the `curl`
|
|
353
|
+
You can retrieve statistics about server requests and responses over a specified time period
|
|
354
|
+
using either a browser, the `curl` or the `http` command (provided by the `httpie` package).
|
|
342
355
|
|
|
343
356
|
When no time period is specified, the query defaults to the last 2 days:
|
|
344
357
|
|
|
358
|
+
You can view requests and responses statistics
|
|
359
|
+
- for the `/analyze` endpoint at http://localhost:8080/metrics/analyze
|
|
360
|
+
- for the `/analyze/staged` endpoint at http://localhost:8080/metrics/analyze/staged.
|
|
361
|
+
|
|
362
|
+
You can retrieve single svg images at the following endpoints:
|
|
363
|
+
- `/metrics/analyze/requests`
|
|
364
|
+
- `/metrics/analyze/responses`
|
|
365
|
+
- `/metrics/analyze/staged/requests`
|
|
366
|
+
- `/metrics/analyze/stages/responses`
|
|
367
|
+
|
|
368
|
+
Examples:
|
|
369
|
+
|
|
345
370
|
```
|
|
346
371
|
http GET "localhost:8080/metrics/analyze/requests" > /tmp/plot.svg
|
|
347
372
|
curl "localhost:8080/metrics/analyze/staged/requests" > /tmp/plot.svg
|
|
@@ -349,7 +374,6 @@ curl "localhost:8080/metrics/analyze/staged/requests" > /tmp/plot.svg
|
|
|
349
374
|
|
|
350
375
|
You can specify the time period in hours, days, or weeks.
|
|
351
376
|
The time period:
|
|
352
|
-
|
|
353
377
|
- cannot be less than one hour
|
|
354
378
|
- cannot be negative
|
|
355
379
|
- ends at the current time (when the query is made)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
logdetective/__init__.py,sha256=VqRngDcuFT7JWms8Qc_MsOvajoXVOKPr-S1kqY3Pqhc,59
|
|
2
|
+
logdetective/constants.py,sha256=A5PzeqlQqDbBS_kzP2hl-lhJ0lCEqdbvW3CaQUYVxjw,1849
|
|
3
|
+
logdetective/drain3.ini,sha256=ni91eCT1TwTznZwcqWoOVMQcGEnWhEDNCoTPF7cfGfY,1360
|
|
4
|
+
logdetective/extractors.py,sha256=7ahzWbTtU9MveG1Q7wU9LO8OJgs85X-cHmWltUhCe9M,3491
|
|
5
|
+
logdetective/logdetective.py,sha256=cC2oL4yPNo94AB2nS4v1jpZi-Qo1g0_FEchL_yQL1UU,5832
|
|
6
|
+
logdetective/models.py,sha256=nrGBmMRu8i6UhFflQKAp81Y3Sd_Aaoor0i_yqSJoLT0,1115
|
|
7
|
+
logdetective/prompts.yml,sha256=dMW2-bdTIqv7LF_owqRD4xinMK5ZWcNhDynnX1zoKns,1722
|
|
8
|
+
logdetective/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
logdetective/server/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
logdetective/server/database/base.py,sha256=oMJUvbWeapIUP-8Cf_DR9ptFg8CsYeaBAIjOVEzx8SM,1668
|
|
11
|
+
logdetective/server/database/models.py,sha256=m_3qNBWJwLSwjJn0AmwSxXMJk75Gu1bXFtGAP_4zps4,14088
|
|
12
|
+
logdetective/server/metric.py,sha256=-uM_-yqxNA-EZTCnNRdQ8g1MicmE5eC6jRFI_mBBYUg,2606
|
|
13
|
+
logdetective/server/models.py,sha256=URqZcfx5yUsifZ1pOwZ_uU3Tyjcdvuq6qEnAvTexl4A,8475
|
|
14
|
+
logdetective/server/plot.py,sha256=B2rOngqx7g-Z3NfttboTip3frkypdF1H7FhK8vh45mE,9655
|
|
15
|
+
logdetective/server/server.py,sha256=AXduOwD6zPNFc-COw-JcTp4bPan9DfXJml52XiBHmds,29613
|
|
16
|
+
logdetective/server/templates/gitlab_full_comment.md.j2,sha256=DQZ2WVFedpuXI6znbHIW4wpF9BmFS8FaUkowh8AnGhE,1627
|
|
17
|
+
logdetective/server/templates/gitlab_short_comment.md.j2,sha256=fzScpayv2vpRLczP_0O0YxtA8rsKvR6gSv4ntNdWb98,1443
|
|
18
|
+
logdetective/server/utils.py,sha256=QO0H1q55YLCLKxkViqex4Uu31LnakpYUKJfZHysonSc,1838
|
|
19
|
+
logdetective/utils.py,sha256=IBAH6hleuhtbA3cAGhiIDb3zwKaovunBfVsG0TKzoKA,7127
|
|
20
|
+
logdetective-0.6.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
21
|
+
logdetective-0.6.0.dist-info/METADATA,sha256=zBYLi3jNjqR-6EYJY4wy5CS-1-ZgEzzRGofcqzXbHco,15880
|
|
22
|
+
logdetective-0.6.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
23
|
+
logdetective-0.6.0.dist-info/entry_points.txt,sha256=3K_vXja6PmcA8sNdUi63WdImeiNhVZcEGPTaoJmltfA,63
|
|
24
|
+
logdetective-0.6.0.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
logdetective/__init__.py,sha256=VqRngDcuFT7JWms8Qc_MsOvajoXVOKPr-S1kqY3Pqhc,59
|
|
2
|
-
logdetective/constants.py,sha256=eiS6eYhEgl_Rlyi_B9j00DDp9A-UDhuFz3ACWtKf_SU,1558
|
|
3
|
-
logdetective/drain3.ini,sha256=ni91eCT1TwTznZwcqWoOVMQcGEnWhEDNCoTPF7cfGfY,1360
|
|
4
|
-
logdetective/extractors.py,sha256=7ahzWbTtU9MveG1Q7wU9LO8OJgs85X-cHmWltUhCe9M,3491
|
|
5
|
-
logdetective/logdetective.py,sha256=SDuzeS9sMp7rs6cTZAEd0ajtyWv9XnDkEPTF82nwaYo,5390
|
|
6
|
-
logdetective/models.py,sha256=nrGBmMRu8i6UhFflQKAp81Y3Sd_Aaoor0i_yqSJoLT0,1115
|
|
7
|
-
logdetective/prompts.yml,sha256=3orDNqqZNadWCaNncgfk8D3Pqqef4IzfScoa_jUJzCY,1452
|
|
8
|
-
logdetective/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
logdetective/server/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
logdetective/server/database/base.py,sha256=oMJUvbWeapIUP-8Cf_DR9ptFg8CsYeaBAIjOVEzx8SM,1668
|
|
11
|
-
logdetective/server/database/models.py,sha256=arIahOCT-hTmh904DXrWSkH7rlo13Ppu-OO80huX5Dc,6118
|
|
12
|
-
logdetective/server/metric.py,sha256=VYMifrfIhcqgyu6YYN0c1nt8fC1iJ2_LCB7Bh2AheoE,2679
|
|
13
|
-
logdetective/server/models.py,sha256=cf1ngu_-19rP_i49s5cEwIzh6SfL_ZpVy4EykCpfWck,8076
|
|
14
|
-
logdetective/server/plot.py,sha256=3o-CNHjel04ekpwSB4ckV7dbiF663cfPkimQ0aP9U_8,7073
|
|
15
|
-
logdetective/server/server.py,sha256=FDKx-6wsVoEwdEgcoepAT3GL0gZKjMSpB1VU-jaKt2w,24618
|
|
16
|
-
logdetective/server/templates/gitlab_comment.md.j2,sha256=kheTkhQ-LfuFkr8av-Mw2a-9VYEUbDTLwaa-CKI6OkI,1622
|
|
17
|
-
logdetective/server/utils.py,sha256=6y4gZCwQG4HcjWJwYdzwP46Jsm3xoNXZWH4kYmSWVZA,1741
|
|
18
|
-
logdetective/utils.py,sha256=_cBBkBwZHX5qxy0K5WK2MnHA4x_oor7R-QED2VZLbCA,6226
|
|
19
|
-
logdetective-0.5.10.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
20
|
-
logdetective-0.5.10.dist-info/METADATA,sha256=NbD3YEoEU-YAhH-VjOo95qWxyk1T1bq5wCih4N5oyqs,14738
|
|
21
|
-
logdetective-0.5.10.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
22
|
-
logdetective-0.5.10.dist-info/entry_points.txt,sha256=3K_vXja6PmcA8sNdUi63WdImeiNhVZcEGPTaoJmltfA,63
|
|
23
|
-
logdetective-0.5.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|