GenLayer Validator Systemd Config and Log Reporting

Currently for Asimov testnet validators, we follow the public documentation and the Google doc provided by GenLayer Foundation to setup the node. This post introduces two improvements for the setup:

  • configure the validator as a systemd service

  • create a cronjob that collects the validator service’s logs every week as we are required to submit them to the foundation

Validator Systemd Service

The last step mentioned in the documentation is Running the node, where we use the following command to start the validator service:

./bin/genlayernode run -c $(pwd)/configs/node/config.yaml --password "your secret password"

As a systemd service config is visible to all the users, we recommend saving this value into a .env file so that the permission can be restricted to the service user later on.

# create a .env file that holds the password and HEURISTKEY value required by Heurist mode
echo "GENLAYERNODE_PASS=<the_password>" >> ~/.env
echo "HEURISTKEY=<your_llm_provider_api_key>" >> ~/.env

# restrict the access of this file
chmod 600 ~/.env

Then we create a systemd service for the validator. Note that this should be done by a sudo user. In our setup, we have created a dedicated user genlayer to run the genlayernode service. You need to change the name in the service definition accordingly if this is not your case.

sudo vim /etc/systemd/system/genlayer-validator.service

[Unit]
Description=Genlayer Validator Node
After=network-online.target

[Service]
User=genlayer
WorkingDirectory=/home/genlayer/genlayer-node-linux-amd64
ExecStart=/bin/bash -c '/home/genlayer/genlayer-node-linux-amd64/bin/genlayernode run -c /home/genlayer/genlayer-node-linux-amd64/configs/node/config.yaml --password "$GENLAYERNODE_PASS"'
Restart=always
RestartSec=3
EnvironmentFile=/home/genlayer/.env

[Install]
WantedBy=multi-user.target

# reload the daemon and start the service
sudo systemctl daemon-reload
sudo systemctl enable --now genlayer-validator.service

Cronjob for Log Collection

As now the validator service is running as a systemd service, you can use journalctl to check the logs. For examples:

# show the latest 100 lines of logs and tail the new logs
sudo journalctl -n 100 -f -u genlayer-validator.service
# show today's logs
sudo journalctl --since="today" -u genlayer-validator.service
# show the logs from 2025-04-30 00:00:00 to 2025-05-06 23:59:59
sudo journalctl --since="2025-04-30" --until="2025-05-06" --no-pager -u genlayer-validator.service

As mentioned in the Google doc: “For the first few weeks please keep a copy of the stdout logs and send them once a week to the GenLayer Foundation until we have better tools for metrics and monitoring”. We can create a cronjob that exports the logs as a tar file so that we can easily scp and submit it.

Create a bash file with the following content, for example, vim ~/export-validator-logs.sh.

#!/bin/bash

# Configuration
SERVICE_NAME="genlayer-validator.service"
BASE_DIR="/tmp"
OWNER_AND_GROUP="root:root"

# Calculate date range (excluding today)
# xxx_ISO format is used for journalctl commands while the other pair is used for folder and tar file names
END_DAY_ISO=$(date -d "yesterday" +%Y-%m-%d)
START_DAY_ISO=$(date -d "$END_DAY_ISO - 6 days" +%Y-%m-%d)
END_DAY=$(date -d "yesterday" +%Y%m%d)
START_DAY=$(date -d "$END_DAY_ISO - 6 days" +%Y%m%d)

# Temporary directory for logs
TEMP_DIR="$BASE_DIR/validator-logs-$START_DAY-$END_DAY"

# Check if the temporary directory exists, and remove it if it does
if [ -d "$TEMP_DIR" ]; then
  echo "Removing existing temporary directory: $TEMP_DIR"
  rm -rf "$TEMP_DIR"
fi

# Create the temporary directory
mkdir -p "$TEMP_DIR"

# Extract the logs for each day (excluding today)
for ((i=0; i<=6; i++)); do
    LOG_DATE_ISO=$(date -d "$START_DAY_ISO + $i days" +%Y-%m-%d)
    journalctl -u "$SERVICE_NAME" --since "$LOG_DATE_ISO 00:00:00" --until "$LOG_DATE_ISO 23:59:59" > "$TEMP_DIR/$(date -d "$START_DAY + $i days" +%Y%m%d).log"
    if [ $? -ne 0 ]; then
        echo "Failed to extract logs for $LOG_DATE"
        exit 1
    fi
done

# Create a compressed tar file
TAR_FILE="$BASE_DIR/validator-logs-$START_DAY-$END_DAY.tar.gz"
tar -czf "$TAR_FILE" -C "$BASE_DIR" "validator-logs-$START_DAY-$END_DAY"

# Cleanup
if [ $? -eq 0 ]; then
    echo "Logs archived successfully: $TAR_FILE"
    chown -R $OWNER_AND_GROUP $TEMP_DIR
    chown $OWNER_AND_GROUP $TAR_FILE
    echo "Changing the generated files ownership to $OWNER_AND_GROUP"
else
    echo "Failed to create tar file"
    exit 1
fi

Change the mod of this script and then add it to the root user’s cronjob list (because journalctl requires sudo access).

chmod +x ~/export-validator-logs.sh
sudo cronjob -e

# execute the script at 01:00 on Friday, adjust the time if you need
0 1 * * 5 /absolute/path/to/export-validator-logs.sh

You can also run the script directly to generate the log collection tar file when you need:

sudo ./export-validator-logs.sh
# output:
Logs archived successfully: /home/genlayer/validator-logs-20250507-20250513.tar.gz
Changing the generated files ownership to genlayer:genlayer

ls validator*
# output:
validator-logs-20250507-20250513.tar.gz

validator-logs-20250507-20250513:
20250507.log  20250508.log  20250509.log  20250510.log  20250511.log  20250512.log  20250513.log