-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: improve logging and add optional perf logging (#248)
Mostly minor changes: - Remove the use of `Console` from server.py. This cascades into other changes downstream - Add latency logs behind a `LOG_PERFORMANCE` env var: - Add a wrapper for all API calls to measure the latency at API level - Add detailed performance monitoring to the tool_calling_llm core `call()` function - Align the http server (uvicorn) logging pattern with the other logging calls Example of perf metrics for tool_calling_llm: ``` 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(TOTAL) 8167ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(get_all_tools_openai_format) +0ms 0ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(start iteration 0) +0ms 0ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(count tokens) +6ms 6ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(llm.completion) +1831ms 1837ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(pre-tool-calls) +0ms 1837ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(tool completed fetch_finding_by_id) +570ms 2407ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(end iteration 0) +0ms 2407ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(start iteration 1) +0ms 2407ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(count tokens) +7ms 2415ms 2025-01-14 09:41:17.177 INFO tool_calling_llm.call(llm.completion) +5752ms 8167ms ```
- Loading branch information
1 parent
b074e30
commit b3ed4fd
Showing
9 changed files
with
147 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import time | ||
import logging | ||
|
||
from functools import wraps | ||
|
||
from holmes.common.env_vars import ( | ||
LOG_PERFORMANCE, | ||
) | ||
|
||
class PerformanceTiming: | ||
def __init__(self, name): | ||
if not LOG_PERFORMANCE: | ||
return | ||
self.ended = False | ||
|
||
self.name = name | ||
self.start_time = time.time() | ||
self.last_measure_time = self.start_time | ||
self.last_measure_label = "Start" | ||
self.timings = [] | ||
|
||
def measure(self, label): | ||
if not LOG_PERFORMANCE: | ||
return | ||
if self.ended: | ||
raise Exception("cannot measure a perf timing that is already ended") | ||
current_time = time.time() | ||
|
||
time_since_start = int((current_time - self.start_time) * 1000) | ||
time_since_last = int((current_time - self.last_measure_time) * 1000) | ||
|
||
self.timings.append((label, time_since_last, time_since_start)) | ||
|
||
self.last_measure_time = current_time | ||
self.last_measure_label = label | ||
|
||
def end(self): | ||
if not LOG_PERFORMANCE: | ||
return | ||
self.ended = True | ||
current_time = time.time() | ||
time_since_start = int((current_time - self.start_time) * 1000) | ||
message = f'{self.name}(TOTAL) {time_since_start}ms' | ||
logging.info(message) | ||
for label, time_since_last, time_since_start in self.timings: | ||
logging.info(f'\t{self.name}({label}) +{time_since_last}ms {time_since_start}ms') | ||
|
||
def log_function_timing(func): | ||
@wraps(func) | ||
def function_timing_wrapper(*args, **kwargs): | ||
start_time = time.perf_counter() | ||
result = func(*args, **kwargs) | ||
end_time = time.perf_counter() | ||
total_time = int((end_time - start_time) * 1000) | ||
logging.info(f'Function "{func.__name__}()" took {total_time}ms') | ||
return result | ||
return function_timing_wrapper |
Oops, something went wrong.