Compare commits

..

No commits in common. "5e0e6c5d1f7993772b7cba6fac0c124d6af72e07" and "47fae9625c67d45cb911c1f812b1cb3b20df1829" have entirely different histories.

View file

@ -9,25 +9,21 @@ on:
jobs: jobs:
build-with-metrics: build-with-metrics:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 15 timeout-minutes: 60
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Setup Rust and Scaphandre - name: Setup Rust and Scaphandre
run: | run: |
# Installer Rust si nécessaire
if ! command -v cargo &> /dev/null; then if ! command -v cargo &> /dev/null; then
curl https://sh.rustup.rs -sSf | sh -s -- -y curl https://sh.rustup.rs -sSf | sh -s -- -y
source "$HOME/.cargo/env" source "$HOME/.cargo/env"
fi fi
# Installer Scaphandre et configurer les permissions # Installer Scaphandre via Cargo
cargo install scaphandre cargo install scaphandre
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
sudo cp $HOME/.cargo/bin/scaphandre /usr/local/bin/
sudo setcap cap_sys_rawio=+ep /usr/local/bin/scaphandre
sudo chmod +r /dev/cpu/*/msr
- name: Setup directories and install dependencies - name: Setup directories and install dependencies
run: | run: |
@ -44,11 +40,7 @@ jobs:
linux-tools-common \ linux-tools-common \
linux-tools-generic \ linux-tools-generic \
python3-pip \ python3-pip \
python3-psutil \ python3-psutil
msr-tools
# Charger le module msr
sudo modprobe msr
# Installer dépendances Python # Installer dépendances Python
pip3 install pandas numpy pip3 install pandas numpy
@ -62,7 +54,6 @@ jobs:
import sys import sys
import time import time
import json import json
import signal
from datetime import datetime from datetime import datetime
def monitor_energy(command, output_file): def monitor_energy(command, output_file):
@ -72,64 +63,72 @@ jobs:
# Préparer le fichier CSV # Préparer le fichier CSV
with open(output_file, 'w', newline='') as csvfile: with open(output_file, 'w', newline='') as csvfile:
writer = csv.writer(csvfile) writer = csv.writer(csvfile)
writer.writerow(['Timestamp', 'Power_Watts', 'Component']) writer.writerow([
'Timestamp',
'Power_Watts',
'Component'
])
def signal_handler(signum, frame): # Commande scaphandre pour la sortie JSON
print("Signal reçu, arrêt du monitoring...") scaphandre_cmd = [
sys.exit(0) 'scaphandre', 'json',
'-t', '120' # Timeout de 2 minutes max
]
signal.signal(signal.SIGTERM, signal_handler) # Lancer le monitoring en arrière-plan
signal.signal(signal.SIGINT, signal_handler) monitor_process = subprocess.Popen(
scaphandre_cmd,
# Lancer la commande principale stdout=subprocess.PIPE,
print(f"Exécution de la commande: {command}") stderr=subprocess.PIPE,
main_process = subprocess.Popen(command, shell=True) universal_newlines=True
)
try: try:
# Monitoring en continu pendant l'exécution de la commande # Attendre un court instant pour que Scaphandre démarre
while main_process.poll() is None: time.sleep(2)
try:
# Exécuter scaphandre pour une seule mesure
scaphandre_output = subprocess.check_output(
['sudo', 'scaphandre', 'json', '-n', '1'],
universal_newlines=True
)
# Traiter la mesure # Exécuter la commande principale
process_measurement(scaphandre_output, output_file) main_process = subprocess.Popen(command, shell=True)
main_process.wait()
# Attendre 1 seconde avant la prochaine mesure # Attendre et traiter les données de Scaphandre
time.sleep(1) try:
monitor_output, _ = monitor_process.communicate(timeout=10)
except subprocess.CalledProcessError as e: process_scaphandre_output(monitor_output, output_file)
print(f"Erreur lors de la mesure: {e}") except subprocess.TimeoutExpired:
continue print("Scaphandre monitoring timed out", file=sys.stderr)
except Exception as e:
print(f"Erreur inattendue: {e}")
continue
return main_process.returncode
finally: finally:
if main_process.poll() is None: # Arrêter le monitoring
main_process.terminate() monitor_process.terminate()
main_process.wait() monitor_process.wait()
def process_measurement(output, output_file): def process_scaphandre_output(output, output_file):
try: try:
data = json.loads(output.strip()) # Diviser le flux JSON en objets individuels
timestamp = data.get('timestamp', datetime.now().isoformat()) json_objects = output.strip().split('\n')
power = data.get('power', {}).get('total_power', 0)
with open(output_file, 'a', newline='') as csvfile: with open(output_file, 'a', newline='') as csvfile:
writer = csv.writer(csvfile) writer = csv.writer(csvfile)
writer.writerow([timestamp, power, 'System'])
except json.JSONDecodeError as e: for json_str in json_objects:
print(f"Erreur de décodage JSON: {e}") try:
data = json.loads(json_str)
# Extraire les informations pertinentes
timestamp = data.get('timestamp', datetime.now().isoformat())
power = data.get('power', {}).get('total_power', 0)
writer.writerow([
timestamp,
power,
'System'
])
except json.JSONDecodeError:
print(f"Could not parse JSON: {json_str}", file=sys.stderr)
except Exception as e: except Exception as e:
print(f"Erreur de traitement: {e}") print(f"Error processing Scaphandre output: {e}", file=sys.stderr)
def main(): def main():
if len(sys.argv) < 3: if len(sys.argv) < 3:
print("Usage: python energy_monitor.py 'command' output_file.csv") print("Usage: python energy_monitor.py 'command' output_file.csv")
@ -138,13 +137,8 @@ jobs:
command = sys.argv[1] command = sys.argv[1]
output_file = sys.argv[2] output_file = sys.argv[2]
try: monitor_energy(command, output_file)
exit_code = monitor_energy(command, output_file)
sys.exit(exit_code)
except Exception as e:
print(f"Erreur fatale: {e}")
sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
EOL EOL
@ -184,13 +178,13 @@ jobs:
- name: Build with Maven and measure energy - name: Build with Maven and measure energy
id: build id: build
timeout-minutes: 5 timeout-minutes: 15
env: env:
MAVEN_OPTS: "-Xmx2048m -XX:+TieredCompilation -XX:TieredStopAtLevel=1" MAVEN_OPTS: "-Xmx2048m -XX:+TieredCompilation -XX:TieredStopAtLevel=1"
run: | run: |
set -eo pipefail set -eo pipefail
# Ajouter Cargo au PATH # Ajouter Cargo et Scaphandre au PATH
source "$HOME/.cargo/env" source "$HOME/.cargo/env"
start_time=$(date +%s%N) start_time=$(date +%s%N)
@ -199,8 +193,8 @@ jobs:
free -m > metrics/system/pre_build_memory.txt free -m > metrics/system/pre_build_memory.txt
# Monitoring énergétique avec Scaphandre # Monitoring énergétique avec Scaphandre
sudo python3 energy_monitor.py \ python3 energy_monitor.py \
"./mvnw -B verify -Dmaven.test.skip=true" \ "./mvnw -B verify -Dmaven.test.skip=true -Dcheckstyle.skip=true -T 1C" \
metrics/power/build_power_metrics.csv metrics/power/build_power_metrics.csv
build_status=$? build_status=$?
@ -212,20 +206,16 @@ jobs:
# Enregistrer le temps de build # Enregistrer le temps de build
echo "$((($end_time - $start_time)/1000000))" > metrics/performance/build_time.txt echo "$((($end_time - $start_time)/1000000))" > metrics/performance/build_time.txt
# Vérifier le contenu du fichier de métriques
echo "=== Build power metrics content ==="
cat metrics/power/build_power_metrics.csv
exit $build_status exit $build_status
- name: Run tests with energy monitoring - name: Run tests with energy monitoring
id: test id: test
if: success() if: success()
timeout-minutes: 5 timeout-minutes: 20
run: | run: |
set -eo pipefail set -eo pipefail
# Ajouter Cargo au PATH # Ajouter Cargo et Scaphandre au PATH
source "$HOME/.cargo/env" source "$HOME/.cargo/env"
start_time=$(date +%s%N) start_time=$(date +%s%N)
@ -234,8 +224,8 @@ jobs:
free -m > metrics/system/pre_test_memory.txt free -m > metrics/system/pre_test_memory.txt
# Monitoring énergétique avec Scaphandre # Monitoring énergétique avec Scaphandre
sudo python3 energy_monitor.py \ python3 energy_monitor.py \
"./mvnw test" \ "./mvnw test -T 1C" \
metrics/power/test_power_metrics.csv metrics/power/test_power_metrics.csv
test_status=$? test_status=$?
@ -247,20 +237,16 @@ jobs:
# Enregistrer le temps des tests # Enregistrer le temps des tests
echo "$((($end_time - $start_time)/1000000))" > metrics/performance/test_time.txt echo "$((($end_time - $start_time)/1000000))" > metrics/performance/test_time.txt
# Vérifier le contenu du fichier de métriques
echo "=== Test power metrics content ==="
cat metrics/power/test_power_metrics.csv
exit $test_status exit $test_status
- name: Build Docker image with energy monitoring - name: Build Docker image with energy monitoring
id: docker-build id: docker-build
if: success() if: success()
timeout-minutes: 5 timeout-minutes: 10
run: | run: |
set -eo pipefail set -eo pipefail
# Ajouter Cargo au PATH # Ajouter Cargo et Scaphandre au PATH
source "$HOME/.cargo/env" source "$HOME/.cargo/env"
start_time=$(date +%s%N) start_time=$(date +%s%N)
@ -270,8 +256,8 @@ jobs:
df -h > metrics/system/pre_docker_disk.txt df -h > metrics/system/pre_docker_disk.txt
# Monitoring énergétique avec Scaphandre # Monitoring énergétique avec Scaphandre
sudo python3 energy_monitor.py \ python3 energy_monitor.py \
"docker build -t app:latest -f .devcontainer/Dockerfile ." \ "docker build -t app:latest -f .devcontainer/Dockerfile . --no-cache" \
metrics/power/docker_build_power_metrics.csv metrics/power/docker_build_power_metrics.csv
build_status=$? build_status=$?
@ -287,10 +273,6 @@ jobs:
# Collecter la taille de l'image # Collecter la taille de l'image
docker images app:latest --format "{{.Size}}" > metrics/performance/docker_image_size.txt docker images app:latest --format "{{.Size}}" > metrics/performance/docker_image_size.txt
# Vérifier le contenu du fichier de métriques
echo "=== Docker build power metrics content ==="
cat metrics/power/docker_build_power_metrics.csv
exit $build_status exit $build_status
- name: Collect final system metrics - name: Collect final system metrics
@ -311,29 +293,6 @@ jobs:
# Marquer la fin du pipeline # Marquer la fin du pipeline
date +%s%N > metrics/pipeline_end_time.txt date +%s%N > metrics/pipeline_end_time.txt
- name: Verify metrics collection
if: always()
run: |
echo "=== Checking power metrics files ==="
for file in metrics/power/*.csv; do
echo "=== Content of $file: ==="
cat "$file"
echo "Size of $file: $(wc -l < "$file") lines"
echo "File permissions: $(ls -l "$file")"
done
echo "=== Checking system metrics files ==="
for file in metrics/system/*; do
echo "=== Content of $file: ==="
cat "$file"
done
echo "=== Checking performance metrics files ==="
for file in metrics/performance/*; do
echo "=== Content of $file: ==="
cat "$file"
done
- name: Save metrics - name: Save metrics
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4