This commit is contained in:
Guillaume Ballet 2026-06-18 21:56:53 -07:00 committed by GitHub
commit 9dd4012141
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 436 additions and 117 deletions

View file

@ -49,6 +49,11 @@ ddc693d2d9d7cc671ebb72d1d50aa05670f95b059b7d90440611af57976871d5 go1.25.10.wind
ca37af2dadd8544464f1a9ca7c3886499d1cdfcb263855d0a1d71f194b2bd222 go1.25.10.windows-amd64.zip
38be57e0398bd93673d65bcae6dc7ee3cf151d7038d0dba5c60a5153022872da go1.25.10.windows-arm64.zip
# version:tamago 1.25.6
# https://github.com/usbarmory/tamago-go/releases/download/tamago-go1.25.6/
fbab70549e5977150d9095829608b5b8c7a6226930f91beb8edd614f2a71348e tamago-go1.25.6.linux-amd64.tar.gz
8bfc5a4f2ff54625c3a26a1b8749a6639d9f85dbd2f687c41c932517c0814368 tamago-go1.25.6.linux-armv7l.tar.gz
# version:golangci 2.10.1
# https://github.com/golangci/golangci-lint/releases/
# https://github.com/golangci/golangci-lint/releases/download/v2.10.1

View file

@ -101,6 +101,13 @@ var (
GOARCH: "wasm",
Tags: "womir",
},
{
Name: "zisk",
GOOS: "tamago",
GOARCH: "riscv64",
Tags: "tamago,zisk",
Env: map[string]string{"CGO_ENABLED": "0", "GO_EXTLINK_ENABLED": "0"},
},
{
Name: "wasm-js",
GOOS: "js",
@ -290,16 +297,31 @@ func doInstallKeeper(cmdline []string) {
flag.CommandLine.Parse(cmdline)
env := build.Env()
// Configure the toolchain.
var csdb *download.ChecksumDB
tc := build.GoToolchain{}
if *dlgo {
csdb := download.MustLoadChecksums("build/checksums.txt")
tc.Root = build.DownloadGo(csdb)
csdb = download.MustLoadChecksums("build/checksums.txt")
}
for _, target := range keeperTargets {
log.Printf("Building keeper-%s", target.Name)
// Configure the toolchain.
if target.GOOS == "tamago" {
if runtime.GOOS != "linux" {
log.Printf("Skipping keeper-%s (tamago builds are only supported on linux hosts)", target.Name)
continue
}
if !*dlgo {
log.Printf("Skipping keeper-%s (tamago build requires -dlgo)", target.Name)
continue
}
tc.Root = downloadTamago(csdb)
} else if *dlgo {
tc.Root = build.DownloadGo(csdb)
}
// Configure the build.
tc.GOARCH = target.GOARCH
tc.GOOS = target.GOOS
@ -338,12 +360,12 @@ func buildFlags(env build.Environment, staticLinking bool, buildTags []string, t
ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitCommit="+env.Commit)
ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitDate="+env.Date)
}
switch targetOS {
// Strip DWARF on darwin. This used to be required for certain things,
// and there is no downside to this, so we just keep doing it.
if targetOS == "darwin" {
case "darwin":
ld = append(ld, "-s")
}
if targetOS == "linux" {
case "linux":
// Enforce the stacksize to 8M, which is the case on most platforms apart from
// alpine Linux.
// See https://sourceware.org/binutils/docs-2.23.1/ld/Options.html#Options
@ -358,6 +380,8 @@ func buildFlags(env build.Environment, staticLinking bool, buildTags []string, t
buildTags = append(buildTags, "osusergo", "netgo")
}
ld = append(ld, "-extldflags", "'"+strings.Join(extld, " ")+"'")
case "tamago":
ld = append(ld, "-T", "0x80010000", "-R", "0x1000")
}
// TODO(gballet): revisit after the input api has been defined
if runtime.GOARCH == "wasm" {
@ -463,6 +487,42 @@ func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string
return filepath.Join(cachedir, base)
}
// downloadTamago downloads the tamago-go toolchain and returns its GOROOT.
func downloadTamago(csdb *download.ChecksumDB) string {
version, err := csdb.FindVersion("tamago")
if err != nil {
log.Fatal(err)
}
if runtime.GOOS != "linux" {
log.Printf("Skipping tamago toolchain download (unsupported host os: %s)", runtime.GOOS)
return ""
}
arch := runtime.GOARCH
if arch == "arm" {
arch = "armv7l"
}
file := fmt.Sprintf("tamago-go%s.%s-%s.tar.gz", version, runtime.GOOS, arch)
ucache, err := os.UserCacheDir()
if err != nil {
log.Fatal(err)
}
dst := filepath.Join(ucache, file)
if err := csdb.DownloadFileFromKnownURL(dst); err != nil {
log.Fatal(err)
}
toolRoot := filepath.Join(ucache, fmt.Sprintf("geth-tamago-go-%s-%s-%s", version, runtime.GOOS, arch))
if err := build.ExtractArchive(dst, toolRoot); err != nil {
log.Fatal(err)
}
goroot, err := filepath.Abs(filepath.Join(toolRoot, "usr/local/tamago-go"))
if err != nil {
log.Fatal(err)
}
return goroot
}
// doCheckGenerate ensures that re-generating generated files does not cause
// any mutations in the source file tree.
func doCheckGenerate() {

View file

@ -0,0 +1,3 @@
module github.com/ethereum/go-ethereum/cmd/keeper/dummy_fastcache
go 1.24.0

View file

@ -0,0 +1,13 @@
package fastcache
type Cache struct{}
func (*Cache) Get(dst, k []byte) []byte { return nil }
func (*Cache) HasGet(dst, k []byte) ([]byte, bool) { return nil, false }
func (*Cache) Set(k, v []byte) {}
func (*Cache) Reset() {}
func (*Cache) Del([]byte) {}
func New(int) *Cache {
return &Cache{}
}

View file

@ -0,0 +1,32 @@
// Copyright 2026 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build zisk
package main
import (
"unsafe"
"github.com/ethereum/go-ethereum/cmd/keeper/zisk"
)
func getInput() []byte {
inputPtr := unsafe.Pointer(uintptr(zisk.INPUT_ADDR + 8))
inputSize := *(*uint64)(inputPtr)
inputDataPtr := unsafe.Pointer(uintptr(zisk.INPUT_ADDR + 16))
return unsafe.Slice((*byte)(inputDataPtr), int(inputSize))
}

View file

@ -1,6 +1,6 @@
module github.com/ethereum/go-ethereum/cmd/keeper
go 1.24.0
go 1.25.6
require (
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6
@ -45,3 +45,5 @@ require (
)
replace github.com/ethereum/go-ethereum => ../../
replace github.com/VictoriaMetrics/fastcache => ./dummy_fastcache

View file

@ -4,10 +4,6 @@ github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0=
github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU=

View file

@ -14,8 +14,8 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build !example && !ziren && !wasm && !womir
// +build !example,!ziren,!wasm,!womir
//go:build !example && !ziren && !wasm && !womiri && !zisk
// +build !example,!ziren,!wasm,!womiri,!zisk
package main

View file

@ -0,0 +1,24 @@
// Copyright 2025 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build tamago
// +build tamago
package main
import (
_ "github.com/ethereum/go-ethereum/cmd/keeper/zisk"
)

106
cmd/keeper/zisk/board.go Normal file
View file

@ -0,0 +1,106 @@
// Copyright 2026 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build tamago && riscv64
package zisk
import (
"unsafe"
)
const (
// ZisK I/O addresses
INPUT_ADDR = 0x90000000
QEMU_EXIT_ADDR = 0x100000
QEMU_EXIT_CODE = 0x5555
OUTPUT_ADDR = 0xa001_0000
UART_ADDR = 0xa000_0200
ARCH_ID_ZISK = 0xFFFEEEE // TEMPORARY // TODO register one
MAX_INPUT = 0x2000
MAX_OUTPUT = 0x1_0000
)
var outputCount uint32 = 0
//go:linkname ramStart runtime.ramStart
var ramStart uint64 = 0xa0020000 // Match ZisK's RAM location
//go:linkname ramSize runtime.ramSize
var ramSize uint64 = 0x1FFE0000 // Match ZisK's RAM size (~512MB)
// ramStackOffset is always defined here as there's no linkramstackoffset build tag
//
//go:linkname ramStackOffset runtime.ramStackOffset
var ramStackOffset uint64 = 0x100000 // 1MB stack (matching ZisK)
// Bloc sets the heap start address to bypass initBloc()
//
//go:linkname Bloc runtime.Bloc
var Bloc uintptr = 0xa0100000 // Start heap after stack (ramStart + ramStackOffset)
// printk implementation for zkVM
//
//go:linkname printk runtime.printk
func printk(c byte) {
// TODO: This is a stub. Just write to the output address
// Write directly to OUTPUT_ADDR
// Format: [count:u32][data:bytes]
// First update the count at OUTPUT_ADDR
outputCount++
*(*uint32)(unsafe.Pointer(uintptr(OUTPUT_ADDR))) = outputCount
// Write the byte at OUTPUT_ADDR + 4 + (outputCount-1)
*(*byte)(unsafe.Pointer(uintptr(OUTPUT_ADDR + 4 + outputCount - 1))) = c
}
// hwinit1 is now defined in hwinit1.s
// we use it to set A0/A1 registers to the input and output address
// Use this as a stub timer. It is all single threaded, and there is no concept of time.
// This may return the cycle count in the future.
var timer int64 = 0
//go:linkname nanotime1 runtime.nanotime1
func nanotime1() int64 {
// Return deterministic time for zkVM
// Could be based on instruction count or fixed increments
timer++
return timer * 1000
}
//go:linkname initRNG runtime.initRNG
func initRNG() {
// Deterministic RNG initialization
// TODO: There is no "proper" rng so nothing to init.
}
//go:linkname getRandomData runtime.getRandomData
func getRandomData(b []byte) {
// Deterministic "random" data
// In a real zkVM, this might come from the input
for i := range b {
b[i] = byte(i & 0xFF)
}
}
// Init initializes the zkVM board
func Init() {
timer = 0
}
// Shutdown is defined in shutdown.s and uses ecall to exit
func Shutdown()

View file

@ -0,0 +1,18 @@
//go:build tamago && riscv64
#include "textflag.h"
// Entry point - this is where execution starts
TEXT cpuinit(SB),NOSPLIT|NOFRAME,$0
// Clear A0/A1 registers so runtime does not think we have
// argc/argv arguments
MOV $0, A0
MOV $0, A1
// Jump to tamago runtime for RISC-V
JMP runtime·rt0_riscv64_tamago(SB)
// hwinit0 is called by the runtime during initialization
TEXT runtime·hwinit0(SB),NOSPLIT|NOFRAME,$0
// Hardware initialization before runtime setup
// For zkVM, nothing special needed here
RET

17
cmd/keeper/zisk/hwinit1.s Normal file
View file

@ -0,0 +1,17 @@
//go:build tamago && riscv64
#include "textflag.h"
#define INPUT_ADDR 0x90000000
#define OUTPUT_ADDR 0xa0010000
// hwinit1 is called after basic runtime initialization
// We set A0/A1 here instead of in the emulator
TEXT runtime·hwinit1(SB),NOSPLIT|NOFRAME,$0
// Set A0 to INPUT_ADDR
MOV $INPUT_ADDR, A0
// Set A1 to OUTPUT_ADDR
MOV $OUTPUT_ADDR, A1
RET

View file

@ -0,0 +1,24 @@
//go:build tamago && riscv64 && zisk
#include "textflag.h"
#define ARCH_ID_ZISK 0xFFFEEEE
#define QEMU_EXIT_ADDR 0x100000
#define QEMU_EXIT_CODE 0x5555
// Shutdown triggers ZisK exit via ecall with a7=93
TEXT ·Shutdown(SB),NOSPLIT|NOFRAME,$0
// Read marchid CSR into A0 (CSRRS x10, 0xF12, x0)
WORD $0xF1202573
MOV $ARCH_ID_ZISK, A1 // Load ZisK arch ID
BNE A0, A1, qemu_exit // If not, jump to qemu_exit
MOV $93, A7 // CAUSE_EXIT = 93
ECALL // System call to exit
RET // Should never reach here
qemu_exit:
MOV $QEMU_EXIT_CODE, T0 // Load the exit code for QEMU
MOV $QEMU_EXIT_ADDR, T1 // Load the exit address for QEMU
ECALL // System call to exit QEMU
RET // Should never reach here

View file

@ -14,8 +14,8 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build !ios && !js && !wasip1 && !tinygo
// +build !ios,!js,!wasip1,!tinygo
//go:build !ios && !js && !wasip1 && !tinygo && !tamago
// +build !ios,!js,!wasip1,!tinygo,!tamago
package metrics

View file

@ -14,8 +14,8 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build !windows && !js && !wasip1 && !tinygo
// +build !windows,!js,!wasip1,!tinygo
//go:build !windows && !js && !wasip1 && !tinygo && !tamago
// +build !windows,!js,!wasip1,!tinygo,!tamago
package metrics

View file

@ -9,7 +9,6 @@ package metrics
import (
"runtime/metrics"
"runtime/pprof"
"time"
)
var (
@ -103,102 +102,3 @@ func readRuntimeStats(v *runtimeStats) {
}
}
}
// CollectProcessMetrics periodically collects various metrics about the running process.
func CollectProcessMetrics(refresh time.Duration) {
// Short circuit if the metrics system is disabled
if !metricsEnabled {
return
}
// Create the various data collectors
var (
cpustats = make([]CPUStats, 2)
diskstats = make([]DiskStats, 2)
rstats = make([]runtimeStats, 2)
)
// This scale factor is used for the runtime's time metrics. It's useful to convert to
// ns here because the runtime gives times in float seconds, but runtimeHistogram can
// only provide integers for the minimum and maximum values.
const secondsToNs = float64(time.Second)
// Define the various metrics to collect
var (
cpuSysLoad = GetOrRegisterGauge("system/cpu/sysload", DefaultRegistry)
cpuSysWait = GetOrRegisterGauge("system/cpu/syswait", DefaultRegistry)
cpuProcLoad = GetOrRegisterGauge("system/cpu/procload", DefaultRegistry)
cpuSysLoadTotal = GetOrRegisterCounterFloat64("system/cpu/sysload/total", DefaultRegistry)
cpuSysWaitTotal = GetOrRegisterCounterFloat64("system/cpu/syswait/total", DefaultRegistry)
cpuProcLoadTotal = GetOrRegisterCounterFloat64("system/cpu/procload/total", DefaultRegistry)
cpuThreads = GetOrRegisterGauge("system/cpu/threads", DefaultRegistry)
cpuGoroutines = GetOrRegisterGauge("system/cpu/goroutines", DefaultRegistry)
cpuSchedLatency = getOrRegisterRuntimeHistogram("system/cpu/schedlatency", secondsToNs, nil)
memPauses = getOrRegisterRuntimeHistogram("system/memory/pauses", secondsToNs, nil)
memAllocs = GetOrRegisterMeter("system/memory/allocs", DefaultRegistry)
memFrees = GetOrRegisterMeter("system/memory/frees", DefaultRegistry)
memTotal = GetOrRegisterGauge("system/memory/held", DefaultRegistry)
heapUsed = GetOrRegisterGauge("system/memory/used", DefaultRegistry)
heapObjects = GetOrRegisterGauge("system/memory/objects", DefaultRegistry)
diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry)
diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry)
diskReadBytesCounter = GetOrRegisterCounter("system/disk/readbytes", DefaultRegistry)
diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry)
diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry)
diskWriteBytesCounter = GetOrRegisterCounter("system/disk/writebytes", DefaultRegistry)
)
var lastCollectTime time.Time
// Iterate loading the different stats and updating the meters.
now, prev := 0, 1
for ; ; now, prev = prev, now {
// Gather CPU times.
ReadCPUStats(&cpustats[now])
collectTime := time.Now()
secondsSinceLastCollect := collectTime.Sub(lastCollectTime).Seconds()
lastCollectTime = collectTime
if secondsSinceLastCollect > 0 {
sysLoad := cpustats[now].GlobalTime - cpustats[prev].GlobalTime
sysWait := cpustats[now].GlobalWait - cpustats[prev].GlobalWait
procLoad := cpustats[now].LocalTime - cpustats[prev].LocalTime
// Convert to integer percentage.
cpuSysLoad.Update(int64(sysLoad / secondsSinceLastCollect * 100))
cpuSysWait.Update(int64(sysWait / secondsSinceLastCollect * 100))
cpuProcLoad.Update(int64(procLoad / secondsSinceLastCollect * 100))
// increment counters (ms)
cpuSysLoadTotal.Inc(sysLoad)
cpuSysWaitTotal.Inc(sysWait)
cpuProcLoadTotal.Inc(procLoad)
}
// Threads
cpuThreads.Update(int64(threadCreateProfile.Count()))
// Go runtime metrics
readRuntimeStats(&rstats[now])
cpuGoroutines.Update(int64(rstats[now].Goroutines))
cpuSchedLatency.update(rstats[now].SchedLatency)
memPauses.update(rstats[now].GCPauses)
memAllocs.Mark(int64(rstats[now].GCAllocBytes - rstats[prev].GCAllocBytes))
memFrees.Mark(int64(rstats[now].GCFreedBytes - rstats[prev].GCFreedBytes))
memTotal.Update(int64(rstats[now].MemTotal))
heapUsed.Update(int64(rstats[now].MemTotal - rstats[now].HeapUnused - rstats[now].HeapFree - rstats[now].HeapReleased))
heapObjects.Update(int64(rstats[now].HeapObjects))
// Disk
if ReadDiskStats(&diskstats[now]) == nil {
diskReads.Mark(diskstats[now].ReadCount - diskstats[prev].ReadCount)
diskReadBytes.Mark(diskstats[now].ReadBytes - diskstats[prev].ReadBytes)
diskWrites.Mark(diskstats[now].WriteCount - diskstats[prev].WriteCount)
diskWriteBytes.Mark(diskstats[now].WriteBytes - diskstats[prev].WriteBytes)
diskReadBytesCounter.Inc(diskstats[now].ReadBytes - diskstats[prev].ReadBytes)
diskWriteBytesCounter.Inc(diskstats[now].WriteBytes - diskstats[prev].WriteBytes)
}
time.Sleep(refresh)
}
}

107
metrics/metrics_notamago.go Normal file
View file

@ -0,0 +1,107 @@
//go:build !tamago
// +build !tamago
package metrics
import (
"time"
)
// CollectProcessMetrics periodically collects various metrics about the running process.
func CollectProcessMetrics(refresh time.Duration) {
// Short circuit if the metrics system is disabled
if !metricsEnabled {
return
}
// Create the various data collectors
var (
cpustats = make([]CPUStats, 2)
diskstats = make([]DiskStats, 2)
rstats = make([]runtimeStats, 2)
)
// This scale factor is used for the runtime's time metrics. It's useful to convert to
// ns here because the runtime gives times in float seconds, but runtimeHistogram can
// only provide integers for the minimum and maximum values.
const secondsToNs = float64(time.Second)
// Define the various metrics to collect
var (
cpuSysLoad = GetOrRegisterGauge("system/cpu/sysload", DefaultRegistry)
cpuSysWait = GetOrRegisterGauge("system/cpu/syswait", DefaultRegistry)
cpuProcLoad = GetOrRegisterGauge("system/cpu/procload", DefaultRegistry)
cpuSysLoadTotal = GetOrRegisterCounterFloat64("system/cpu/sysload/total", DefaultRegistry)
cpuSysWaitTotal = GetOrRegisterCounterFloat64("system/cpu/syswait/total", DefaultRegistry)
cpuProcLoadTotal = GetOrRegisterCounterFloat64("system/cpu/procload/total", DefaultRegistry)
cpuThreads = GetOrRegisterGauge("system/cpu/threads", DefaultRegistry)
cpuGoroutines = GetOrRegisterGauge("system/cpu/goroutines", DefaultRegistry)
cpuSchedLatency = getOrRegisterRuntimeHistogram("system/cpu/schedlatency", secondsToNs, nil)
memPauses = getOrRegisterRuntimeHistogram("system/memory/pauses", secondsToNs, nil)
memAllocs = GetOrRegisterMeter("system/memory/allocs", DefaultRegistry)
memFrees = GetOrRegisterMeter("system/memory/frees", DefaultRegistry)
memTotal = GetOrRegisterGauge("system/memory/held", DefaultRegistry)
heapUsed = GetOrRegisterGauge("system/memory/used", DefaultRegistry)
heapObjects = GetOrRegisterGauge("system/memory/objects", DefaultRegistry)
diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry)
diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry)
diskReadBytesCounter = GetOrRegisterCounter("system/disk/readbytes", DefaultRegistry)
diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry)
diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry)
diskWriteBytesCounter = GetOrRegisterCounter("system/disk/writebytes", DefaultRegistry)
)
var lastCollectTime time.Time
// Iterate loading the different stats and updating the meters.
now, prev := 0, 1
for ; ; now, prev = prev, now {
// Gather CPU times.
ReadCPUStats(&cpustats[now])
collectTime := time.Now()
secondsSinceLastCollect := collectTime.Sub(lastCollectTime).Seconds()
lastCollectTime = collectTime
if secondsSinceLastCollect > 0 {
sysLoad := cpustats[now].GlobalTime - cpustats[prev].GlobalTime
sysWait := cpustats[now].GlobalWait - cpustats[prev].GlobalWait
procLoad := cpustats[now].LocalTime - cpustats[prev].LocalTime
// Convert to integer percentage.
cpuSysLoad.Update(int64(sysLoad / secondsSinceLastCollect * 100))
cpuSysWait.Update(int64(sysWait / secondsSinceLastCollect * 100))
cpuProcLoad.Update(int64(procLoad / secondsSinceLastCollect * 100))
// increment counters (ms)
cpuSysLoadTotal.Inc(sysLoad)
cpuSysWaitTotal.Inc(sysWait)
cpuProcLoadTotal.Inc(procLoad)
}
// Threads
cpuThreads.Update(int64(threadCreateProfile.Count()))
// Go runtime metrics
readRuntimeStats(&rstats[now])
cpuGoroutines.Update(int64(rstats[now].Goroutines))
cpuSchedLatency.update(rstats[now].SchedLatency)
memPauses.update(rstats[now].GCPauses)
memAllocs.Mark(int64(rstats[now].GCAllocBytes - rstats[prev].GCAllocBytes))
memFrees.Mark(int64(rstats[now].GCFreedBytes - rstats[prev].GCFreedBytes))
memTotal.Update(int64(rstats[now].MemTotal))
heapUsed.Update(int64(rstats[now].MemTotal - rstats[now].HeapUnused - rstats[now].HeapFree - rstats[now].HeapReleased))
heapObjects.Update(int64(rstats[now].HeapObjects))
// Disk
if ReadDiskStats(&diskstats[now]) == nil {
diskReads.Mark(diskstats[now].ReadCount - diskstats[prev].ReadCount)
diskReadBytes.Mark(diskstats[now].ReadBytes - diskstats[prev].ReadBytes)
diskWrites.Mark(diskstats[now].WriteCount - diskstats[prev].WriteCount)
diskWriteBytes.Mark(diskstats[now].WriteBytes - diskstats[prev].WriteBytes)
diskReadBytesCounter.Inc(diskstats[now].ReadBytes - diskstats[prev].ReadBytes)
diskWriteBytesCounter.Inc(diskstats[now].WriteBytes - diskstats[prev].WriteBytes)
}
time.Sleep(refresh)
}
}

12
metrics/metrics_tamago.go Normal file
View file

@ -0,0 +1,12 @@
//go:build tamago
// +build tamago
package metrics
import (
"time"
)
// CollectProcessMetrics periodically collects various metrics about the running process.
func CollectProcessMetrics(time.Duration) {
}