Skip to content

orh4/server-stats-github-profile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

server-stats-github-profile

Display your homelab/server's statistics on your GitHub profile or repository!

I already have this script working on my own Github profile as a live demo of this repo, feel free to take a look! https://github.com/orh4

Example badges generated by this script:

CPU TEMP ENERGY RATE BATTERY PERCENTAGE UPTIME LATENCY

PREREQUISITES

  1. This script is Linux-only. It uses Linux-only paths (such as /sys/class/thermal/thermal_zone0) and commands (upower, etc.)
  2. You must have bash (version 4.0+), upower (for energy-rate and battery percentage), ping (for obtaining server latency from a specific ip), and git (for pushing stats to github). The rest are already bundled in most Linux server distributions.
  3. This updates your README via Github Actions and generating a fine-grained token for your specific repo.

ROADMAP / SUMMARY OF STEPS

  1. Install or check if you already have the required packages.
  2. Clone the repository.
  3. Clone your own profile's repository or the repository you want to use this script in.
  4. Move all of the contents from server-stats-github-repo into your chosen repository.
  5. Make a fine-grained token specifically for your repo (it is recommended to let it expire after 30 days) with read-write perms for contents and workflows.
  6. "git config credential.helper store", "git add .", and "git push origin main" to push all the changes in your chosen repo to the remote repo.
  7. Configuration of the "config.env" (optional), the script, the workflow, and the README template.
  8. Verification of the script and the GitHub Actions workflow.
  9. Automating the script via cron.

SECTIONS

INSTALLATION

STEP 0: (required packages)

If you don't already have the required packages installed, or if you want to check, run:

On Ubuntu/Debian:

sudo apt update
sudo apt install upower iputils-ping git

On Arch:

sudo pacman -S upower iputils git

STEP 1: (cloning this repository)

Clone this repository onto your server by running:

git clone https://github.com/orh4/server-stats-github-profile.git
cd server-stats-github-profile

STEP 2: (cloning your desired repository)

Clone your profile's repository or your desired repository onto your server by runnning:

git clone https://github.com/YOURUSERNAME/YOURUSERNAME

OR

git clone https://github.com/YOURUSERNAME/yourdesiredrepo

Create your profile's repository if you haven't already by creating a repository with your GitHub username and a README.

Make sure you also own the repository you plan to use this script in.

STEP 3: (moving the contents from this repo to your repo)

Copy the contents from this repo (server-stats-github-profile) into your cloned profile's repository (or your desired repo) by running:

cp -r server-stats-github-profile/* your-repo/

STEP 4: (making a fine-grained token)

To create a fine-grained token go to:

On GitHub go to: Settings > Developer Settings (scroll down) > Personal Access Tokens > Fine-grained tokens > Generate new token

For the configuration, select:

Name: whatever your want (preferably something like "profile" or your repository's name.)
Resource owner: (yourself)
Expiration: 30 days (it is recommended to keep it this way for security purposes.)
Repository access: Only select repositories > Select your repository
Permissions: Contents - Access: Read and write, Workflows -  Access: Read and write (GitHub won't let you push all the contents since it has a workflow included in them.)

Then generate the token.

Now, copy the token and keep it safe as you will be unable to view it again once you close the tab.

STEP 5: (pushing changes + setting up a bot account)

Now, you have to push the changes made to your repository. I would recommend creating a bot account on GitHub to carry out the automated commits.

Since the script automatically runs every set amount of time (via cron), if you were to push these automated commits under your own username, it would spike up your contribution graph. It would be messy and honestly even a bit dishonest if you let this script farm commmits on your account. I highly recommend creating a seperate GitHub bot account to carry out the automated commits for transparency and separating human commits from automated commits.

You should create the bot account (preferrably with a username like "yourusername-bot") and add it as a Collaborator by going to your repository and going to Settings > Collaborators > Add people.

To push the changes made to your profile's repository (or your desired repository) run:

git config credential.helper store
git add .
git push origin main

Then enter your bot account's username and your fine-grained token.

If git push origin main fails with a 403 error (not authorised), check your fine-grained token and make sure "Workflows" with "Read and write" permissions were included. If not, delete the fine-grained token and generate a new one with read-write permissions for Contents and Workflows.

STEP 6: (configuration)

You have been given a "config.env" file. cd into your repository's folder and open it in your desired text editor (nano, nvim, vim, etc.)

There currently 12 static environment variables you can configure in the given "config.env" file.

For Network:

PING_IP (The IP which the script pings to get the avaerage latency from.) (eg. 8.8.8.8, google.com, your router's ip, etc.)
PING_WAIT_TIME (The time the script takes  between each ping) (in seconds)
PING_COUNT (How many times the script will ping the given IP) (in integers)

For File Paths:

REPO_PATH (Path to your profile's or your desired repo.)
JSON_PATH (The path to the output JSON file along with it's name.) (It is recommended to keep the output JSON's name as "stats.json" as any other name would break the script without changes.)
BADGES_JSON_PATH (Same thing as "JSON_PATH", just keep it the same.)

For Debug Messages:

UPTIME_GET_MSG
CPU_TEMP_GET_MSG
BATTERY_PERCENTAGE_GET_MSG
BATTERY_TIME_LEFT_MSG
ENERGY_RATE_GET_MSG
PING_GET_MSG

Self explanatory.

You don't have to use the "config.env" if you don't want to. The script is simple and structured well enough to where configuring values should be easy.

You can comment out the statistics you don't want to collect (such as battery percentage and battery time left) like so:

# echo $BATTERY_PERCENTAGE_GET_MSG
# BATTERY_PERCENTAGE=$(upower -b | awk '/percentage/ {print $2}')

# echo $BATTERY_TIME_LEFT_MSG
# BATTERY_TIME_LEFT=$(upower -b | awk '/time to empty/ {print $4}')

In the case where there is no "config.env" file (presumably because you deleted it), the script will just default to the values configured within itself.

GitHub Actions workflow (optional)

You can edit the workflow given in this repository (named "update-readme.yml") by going to .github/workflows in your repository.

You can edit the cron config under "on:" and then "schedule:"

You can also remove the values you don't use under the huge "run:" block in "steps:" by the removing the variables (eg. ENERGY_RATE) and the sed commands (eg. sed -i "s|__ENERGY_RATE__|$ENERGY_RATE|g" README.md and sed -i "s|__BADGES_ENERGY_RATE__|$BADGES_ENERGY_RATE|g" README.md)

The README template

This is where you will display your server's stats.

In your repository, there should now be a file named "template.md", open it in your preferred text editor on your server or you can even edit it on GitHub as well.

You have already been provided a sample template with a table, values, and badges.

To configure where the stats will be shown on your README, you have to edit the "template.md" and add the placeholder values for each of your desired values.

The names of these placeholder values follows a similar pattern. They just take the name of their respective variables with just two underscores at the start and end (like __UPTIME__.)

For standard values (in plain text):

__LAST_UPDATED__ (time when the values were taken.)
__CPU_TEMP__ (for CPU temperature.)
__ENERGY_RATE__ (for energy-rate, only works when there is a battery connected.)
__BATTERY_PERCENTAGE__ (current battery percentage, doesn't work when there is no battery.)
__BATTERY_TIME_LEFT__ (the battery time left.)
__UPTIME__ (how long the server has been up.)
__LATENCY__ (the average latency from the configured ip.)

format: __VARIABLE_NAME__

For URL-friendly values (used in badges):

__BADGES_LAST_UPDATED__ (time when the values were taken.)
__BADGES_CPU_TEMP__ (for CPU temperature.)
__BADGES_ENERGY_RATE__ (for energy-rate, only works when there is a battery connected.)
__BADGES_BATTERY_PERCENTAGE__ (current battery percentage, doesn't work when there is no battery.)
__BADGES_BATTERY_TIME_LEFT__ (the battery time left.)
__BADGES_UPTIME__ (how long the server has been up.)
__BADGES_LATENCY__ (the average latency from the configured ip.)

format: __BADGES_VARIABLE_NAME__

An example template would be:

My homelab's current stats (updated every 30 minutes):
- LAST UPDATED: __LAST_UPDATED__

UPTIME: __UPTIME__
LATENCY: __LATENCY__
CPU TEMPERATURE: __CPU_TEMP__

![CPU TEMP](https://img.shields.io/badge/CPU%20TEMP-__BADGES_CPU_TEMP__-blue)
![LATENCY](https://img.shields.io/badge/LATENCY-__BADGES_LATENCY__-orange)
![UPTIME](https://img.shields.io/badge/UPTIME-__BADGES_UPTIME__-white)

You can check out my profile as well! I have this script working on my profile's repository and README already.

STEP 7: (verification and github actions)

On GitHub, verify that the files were pushed to your profile's repository (or your desired repo) by navigating over to the repository's page.

When on your repository's page, go to the "GitHub Actions" page and keep it open.

On your server, navigate to your cloned repository's folder by running:

cd ~/your-repo

Then run your script:

chmod +x script.sh
./script.sh

Read the output and check for any errors. There is a troubleshooting guide on the bottom of this README if you need help.

Then, on GitHub, first verify if the script's commit pushed the changes to your repository and then go back to the "GitHub Actions" page.

On the "GitHub Actions" pages, click on the "README updater" workflow (on the left side) and click "Run workflow". It should be running without any errors.

Now, check your repository's README. It should automatically change the values from the template you configured into the actual collected statistics from your server after a few seconds (just keep refreshing the page.)

STEP 8: (automation)

To ensure the script automatically runs without your input, run:

crontab -e

Select the text editor you prefer (you can use nano if you want.)

Then when you are in the file add:

*/30 * * * * $HOME/your-repo/script.sh

To the run the script every 30 minutes.

If you want to change the timing, you should follow this cron syntax:

EXAMPLE: */30 * * * * $HOME/yourusername/script.sh

Every 15 minutes: */15 * * * * $HOME/yourusername/script.sh
Every the start of every hour (eg. 3:00, 4:00, 5:00, etc.): 0 * * * * $HOME/yourusername/script.sh

You can search up cron syntax online. I recommend checking out: https://crontab.guru

Congrats! The script now automatically updates your README with your server's statistics!

TROUBLESHOOTING / Q&A

"When running the script, some values are NIl/NULL."

NULL means the variable itself doesn't exist (presumably because you commented it out) and NIL means no value was able to be obtained. For LATENCY, try changing the IP to a working one (such as 8.8.8.8 or google.com), if the problem persists, check if your server has internet connectivity issues. For other values, such as battery-related ones you may not the actual hardware installed on your server, or upower was unable to get the values, which may indicate issues beyond just "the script not working". Some paths are hardcoded, such as "/sys/class/thermal/thermal_zone0/temp" for CPU temperature which I admit, is not good practice, it should work regardless, but if you do run into issues, run ls /sys/class/thermal/ and find the thermal zones available on your server.

"Some variables are UNDEFINED."

That just indicates the variables you have commented out. Nothing to worry about.

"I am getting messages in my GitHub inbox regarding failed GitHub actions."

The GitHub workflow provided in this repository automatically runs every 15 minutes as a failsafe if it doesn't run when the script pushes out a commit. Most of the time, the README is already updated, and the "stats.json" hasn't changed, so it fails because there are no changed values or placeholder values to replace. You can modify the "README updater" workflow by going to .github/workflows and editing the "update-readme.yml" in your preferred text editor. Under "on:" and then under "schedule:" you can edit the cron config to whatever you like.

"My README doesn't automatically update."

Check your cron config by running crontab -e and check whether your script is mentioned there and make sure it's correct path is given.

REGARDING THIS PROJECT

This script, as stated at the top, is currently Linux-only. My target audience is for Linux communities and hasn't changed. I am open to anyone providing ports of this script to Windows (WSL) or MacOS, but it is not my priority or main focus regarding this project.

Of course, improvements and suggestions are valuable to me, and I will take all of them into consideration. I am to open any and all discussion regarding this project.

Why did I start this project? Well, I wanted to view my server's basic statistics and monitor it while on the go, such as at school. I would normally use tailscale, but that was being blocked by my school's WiFi, so I thought about using GitHub as a work-around (GitHub is also being blocked on school's WiFi, anyways). I also wanted to learn a bit of shell, I have been using Linux for a while now and I wanted to test my competence a bit. I technically made this script in two days after reading shell documentation and reading about shell syntax, but I finished this project in about 2 weeks because of fine-tuning, polishing, documentaion, better and more error-handling, school, and etc. This script is still not perfect, but it works and I have done my best to make it easy to understand and configure.

I also made this project as a fun way to show off your homelab on your GitHub profile. You can show that you run a homelab and you can do automation, which is a win-win in my opinion. The script only collects basic statistics, which shouldn't be a problem or a security risk displaying them online.

PLANS / TO-DO:

  1. Convert the variable stats into functions. (not a requirement, maybe a bit of over-engineering.) (LOW-MEDIUM PRIORITY)
  2. Possibly add more stats (although I am already happy with how it is already.) (LOW PRIORITY)
  3. Make an install script (The script is pretty simple and configuration should be easy, but a simple installation script wouldn't hurt.) (MEDIUM PRIORITY)