system_collector_macos.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //go:build darwin
  2. package diagnostic
  3. import (
  4. "context"
  5. "fmt"
  6. "os/exec"
  7. "strconv"
  8. )
  9. type SystemCollectorImpl struct {
  10. version string
  11. }
  12. func NewSystemCollectorImpl(
  13. version string,
  14. ) *SystemCollectorImpl {
  15. return &SystemCollectorImpl{
  16. version,
  17. }
  18. }
  19. func (collector *SystemCollectorImpl) Collect(ctx context.Context) (*SystemInformation, string, error) {
  20. memoryInfo, memoryInfoRaw, memoryInfoErr := collectMemoryInformation(ctx)
  21. fdInfo, fdInfoRaw, fdInfoErr := collectFileDescriptorInformation(ctx)
  22. disks, disksRaw, diskErr := collectDiskVolumeInformationUnix(ctx)
  23. osInfo, osInfoRaw, osInfoErr := collectOSInformationUnix(ctx)
  24. if memoryInfoErr != nil {
  25. return nil, RawSystemInformation(osInfoRaw, memoryInfoRaw, fdInfoRaw, disksRaw), memoryInfoErr
  26. }
  27. if fdInfoErr != nil {
  28. return nil, RawSystemInformation(osInfoRaw, memoryInfoRaw, fdInfoRaw, disksRaw), fdInfoErr
  29. }
  30. if diskErr != nil {
  31. return nil, RawSystemInformation(osInfoRaw, memoryInfoRaw, fdInfoRaw, disksRaw), diskErr
  32. }
  33. if osInfoErr != nil {
  34. return nil, RawSystemInformation(osInfoRaw, memoryInfoRaw, fdInfoRaw, disksRaw), osInfoErr
  35. }
  36. return NewSystemInformation(
  37. memoryInfo.MemoryMaximum,
  38. memoryInfo.MemoryCurrent,
  39. fdInfo.FileDescriptorMaximum,
  40. fdInfo.FileDescriptorCurrent,
  41. osInfo.OsSystem,
  42. osInfo.Name,
  43. osInfo.OsVersion,
  44. osInfo.OsRelease,
  45. osInfo.Architecture,
  46. collector.version,
  47. disks,
  48. ), "", nil
  49. }
  50. func collectFileDescriptorInformation(ctx context.Context) (
  51. *FileDescriptorInformation,
  52. string,
  53. error,
  54. ) {
  55. const (
  56. fileDescriptorMaximumKey = "kern.maxfiles"
  57. fileDescriptorCurrentKey = "kern.num_files"
  58. )
  59. command := exec.CommandContext(ctx, "sysctl", fileDescriptorMaximumKey, fileDescriptorCurrentKey)
  60. stdout, err := command.Output()
  61. if err != nil {
  62. return nil, "", fmt.Errorf("error retrieving output from command '%s': %w", command.String(), err)
  63. }
  64. output := string(stdout)
  65. fileDescriptorInfo, err := ParseFileDescriptorInformationFromKV(
  66. output,
  67. fileDescriptorMaximumKey,
  68. fileDescriptorCurrentKey,
  69. )
  70. if err != nil {
  71. return nil, output, err
  72. }
  73. // returning raw output in case other collected information
  74. // resulted in errors
  75. return fileDescriptorInfo, output, nil
  76. }
  77. func collectMemoryInformation(ctx context.Context) (
  78. *MemoryInformation,
  79. string,
  80. error,
  81. ) {
  82. const (
  83. memoryMaximumKey = "hw.memsize"
  84. memoryAvailableKey = "hw.memsize_usable"
  85. )
  86. command := exec.CommandContext(
  87. ctx,
  88. "sysctl",
  89. memoryMaximumKey,
  90. memoryAvailableKey,
  91. )
  92. stdout, err := command.Output()
  93. if err != nil {
  94. return nil, "", fmt.Errorf("error retrieving output from command '%s': %w", command.String(), err)
  95. }
  96. output := string(stdout)
  97. mapper := func(field string) (uint64, error) {
  98. const kiloBytes = 1024
  99. value, err := strconv.ParseUint(field, 10, 64)
  100. return value / kiloBytes, err
  101. }
  102. memoryInfo, err := ParseMemoryInformationFromKV(output, memoryMaximumKey, memoryAvailableKey, mapper)
  103. if err != nil {
  104. return nil, output, err
  105. }
  106. // returning raw output in case other collected information
  107. // resulted in errors
  108. return memoryInfo, output, nil
  109. }