Skip to content
This repository was archived by the owner on May 29, 2025. It is now read-only.

Commit c951263

Browse files
authored
Merge pull request #419 from valory-xyz/develop
Release `v0.22.5`
2 parents 154ebe5 + 2f01c60 commit c951263

File tree

6 files changed

+226
-34
lines changed

6 files changed

+226
-34
lines changed

README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Ensure your machine satisfies the requirements:
2121
## Resource Requirements
2222

2323
- You need xDAI on Gnosis Chain in one of your wallets.
24-
- You need an RPC for your agent instance. We recommend [Nodies RPC](https://www.nodies.app/).
24+
- You need an RPC for your agent instance. We recommend [Quicknode RPC](https://www.quicknode.com/).
2525
- (From release v0.16.0 onwards) You will need a Subgraph API key that can be obtained at [The Graph](https://thegraph.com/studio/apikeys/).
2626

2727
## Run the Service
@@ -105,7 +105,7 @@ Services can become staked by invoking the `stake()` contract method, where serv
105105
Once the command has completed, i.e. the service is running, you can see the live logs with:
106106

107107
```bash
108-
docker logs trader_abci_0 --follow
108+
docker logs $(docker ps --filter "name=trader" --format "{{.Names}}" | grep "_abci" | head -n 1) --follow
109109
```
110110

111111
To stop your agent, use:
@@ -153,16 +153,16 @@ Note: In this case, if the service is staked, then it will not update the on-cha
153153
cd trader; poetry run python ../report.py; cd ..
154154
```
155155

156-
3. Use this command to investigate your agent's logs:
156+
3. Use the `analyse_logs.py` script to investigate your agent's logs:
157157
158158
```bash
159-
cd trader; poetry run autonomy analyse logs --from-dir trader_service/abci_build/persistent_data/logs/ --agent aea_0 --reset-db; cd ..
159+
cd trader; poetry run python ../analyse_logs.py --agent aea_0 --reset-db; cd ..
160160
```
161161
162-
For example, inspect the state transitions using this command:
162+
For example, inspect the state transitions using the following command:
163163
164164
```bash
165-
cd trader; poetry run autonomy analyse logs --from-dir trader_service/abci_build/persistent_data/logs/ --agent aea_0 --fsm --reset-db; cd ..
165+
cd trader; poetry run python ../analyse_logs.py --agent aea_0 --fsm --reset-db; cd ..
166166
```
167167
168168
This will output the different state transitions of your agent per period, for example:
@@ -411,7 +411,11 @@ Error: Service terminatation failed with following error; ChainInteractionError(
411411
412412
## Build deployments without executing the service
413413
414-
The script builds both a Docker Compose deployment (on `./trader/trader_service/abci_build`) and a Kubernetes deployment (on `./trader/trader_service/abci_build_k8s`). Then, by default, the script will launch the local Docker Compose deployment. If you just want to build the deployment without executing the service (for example, if you are deploying to a custom Kubernetes cluster), then execute the script as
414+
The script builds both a Docker Compose deployment (on `./trader/trader_service/abci_build_????`)
415+
and a Kubernetes deployment (on `./trader/trader_service/abci_build_k8s`).
416+
Then, by default, the script will launch the local Docker Compose deployment.
417+
If you just want to build the deployment without executing the service
418+
(for example, if you are deploying to a custom Kubernetes cluster), then execute the script as:
415419
416420
```bash
417421
./run_service.sh --build-only

analyse_logs.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import os
2+
import subprocess
3+
import sys
4+
import argparse
5+
6+
7+
def _parse_args():
8+
"""Parse the script arguments."""
9+
parser = argparse.ArgumentParser(description="Analyse agent logs.")
10+
11+
parser.add_argument(
12+
"--service-dir",
13+
default="trader_service",
14+
help="The service directory containing build directories (default: 'trader_service')."
15+
)
16+
parser.add_argument(
17+
"--from-dir",
18+
help="Path to the logs directory. If not provided, it is auto-detected."
19+
)
20+
parser.add_argument(
21+
"--agent",
22+
default="aea_0",
23+
help="The agent name to analyze (default: 'aea_0')."
24+
)
25+
parser.add_argument(
26+
"--reset-db",
27+
action="store_true",
28+
help="Use this flag to disable resetting the log database."
29+
)
30+
parser.add_argument(
31+
"--start-time",
32+
help="Start time in `YYYY-MM-DD H:M:S,MS` format."
33+
)
34+
parser.add_argument(
35+
"--end-time",
36+
help="End time in `YYYY-MM-DD H:M:S,MS` format."
37+
)
38+
parser.add_argument(
39+
"--log-level",
40+
choices=["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"],
41+
help="Logging level."
42+
)
43+
parser.add_argument(
44+
"--period",
45+
type=int,
46+
help="Period ID."
47+
)
48+
parser.add_argument(
49+
"--round",
50+
help="Round name."
51+
)
52+
parser.add_argument(
53+
"--behaviour",
54+
help="Behaviour name filter."
55+
)
56+
parser.add_argument(
57+
"--fsm",
58+
action="store_true",
59+
help="Print only the FSM execution path."
60+
)
61+
parser.add_argument(
62+
"--include-regex",
63+
help="Regex pattern to include in the result."
64+
)
65+
parser.add_argument(
66+
"--exclude-regex",
67+
help="Regex pattern to exclude from the result."
68+
)
69+
70+
return parser.parse_args()
71+
72+
73+
def find_build_directory(service_dir):
74+
"""Find the appropriate build directory within the service directory."""
75+
try:
76+
# create a list of all build directories
77+
build_dirs = [
78+
d for d in os.listdir(service_dir)
79+
if d.startswith("abci_build_") and os.path.isdir(os.path.join(service_dir, d))
80+
]
81+
# iterate through the build directories to find the one that contains logs
82+
for build_dir in build_dirs:
83+
build_dir = os.path.join(service_dir, build_dir)
84+
logs_dir = os.path.join(build_dir, "persistent_data", "logs")
85+
# Check if the logs folder exists and contains files
86+
if os.path.exists(logs_dir) and os.listdir(logs_dir):
87+
return build_dir
88+
return os.path.join(service_dir, "abci_build")
89+
except FileNotFoundError:
90+
print(f"Service directory '{service_dir}' not found")
91+
sys.exit(1)
92+
93+
94+
def run_analysis(logs_dir, **kwargs):
95+
"""Run the log analysis command."""
96+
command = [
97+
"poetry", "run", "autonomy", "analyse", "logs",
98+
"--from-dir", logs_dir,
99+
]
100+
if kwargs.get("agent"):
101+
command.extend(["--agent", kwargs.get("agent")])
102+
if kwargs.get("reset_db"):
103+
command.extend(["--reset-db"])
104+
if kwargs.get("start_time"):
105+
command.extend(["--start-time", kwargs.get("start_time")])
106+
if kwargs.get("end_time"):
107+
command.extend(["--end-time", kwargs.get("end_time")])
108+
if kwargs.get("log_level"):
109+
command.extend(["--log-level", kwargs.get("log_level")])
110+
if kwargs.get("period"):
111+
command.extend(["--period", kwargs.get("period")])
112+
if kwargs.get("round"):
113+
command.extend(["--round", kwargs.get("round")])
114+
if kwargs.get("behaviour"):
115+
command.extend(["--behaviour", kwargs.get("behaviour")])
116+
if kwargs.get("fsm"):
117+
command.extend(["--fsm"])
118+
if kwargs.get("include_regex"):
119+
command.extend(["--include-regex", kwargs.get("include_regex")])
120+
if kwargs.get("exclude_regex"):
121+
command.extend(["--exclude-regex", kwargs.get("exclude_regex")])
122+
123+
try:
124+
subprocess.run(command, check=True)
125+
print("Analysis completed successfully.")
126+
except subprocess.CalledProcessError as e:
127+
print(f"Command failed with exit code {e.returncode}")
128+
sys.exit(e.returncode)
129+
except FileNotFoundError:
130+
print("Poetry or autonomy not found. Ensure they are installed and accessible.")
131+
sys.exit(1)
132+
133+
134+
if __name__ == "__main__":
135+
# Parse user arguments
136+
args = _parse_args()
137+
138+
# Determine the logs directory
139+
if args.from_dir:
140+
logs_dir = args.from_dir
141+
if not os.path.exists(logs_dir):
142+
print(f"Specified logs directory '{logs_dir}' not found.")
143+
sys.exit(1)
144+
else:
145+
# Auto-detect the logs directory
146+
build_dir = find_build_directory(args.service_dir)
147+
logs_dir = os.path.join(build_dir, "persistent_data", "logs")
148+
if not os.path.exists(logs_dir):
149+
print(f"Logs directory '{logs_dir}' not found.")
150+
sys.exit(1)
151+
152+
# Run the analysis
153+
run_analysis(logs_dir, **vars(args))

report.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@
111111
SECONDS_PER_DAY = 60 * 60 * 24
112112

113113
OUTPUT_WIDTH = 80
114+
TRADER_CONTAINER_PREFIX = "trader"
115+
AGENT_CONTAINER_IDENTIFIER = "abci"
116+
NODE_CONTAINER_IDENTIFIER = "tm"
114117

115118

116119
class ColorCode:
@@ -238,19 +241,19 @@ def _warning_message(current_value: int, threshold: int = 0, message: str = "")
238241

239242
def _get_agent_status() -> str:
240243
client = docker.from_env()
241-
trader_abci_container = (
242-
client.containers.get("trader_abci_0")
243-
if "trader_abci_0" in [c.name for c in client.containers.list()]
244-
else None
245-
)
246-
trader_tm_container = (
247-
client.containers.get("trader_tm_0")
248-
if "trader_tm_0" in [c.name for c in client.containers.list()]
249-
else None
250-
)
251-
252-
is_running = trader_abci_container and trader_tm_container
253-
return _color_bool(is_running, "Running", "Stopped")
244+
agent_running = node_running = service_running = False
245+
for container in client.containers.list():
246+
container_name = container.name
247+
if TRADER_CONTAINER_PREFIX in container_name:
248+
if AGENT_CONTAINER_IDENTIFIER in container_name:
249+
agent_running = True
250+
if NODE_CONTAINER_IDENTIFIER in container_name:
251+
node_running = True
252+
if agent_running and node_running:
253+
service_running = True
254+
break
255+
256+
return _color_bool(service_running, "Running", "Stopped")
254257

255258

256259
def _parse_args() -> Any:

run_service.sh

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ directory="trader"
737737
service_repo=https://github.com/$org_name/$directory.git
738738
# This is a tested version that works well.
739739
# Feel free to replace this with a different version of the repo, but be careful as there might be breaking changes
740-
service_version="v0.21.4"
740+
service_version="v0.22.0"
741741

742742
# Define constants for on-chain interaction
743743
gnosis_chain_id=100
@@ -832,10 +832,15 @@ command -v docker >/dev/null 2>&1 ||
832832
exit 1
833833
}
834834

835-
docker rm -f abci0 node0 trader_abci_0 trader_tm_0 &> /dev/null ||
835+
containers=$(docker ps --filter name=trader_* -aq) &> /dev/null ||
836836
{ echo >&2 "Docker is not running!";
837837
exit 1
838838
}
839+
if [[ -n "$containers" ]]; then
840+
docker rm -f $containers
841+
fi
842+
843+
docker network prune --force
839844

840845
try_read_storage
841846

@@ -1275,8 +1280,7 @@ export DISABLE_TRADING=false
12751280
export STOP_TRADING_IF_STAKING_KPI_MET=true
12761281
export RESET_PAUSE_DURATION=45
12771282
export MECH_WRAPPED_NATIVE_TOKEN_ADDRESS=$WXDAI_ADDRESS
1278-
export MECH_CHAIN_ID=ethereum
1279-
export TOOLS_ACCURACY_HASH=QmebjcPizAdVFSUAfMBgAGFJhLPVBMvV68LxhSq4LPvv9d
1283+
export TOOLS_ACCURACY_HASH=QmZSkE49cnp3KeR9r6bp3hP4M2LPAmG4beHq4isz55ghv5
12801284

12811285
if [ -n "$SUBGRAPH_API_KEY" ]; then
12821286
export CONDITIONAL_TOKENS_SUBGRAPH_URL="https://gateway-arbitrum.network.thegraph.com/api/$SUBGRAPH_API_KEY/subgraphs/id/7s9rGBffUTL8kDZuxvvpuc46v44iuDarbrADBFw5uVp2"
@@ -1287,9 +1291,9 @@ if [ -n "$SUBGRAPH_API_KEY" ]; then
12871291
fi
12881292

12891293
service_dir="trader_service"
1290-
build_dir="abci_build"
1294+
directory=$(ls -d "$service_dir"/abci_build_???? 2>/dev/null || echo "$service_dir/abci_build")
1295+
build_dir=$(basename "$directory")
12911296
build_dir_k8s="abci_build_k8s"
1292-
directory="$service_dir/$build_dir"
12931297

12941298
if [ -d $directory ]
12951299
then
@@ -1329,19 +1333,28 @@ if [[ -d "$build_dir_k8s" ]]; then
13291333
echo "Directory removed: $build_dir"
13301334
fi
13311335
export OPEN_AUTONOMY_PRIVATE_KEY_PASSWORD="$password" && poetry run autonomy deploy build --kubernetes "../../$keys_json_path" --n $n_agents -ltm
1336+
build_dir=$(ls -d abci_build_???? 2>/dev/null || echo "abci_build")
13321337
mv $build_dir $build_dir_k8s
13331338
echo "Kubernetes deployment built on ./trader/$service_dir/$build_dir_k8s"
13341339

13351340
export OPEN_AUTONOMY_PRIVATE_KEY_PASSWORD="$password" && poetry run autonomy deploy build "../../$keys_json_path" --n $n_agents -ltm
1341+
build_dir=$(ls -d abci_build_???? 2>/dev/null || echo "abci_build")
13361342
echo "Docker Compose deployment built on ./trader/$service_dir/$build_dir"
13371343

13381344
cd ..
13391345

13401346
# warm start is disabled as no global weights are provided to calibrate the tools' weights
13411347
# warm_start
13421348

1343-
add_volume_to_service_docker_compose "$PWD/trader_service/abci_build/docker-compose.yaml" "trader_abci_0" "/data" "$path_to_store"
1344-
add_volume_to_service_k8s "$PWD/trader_service/abci_build_k8s/build.yaml"
1349+
directory="$service_dir/$build_dir"
1350+
if [ "$build_dir" = "abci_build" ]; then
1351+
suffix="abci_build"
1352+
else
1353+
suffix=${build_dir##*_}
1354+
fi
1355+
abci_0="trader${suffix}_abci_0"
1356+
add_volume_to_service_docker_compose "$PWD/$directory/docker-compose.yaml" "$abci_0" "/data" "$path_to_store"
1357+
add_volume_to_service_k8s "$PWD/$service_dir/$build_dir_k8s/build.yaml"
13451358
sudo chown -R $(whoami) "$path_to_store"
13461359

13471360
if [[ "$build_only" == true ]]; then

0 commit comments

Comments
 (0)