Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
79b88a8
Refine uv lock maintenance loops
junhaoliao Oct 25, 2025
929bd25
feat(log-converter): Add log-converter binary which converts unstruct…
gibber9809 Oct 25, 2025
1677431
fix(clp-mcp-server): Include log viewer links in formatted log events…
20001020ycx Oct 26, 2025
9e82bdb
chore(deployment): Exclude generated `.env` file under `presto-clp` f…
junhaoliao Oct 26, 2025
6c6de99
fix(deployment): Update archives directory mount paths in Presto Dock…
junhaoliao Oct 26, 2025
2ac456e
feat(clp-package)!: Add `compress-from-s3` Python and shell scripts f…
Eden-D-Zhang Oct 26, 2025
cbb8629
fix lock.yaml
junhaoliao Oct 27, 2025
03f33a2
ci: Add clp-uv-checks workflow for validating Python UV lock files.
junhaoliao Oct 27, 2025
212a904
fix(deps): Ensure lock.yaml ends with a newline.
junhaoliao Oct 27, 2025
cb57c0e
Merge branch 'main' into codex/fix-issue-#1381-in-repository
junhaoliao Oct 27, 2025
143058d
use LF for newlines
junhaoliao Oct 27, 2025
47a58d5
ci(workflows): Rename rust-checks job to uv-checks in clp-uv-checks w…
junhaoliao Oct 27, 2025
dae6cb7
ci(workflows): Add uv installation step in clp-uv-checks workflow.
junhaoliao Oct 27, 2025
6da77ea
Fix hyphenation in "up-to-date" adjective.
junhaoliao Oct 27, 2025
16f34b7
ci(workflows): Adjust placement of version comment in clp-uv-checks w…
junhaoliao Oct 27, 2025
dd13a01
ci(workflows): Adjust spacing in checkout action comment in clp-uv-ch…
junhaoliao Oct 27, 2025
874df6d
feat(deployment): Add `--setup-only` flag to `start-clp.sh` to set up…
junhaoliao Oct 27, 2025
1b92ca8
fix(docker): Include `libmariadbcpp.so` (required by `spider_schedule…
junhaoliao Oct 27, 2025
fdd2f82
fix(deployment): Use CLP Package's Docker Compose network for Presto …
junhaoliao Oct 27, 2025
fde9a1a
Merge branch 'main' into codex/fix-issue-#1381-in-repository
junhaoliao Oct 27, 2025
39417f0
Improve docs - Apply suggestions from code review
junhaoliao Oct 27, 2025
b5dc6ca
fix(ci): Update uv installation method to use the setup-uv action
junhaoliao Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/clp-uv-checks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: "clp-uv-checks"

on:
pull_request:
paths: &monitored_paths
- ".github/workflows/clp-uv-checks.yaml"
- "components/clp-mcp-server/pyproject.toml"
- "components/clp-mcp-server/uv.lock"
- "components/clp-package-utils/pyproject.toml"
- "components/clp-package-utils/uv.lock"
- "components/clp-py-utils/pyproject.toml"
- "components/clp-py-utils/uv.lock"
- "components/job-orchestration/pyproject.toml"
- "components/job-orchestration/uv.lock"
- "integration-tests/pyproject.toml"
- "integration-tests/uv.lock"
push:
paths: *monitored_paths
schedule:
# Run daily at 00:15 UTC (the 15 is to avoid periods of high load)
- cron: "15 0 * * *"
workflow_dispatch:

concurrency:
group: "${{github.workflow}}-${{github.ref}}"
# Cancel in-progress jobs for efficiency
cancel-in-progress: true

jobs:
uv-checks:
strategy:
matrix:
os:
- "macos-15"
- "ubuntu-22.04"
- "ubuntu-24.04"
runs-on: "${{matrix.os}}"
steps:
- uses: "actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8" # v5.0.0
with:
submodules: "recursive"

- name: "Install task"
shell: "bash"
run: "npm install -g @go-task/[email protected]"

- name: "Install the latest version of uv"
uses: "astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41" # v7.1.2

- name: "Validate lock files"
shell: "bash"
run: "task deps:lock:check-uv"
7 changes: 5 additions & 2 deletions components/clp-mcp-server/clp_mcp_server/server/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ def format_query_results(query_results: list[dict[str, Any]]) -> list[str]:
kv-pairs:
- "timestamp": An integer representing the epoch timestamp in milliseconds.
- "message": A string representing the log message.
- "link": A string representing the link to open the log viewer displaying the message.

The message will be formatted as `timestamp: <date string>, message: <message>`:
The message will be formatted as `timestamp: <date string>, message: <message>, link: <link>`.

:param query_results: A list of dictionaries representing kv-pair log events.
:return: A list of strings representing formatted log events.
Expand All @@ -105,7 +106,9 @@ def format_query_results(query_results: list[dict[str, Any]]) -> list[str]:
logger.warning("Empty message attached to a log event: %s.", obj)
continue

formatted_log_events.append(f"timestamp: {timestamp_str}, message: {message}")
link = obj["link"]

formatted_log_events.append(f"timestamp: {timestamp_str}, message: {message}, link: {link}")

return formatted_log_events

Expand Down
64 changes: 48 additions & 16 deletions components/clp-mcp-server/tests/server/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
class TestUtils:
"""Test suite for utility functions."""

LINK = "http://localhost:4000/"

# Error Messages:
INVALID_DATE_STRING_ERROR = "Invalid date string"
INVALID_DATE_STRING_FORMAT_ERROR = "Timestamp must end with 'Z' to indicate UTC."
Expand All @@ -24,54 +26,68 @@ class TestUtils:
{
"timestamp": None,
"message": '{"message":"Log with None timestamp"}\n',
"link": LINK
},
{
"timestamp": "1729267200000", # str instead of int
"message": '{"message":"Log with str timestamp"}\n',
"link": LINK
},
{
"timestamp": 1729267200000.0, # float instead of int
"message": '{"message":"Log with float timestamp"}\n',
"link": LINK
},
]
EXPECTED_INVALID_TYPE = [
'timestamp: N/A, message: {"message":"Log with None timestamp"}\n',
'timestamp: N/A, message: {"message":"Log with str timestamp"}\n',
'timestamp: N/A, message: {"message":"Log with float timestamp"}\n',
f'timestamp: N/A, message: {{"message":"Log with None timestamp"}}\n, link: {LINK}',
f'timestamp: N/A, message: {{"message":"Log with str timestamp"}}\n, link: {LINK}',
f'timestamp: N/A, message: {{"message":"Log with float timestamp"}}\n, link: {LINK}'
]

# Test case: invalid timestamp values.
INVALID_VALUE_ENTRIES = [
{
"timestamp": 9999999999999999,
"message": '{"message":"Log with overflow timestamp"}\n',
"link": LINK
},
{
"timestamp": -9999999999999999,
"message": '{"message":"Log with negative overflow timestamp"}\n',
"link": LINK
},
]
EXPECTED_INVALID_VALUE = [
'timestamp: N/A, message: {"message":"Log with overflow timestamp"}\n',
'timestamp: N/A, message: {"message":"Log with negative overflow timestamp"}\n',
(
f'timestamp: N/A, message: {{"message":"Log with overflow timestamp"}}\n,'
f' link: {LINK}'
),
(
f'timestamp: N/A, message: {{"message":"Log with negative overflow timestamp"}}\n,'
f' link: {LINK}'
)
]

# Test case: missing timestamp and message fields.
MISSING_TIMESTAMP_AND_MESSAGE_ENTRY = [
{
"_id": "test001",
"link": LINK
},
{
"_id": "test002",
"message": '{"message":"Log with no timestamp"}\n',
"link": LINK
},
{
"_id": "test003",
"timestamp": 0,
"link": LINK
}
]
EXPECTED_MISSING_TIMESTAMP_AND_MESSAGE = [
'timestamp: N/A, message: {"message":"Log with no timestamp"}\n',
f'timestamp: N/A, message: {{"message":"Log with no timestamp"}}\n, link: {LINK}',
]

# Testing basic functionality.
Expand All @@ -83,6 +99,7 @@ class TestUtils:
"orig_file_path": "/var/log/app.log",
"archive_id": "abc123",
"log_event_ix": 99,
"link": LINK
},
{
"_id": "test001",
Expand All @@ -91,6 +108,7 @@ class TestUtils:
"orig_file_path": "/var/log/app.log",
"archive_id": "abc123",
"log_event_ix": 100,
"link": LINK
},
{
"_id": "test002",
Expand All @@ -102,6 +120,7 @@ class TestUtils:
"orig_file_path": "/var/log/app.log",
"archive_id": "abc124",
"log_event_ix": 101,
"link": LINK
},
{
"_id": "test003",
Expand All @@ -113,29 +132,42 @@ class TestUtils:
"orig_file_path": "/var/log/app.log",
"archive_id": "abc125",
"log_event_ix": 102,
"link": (
"http://localhost:4000/streamFile"
"?dataset=default"
'&type=json'
"&streamId=abc125"
"&logEventIdx=102"
),
},
]

EXPECTED_RESULTS = [
(
'timestamp: 2024-10-18T16:00:00.123Z, message: '
'{"ts":1729267200123,"pid":1234,"tid":5678,'
'"message":"Log with millisecond precision"}\n'
'"message":"Log with millisecond precision"}\n, '
"link: http://localhost:4000/streamFile"
"?dataset=default"
'&type=json'
"&streamId=abc125"
"&logEventIdx=102"

),
(
'timestamp: 2024-10-18T16:00:00.000Z, message: '
'{"ts":1729267200000,"pid":1234,"tid":5678,'
'"message":"Log with zero milliseconds"}\n'
f'timestamp: 2024-10-18T16:00:00.000Z, message: '
f'{{"ts":1729267200000,"pid":1234,"tid":5678,'
f'"message":"Log with zero milliseconds"}}\n, link: {LINK}'
),
(
'timestamp: 1970-01-01T00:00:00.000Z, message: '
'{"ts":0,"pid":null,"tid":null,'
'"message":"Log at epoch zero"}\n'
f'timestamp: 1970-01-01T00:00:00.000Z, message: '
f'{{"ts":0,"pid":null,"tid":null,'
f'"message":"Log at epoch zero"}}\n, link: {LINK}'
),
(
'timestamp: N/A, message: '
'{"pid":null,"tid":null,'
'"message":"Log at epoch none"}\n'
f'timestamp: N/A, message: '
f'{{"pid":null,"tid":null,'
f'"message":"Log at epoch none"}}\n, link: {LINK}'
),
]

Expand Down
Loading
Loading