forked from erigontech/erigon
-
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.
metrics: Add memory usage statistics to Prometheus (erigontech#9465)
### Prometheus preview ![image](https://github.com/ledgerwatch/erigon/assets/7486955/b720da11-71d1-4f81-8841-35c30e9a1348) --------- Co-authored-by: alex.sharov <AskAlexSharov@gmail.com>
- Loading branch information
1 parent
d7a73e0
commit 0d9a955
Showing
7 changed files
with
188 additions
and
2 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,28 @@ | ||
package diagnostics | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
|
||
"github.com/ledgerwatch/erigon-lib/common/mem" | ||
) | ||
|
||
func SetupMemAccess(metricsMux *http.ServeMux) { | ||
metricsMux.HandleFunc("/mem", func(w http.ResponseWriter, r *http.Request) { | ||
w.Header().Set("Access-Control-Allow-Origin", "*") | ||
w.Header().Set("Content-Type", "application/json") | ||
writeMem(w) | ||
}) | ||
} | ||
|
||
func writeMem(w http.ResponseWriter) { | ||
memStats, err := mem.ReadVirtualMemStats() | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
if err := json.NewEncoder(w).Encode(memStats); err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
} | ||
} |
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
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,19 @@ | ||
//go:build !linux | ||
|
||
package mem | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"github.com/ledgerwatch/log/v3" | ||
"github.com/shirou/gopsutil/v3/process" | ||
) | ||
|
||
func ReadVirtualMemStats() (process.MemoryMapsStat, error) { | ||
return process.MemoryMapsStat{}, errors.New("unsupported platform") | ||
} | ||
|
||
func UpdatePrometheusVirtualMemStats(p process.MemoryMapsStat) {} | ||
|
||
func LogVirtualMemStats(ctx context.Context, logger log.Logger) {} |
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,100 @@ | ||
//go:build linux | ||
|
||
package mem | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"reflect" | ||
"time" | ||
|
||
"github.com/ledgerwatch/log/v3" | ||
"github.com/shirou/gopsutil/v3/process" | ||
|
||
"github.com/ledgerwatch/erigon-lib/metrics" | ||
) | ||
|
||
type VirtualMemStat struct { | ||
process.MemoryMapsStat | ||
} | ||
|
||
// Fields converts VirtualMemStat to slice | ||
func (m VirtualMemStat) Fields() []interface{} { | ||
typ := reflect.TypeOf(m.MemoryMapsStat) | ||
val := reflect.ValueOf(m.MemoryMapsStat) | ||
|
||
var s []interface{} | ||
for i := 0; i < typ.NumField(); i++ { | ||
t := typ.Field(i).Name | ||
if t == "Path" { // always empty for aggregated smap statistics | ||
continue | ||
} | ||
|
||
s = append(s, t, val.Field(i).Interface()) | ||
} | ||
|
||
return s | ||
} | ||
|
||
var ( | ||
memRssGauge = metrics.NewGauge(`mem_rss`) | ||
memSizeGauge = metrics.NewGauge(`mem_size`) | ||
memPssGauge = metrics.NewGauge(`mem_pss`) | ||
memSharedCleanGauge = metrics.NewGauge(`mem_shared{type="clean"}`) | ||
memSharedDirtyGauge = metrics.NewGauge(`mem_shared{type="dirty"}`) | ||
memPrivateCleanGauge = metrics.NewGauge(`mem_private{type="clean"}`) | ||
memPrivateDirtyGauge = metrics.NewGauge(`mem_private{type="dirty"}`) | ||
memReferencedGauge = metrics.NewGauge(`mem_referenced`) | ||
memAnonymousGauge = metrics.NewGauge(`mem_anonymous`) | ||
memSwapGauge = metrics.NewGauge(`mem_swap`) | ||
) | ||
|
||
func ReadVirtualMemStats() (process.MemoryMapsStat, error) { | ||
pid := os.Getpid() | ||
proc, err := process.NewProcess(int32(pid)) | ||
if err != nil { | ||
return process.MemoryMapsStat{}, err | ||
} | ||
|
||
memoryMaps, err := proc.MemoryMaps(true) | ||
if err != nil { | ||
return process.MemoryMapsStat{}, err | ||
} | ||
|
||
return (*memoryMaps)[0], nil | ||
} | ||
|
||
func UpdatePrometheusVirtualMemStats(p process.MemoryMapsStat) { | ||
memRssGauge.SetUint64(p.Rss) | ||
memSizeGauge.SetUint64(p.Size) | ||
memPssGauge.SetUint64(p.Pss) | ||
memSharedCleanGauge.SetUint64(p.SharedClean) | ||
memSharedDirtyGauge.SetUint64(p.SharedDirty) | ||
memPrivateCleanGauge.SetUint64(p.PrivateClean) | ||
memPrivateDirtyGauge.SetUint64(p.PrivateDirty) | ||
memReferencedGauge.SetUint64(p.Referenced) | ||
memAnonymousGauge.SetUint64(p.Anonymous) | ||
memSwapGauge.SetUint64(p.Swap) | ||
} | ||
|
||
func LogVirtualMemStats(ctx context.Context, logger log.Logger) { | ||
logEvery := time.NewTicker(180 * time.Second) | ||
defer logEvery.Stop() | ||
|
||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
case <-logEvery.C: | ||
memStats, err := ReadVirtualMemStats() | ||
if err != nil { | ||
logger.Warn("[mem] error reading virtual memory stats", "err", err) | ||
continue | ||
} | ||
|
||
v := VirtualMemStat{memStats} | ||
logger.Info("[mem] virtual memory stats", v.Fields()...) | ||
UpdatePrometheusVirtualMemStats(memStats) | ||
} | ||
} | ||
} |
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
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
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