tools.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //! Tools to collect benchmark metadata.
  2. use git_version::git_version;
  3. use serde::Serialize;
  4. use std::fs::{read_to_string, File};
  5. use std::io::{BufRead, BufReader};
  6. use std::process;
  7. /// Collection of metadata for benchmarks.
  8. #[derive(Clone, Debug, Serialize)]
  9. pub struct BenchmarkMetaData {
  10. /// The hostname of the system.
  11. pub hostname: String,
  12. /// The username of the current user.
  13. pub username: String,
  14. /// A timestamp.
  15. pub timestamp: String,
  16. /// How this program was executed.
  17. pub cmdline: Vec<String>,
  18. /// The process ID.
  19. pub pid: u32,
  20. /// The git version of this software.
  21. pub git_version: String,
  22. }
  23. impl BenchmarkMetaData {
  24. /// Collect the metadata.
  25. pub fn collect() -> Self {
  26. BenchmarkMetaData {
  27. hostname: get_hostname(),
  28. username: get_username(),
  29. timestamp: get_timestamp(),
  30. cmdline: get_cmdline(),
  31. pid: get_pid(),
  32. git_version: git_version!(args = ["--abbrev=40", "--always", "--dirty"]).to_string(),
  33. }
  34. }
  35. }
  36. fn run_command_with_args(cmd: &str, args: &[&str]) -> String {
  37. String::from_utf8(
  38. process::Command::new(cmd)
  39. .args(args)
  40. .output()
  41. .expect("process failed")
  42. .stdout,
  43. )
  44. .expect("utf-8 decoding failed")
  45. .trim()
  46. .to_string()
  47. }
  48. fn run_command(cmd: &str) -> String {
  49. String::from_utf8(
  50. process::Command::new(cmd)
  51. .output()
  52. .expect("process failed")
  53. .stdout,
  54. )
  55. .expect("utf-8 decoding failed")
  56. .trim()
  57. .to_string()
  58. }
  59. fn read_file(path: &str) -> String {
  60. read_to_string(path).expect("read_to_string failed")
  61. }
  62. /// Get the username of the current user.
  63. pub fn get_username() -> String {
  64. run_command("whoami")
  65. }
  66. /// Get the hostname of this machine.
  67. pub fn get_hostname() -> String {
  68. read_file("/proc/sys/kernel/hostname").trim().to_string()
  69. }
  70. /// Get a current timestamp.
  71. pub fn get_timestamp() -> String {
  72. run_command_with_args("date", &["--iso-8601=s"])
  73. }
  74. /// Get command line arguments used to run this program.
  75. pub fn get_cmdline() -> Vec<String> {
  76. let f = File::open("/proc/self/cmdline").expect("cannot open file");
  77. let mut reader = BufReader::new(f);
  78. let mut cmdline: Vec<String> = Vec::new();
  79. loop {
  80. let mut bytes = Vec::<u8>::new();
  81. let num_bytes = reader.read_until(0, &mut bytes).expect("read failed");
  82. if num_bytes == 0 {
  83. break;
  84. }
  85. bytes.pop();
  86. cmdline.push(String::from_utf8(bytes).expect("utf-8 decoding failed"))
  87. }
  88. cmdline
  89. }
  90. /// Get process ID (PID) of the current process.
  91. pub fn get_pid() -> u32 {
  92. process::id()
  93. }