github.com/sj-piano/go-ethereum@v1.9.7/metrics/disk_linux.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Contains the Linux implementation of process disk IO counter retrieval.
    18  
    19  package metrics
    20  
    21  import (
    22  	"bufio"
    23  	"fmt"
    24  	"io"
    25  	"os"
    26  	"strconv"
    27  	"strings"
    28  )
    29  
    30  // ReadDiskStats retrieves the disk IO stats belonging to the current process.
    31  func ReadDiskStats(stats *DiskStats) error {
    32  	// Open the process disk IO counter file
    33  	inf, err := os.Open(fmt.Sprintf("/proc/%d/io", os.Getpid()))
    34  	if err != nil {
    35  		return err
    36  	}
    37  	defer inf.Close()
    38  	in := bufio.NewReader(inf)
    39  
    40  	// Iterate over the IO counter, and extract what we need
    41  	for {
    42  		// Read the next line and split to key and value
    43  		line, err := in.ReadString('\n')
    44  		if err != nil {
    45  			if err == io.EOF {
    46  				return nil
    47  			}
    48  			return err
    49  		}
    50  		parts := strings.Split(line, ":")
    51  		if len(parts) != 2 {
    52  			continue
    53  		}
    54  		key := strings.TrimSpace(parts[0])
    55  		value, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64)
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		// Update the counter based on the key
    61  		switch key {
    62  		case "syscr":
    63  			stats.ReadCount = value
    64  		case "syscw":
    65  			stats.WriteCount = value
    66  		case "rchar":
    67  			stats.ReadBytes = value
    68  		case "wchar":
    69  			stats.WriteBytes = value
    70  		}
    71  	}
    72  }