Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

117 rader
3.4 KiB

  1. // Copyright 2019 The Prometheus Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package prometheus
  14. import (
  15. "syscall"
  16. "unsafe"
  17. "golang.org/x/sys/windows"
  18. )
  19. func canCollectProcess() bool {
  20. return true
  21. }
  22. var (
  23. modpsapi = syscall.NewLazyDLL("psapi.dll")
  24. modkernel32 = syscall.NewLazyDLL("kernel32.dll")
  25. procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
  26. procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount")
  27. )
  28. type processMemoryCounters struct {
  29. // System interface description
  30. // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex
  31. // Refer to the Golang internal implementation
  32. // https://golang.org/src/internal/syscall/windows/psapi_windows.go
  33. _ uint32
  34. PageFaultCount uint32
  35. PeakWorkingSetSize uintptr
  36. WorkingSetSize uintptr
  37. QuotaPeakPagedPoolUsage uintptr
  38. QuotaPagedPoolUsage uintptr
  39. QuotaPeakNonPagedPoolUsage uintptr
  40. QuotaNonPagedPoolUsage uintptr
  41. PagefileUsage uintptr
  42. PeakPagefileUsage uintptr
  43. PrivateUsage uintptr
  44. }
  45. func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {
  46. mem := processMemoryCounters{}
  47. r1, _, err := procGetProcessMemoryInfo.Call(
  48. uintptr(handle),
  49. uintptr(unsafe.Pointer(&mem)),
  50. uintptr(unsafe.Sizeof(mem)),
  51. )
  52. if r1 != 1 {
  53. return mem, err
  54. } else {
  55. return mem, nil
  56. }
  57. }
  58. func getProcessHandleCount(handle windows.Handle) (uint32, error) {
  59. var count uint32
  60. r1, _, err := procGetProcessHandleCount.Call(
  61. uintptr(handle),
  62. uintptr(unsafe.Pointer(&count)),
  63. )
  64. if r1 != 1 {
  65. return 0, err
  66. } else {
  67. return count, nil
  68. }
  69. }
  70. func (c *processCollector) processCollect(ch chan<- Metric) {
  71. h, err := windows.GetCurrentProcess()
  72. if err != nil {
  73. c.reportError(ch, nil, err)
  74. return
  75. }
  76. var startTime, exitTime, kernelTime, userTime windows.Filetime
  77. err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
  78. if err != nil {
  79. c.reportError(ch, nil, err)
  80. return
  81. }
  82. ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9))
  83. ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime))
  84. mem, err := getProcessMemoryInfo(h)
  85. if err != nil {
  86. c.reportError(ch, nil, err)
  87. return
  88. }
  89. ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage))
  90. ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize))
  91. handles, err := getProcessHandleCount(h)
  92. if err != nil {
  93. c.reportError(ch, nil, err)
  94. return
  95. }
  96. ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles))
  97. ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
  98. }
  99. func fileTimeToSeconds(ft windows.Filetime) float64 {
  100. return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
  101. }