github.com/vicanso/pike@v1.0.1-0.20210630235453-9099e041f6ec/app/app.go (about)

     1  // MIT License
     2  
     3  // Copyright (c) 2020 Tree Xie
     4  
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy
     6  // of this software and associated documentation files (the "Software"), to deal
     7  // in the Software without restriction, including without limitation the rights
     8  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  // copies of the Software, and to permit persons to whom the Software is
    10  // furnished to do so, subject to the following conditions:
    11  
    12  // The above copyright notice and this permission notice shall be included in all
    13  // copies or substantial portions of the Software.
    14  
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    18  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    19  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    20  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    21  // SOFTWARE.
    22  
    23  package app
    24  
    25  import (
    26  	"os"
    27  	"runtime"
    28  	"strconv"
    29  	"strings"
    30  	"time"
    31  
    32  	"github.com/shirou/gopsutil/v3/process"
    33  	"github.com/vicanso/pike/log"
    34  	"go.uber.org/atomic"
    35  	"go.uber.org/zap"
    36  )
    37  
    38  type Info struct {
    39  	GOARCH       string `json:"goarch,omitempty"`
    40  	GOOS         string `json:"goos,omitempty"`
    41  	GoVersion    string `json:"goVersion,omitempty"`
    42  	Version      string `json:"version,omitempty"`
    43  	BuildedAt    string `json:"buildedAt,omitempty"`
    44  	CommitID     string `json:"commitID,omitempty"`
    45  	Uptime       string `json:"uptime,omitempty"`
    46  	GoMaxProcs   int    `json:"goMaxProcs,omitempty"`
    47  	CPUUsage     int32  `json:"cpuUsage,omitempty"`
    48  	RoutineCount int    `json:"routineCount,omitempty"`
    49  	ThreadCount  int32  `json:"threadCount,omitempty"`
    50  	RSS          uint64 `json:"rss,omitempty"`
    51  	RSSHumanize  string `json:"rssHumanize,omitempty"`
    52  	Swap         uint64 `json:"swap,omitempty"`
    53  	SwapHumanize string `json:"swapHumanize,omitempty"`
    54  }
    55  
    56  var buildedAt time.Time
    57  var commitID string
    58  var version string
    59  var startedAt = time.Now()
    60  var currentProcess *process.Process
    61  var cpuUsage = atomic.NewInt32(-1)
    62  
    63  func init() {
    64  	p, err := process.NewProcess(int32(os.Getpid()))
    65  	if err != nil {
    66  		log.Default().Error("new process fail",
    67  			zap.Error(err),
    68  		)
    69  	}
    70  	currentProcess = p
    71  	_ = UpdateCPUUsage()
    72  }
    73  
    74  // SetBuildInfo set build info
    75  func SetBuildInfo(build, id, ver, buildBy string) {
    76  	if strings.Contains(build, ".") && len(build) == 15 {
    77  		buildedAt, _ = time.Parse("20060102.150405", build)
    78  	} else {
    79  		buildedAt, _ = time.Parse(time.RFC3339, build)
    80  	}
    81  	commitID = id
    82  	if len(id) > 7 {
    83  		commitID = id[0:7]
    84  	}
    85  	version = ver
    86  }
    87  
    88  const MB = 1024 * 1024
    89  
    90  func bytesToMB(value uint64) string {
    91  	v := value / MB
    92  	return strconv.Itoa(int(v)) + " MB"
    93  }
    94  
    95  func GetVersion() string {
    96  	return version
    97  }
    98  
    99  // GetInfo get application info
   100  func GetInfo() *Info {
   101  	uptime := ""
   102  	d := time.Since(startedAt)
   103  	if d > 24*time.Hour {
   104  		uptime = strconv.Itoa(int(d/(24*time.Hour))) + "d"
   105  	} else if d > time.Hour {
   106  		uptime = strconv.Itoa(int(d.Hours())) + "h"
   107  	} else {
   108  		uptime = (time.Second * time.Duration(d.Seconds())).String()
   109  	}
   110  
   111  	info := &Info{
   112  		GOARCH:       runtime.GOARCH,
   113  		GOOS:         runtime.GOOS,
   114  		GoVersion:    runtime.Version(),
   115  		Version:      GetVersion(),
   116  		BuildedAt:    buildedAt.Format(time.RFC3339),
   117  		CommitID:     commitID,
   118  		Uptime:       uptime,
   119  		GoMaxProcs:   runtime.GOMAXPROCS(0),
   120  		CPUUsage:     cpuUsage.Load(),
   121  		RoutineCount: runtime.NumGoroutine(),
   122  	}
   123  	if currentProcess != nil {
   124  		info.ThreadCount, _ = currentProcess.NumThreads()
   125  		memInfo, _ := currentProcess.MemoryInfo()
   126  		if memInfo != nil {
   127  			info.RSS = memInfo.RSS
   128  			info.RSSHumanize = bytesToMB(memInfo.RSS)
   129  			info.Swap = memInfo.Swap
   130  			info.SwapHumanize = bytesToMB(memInfo.Swap)
   131  		}
   132  	}
   133  	return info
   134  }
   135  
   136  // UpdateCPUUsage update cpu usage
   137  func UpdateCPUUsage() error {
   138  	if currentProcess == nil {
   139  		return nil
   140  	}
   141  	usage, err := currentProcess.Percent(0)
   142  	if err != nil {
   143  		return err
   144  	}
   145  	cpuUsage.Store(int32(usage))
   146  	return nil
   147  }