1
#pragma once
2

            
3
#include <string>
4

            
5
#include "envoy/filesystem/filesystem.h"
6

            
7
#include "absl/strings/str_cat.h"
8

            
9
namespace Envoy {
10
namespace Extensions {
11
namespace ResourceMonitors {
12
namespace CpuUtilizationMonitor {
13

            
14
/**
15
 * Utility class providing paths and detection methods for cgroup CPU subsystem.
16
 */
17
struct CpuPaths {
18

            
19
  struct V1 {
20
    // Returns the full path to the CPU shares file (cpu.shares).
21
7
    static std::string getSharesPath() { return absl::StrCat(CGROUP_V1_CPU_BASE, SHARES); }
22

            
23
    // Returns the full path to the CPU usage file (cpuacct.usage).
24
5
    static std::string getUsagePath() { return absl::StrCat(CGROUP_V1_CPUACCT_BASE, USAGE); }
25

            
26
    // Returns the base path for cgroup v1 CPU subsystem.
27
1
    static std::string getCpuBasePath() { return CGROUP_V1_CPU_BASE; }
28

            
29
    // Returns the base path for cgroup v1 cpuacct subsystem.
30
1
    static std::string getCpuacctBasePath() { return CGROUP_V1_CPUACCT_BASE; }
31

            
32
  private:
33
    // Base paths for cgroup v1 subsystems.
34
    static constexpr const char* const CGROUP_V1_CPU_BASE = "/sys/fs/cgroup/cpu";
35
    static constexpr const char* const CGROUP_V1_CPUACCT_BASE = "/sys/fs/cgroup/cpuacct";
36
    // File names for CPU stats in cgroup v1.
37
    static constexpr const char* const SHARES = "/cpu.shares";
38
    static constexpr const char* const USAGE = "/cpuacct.usage";
39
  };
40

            
41
  struct V2 {
42
    // Returns the full path to the CPU stat file (cpu.stat).
43
12
    static std::string getStatPath() { return absl::StrCat(CGROUP_V2_BASE, STAT); }
44

            
45
    // Returns the full path to the CPU max file (cpu.max).
46
9
    static std::string getMaxPath() { return absl::StrCat(CGROUP_V2_BASE, MAX); }
47

            
48
    // Returns the full path to the effective CPUs file (cpuset.cpus.effective).
49
8
    static std::string getEffectiveCpusPath() {
50
8
      return absl::StrCat(CGROUP_V2_BASE, EFFECTIVE_CPUS);
51
8
    }
52

            
53
  private:
54
    static constexpr const char* const CGROUP_V2_BASE = "/sys/fs/cgroup";
55
    static constexpr const char* const STAT = "/cpu.stat";
56
    static constexpr const char* const MAX = "/cpu.max";
57
    static constexpr const char* const EFFECTIVE_CPUS = "/cpuset.cpus.effective";
58
  };
59

            
60
  // Returns whether cgroup v2 CPU subsystem is available.
61
8
  static bool isV2(Filesystem::Instance& fs) {
62
8
    return fs.fileExists(V2::getStatPath()) && fs.fileExists(V2::getMaxPath()) &&
63
8
           fs.fileExists(V2::getEffectiveCpusPath());
64
8
  }
65

            
66
  // Returns whether cgroup v1 CPU subsystem is available.
67
5
  static bool isV1(Filesystem::Instance& fs) {
68
5
    return fs.fileExists(V1::getSharesPath()) && fs.fileExists(V1::getUsagePath());
69
5
  }
70
};
71

            
72
} // namespace CpuUtilizationMonitor
73
} // namespace ResourceMonitors
74
} // namespace Extensions
75
} // namespace Envoy