Skip to content

Commit 6a17c67

Browse files
committed
add labels, fix double ".cpu.cpu"
1 parent ffb919e commit 6a17c67

File tree

5 files changed

+60
-59
lines changed

5 files changed

+60
-59
lines changed

pyroscope_ffi/ruby/ext/rbspy/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub extern "C" fn initialize_agent(
146146

147147
let compression = Compression::from_str(&compression_string);
148148
let report_encoding = ReportEncoding::from_str(&report_encoding)
149-
.unwrap_or(ReportEncoding::PPROF);
149+
.unwrap_or(ReportEncoding::FOLDED);
150150

151151
let pid = std::process::id();
152152

src/encode/pprof.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33
use prost::Message;
44

55
use crate::backend::types::{EncodedReport, Report};
6-
use crate::encode::profiles::{Function, Line, Location, Profile, Sample, ValueType};
6+
use crate::encode::profiles::{Function, Label, Line, Location, Profile, Sample, ValueType};
77

88

99
struct PProfBuilder {
@@ -68,7 +68,7 @@ impl PProfBuilder {
6868
}
6969
}
7070

71-
pub fn encode(reports: Vec<Report>) -> Vec<EncodedReport> {
71+
pub fn encode(reports: Vec<Report>, sample_rate: u32, start_time_nanos: u64, duration_nanos: u64) -> Vec<EncodedReport> {
7272
let mut b = PProfBuilder {
7373
strings: HashMap::new(),
7474
functions: HashMap::new(),
@@ -82,8 +82,8 @@ pub fn encode(reports: Vec<Report>) -> Vec<EncodedReport> {
8282
string_table: vec![],
8383
drop_frames: 0,
8484
keep_frames: 0,
85-
time_nanos: 0,
86-
duration_nanos: 0,
85+
time_nanos: start_time_nanos as i64,
86+
duration_nanos: duration_nanos as i64,
8787
period_type: None,
8888
period: 0,
8989
comment: vec![],
@@ -93,10 +93,16 @@ pub fn encode(reports: Vec<Report>) -> Vec<EncodedReport> {
9393
{
9494
let count = b.add_string(&"count".to_string());
9595
let samples = b.add_string(&"samples".to_string());
96+
let milliseconds = b.add_string(&"milliseconds".to_string());
9697
b.profile.sample_type.push(ValueType {
9798
r#type: samples,
9899
unit: count,
99100
});
101+
b.profile.period = 1_000 / sample_rate as i64;
102+
b.profile.period_type = Some(ValueType {
103+
r#type: 0,
104+
unit: milliseconds,
105+
})
100106
}
101107
for report in &reports {
102108
for (stacktrace, value) in &report.data {
@@ -115,6 +121,25 @@ pub fn encode(reports: Vec<Report>) -> Vec<EncodedReport> {
115121
let location_id = b.add_location(function_id);
116122
sample.location_id.push(location_id as u64);
117123
}
124+
let mut labels = HashMap::new();
125+
for l in &stacktrace.metadata.tags {
126+
let k = b.add_string(&l.key);
127+
let v = b.add_string(&l.value);
128+
labels.insert(k, v);
129+
}
130+
for l in &report.metadata.tags {
131+
let k = b.add_string(&l.key);
132+
let v = b.add_string(&l.value);
133+
labels.insert(k, v);
134+
}
135+
for (k, v) in &labels {
136+
sample.label.push(Label {
137+
key: *k,
138+
str: *v,
139+
num: 0,
140+
num_unit: 0,
141+
})
142+
}
118143
b.profile.sample.push(sample);
119144
}
120145
}
@@ -126,4 +151,4 @@ pub fn encode(reports: Vec<Report>) -> Vec<EncodedReport> {
126151
data: b.profile.encode_to_vec(),
127152
metadata: Default::default(),
128153
}]
129-
}
154+
}

src/pyroscope.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{
2020

2121
use crate::backend::BackendImpl;
2222
use crate::pyroscope::Compression::GZIP;
23+
use crate::pyroscope::ReportEncoding::{PPROF};
2324

2425
const LOG_TAG: &str = "Pyroscope::Agent";
2526

@@ -181,7 +182,8 @@ impl PyroscopeConfig {
181182
report_encoding: report_encoding,
182183
..self
183184
}
184-
}}
185+
}
186+
}
185187

186188
/// PyroscopeAgent Builder
187189
///
@@ -353,8 +355,12 @@ impl PyroscopeAgentBuilder {
353355
// use match instead of if let to avoid the need to borrow
354356
let config = match self.backend.spy_extension()? {
355357
Some(extension) => {
356-
let application_name = config.application_name.clone();
357-
config.application_name(format!("{}.{}", application_name, extension))
358+
if config.report_encoding == PPROF {
359+
config
360+
} else {
361+
let application_name = config.application_name.clone();
362+
config.application_name(format!("{}.{}", application_name, extension))
363+
}
358364
}
359365
None => config,
360366
};
@@ -390,7 +396,7 @@ impl PyroscopeAgentBuilder {
390396
handle: None,
391397
running: Arc::new((
392398
#[allow(clippy::mutex_atomic)]
393-
Mutex::new(false),
399+
Mutex::new(false),
394400
Condvar::new(),
395401
)),
396402
_state: PhantomData,
@@ -413,10 +419,10 @@ impl FromStr for Compression {
413419
}
414420
}
415421

416-
#[derive(Clone, Debug)]
422+
#[derive(Clone, PartialEq, Debug)]
417423
pub enum ReportEncoding {
418424
FOLDED,
419-
PPROF
425+
PPROF,
420426
}
421427

422428
impl FromStr for ReportEncoding {
@@ -425,7 +431,7 @@ impl FromStr for ReportEncoding {
425431
match input {
426432
"collapsed" => Ok(ReportEncoding::FOLDED),
427433
"folded" => Ok(ReportEncoding::FOLDED),
428-
"PPROF" => Ok(ReportEncoding::PPROF),
434+
"pprof" => Ok(ReportEncoding::PPROF),
429435
_ => Err(()),
430436
}
431437
}
@@ -447,7 +453,9 @@ pub struct PyroscopeAgentReady;
447453
pub struct PyroscopeAgentRunning;
448454

449455
impl PyroscopeAgentState for PyroscopeAgentBare {}
456+
450457
impl PyroscopeAgentState for PyroscopeAgentReady {}
458+
451459
impl PyroscopeAgentState for PyroscopeAgentRunning {}
452460

453461
/// PyroscopeAgent is the main object of the library. It is used to start and stop the profiler, schedule the timer, and send the profiler data to the server.
@@ -643,6 +651,7 @@ impl PyroscopeAgent<PyroscopeAgentReady> {
643651
Ok(self.transition())
644652
}
645653
}
654+
646655
impl PyroscopeAgent<PyroscopeAgentRunning> {
647656
/// Stop the agent. The agent will stop profiling and send a last report to the server.
648657
///

src/session.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
pyroscope::{PyroscopeConfig, Compression},
1414
utils::{get_time_range, merge_tags_with_app_name},
1515
Result,
16-
encode::{folded, pprof}
16+
encode::{folded, pprof},
1717
};
1818
use crate::backend::EncodedReport;
1919
use crate::pyroscope::ReportEncoding;
@@ -140,7 +140,6 @@ impl Session {
140140
return Ok(());
141141
}
142142

143-
144143
let reports = self.process_reports(&self.reports);
145144
let reports = self.encode_reports(reports);
146145
let reports = self.compress_reports(reports);
@@ -161,16 +160,20 @@ impl Session {
161160
}
162161
}
163162

164-
// Encode reports to folded or protobuf format
165163
fn encode_reports(&self, reports: Vec<Report>) -> Vec<EncodedReport> {
164+
log::debug!(target: LOG_TAG, "Encoding {} reports to {:?}", reports.len(), self.config.report_encoding);
166165
match &self.config.report_encoding {
167166
ReportEncoding::FOLDED => folded::encode(reports),
168-
ReportEncoding::PPROF => pprof::encode(reports),
167+
ReportEncoding::PPROF => pprof::encode(reports,
168+
self.config.sample_rate,
169+
self.from * 1_000_000,
170+
(self.until - self.from) * 1_000_000,
171+
),
169172
}
170173
}
171174

172-
// Optionally compress reports
173175
fn compress_reports(&self, reports: Vec<EncodedReport>) -> Vec<EncodedReport> {
176+
log::debug!(target: LOG_TAG, "Compressing {} reports to {:?}", reports.len(), self.config.compression);
174177
reports.into_iter().map(|r|
175178
match &self.config.compression {
176179
None => r,

tests/session.rs

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use pyroscope::{
44
session::{Session, SessionManager, SessionSignal},
55
};
66
use std::collections::HashMap;
7-
use pyroscope::backend::{StackFrame, StackTrace};
8-
use pyroscope::pyroscope::ReportEncoding;
97

108
#[test]
119
fn test_session_manager_new() {
@@ -23,54 +21,20 @@ fn test_session_manager_push_kill() {
2321
#[test]
2422
fn test_session_new() {
2523
let config = PyroscopeConfig {
26-
url: "http://localhost:4040".to_string(),
24+
url: "http://localhost:8080".to_string(),
2725
application_name: "test".to_string(),
2826
tags: HashMap::new(),
2927
sample_rate: 100u32,
3028
spy_name: "test-rs".to_string(),
31-
// report_encoding: ReportEncoding::PPROF,
32-
report_encoding: ReportEncoding::FOLDED,
3329
..Default::default()
3430
};
35-
let f1 = StackFrame {
36-
module: None,
37-
name: Some("f1".to_string()),
3831

39-
filename: None,
40-
relative_path: None,
41-
absolute_path: None,
42-
line: None,
43-
};
44-
let f2 = StackFrame {
45-
module: None,
46-
name: Some("f2".to_string()),
47-
filename: None,
48-
relative_path: None,
49-
absolute_path: None,
50-
line: None,
51-
};
52-
53-
let s1 = StackTrace{
54-
pid: None,
55-
thread_id: None,
56-
thread_name: None,
57-
frames: vec![f1.clone(), f2.clone()],
58-
metadata: Default::default()
59-
};
60-
let s2 = StackTrace{
61-
pid: None,
62-
thread_id: None,
63-
thread_name: None,
64-
frames: vec![f2.clone(), f1.clone()],
65-
metadata: Default::default()
66-
};
67-
68-
69-
let report = vec![Report::new(HashMap::from([(s1, 2), (s2, 4)]))];
32+
let report = vec![Report::new(HashMap::new())];
7033

71-
let session = Session::new(1661783070, config, report).unwrap();
34+
let session = Session::new(1950, config, report).unwrap();
7235

73-
session.send().unwrap()
36+
assert_eq!(session.from, 1940);
37+
assert_eq!(session.until, 1950);
7438
}
7539

7640
#[test]

0 commit comments

Comments
 (0)