mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
cmd/keeper, cmd/utils, metrics: add zisk target using tamago
This commit is contained in:
parent
13d8df63f4
commit
60e0277eb4
18 changed files with 437 additions and 115 deletions
|
|
@ -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
|
||||
|
|
|
|||
70
build/ci.go
70
build/ci.go
|
|
@ -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,37 @@ func doInstallKeeper(cmdline []string) {
|
|||
flag.CommandLine.Parse(cmdline)
|
||||
env := build.Env()
|
||||
|
||||
// Configure the toolchain.
|
||||
var (
|
||||
csdb *download.ChecksumDB
|
||||
tamagoRoot string
|
||||
)
|
||||
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.Name == "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
|
||||
}
|
||||
|
||||
if tamagoRoot == "" {
|
||||
tamagoRoot = downloadTamago(csdb)
|
||||
}
|
||||
tc.Root = tamagoRoot
|
||||
} else if *dlgo {
|
||||
tc.Root = build.DownloadGo(csdb)
|
||||
}
|
||||
|
||||
// Configure the build.
|
||||
tc.GOARCH = target.GOARCH
|
||||
tc.GOOS = target.GOOS
|
||||
|
|
@ -463,6 +491,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, "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() {
|
||||
|
|
|
|||
3
cmd/keeper/dummy_fastcache/go.mod
Normal file
3
cmd/keeper/dummy_fastcache/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module github.com/ethereum/go-ethereum/cmd/keeper/dummy_fastcache
|
||||
|
||||
go 1.24.0
|
||||
13
cmd/keeper/dummy_fastcache/main.go
Normal file
13
cmd/keeper/dummy_fastcache/main.go
Normal 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{}
|
||||
}
|
||||
32
cmd/keeper/getpayload_zisk.go
Normal file
32
cmd/keeper/getpayload_zisk.go
Normal 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))
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -11,7 +11,6 @@ require (
|
|||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/VictoriaMetrics/fastcache v1.13.0 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.20.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/consensys/gnark-crypto v0.18.1 // indirect
|
||||
github.com/crate-crypto/go-eth-kzg v1.5.0 // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
|
||||
|
|
@ -45,3 +44,5 @@ require (
|
|||
)
|
||||
|
||||
replace github.com/ethereum/go-ethereum => ../../
|
||||
|
||||
replace github.com/VictoriaMetrics/fastcache => ./dummy_fastcache
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
24
cmd/keeper/tamago_board.go
Normal file
24
cmd/keeper/tamago_board.go
Normal 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
106
cmd/keeper/zisk/board.go
Normal 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()
|
||||
18
cmd/keeper/zisk/cpu_riscv64.s
Normal file
18
cmd/keeper/zisk/cpu_riscv64.s
Normal 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
17
cmd/keeper/zisk/hwinit1.s
Normal 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
|
||||
24
cmd/keeper/zisk/shutdown.s
Normal file
24
cmd/keeper/zisk/shutdown.s
Normal 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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
107
metrics/metrics_notamago.go
Normal 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
12
metrics/metrics_tamago.go
Normal 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) {
|
||||
}
|
||||
Loading…
Reference in a new issue