storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/os-instrumented.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2021 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"os"
    21  	"strings"
    22  	"time"
    23  
    24  	"storj.io/minio/pkg/disk"
    25  	trace "storj.io/minio/pkg/trace"
    26  )
    27  
    28  //go:generate stringer -type=osMetric -trimprefix=osMetric $GOFILE
    29  
    30  type osMetric uint8
    31  
    32  const (
    33  	osMetricRemoveAll osMetric = iota
    34  	osMetricMkdirAll
    35  	osMetricRename
    36  	osMetricOpenFile
    37  	osMetricOpen
    38  	osMetricOpenFileDirectIO
    39  	osMetricLstat
    40  	osMetricRemove
    41  	osMetricStat
    42  	osMetricAccess
    43  	// .... add more
    44  
    45  	osMetricLast
    46  )
    47  
    48  func osTrace(s osMetric, startTime time.Time, duration time.Duration, path string) trace.Info {
    49  	return trace.Info{
    50  		TraceType: trace.OS,
    51  		Time:      startTime,
    52  		NodeName:  globalLocalNodeName,
    53  		FuncName:  "os." + s.String(),
    54  		OSStats: trace.OSStats{
    55  			Duration: duration,
    56  			Path:     path,
    57  		},
    58  	}
    59  }
    60  
    61  func updateOSMetrics(s osMetric, paths ...string) func() {
    62  	if globalTrace.NumSubscribers() == 0 {
    63  		return func() {}
    64  	}
    65  
    66  	startTime := time.Now()
    67  	return func() {
    68  		duration := time.Since(startTime)
    69  
    70  		globalTrace.Publish(osTrace(s, startTime, duration, strings.Join(paths, " -> ")))
    71  	}
    72  }
    73  
    74  // RemoveAll captures time taken to call the underlying os.RemoveAll
    75  func RemoveAll(dirPath string) error {
    76  	defer updateOSMetrics(osMetricRemoveAll, dirPath)()
    77  	return os.RemoveAll(dirPath)
    78  }
    79  
    80  // MkdirAll captures time taken to call os.MkdirAll
    81  func MkdirAll(dirPath string, mode os.FileMode) error {
    82  	defer updateOSMetrics(osMetricMkdirAll, dirPath)()
    83  	return os.MkdirAll(dirPath, mode)
    84  }
    85  
    86  // Rename captures time taken to call os.Rename
    87  func Rename(src, dst string) error {
    88  	defer updateOSMetrics(osMetricRename, src, dst)()
    89  	return os.Rename(src, dst)
    90  }
    91  
    92  // OpenFile captures time taken to call os.OpenFile
    93  func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
    94  	defer updateOSMetrics(osMetricOpenFile, name)()
    95  	return os.OpenFile(name, flag, perm)
    96  }
    97  
    98  // Access captures time taken to call syscall.Access()
    99  // on windows, plan9 and solaris syscall.Access uses
   100  // os.Lstat()
   101  func Access(name string) error {
   102  	defer updateOSMetrics(osMetricAccess, name)()
   103  	return access(name)
   104  }
   105  
   106  // Open captures time taken to call os.Open
   107  func Open(name string) (*os.File, error) {
   108  	defer updateOSMetrics(osMetricOpen, name)()
   109  	return os.Open(name)
   110  }
   111  
   112  // OpenFileDirectIO captures time taken to call disk.OpenFileDirectIO
   113  func OpenFileDirectIO(name string, flag int, perm os.FileMode) (*os.File, error) {
   114  	defer updateOSMetrics(osMetricOpenFileDirectIO, name)()
   115  	return disk.OpenFileDirectIO(name, flag, perm)
   116  }
   117  
   118  // Lstat captures time taken to call os.Lstat
   119  func Lstat(name string) (os.FileInfo, error) {
   120  	defer updateOSMetrics(osMetricLstat, name)()
   121  	return os.Lstat(name)
   122  }
   123  
   124  // Remove captures time taken to call os.Remove
   125  func Remove(deletePath string) error {
   126  	defer updateOSMetrics(osMetricRemove, deletePath)()
   127  	return os.Remove(deletePath)
   128  }
   129  
   130  // Stat captures time taken to call os.Stat
   131  func Stat(name string) (os.FileInfo, error) {
   132  	defer updateOSMetrics(osMetricStat, name)()
   133  	return os.Stat(name)
   134  }