-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9b90e58
Showing
11 changed files
with
616 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Release | ||
|
||
on: | ||
push: | ||
branches-ignore: | ||
- '**' | ||
tags: | ||
- 'v*.*.*' | ||
|
||
jobs: | ||
goreleaser: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Setup Go | ||
uses: actions/setup-go@v1 | ||
with: | ||
go-version: 1.15 | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
- name: Docker Login | ||
if: success() && startsWith(github.ref, 'refs/tags/v') | ||
env: | ||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | ||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} | ||
run: | | ||
echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin | ||
- name: Run GoReleaser | ||
uses: goreleaser/goreleaser-action@v2 | ||
with: | ||
version: latest | ||
args: release --rm-dist | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
project_name: ethexporter | ||
|
||
builds: | ||
- id: linux-amd64 | ||
main: ./ethexporter | ||
binary: ethexporter | ||
goos: | ||
- linux | ||
goarch: | ||
- amd64 | ||
flags: | ||
- -v | ||
- -trimpath | ||
ldflags: | ||
- -s -w | ||
|
||
snapshot: | ||
name_template: "{{.Tag}}-snapshot" | ||
|
||
archives: | ||
- name_template: "{{ tolower .ProjectName }}-{{ tolower .Os }}-{{ tolower .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" | ||
format: binary | ||
|
||
dockers: | ||
- | ||
binaries: | ||
- ethexporter | ||
builds: | ||
- linux-amd64 | ||
goos: "linux" | ||
goarch: "amd64" | ||
image_templates: | ||
- "ethersphere/ethexporter:{{ .Major }}" | ||
- "ethersphere/ethexporter:{{ .Major }}.{{ .Minor }}" | ||
- "ethersphere/ethexporter:{{ .Major }}.{{ .Minor }}.{{ .Patch }}" | ||
- "ethersphere/ethexporter:latest" | ||
dockerfile: Dockerfile.goreleaser | ||
build_flag_templates: | ||
- "--pull" | ||
- "--label=org.opencontainers.image.created={{.Date}}" | ||
- "--label=org.opencontainers.image.title={{.ProjectName}}" | ||
- "--label=org.opencontainers.image.revision={{.FullCommit}}" | ||
- "--label=org.opencontainers.image.version={{.Version}}" | ||
extra_files: | ||
- data/addresses.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
FROM golang:1.15 AS build | ||
|
||
WORKDIR /src | ||
# enable modules caching in separate layer | ||
COPY go.mod go.sum ./ | ||
RUN go mod download | ||
|
||
COPY . ./ | ||
|
||
RUN go build -trimpath -ldflags "-s -w" -o dist/ethexporter ./ethexporter | ||
|
||
FROM debian:10.2-slim AS runtime | ||
|
||
ENV PORT 9890 | ||
ENV DATA /app | ||
|
||
RUN mkdir -p /app && chown nobody:nogroup /app | ||
|
||
ENV DEBIAN_FRONTEND noninteractive | ||
|
||
RUN apt-get update && apt-get install -y \ | ||
ca-certificates; \ | ||
apt-get clean; \ | ||
rm -rf /var/lib/apt/lists/*; | ||
|
||
COPY --from=build /src/dist/ethexporter /usr/local/bin/ethexporter | ||
COPY data/addresses.txt /app/addresses.txt | ||
|
||
USER nobody | ||
VOLUME /app | ||
WORKDIR /app | ||
|
||
ENTRYPOINT ["ethexporter"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
FROM debian:10.2-slim | ||
|
||
ENV PORT 9890 | ||
ENV DATA /app | ||
|
||
RUN mkdir -p /app && chown nobody:nogroup /app | ||
|
||
ENV DEBIAN_FRONTEND noninteractive | ||
|
||
RUN apt-get update && apt-get install -y \ | ||
ca-certificates; \ | ||
apt-get clean; \ | ||
rm -rf /var/lib/apt/lists/*; | ||
|
||
COPY ethexporter /usr/local/bin/ethexporter | ||
COPY ./data/addresses.txt /app/addresses.txt | ||
|
||
USER nobody | ||
VOLUME /app | ||
WORKDIR /app | ||
|
||
ENTRYPOINT ["ethexporter"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# ETHexporter | ||
|
||
This project is a fork from [hunterlong/ethexporter](https://github.com/hunterlong/ethexporter) | ||
|
||
A lightweight Prometheus exporter and [Grafana Dashboard](https://grafana.com/dashboards/6970) that will output Ethereum wallet balances from a list of addresses you specify. ETHexporter attaches to a geth server to fetch ethereum wallet balances for your Grafana dashboards. You can also use [TOKENexporter](https://github.com/hunterlong/tokenexporter) for ERC20 token balances. | ||
|
||
## watch addresses | ||
The `addresses.txt` file holds all the addresses to fetch balances for. Use the format `name:address` on each new line. | ||
``` | ||
etherdelta:0x8d12A197cB00D4747a1fe03395095ce2A5CC6819 | ||
bittrex:0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98 | ||
``` | ||
|
||
## grafana dashboard | ||
ETHexporter includes a [Grafana Dashboard](https://grafana.com/dashboards/6970) so you visualize Ethereum wallet balances with ease. Import Grafana Dashboard ID: `6970` once you've started your | ||
Docker container. | ||
|
||
<p align="center"><img width="70%" src="https://img.cjx.io/ethexportergrafana.png"></p> | ||
|
||
## build docker image | ||
Clone this repo and then follow the simple steps below! | ||
|
||
### build docker image | ||
`docker build -t ethexporter:latest .` | ||
|
||
### run ethexporter | ||
You'll need access to an ethereum Geth server to fetch balances. You can use [Infura.io](https://infura.io/setup) or [Slock.it](https://rpc.slock.it/). | ||
``` | ||
docker run -d -p 9890:9890 \ | ||
-e GETH="https://rpc.slock.it/mainnet" \ | ||
ethersphere/ethexporter:latest | ||
``` | ||
|
||
## pull from dockerhub | ||
Create a `addresses.txt` file with the correct format mentioned above. | ||
``` | ||
docker run -d -v $(pwd)/addresses.txt:/app/addresses.txt \ | ||
-p 9890:9890 \ | ||
-e GETH=https://rpc.slock.it/goerli \ | ||
ethersphere/ethexporter:latest | ||
``` | ||
The Docker image should be running with the default addresses. | ||
|
||
## /metrics response | ||
``` | ||
eth_balance{name="etherdelta",address="0x8d12A197cB00D4747a1fe03395095ce2A5CC6819"} 24919.37437 | ||
eth_balance{name="bittrex",address="0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98"} 687509.5097 | ||
eth_balance{name="poloniex",address="0x32Be343B94f860124dC4fEe278FDCBD38C102D88"} 72284.47401 | ||
eth_balance{name="kraken",address="0x267be1c1d684f78cb4f6a176c4911b741e4ffdc0"} 159592.0022 | ||
eth_balance_total 944305.360280000022612512 | ||
eth_load_seconds 1.15 | ||
eth_loaded_addresses 4 | ||
eth_total_addresses 4 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
etherdelta:0x8d12A197cB00D4747a1fe03395095ce2A5CC6819 | ||
bittrex:0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98 | ||
poloniex:0x32Be343B94f860124dC4fEe278FDCBD38C102D88 | ||
kraken:0x267be1c1d684f78cb4f6a176c4911b741e4ffdc0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"context" | ||
"fmt" | ||
"math/big" | ||
"net/http" | ||
"os" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/ethclient" | ||
) | ||
|
||
var ( | ||
allWatching []*Watching | ||
data string | ||
port string | ||
updates string | ||
prefix string | ||
interval int | ||
loadSeconds float64 | ||
totalLoaded int64 | ||
eth *ethclient.Client | ||
) | ||
|
||
type Watching struct { | ||
Name string | ||
Address string | ||
Balance string | ||
} | ||
|
||
// | ||
// Connect to geth server | ||
func ConnectionToGeth(url string) error { | ||
var err error | ||
eth, err = ethclient.Dial(url) | ||
return err | ||
} | ||
|
||
// | ||
// Fetch ETH balance from Geth server | ||
func GetEthBalance(address string) *big.Float { | ||
balance, err := eth.BalanceAt(context.TODO(), common.HexToAddress(address), nil) | ||
if err != nil { | ||
fmt.Printf("Error fetching ETH Balance for address: %v\n", address) | ||
} | ||
return ToEther(balance) | ||
} | ||
|
||
// | ||
// Fetch ETH balance from Geth server | ||
func CurrentBlock() uint64 { | ||
block, err := eth.BlockByNumber(context.TODO(), nil) | ||
if err != nil { | ||
fmt.Printf("Error fetching current block height: %v\n", err) | ||
return 0 | ||
} | ||
return block.NumberU64() | ||
} | ||
|
||
// | ||
// CONVERTS WEI TO ETH | ||
func ToEther(o *big.Int) *big.Float { | ||
pul, int := big.NewFloat(0), big.NewFloat(0) | ||
int.SetInt(o) | ||
pul.Mul(big.NewFloat(0.000000000000000001), int) | ||
return pul | ||
} | ||
|
||
// | ||
// HTTP response handler for /metrics | ||
func MetricsHttp(w http.ResponseWriter, r *http.Request) { | ||
var allOut []string | ||
total := big.NewFloat(0) | ||
for _, v := range allWatching { | ||
if v.Balance == "" { | ||
v.Balance = "0" | ||
} | ||
bal := big.NewFloat(0) | ||
bal.SetString(v.Balance) | ||
total.Add(total, bal) | ||
allOut = append(allOut, fmt.Sprintf("%veth_balance{name=\"%v\",address=\"%v\"} %v", prefix, v.Name, v.Address, v.Balance)) | ||
} | ||
allOut = append(allOut, fmt.Sprintf("%veth_balance_total %0.18f", prefix, total)) | ||
allOut = append(allOut, fmt.Sprintf("%veth_load_seconds %0.2f", prefix, loadSeconds)) | ||
allOut = append(allOut, fmt.Sprintf("%veth_loaded_addresses %v", prefix, totalLoaded)) | ||
allOut = append(allOut, fmt.Sprintf("%veth_total_addresses %v", prefix, len(allWatching))) | ||
fmt.Fprintln(w, strings.Join(allOut, "\n")) | ||
} | ||
|
||
// | ||
// Open the addresses.txt file (name:address) | ||
func OpenAddresses(filename string) error { | ||
file, err := os.Open(filename) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
object := strings.Split(scanner.Text(), ":") | ||
if common.IsHexAddress(object[1]) { | ||
w := &Watching{ | ||
Name: object[0], | ||
Address: object[1], | ||
} | ||
allWatching = append(allWatching, w) | ||
} | ||
} | ||
if err := scanner.Err(); err != nil { | ||
return err | ||
} | ||
return err | ||
} | ||
|
||
func main() { | ||
gethUrl := os.Getenv("GETH") | ||
port = os.Getenv("PORT") | ||
if port == "" { | ||
port = "9890" | ||
} | ||
data = os.Getenv("DATA") | ||
if data == "" { | ||
data = "." | ||
} | ||
interval, _ = strconv.Atoi(os.Getenv("INTERVAL")) | ||
if interval == 0 { | ||
interval = 15 | ||
} | ||
prefix = os.Getenv("PREFIX") | ||
|
||
err := OpenAddresses(data + "/addresses.txt") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
err = ConnectionToGeth(gethUrl) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// check address balances | ||
go func() { | ||
for { | ||
totalLoaded = 0 | ||
t1 := time.Now() | ||
fmt.Printf("Checking %v wallets...\n", len(allWatching)) | ||
for _, v := range allWatching { | ||
v.Balance = GetEthBalance(v.Address).String() | ||
totalLoaded++ | ||
} | ||
t2 := time.Now() | ||
loadSeconds = t2.Sub(t1).Seconds() | ||
fmt.Printf("Finished checking %v wallets in %0.0f seconds, sleeping for %v seconds.\n", len(allWatching), loadSeconds, 15) | ||
time.Sleep(time.Duration(interval) * time.Second) | ||
} | ||
}() | ||
|
||
block := CurrentBlock() | ||
|
||
fmt.Printf("ETHexporter has started on port %v using Geth server: %v at block #%v\n", port, gethUrl, block) | ||
http.HandleFunc("/metrics", MetricsHttp) | ||
panic(http.ListenAndServe("0.0.0.0:"+port, nil)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/ethersphere/ethexporter | ||
|
||
go 1.14 | ||
|
||
require github.com/ethereum/go-ethereum v1.9.25 |
Oops, something went wrong.