Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vandot committed Feb 12, 2021
0 parents commit 9b90e58
Show file tree
Hide file tree
Showing 11 changed files with 616 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/release.yaml
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 }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
45 changes: 45 additions & 0 deletions .goreleaser.yaml
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
33 changes: 33 additions & 0 deletions Dockerfile
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"]
22 changes: 22 additions & 0 deletions Dockerfile.goreleaser
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"]
54 changes: 54 additions & 0 deletions README.md
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
```
4 changes: 4 additions & 0 deletions data/addresses.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
etherdelta:0x8d12A197cB00D4747a1fe03395095ce2A5CC6819
bittrex:0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98
poloniex:0x32Be343B94f860124dC4fEe278FDCBD38C102D88
kraken:0x267be1c1d684f78cb4f6a176c4911b741e4ffdc0
168 changes: 168 additions & 0 deletions ethexporter/main.go
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))
}
5 changes: 5 additions & 0 deletions go.mod
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
Loading

0 comments on commit 9b90e58

Please sign in to comment.