Repository: prometheus/procfs
Pull request #162 (2019-05-21 17:04:21)

Refactor toplevel functions
See issue #44 

pgier: @discordianfish Does this look ok to you?
pgier: Rabased and cleaned up the commits.

Patch:
diff --git a/README.md b/README.md
index 951c043..a89bdef 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,13 @@ fs, err := procfs.NewFS("/proc")
 stats, err := fs.NewStat()
 ```
 
+Some sub-packages such as `blockdevice`, require access to both the proc and sys filesystems.
+
+```go
+    fs, err := blockdevice.NewFS("/proc", "/sys")
+    stats, err := fs.ProcDiskstats()
+```
+
 ## Building and Testing
 
 The procfs library is normally built as part of another application.  However, when making
@@ -30,7 +37,7 @@ changes to the library, the `make test` command can be used to run the API test
 ### Updating Test Fixtures
 
 The procfs library includes a set of test fixtures which include many example files from
-the `/proc` and `/sys` filesystems.  These fixtures are included as a ttar (text tar) file
+the `/proc` and `/sys` filesystems.  These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file
 which is extracted automatically during testing.  To add/update the test fixtures, first
 ensure the `fixtures` directory is up to date by removing the existing directory and then
 extracting the ttar file using `make fixtures/.unpacked` or just `make test`.
diff --git a/bcache/get.go b/bcache/get.go
index 8d404bd..a8896bd 100644
--- a/bcache/get.go
+++ b/bcache/get.go
@@ -32,6 +32,12 @@ type FS struct {
 	sys *fs.FS
 }
 
+// NewDefaultFS returns a new Bcache using the default sys fs mount point. It will error
+// if the mount point can't be read.
+func NewDefaultFS() (FS, error) {
+	return NewFS(fs.DefaultSysMountPoint)
+}
+
 // NewFS returns a new Bcache using the given sys fs mount point. It will error
 // if the mount point can't be read.
 func NewFS(mountPoint string) (FS, error) {
diff --git a/blockdevice/stats.go b/blockdevice/stats.go
index 2e8e124..c8735cc 100644
--- a/blockdevice/stats.go
+++ b/blockdevice/stats.go
@@ -95,6 +95,12 @@ type FS struct {
 	sys  *fs.FS
 }
 
+// NewDefaultFS returns a new blockdevice fs using the default mountPoints for proc and sys.
+// It will error if either of these mount points can't be read.
+func NewDefaultFS() (FS, error) {
+	return NewFS(fs.DefaultProcMountPoint, fs.DefaultSysMountPoint)
+}
+
 // NewFS returns a new blockdevice fs using the given mountPoints for proc and sys.
 // It will error if either of these mount points can't be read.
 func NewFS(procMountPoint string, sysMountPoint string) (FS, error) {
diff --git a/buddyinfo.go b/buddyinfo.go
index 5cd22a8..63d4229 100644
--- a/buddyinfo.go
+++ b/buddyinfo.go
@@ -31,18 +31,8 @@ type BuddyInfo struct {
 	Sizes []float64
 }
 
-// NewBuddyInfo reads the buddyinfo statistics.
-func NewBuddyInfo() ([]BuddyInfo, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return fs.NewBuddyInfo()
-}
-
 // NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
-func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
+func (fs FS) BuddyInfo() ([]BuddyInfo, error) {
 	file, err := os.Open(fs.proc.Path("buddyinfo"))
 	if err != nil {
 		return nil, err
diff --git a/fs.go b/fs.go
index 5b4a1f0..0102ab0 100644
--- a/fs.go
+++ b/fs.go
@@ -26,6 +26,12 @@ type FS struct {
 // DefaultMountPoint is the common mount point of the proc filesystem.
 const DefaultMountPoint = fs.DefaultProcMountPoint
 
+// NewDefaultFS returns a new proc FS mounted under the default proc mountPoint.
+// It will error if the mount point directory can't be read or is a file.
+func NewDefaultFS() (FS, error) {
+	return NewFS(DefaultMountPoint)
+}
+
 // NewFS returns a new proc FS mounted under the given proc mountPoint. It will error
 // if the mount point directory can't be read or is a file.
 func NewFS(mountPoint string) (FS, error) {
diff --git a/ipvs.go b/ipvs.go
index 41e645d..2d6cb8d 100644
--- a/ipvs.go
+++ b/ipvs.go
@@ -62,18 +62,8 @@ type IPVSBackendStatus struct {
 	Weight uint64
 }
 
-// NewIPVSStats reads the IPVS statistics.
-func NewIPVSStats() (IPVSStats, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-
-	return fs.NewIPVSStats()
-}
-
-// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
-func (fs FS) NewIPVSStats() (IPVSStats, error) {
+// IPVSStats reads the IPVS statistics from the specified `proc` filesystem.
+func (fs FS) IPVSStats() (IPVSStats, error) {
 	file, err := os.Open(fs.proc.Path("net/ip_vs_stats"))
 	if err != nil {
 		return IPVSStats{}, err
@@ -131,18 +121,8 @@ func parseIPVSStats(file io.Reader) (IPVSStats, error) {
 	return stats, nil
 }
 
-// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs.
-func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return []IPVSBackendStatus{}, err
-	}
-
-	return fs.NewIPVSBackendStatus()
-}
-
-// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
-func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
+// IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
+func (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) {
 	file, err := os.Open(fs.proc.Path("net/ip_vs"))
 	if err != nil {
 		return nil, err
diff --git a/mdstat.go b/mdstat.go
index 6ac7a12..71c1067 100644
--- a/mdstat.go
+++ b/mdstat.go
@@ -42,64 +42,64 @@ type MDStat struct {
 	BlocksSynced int64
 }
 
-// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
-func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
-	mdStatusFilePath := fs.proc.Path("mdstat")
-	content, err := ioutil.ReadFile(mdStatusFilePath)
+// MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of
+// structs containing the relevant info.  More information available here:
+// https://raid.wiki.kernel.org/index.php/Mdstat
+func (fs FS) MDStat() ([]MDStat, error) {
+	data, err := ioutil.ReadFile(fs.proc.Path("mdstat"))
 	if err != nil {
-		return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
+		return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
 	}
+	mdstat, err := parseMDStat(data)
+	if err != nil {
+		return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
+	}
+	return mdstat, nil
+}
 
-	mdStates := []MDStat{}
-	lines := strings.Split(string(content), "\n")
+// parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of
+// structs containing the relevant info.
+func parseMDStat(mdstatData []byte) ([]MDStat, error) {
+	mdStats := []MDStat{}
+	lines := strings.Split(string(mdstatData), "\n")
 	for i, l := range lines {
-		if l == "" {
-			continue
-		}
-		if l[0] == ' ' {
-			continue
-		}
-		if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
+		if strings.TrimSpace(l) == "" || l[0] == ' ' ||
+			strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
 			continue
 		}
 
-		mainLine := strings.Split(l, " ")
-		if len(mainLine) < 3 {
-			return mdStates, fmt.Errorf("error parsing mdline: %s", l)
+		deviceFields := strings.Fields(l)
+		if len(deviceFields) < 3 {
+			return nil, fmt.Errorf("not enough fields in mdline (expected at least 3): %s", l)
 		}
-		mdName := mainLine[0]
-		activityState := mainLine[2]
+		mdName := deviceFields[0]
+		activityState := deviceFields[2]
 
 		if len(lines) <= i+3 {
-			return mdStates, fmt.Errorf(
-				"error parsing %s: too few lines for md device %s",
-				mdStatusFilePath,
-				mdName,
-			)
+			return mdStats, fmt.Errorf("missing lines for md device %s", mdName)
 		}
 
-		active, total, size, err := evalStatusline(lines[i+1])
+		active, total, size, err := evalStatusLine(lines[i+1])
 		if err != nil {
-			return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
+			return nil, err
 		}
 
-		// j is the line number of the syncing-line.
-		j := i + 2
+		syncLineIdx := i + 2
 		if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line
-			j = i + 3
+			syncLineIdx++
 		}
 
-		// If device is syncing at the moment, get the number of currently
+		// If device is recovering/syncing at the moment, get the number of currently
 		// synced bytes, otherwise that number equals the size of the device.
 		syncedBlocks := size
-		if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
-			syncedBlocks, err = evalBuildline(lines[j])
+		if strings.Contains(lines[syncLineIdx], "recovery") || strings.Contains(lines[syncLineIdx], "resync") {
+			syncedBlocks, err = evalRecoveryLine(lines[syncLineIdx])
 			if err != nil {
-				return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
+				return nil, err
 			}
 		}
 
-		mdStates = append(mdStates, MDStat{
+		mdStats = append(mdStats, MDStat{
 			Name:          mdName,
 			ActivityState: activityState,
 			DisksActive:   active,
@@ -109,10 +109,10 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
 		})
 	}
 
-	return mdStates, nil
+	return mdStats, nil
 }
 
-func evalStatusline(statusline string) (active, total, size int64, err error) {
+func evalStatusLine(statusline string) (active, total, size int64, err error) {
 	matches := statuslineRE.FindStringSubmatch(statusline)
 	if len(matches) != 4 {
 		return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline)
@@ -136,7 +136,7 @@ func evalStatusline(statusline string) (active, total, size int64, err error) {
 	return active, total, size, nil
 }
 
-func evalBuildline(buildline string) (syncedBlocks int64, err error) {
+func evalRecoveryLine(buildline string) (syncedBlocks int64, err error) {
 	matches := buildlineRE.FindStringSubmatch(buildline)
 	if len(matches) != 2 {
 		return 0, fmt.Errorf("unexpected buildline: %s", buildline)
diff --git a/net_dev.go b/net_dev.go
index 8249c98..a0b7a01 100644
--- a/net_dev.go
+++ b/net_dev.go
@@ -47,23 +47,13 @@ type NetDevLine struct {
 // are interface names.
 type NetDev map[string]NetDevLine
 
-// NewNetDev returns kernel/system statistics read from /proc/net/dev.
-func NewNetDev() (NetDev, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return fs.NewNetDev()
-}
-
-// NewNetDev returns kernel/system statistics read from /proc/net/dev.
-func (fs FS) NewNetDev() (NetDev, error) {
+// NetDev returns kernel/system statistics read from /proc/net/dev.
+func (fs FS) NetDev() (NetDev, error) {
 	return newNetDev(fs.proc.Path("net/dev"))
 }
 
-// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
-func (p Proc) NewNetDev() (NetDev, error) {
+// NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
+func (p Proc) NetDev() (NetDev, error) {
 	return newNetDev(p.path("net/dev"))
 }
 
diff --git a/nfs/nfs.go b/nfs/nfs.go
index 7ee262f..96e69ca 100644
--- a/nfs/nfs.go
+++ b/nfs/nfs.go
@@ -275,6 +275,12 @@ type FS struct {
 	proc *fs.FS
 }
 
+// NewDefaultFS returns a new FS mounted under the default mountPoint. It will error
+// if the mount point can't be read.
+func NewDefaultFS() (FS, error) {
+	return NewFS(fs.DefaultProcMountPoint)
+}
+
 // NewFS returns a new FS mounted under the given mountPoint. It will error
 // if the mount point can't be read.
 func NewFS(mountPoint string) (FS, error) {
diff --git a/proc.go b/proc.go
index 8e38493..1471c29 100644
--- a/proc.go
+++ b/proc.go
@@ -54,7 +54,7 @@ func NewProc(pid int) (Proc, error) {
 	if err != nil {
 		return Proc{}, err
 	}
-	return fs.NewProc(pid)
+	return fs.Proc(pid)
 }
 
 // AllProcs returns a list of all currently available processes under /proc.
@@ -76,11 +76,11 @@ func (fs FS) Self() (Proc, error) {
 	if err != nil {
 		return Proc{}, err
 	}
-	return fs.NewProc(pid)
+	return fs.Proc(pid)
 }
 
-// NewProc returns a process for the given pid.
-func (fs FS) NewProc(pid int) (Proc, error) {
+// Proc returns a process for the given pid.
+func (fs FS) Proc(pid int) (Proc, error) {
 	if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil {
 		return Proc{}, err
 	}
diff --git a/proc_io.go b/proc_io.go
index 0251c83..0ff89b1 100644
--- a/proc_io.go
+++ b/proc_io.go
@@ -39,8 +39,8 @@ type ProcIO struct {
 	CancelledWriteBytes int64
 }
 
-// NewIO creates a new ProcIO instance from a given Proc instance.
-func (p Proc) NewIO() (ProcIO, error) {
+// IO creates a new ProcIO instance from a given Proc instance.
+func (p Proc) IO() (ProcIO, error) {
 	pio := ProcIO{}
 
 	f, err := os.Open(p.path("io"))
diff --git a/proc_limits.go b/proc_limits.go
index f04ba6f..5b74243 100644
--- a/proc_limits.go
+++ b/proc_limits.go
@@ -77,8 +77,8 @@ var (
 	limitsDelimiter = regexp.MustCompile("  +")
 )
 
-// NewLimits returns the current soft limits of the process.
-func (p Proc) NewLimits() (ProcLimits, error) {
+// Limits returns the current soft limits of the process.
+func (p Proc) Limits() (ProcLimits, error) {
 	f, err := os.Open(p.path("limits"))
 	if err != nil {
 		return ProcLimits{}, err
diff --git a/proc_ns.go b/proc_ns.go
index 3f8d6d6..c66740f 100644
--- a/proc_ns.go
+++ b/proc_ns.go
@@ -29,9 +29,9 @@ type Namespace struct {
 // Namespaces contains all of the namespaces that the process is contained in.
 type Namespaces map[string]Namespace
 
-// NewNamespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
+// Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
 // process is a member.
-func (p Proc) NewNamespaces() (Namespaces, error) {
+func (p Proc) Namespaces() (Namespaces, error) {
 	d, err := os.Open(p.path("ns"))
 	if err != nil {
 		return nil, err
diff --git a/proc_psi.go b/proc_psi.go
index a23d4c0..46fe266 100644
--- a/proc_psi.go
+++ b/proc_psi.go
@@ -51,19 +51,10 @@ type PSIStats struct {
 	Full *PSILine
 }
 
-// NewPSIStatsForResource reads pressure stall information for the specified
-// resource. At time of writing this can be either "cpu", "memory" or "io".
-func NewPSIStatsForResource(resource string) (PSIStats, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return PSIStats{}, err
-	}
-
-	return fs.NewPSIStatsForResource(resource)
-}
-
-// NewPSIStatsForResource reads pressure stall information from /proc/pressure/<resource>
-func (fs FS) NewPSIStatsForResource(resource string) (PSIStats, error) {
+// PSIStatsForResource reads pressure stall information for the specified
+// resource from /proc/pressure/<resource>. At time of writing this can be
+// either "cpu", "memory" or "io".
+func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
 	file, err := os.Open(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
 	if err != nil {
 		return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %s", resource)
diff --git a/proc_stat.go b/proc_stat.go
index 4c8b03c..dd29010 100644
--- a/proc_stat.go
+++ b/proc_stat.go
@@ -104,8 +104,8 @@ type ProcStat struct {
 	proc fs.FS
 }
 
-// NewStat returns the current status information of the process.
-func (p Proc) NewStat() (ProcStat, error) {
+// Stat returns the current status information of the process.
+func (p Proc) Stat() (ProcStat, error) {
 	f, err := os.Open(p.path("stat"))
 	if err != nil {
 		return ProcStat{}, err
@@ -178,7 +178,7 @@ func (s ProcStat) ResidentMemory() int {
 // StartTime returns the unix timestamp of the process in seconds.
 func (s ProcStat) StartTime() (float64, error) {
 	fs := FS{proc: s.proc}
-	stat, err := fs.NewStat()
+	stat, err := fs.Stat()
 	if err != nil {
 		return 0, err
 	}
diff --git a/stat.go b/stat.go
index 44c9af1..06e08ae 100644
--- a/stat.go
+++ b/stat.go
@@ -78,16 +78,6 @@ type Stat struct {
 	SoftIRQ SoftIRQStat
 }
 
-// NewStat returns kernel/system statistics read from /proc/stat.
-func NewStat() (Stat, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return Stat{}, err
-	}
-
-	return fs.NewStat()
-}
-
 // Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
 func parseCPUStat(line string) (CPUStat, int64, error) {
 	cpuStat := CPUStat{}
@@ -149,8 +139,8 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
 	return softIRQStat, total, nil
 }
 
-// NewStat returns an information about current kernel/system statistics.
-func (fs FS) NewStat() (Stat, error) {
+// Stat returns an information about current kernel/system statistics.
+func (fs FS) Stat() (Stat, error) {
 	// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
 
 	f, err := os.Open(fs.proc.Path("stat"))
diff --git a/sysfs/class_power_supply.go b/sysfs/class_power_supply.go
index 64720ef..90c32e5 100644
--- a/sysfs/class_power_supply.go
+++ b/sysfs/class_power_supply.go
@@ -102,18 +102,8 @@ type PowerSupply struct {
 // The map keys are the names of the power supplies.
 type PowerSupplyClass map[string]PowerSupply
 
-// NewPowerSupplyClass returns info for all power supplies read from /sys/class/power_supply/.
-func NewPowerSupplyClass() (PowerSupplyClass, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return fs.NewPowerSupplyClass()
-}
-
-// NewPowerSupplyClass returns info for all power supplies read from /sys/class/power_supply/.
-func (fs FS) NewPowerSupplyClass() (PowerSupplyClass, error) {
+// PowerSupplyClass returns info for all power supplies read from /sys/class/power_supply/.
+func (fs FS) PowerSupplyClass() (PowerSupplyClass, error) {
 	path := fs.sys.Path("class/power_supply")
 
 	powerSupplyDirs, err := ioutil.ReadDir(path)
diff --git a/sysfs/class_thermal.go b/sysfs/class_thermal.go
index 2d70795..cfe11ad 100644
--- a/sysfs/class_thermal.go
+++ b/sysfs/class_thermal.go
@@ -35,8 +35,8 @@ type ClassThermalZoneStats struct {
 	Passive *uint64 // Optional: millidegrees Celsius. (0 for disabled, > 1000 for enabled+value)
 }
 
-// NewClassThermalZoneStats returns Thermal Zone metrics for all zones.
-func (fs FS) NewClassThermalZoneStats() ([]ClassThermalZoneStats, error) {
+// ClassThermalZoneStats returns Thermal Zone metrics for all zones.
+func (fs FS) ClassThermalZoneStats() ([]ClassThermalZoneStats, error) {
 	zones, err := filepath.Glob(fs.sys.Path("class/thermal/thermal_zone[0-9]*"))
 	if err != nil {
 		return []ClassThermalZoneStats{}, err
diff --git a/sysfs/fs.go b/sysfs/fs.go
index c0cb9b6..b3354f3 100644
--- a/sysfs/fs.go
+++ b/sysfs/fs.go
@@ -26,6 +26,12 @@ type FS struct {
 // DefaultMountPoint is the common mount point of the sys filesystem.
 const DefaultMountPoint = fs.DefaultSysMountPoint
 
+// NewDefaultFS returns a new FS mounted under the default mountPoint. It will error
+// if the mount point can't be read.
+func NewDefaultFS() (FS, error) {
+	return NewFS(DefaultMountPoint)
+}
+
 // NewFS returns a new FS mounted under the given mountPoint. It will error
 // if the mount point can't be read.
 func NewFS(mountPoint string) (FS, error) {
diff --git a/sysfs/net_class.go b/sysfs/net_class.go
index c28051e..909f7fb 100644
--- a/sysfs/net_class.go
+++ b/sysfs/net_class.go
@@ -65,16 +65,6 @@ type NetClassIface struct {
 // are interface (iface) names.
 type NetClass map[string]NetClassIface
 
-// NewNetClass returns info for all net interfaces (iface) read from /sys/class/net/<iface>.
-func NewNetClass() (NetClass, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return fs.NewNetClass()
-}
-
 // NetClassDevices scans /sys/class/net for devices and returns them as a list of names.
 func (fs FS) NetClassDevices() ([]string, error) {
 	var res []string
@@ -95,8 +85,8 @@ func (fs FS) NetClassDevices() ([]string, error) {
 	return res, nil
 }
 
-// NewNetClass returns info for all net interfaces (iface) read from /sys/class/net/<iface>.
-func (fs FS) NewNetClass() (NetClass, error) {
+// NetClass returns info for all net interfaces (iface) read from /sys/class/net/<iface>.
+func (fs FS) NetClass() (NetClass, error) {
 	devices, err := fs.NetClassDevices()
 	if err != nil {
 		return nil, err
diff --git a/sysfs/system_cpu.go b/sysfs/system_cpu.go
index 4bcf86b..001039c 100644
--- a/sysfs/system_cpu.go
+++ b/sysfs/system_cpu.go
@@ -46,18 +46,8 @@ type SystemCPUCpufreqStats struct {
 
 // TODO: Add thermal_throttle support.
 
-// NewSystemCpufreq returns CPU frequency metrics for all CPUs.
-func NewSystemCpufreq() ([]SystemCPUCpufreqStats, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return []SystemCPUCpufreqStats{}, err
-	}
-
-	return fs.NewSystemCpufreq()
-}
-
-// NewSystemCpufreq returns CPU frequency metrics for all CPUs.
-func (fs FS) NewSystemCpufreq() ([]SystemCPUCpufreqStats, error) {
+// SystemCpufreq returns CPU frequency metrics for all CPUs.
+func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) {
 	var g errgroup.Group
 
 	cpus, err := filepath.Glob(fs.sys.Path("devices/system/cpu/cpu[0-9]*"))
diff --git a/xfs/xfs.go b/xfs/xfs.go
index 8a7288f..3aad661 100644
--- a/xfs/xfs.go
+++ b/xfs/xfs.go
@@ -177,6 +177,12 @@ type FS struct {
 	sys  *fs.FS
 }
 
+// NewDefaultFS returns a new XFS handle using the default proc and sys mountPoints.
+// It will error if either of the mounts point can't be read.
+func NewDefaultFS() (FS, error) {
+	return NewFS(fs.DefaultProcMountPoint, fs.DefaultSysMountPoint)
+}
+
 // NewFS returns a new XFS handle using the given proc and sys mountPoints. It will error
 // if either of the mounts point can't be read.
 func NewFS(procMountPoint string, sysMountPoint string) (FS, error) {


Test patch:
diff --git a/buddyinfo_test.go b/buddyinfo_test.go
index 7016466..002e3be 100644
--- a/buddyinfo_test.go
+++ b/buddyinfo_test.go
@@ -19,7 +19,7 @@ import (
 )
 
 func TestBuddyInfo(t *testing.T) {
-	buddyInfo, err := getProcFixtures(t).NewBuddyInfo()
+	buddyInfo, err := getProcFixtures(t).BuddyInfo()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/ipvs_test.go b/ipvs_test.go
index aa87d3c..4feb0cb 100644
--- a/ipvs_test.go
+++ b/ipvs_test.go
@@ -163,7 +163,7 @@ func TestIPVSStats(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	stats, err := fs.NewIPVSStats()
+	stats, err := fs.IPVSStats()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -217,7 +217,7 @@ func TestParseIPPortIPv6(t *testing.T) {
 }
 
 func TestIPVSBackendStatus(t *testing.T) {
-	backendStats, err := getProcFixtures(t).NewIPVSBackendStatus()
+	backendStats, err := getProcFixtures(t).IPVSBackendStatus()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/mdstat_test.go b/mdstat_test.go
index cc1b557..99a5adf 100644
--- a/mdstat_test.go
+++ b/mdstat_test.go
@@ -18,7 +18,7 @@ import (
 )
 
 func TestMDStat(t *testing.T) {
-	mdStates, err := getProcFixtures(t).ParseMDStat()
+	mdStats, err := getProcFixtures(t).MDStat()
 	if err != nil {
 		t.Fatalf("parsing of reference-file failed entirely: %s", err)
 	}
@@ -33,10 +33,10 @@ func TestMDStat(t *testing.T) {
 		"md7":   {"md7", "active", 3, 4, 7813735424, 7813735424},
 	}
 
-	if want, have := len(refs), len(mdStates); want != have {
+	if want, have := len(refs), len(mdStats); want != have {
 		t.Errorf("want %d parsed md-devices, have %d", want, have)
 	}
-	for _, md := range mdStates {
+	for _, md := range mdStats {
 		if want, have := refs[md.Name], md; want != have {
 			t.Errorf("%s: want %v, have %v", md.Name, want, have)
 		}
diff --git a/mountstats_test.go b/mountstats_test.go
index e41fcf3..c6e95b8 100644
--- a/mountstats_test.go
+++ b/mountstats_test.go
@@ -361,7 +361,7 @@ func TestMountStats(t *testing.T) {
 		if tt.s != "" {
 			mounts, err = parseMountStats(strings.NewReader(tt.s))
 		} else {
-			proc, e := getProcFixtures(t).NewProc(26231)
+			proc, e := getProcFixtures(t).Proc(26231)
 			if e != nil {
 				t.Fatalf("failed to create proc: %v", err)
 			}
diff --git a/net_dev_test.go b/net_dev_test.go
index 1c829bb..c26c7b2 100644
--- a/net_dev_test.go
+++ b/net_dev_test.go
@@ -31,13 +31,13 @@ func TestNetDevParseLine(t *testing.T) {
 	}
 }
 
-func TestNewNetDev(t *testing.T) {
+func TestNetDev(t *testing.T) {
 	fs, err := NewFS(procTestFixtures)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	netDev, err := fs.NewNetDev()
+	netDev, err := fs.NetDev()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -59,13 +59,13 @@ func TestNewNetDev(t *testing.T) {
 	}
 }
 
-func TestProcNewNetDev(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+func TestProcNetDev(t *testing.T) {
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	netDev, err := p.NewNetDev()
+	netDev, err := p.NetDev()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/proc_io_test.go b/proc_io_test.go
index c0d55cd..a800f37 100644
--- a/proc_io_test.go
+++ b/proc_io_test.go
@@ -16,12 +16,12 @@ package procfs
 import "testing"
 
 func TestProcIO(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	s, err := p.NewIO()
+	s, err := p.IO()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/proc_limits_test.go b/proc_limits_test.go
index 290f675..9148e28 100644
--- a/proc_limits_test.go
+++ b/proc_limits_test.go
@@ -15,13 +15,13 @@ package procfs
 
 import "testing"
 
-func TestNewLimits(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+func TestLimits(t *testing.T) {
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	l, err := p.NewLimits()
+	l, err := p.Limits()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/proc_ns_test.go b/proc_ns_test.go
index ef62266..0a8ce6c 100644
--- a/proc_ns_test.go
+++ b/proc_ns_test.go
@@ -18,12 +18,12 @@ import (
 )
 
 func TestNewNamespaces(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	namespaces, err := p.NewNamespaces()
+	namespaces, err := p.Namespaces()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/proc_psi_test.go b/proc_psi_test.go
index d238fe1..f7a1b69 100644
--- a/proc_psi_test.go
+++ b/proc_psi_test.go
@@ -20,7 +20,7 @@ import (
 
 func TestPSIStats(t *testing.T) {
 	t.Run("fake", func(*testing.T) {
-		stats, err := getProcFixtures(t).NewPSIStatsForResource("fake")
+		stats, err := getProcFixtures(t).PSIStatsForResource("fake")
 		if err == nil {
 			t.Fatal("fake resource does not have PSI statistics")
 		}
@@ -31,7 +31,7 @@ func TestPSIStats(t *testing.T) {
 	})
 
 	t.Run("cpu", func(t *testing.T) {
-		stats, err := getProcFixtures(t).NewPSIStatsForResource("cpu")
+		stats, err := getProcFixtures(t).PSIStatsForResource("cpu")
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -68,7 +68,7 @@ func TestPSIStats(t *testing.T) {
 
 	for _, resource := range res {
 		t.Run(resource, func(t *testing.T) {
-			stats, err := getProcFixtures(t).NewPSIStatsForResource(resource)
+			stats, err := getProcFixtures(t).PSIStatsForResource(resource)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/proc_stat_test.go b/proc_stat_test.go
index 3822f55..8b23cf1 100644
--- a/proc_stat_test.go
+++ b/proc_stat_test.go
@@ -19,12 +19,12 @@ import (
 )
 
 func TestProcStat(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	s, err := p.NewStat()
+	s, err := p.Stat()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -118,10 +118,10 @@ func testProcStat(pid int) (ProcStat, error) {
 	if err != nil {
 		return ProcStat{}, err
 	}
-	p, err := fs.NewProc(pid)
+	p, err := fs.Proc(pid)
 	if err != nil {
 		return ProcStat{}, err
 	}
 
-	return p.NewStat()
+	return p.Stat()
 }
diff --git a/proc_status_test.go b/proc_status_test.go
index fdf2ac4..2a9fac6 100644
--- a/proc_status_test.go
+++ b/proc_status_test.go
@@ -18,7 +18,7 @@ import (
 )
 
 func TestProcStatus(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -62,7 +62,7 @@ func TestProcStatus(t *testing.T) {
 }
 
 func TestProcStatusName(t *testing.T) {
-	p, err := getProcFixtures(t).NewProc(26231)
+	p, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/proc_test.go b/proc_test.go
index f4da574..f05c14f 100644
--- a/proc_test.go
+++ b/proc_test.go
@@ -22,7 +22,7 @@ import (
 func TestSelf(t *testing.T) {
 	fs := getProcFixtures(t)
 
-	p1, err := fs.NewProc(26231)
+	p1, err := fs.Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -58,7 +58,7 @@ func TestCmdLine(t *testing.T) {
 		{process: 26232, want: []string{}},
 		{process: 26233, want: []string{"com.github.uiautomator"}},
 	} {
-		p1, err := getProcFixtures(t).NewProc(tt.process)
+		p1, err := getProcFixtures(t).Proc(tt.process)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -80,7 +80,7 @@ func TestComm(t *testing.T) {
 		{process: 26231, want: "vim"},
 		{process: 26232, want: "ata_sff"},
 	} {
-		p1, err := getProcFixtures(t).NewProc(tt.process)
+		p1, err := getProcFixtures(t).Proc(tt.process)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -102,7 +102,7 @@ func TestExecutable(t *testing.T) {
 		{process: 26231, want: "/usr/bin/vim"},
 		{process: 26232, want: ""},
 	} {
-		p, err := getProcFixtures(t).NewProc(tt.process)
+		p, err := getProcFixtures(t).Proc(tt.process)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -126,7 +126,7 @@ func TestCwd(t *testing.T) {
 		{process: 26232, want: "/does/not/exist", brokenLink: true},
 		{process: 26233, want: ""},
 	} {
-		p, err := getProcFixtures(t).NewProc(tt.process)
+		p, err := getProcFixtures(t).Proc(tt.process)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -154,7 +154,7 @@ func TestRoot(t *testing.T) {
 		{process: 26232, want: "/does/not/exist", brokenLink: true},
 		{process: 26233, want: ""},
 	} {
-		p, err := getProcFixtures(t).NewProc(tt.process)
+		p, err := getProcFixtures(t).Proc(tt.process)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -173,7 +173,7 @@ func TestRoot(t *testing.T) {
 }
 
 func TestFileDescriptors(t *testing.T) {
-	p1, err := getProcFixtures(t).NewProc(26231)
+	p1, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -188,7 +188,7 @@ func TestFileDescriptors(t *testing.T) {
 }
 
 func TestFileDescriptorTargets(t *testing.T) {
-	p1, err := getProcFixtures(t).NewProc(26231)
+	p1, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -210,7 +210,7 @@ func TestFileDescriptorTargets(t *testing.T) {
 }
 
 func TestFileDescriptorsLen(t *testing.T) {
-	p1, err := getProcFixtures(t).NewProc(26231)
+	p1, err := getProcFixtures(t).Proc(26231)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/stat_test.go b/stat_test.go
index 00c280b..87ef5a3 100644
--- a/stat_test.go
+++ b/stat_test.go
@@ -16,7 +16,7 @@ package procfs
 import "testing"
 
 func TestStat(t *testing.T) {
-	s, err := getProcFixtures(t).NewStat()
+	s, err := getProcFixtures(t).Stat()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/sysfs/class_power_supply_test.go b/sysfs/class_power_supply_test.go
index e8402a6..d765492 100644
--- a/sysfs/class_power_supply_test.go
+++ b/sysfs/class_power_supply_test.go
@@ -21,13 +21,13 @@ import (
 	"testing"
 )
 
-func TestNewPowerSupplyClass(t *testing.T) {
+func TestPowerSupplyClass(t *testing.T) {
 	fs, err := NewFS(sysTestFixtures)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	psc, err := fs.NewPowerSupplyClass()
+	psc, err := fs.PowerSupplyClass()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/sysfs/class_thermal_test.go b/sysfs/class_thermal_test.go
index 4e6b0d6..3f86967 100644
--- a/sysfs/class_thermal_test.go
+++ b/sysfs/class_thermal_test.go
@@ -28,7 +28,7 @@ func TestClassThermalZoneStats(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	thermalTest, err := fs.NewClassThermalZoneStats()
+	thermalTest, err := fs.ClassThermalZoneStats()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/sysfs/net_class_test.go b/sysfs/net_class_test.go
index 3f376e2..39a7c27 100644
--- a/sysfs/net_class_test.go
+++ b/sysfs/net_class_test.go
@@ -39,13 +39,13 @@ func TestNewNetClassDevices(t *testing.T) {
 	}
 }
 
-func TestNewNetClass(t *testing.T) {
+func TestNetClass(t *testing.T) {
 	fs, err := NewFS(sysTestFixtures)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	nc, err := fs.NewNetClass()
+	nc, err := fs.NetClass()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/sysfs/system_cpu_test.go b/sysfs/system_cpu_test.go
index f4ecfc5..36317d8 100644
--- a/sysfs/system_cpu_test.go
+++ b/sysfs/system_cpu_test.go
@@ -24,13 +24,13 @@ func makeUint64(v uint64) *uint64 {
 	return &v
 }
 
-func TestNewSystemCpufreq(t *testing.T) {
+func TestSystemCpufreq(t *testing.T) {
 	fs, err := NewFS(sysTestFixtures)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	c, err := fs.NewSystemCpufreq()
+	c, err := fs.SystemCpufreq()
 	if err != nil {
 		t.Fatal(err)
 	}