-
Notifications
You must be signed in to change notification settings - Fork 196
feat(metrics): add CSV extraction and CI workflow #734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Copyright (c) 2023-2026, Nubificus LTD | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| name: metrics | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| schedule: | ||
| - cron: '0 0 * * 1' # every Monday at midnight | ||
|
|
||
| jobs: | ||
| measure: | ||
| runs-on: [self-hosted, linux, amd64] | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - unikernel: solo5-hvt | ||
| image: harbor.nbfc.io/nubificus/urunc/redis-hvt-rumprun:latest | ||
| - unikernel: unikraft-nginx | ||
| image: harbor.nbfc.io/nubificus/urunc/nginx-unikraft-fc-initrd:latest | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup timestamping shim | ||
| run: | | ||
| sudo tee /usr/local/bin/containerd-shim-uruncts-v2 > /dev/null << 'EOT' | ||
| #!/bin/bash | ||
| URUNC_TIMESTAMPS=1 /usr/local/bin/containerd-shim-urunc-v2 $@ | ||
| EOT | ||
| sudo chmod +x /usr/local/bin/containerd-shim-uruncts-v2 | ||
|
|
||
| - name: Run metrics measurement | ||
| run: | | ||
| cd script/performance | ||
| sudo python3 measure_to_csv.py \ | ||
| 5 \ | ||
| ${{ matrix.image }} \ | ||
| metrics-${{ matrix.unikernel }}.csv | ||
|
|
||
| - name: Upload CSV artifact | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: metrics-${{ matrix.unikernel }} | ||
| path: script/performance/metrics-${{ matrix.unikernel }}.csv | ||
| if-no-files-found: warn | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # Copyright (c) 2023-2026, Nubificus LTD | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| from __modules__ import ( | ||
| emptyFile, spawnContainer, deleteContainer, | ||
| parseSingleContainerTimestamps, TimestampSeries, myprint | ||
| ) | ||
| from sys import argv | ||
| from time import sleep | ||
| import csv | ||
|
|
||
| LOGFILE = "/tmp/urunc.zlog" | ||
| DELAY = 2 | ||
|
|
||
| # Key phase definitions: (start_tsID, end_tsID, column_name) | ||
| PHASES = [ | ||
| ("TS00", "TS11", "create_ns"), # full create phase | ||
| ("TS12", "TS19", "start_ns"), # full start phase | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed "TS19" is used as the end timestamp for start_ns, but checking internal/metrics/schema.go the last defined timestamp is TS18 (RX.execve_hypervisor) TimestampCount (value 19) is a sentinel and is never written to the log file. Because get_phase_duration returns "N/A" when the end key isn't found in the map, start_ns would always come out as "N/A" in every CSV row. worth double-checking if TS18 is the intended end of the start phase, the fix would be: ("TS12", "TS18", "start_ns")
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! Changed TS19 to TS18 in commit 2a29d93. Thanks for catching that! |
||
| ("TS16", "TS17", "network_ns"), # network setup | ||
| ("TS17", "TS18", "disk_ns"), # disk setup | ||
| ] | ||
|
|
||
|
|
||
| def get_phase_duration(series, start_id, end_id): | ||
| ts_map = {ts.tsID: ts for ts in series.sorted} | ||
| if start_id in ts_map and end_id in ts_map: | ||
| return ts_map[end_id].timestamp - ts_map[start_id].timestamp | ||
| return "N/A" | ||
|
|
||
|
|
||
| def main(): | ||
| if len(argv) != 4: | ||
| print("Error: Missing arguments!") | ||
| print("") | ||
| print("Usage:") | ||
| print(f"\t{argv[0]} <ITERATIONS> <IMAGE> <OUTPUT_CSV>") | ||
| print("") | ||
| print("Example:") | ||
| print(f"\t{argv[0]} 5 " | ||
| "harbor.nbfc.io/nubificus/urunc/" | ||
| "redis-hvt-rumprun:latest metrics.csv") | ||
| exit(1) | ||
|
|
||
| iterations = int(argv[1]) | ||
| image = argv[2] | ||
| output_file = argv[3] | ||
| name = "urunc-metrics-test" | ||
|
|
||
| myprint(f"Collecting metrics for {iterations} iterations") | ||
| myprint(f"Image: {image}") | ||
| sleep(2) | ||
|
|
||
| emptyFile(LOGFILE) | ||
| container_ids = [] | ||
|
|
||
| for i in range(iterations): | ||
| myprint(f"Running iteration {i+1} of {iterations}") | ||
| container_id = spawnContainer(image=image, name=name) | ||
| container_ids.append(container_id) | ||
| sleep(DELAY) | ||
| success = deleteContainer(name=name) | ||
| if not success: | ||
| print("Error removing container.") | ||
| exit(1) | ||
|
|
||
| myprint("Writing CSV...") | ||
|
|
||
| with open(output_file, "w", newline="") as f: | ||
| writer = csv.writer(f) | ||
| writer.writerow(["containerID", "create_ns", "start_ns", | ||
| "network_ns", "disk_ns"]) | ||
| for container_id in container_ids: | ||
| data = parseSingleContainerTimestamps( | ||
| filename=LOGFILE, containerID=container_id) | ||
| if not data: | ||
| continue | ||
| series = TimestampSeries(data=data) | ||
| row = [container_id] | ||
| for start_id, end_id, _ in PHASES: | ||
| row.append(get_phase_duration(series, start_id, end_id)) | ||
| writer.writerow(row) | ||
|
|
||
| myprint(f"Saved metrics to {output_file}") | ||
| emptyFile(LOGFILE) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if intentional, but the other workflows in this repo all pin actions to a full commit SHA with a version comment ,no floating @v4 references anywhere else in .github/workflows/. Might be worth pinning to match the project pattern:
uses: actions/checkout@ # v4
uses: actions/upload-artifact@ # v4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed! Pinned both actions to full commit SHAs in commit 2a29d93 to match the project convention.