Skip to content

Commit 1298cd5

Browse files
authored
Merge pull request #4 from omarabid/main
SessionManager + Logging
2 parents a6ad42e + c9d7438 commit 1298cd5

File tree

5 files changed

+184
-4
lines changed

5 files changed

+184
-4
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ readme = "README.md"
1515

1616
[dependencies]
1717
thiserror ="1.0"
18+
log = "0.4"
1819
reqwest = {version = "0.11", features = ["blocking"]}
1920
pprof = { version="0.6.2"}
2021
libc = "^0.2.66"
2122

2223
[dev-dependencies]
2324
tokio = { version = "1.13", features = ["full"] }
25+
pretty_env_logger = "0.4.0"
2426

2527
[profile.dev]
2628
opt-level=0

examples/basic.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,36 @@ fn main() -> Result<()> {
2020
.tags(&[("TagA", "ValueA"), ("TagB", "ValueB")])
2121
.build()?;
2222

23+
// Show start time
24+
let start = std::time::SystemTime::now()
25+
.duration_since(std::time::UNIX_EPOCH)
26+
.unwrap()
27+
.as_secs();
28+
println!("Start Time: {}", start);
29+
2330
// Start Agent
2431
agent.start()?;
2532

2633
let _result = fibonacci(47);
2734

35+
// Show stop time
36+
let stop = std::time::SystemTime::now()
37+
.duration_since(std::time::UNIX_EPOCH)
38+
.unwrap()
39+
.as_secs();
40+
println!("Stop Time: {}", stop);
41+
2842
// Stop Agent
2943
agent.stop()?;
3044

45+
drop(agent);
46+
47+
// Show program exit time
48+
let exit = std::time::SystemTime::now()
49+
.duration_since(std::time::UNIX_EPOCH)
50+
.unwrap()
51+
.as_secs();
52+
println!("Exit Time: {}", exit);
53+
3154
Ok(())
3255
}

examples/with-logger.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2021 Developers of Pyroscope.
2+
3+
// Licensed under the Apache License, Version 2.0 <LICENSE or
4+
// https://www.apache.org/licenses/LICENSE-2.0>. This file may not be copied, modified, or distributed
5+
// except according to those terms.
6+
7+
extern crate pyroscope;
8+
9+
use log::{debug, error, info, trace, warn};
10+
11+
use pyroscope::{PyroscopeAgent, Result};
12+
13+
fn fibonacci(n: u64) -> u64 {
14+
match n {
15+
0 | 1 => 1,
16+
n => fibonacci(n - 1) + fibonacci(n - 2),
17+
}
18+
}
19+
20+
fn main() -> Result<()> {
21+
// Force rustc to display the log messages in the console.
22+
std::env::set_var("RUST_LOG", "trace");
23+
24+
// Initialize the logger.
25+
pretty_env_logger::init_timed();
26+
27+
info!("With Logger example");
28+
29+
// Create a new agent.
30+
let mut agent = PyroscopeAgent::builder("http://localhost:4040", "example.logger").build()?;
31+
32+
// Start Agent
33+
agent.start()?;
34+
35+
let _result = fibonacci(47);
36+
37+
// Stop Agent
38+
agent.stop()?;
39+
40+
Ok(())
41+
}

src/pyroscope.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use crate::backends::pprof::Pprof;
1515
use crate::backends::Backend;
1616
use crate::error::Result;
1717
use crate::session::Session;
18+
use crate::session::SessionManager;
19+
use crate::session::SessionSignal;
1820
use crate::timer::Timer;
1921

2022
/// Represent PyroscopeAgent Configuration
@@ -93,7 +95,9 @@ impl PyroscopeAgentBuilder {
9395

9496
/// Set the agent backend. Default is pprof.
9597
pub fn backend<T: 'static>(self, backend: T) -> Self
96-
where T: Backend {
98+
where
99+
T: Backend,
100+
{
97101
Self {
98102
backend: Arc::new(Mutex::new(backend)),
99103
..self
@@ -121,15 +125,22 @@ impl PyroscopeAgentBuilder {
121125
// Initiliaze the backend
122126
let backend = Arc::clone(&self.backend);
123127
backend.lock()?.initialize(self.config.sample_rate)?;
128+
log::trace!("PyroscopeAgent - Backend initialized");
124129

125130
// Start Timer
126131
let timer = Timer::default().initialize()?;
132+
log::trace!("PyroscopeAgent - Timer initialized");
133+
134+
// Start the SessionManager
135+
let session_manager = SessionManager::new()?;
136+
log::trace!("PyroscopeAgent - SessionManager initialized");
127137

128138
// Return PyroscopeAgent
129139
Ok(PyroscopeAgent {
130140
backend: self.backend,
131141
config: self.config,
132142
timer,
143+
session_manager,
133144
tx: None,
134145
handle: None,
135146
running: Arc::new((Mutex::new(false), Condvar::new())),
@@ -142,6 +153,7 @@ impl PyroscopeAgentBuilder {
142153
pub struct PyroscopeAgent {
143154
pub backend: Arc<Mutex<dyn Backend>>,
144155
timer: Timer,
156+
session_manager: SessionManager,
145157
tx: Option<Sender<u64>>,
146158
handle: Option<JoinHandle<Result<()>>>,
147159
running: Arc<(Mutex<bool>, Condvar)>,
@@ -153,9 +165,29 @@ pub struct PyroscopeAgent {
153165
impl Drop for PyroscopeAgent {
154166
/// Properly shutdown the agent.
155167
fn drop(&mut self) {
168+
log::debug!("PyroscopeAgent::drop()");
169+
156170
// Stop Timer
157171
self.timer.drop_listeners().unwrap(); // Drop listeners
172+
log::trace!("PyroscopeAgent - Dropped timer listeners");
158173
self.timer.handle.take().unwrap().join().unwrap().unwrap(); // Wait for the Timer thread to finish
174+
log::trace!("PyroscopeAgent - Dropped timer thread");
175+
176+
// Stop the SessionManager
177+
self.session_manager.push(SessionSignal::Kill).unwrap();
178+
log::trace!("PyroscopeAgent - Sent kill signal to SessionManager");
179+
self.session_manager
180+
.handle
181+
.take()
182+
.unwrap()
183+
.join()
184+
.unwrap()
185+
.unwrap();
186+
log::trace!("PyroscopeAgent - Dropped SessionManager thread");
187+
188+
// Wait for main thread to finish
189+
self.handle.take().unwrap().join().unwrap().unwrap();
190+
log::trace!("PyroscopeAgent - Dropped main thread");
159191
}
160192
}
161193

@@ -168,6 +200,8 @@ impl PyroscopeAgent {
168200

169201
/// Start profiling and sending data. The agent will keep running until stopped.
170202
pub fn start(&mut self) -> Result<()> {
203+
log::debug!("PyroscopeAgent - Starting");
204+
171205
// Create a clone of Backend
172206
let backend = Arc::clone(&self.backend);
173207
// Call start()
@@ -188,13 +222,27 @@ impl PyroscopeAgent {
188222

189223
let config = self.config.clone();
190224

225+
let stx = self.session_manager.tx.clone();
226+
191227
self.handle = Some(std::thread::spawn(move || {
228+
log::trace!("PyroscopeAgent - Main Thread started");
229+
192230
while let Ok(time) = rx.recv() {
231+
log::trace!("PyroscopeAgent - Sending session {}", time);
232+
233+
// Generate report from backend
193234
let report = backend.lock()?.report()?;
194-
// start a new session
195-
Session::new(time, config.clone(), report)?.send()?;
235+
236+
// Send new Session to SessionManager
237+
stx.send(SessionSignal::Session(Session::new(
238+
time,
239+
config.clone(),
240+
report,
241+
)?))?;
196242

197243
if time == 0 {
244+
log::trace!("PyroscopeAgent - Session Killed");
245+
198246
let (lock, cvar) = &*pair;
199247
let mut running = lock.lock()?;
200248
*running = false;
@@ -212,6 +260,7 @@ impl PyroscopeAgent {
212260

213261
/// Stop the agent.
214262
pub fn stop(&mut self) -> Result<()> {
263+
log::debug!("PyroscopeAgent - Stopping");
215264
// get tx and send termination signal
216265
self.tx.take().unwrap().send(0)?;
217266

@@ -230,6 +279,7 @@ impl PyroscopeAgent {
230279

231280
/// Add tags. This will restart the agent.
232281
pub fn add_tags(&mut self, tags: &[(&str, &str)]) -> Result<()> {
282+
log::debug!("PyroscopeAgent - Adding tags");
233283
// Stop Agent
234284
self.stop()?;
235285

@@ -251,6 +301,7 @@ impl PyroscopeAgent {
251301

252302
/// Remove tags. This will restart the agent.
253303
pub fn remove_tags(&mut self, tags: &[&str]) -> Result<()> {
304+
log::debug!("PyroscopeAgent - Removing tags");
254305
// Stop Agent
255306
self.stop()?;
256307

src/session.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,72 @@
44
// https://www.apache.org/licenses/LICENSE-2.0>. This file may not be copied, modified, or distributed
55
// except according to those terms.
66

7-
use std::{thread, thread::JoinHandle};
7+
use std::{
8+
sync::mpsc::{sync_channel, Receiver, SyncSender},
9+
thread,
10+
thread::JoinHandle,
11+
};
812

913
use crate::pyroscope::PyroscopeConfig;
1014
use crate::utils::merge_tags_with_app_name;
1115
use crate::Result;
1216

17+
/// Session Signal
18+
#[derive(Debug)]
19+
pub enum SessionSignal {
20+
Session(Session),
21+
Kill,
22+
}
23+
24+
/// SessionManager
25+
#[derive(Debug)]
26+
pub struct SessionManager {
27+
pub handle: Option<JoinHandle<Result<()>>>,
28+
pub tx: SyncSender<SessionSignal>,
29+
}
30+
31+
impl SessionManager {
32+
/// Create a new SessionManager
33+
pub fn new() -> Result<Self> {
34+
log::info!("SessionManager - Creating SessionManager");
35+
36+
// Create a channel for sending and receiving sessions
37+
let (tx, rx): (SyncSender<SessionSignal>, Receiver<SessionSignal>) = sync_channel(10);
38+
39+
// Create a thread for the SessionManager
40+
let handle = Some(thread::spawn(move || {
41+
log::trace!("SessionManager - SessionManager thread started");
42+
while let Ok(signal) = rx.recv() {
43+
match signal {
44+
SessionSignal::Session(session) => {
45+
// Send the session
46+
session.send()?;
47+
log::trace!("SessionManager - Session sent");
48+
}
49+
SessionSignal::Kill => {
50+
// Kill the session manager
51+
return Ok(());
52+
log::trace!("SessionManager - Kill signal received");
53+
}
54+
}
55+
}
56+
Ok(())
57+
}));
58+
59+
Ok(SessionManager { handle, tx })
60+
}
61+
62+
/// Push a new session into the SessionManager
63+
pub fn push(&self, session: SessionSignal) -> Result<()> {
64+
// Push the session into the SessionManager
65+
self.tx.send(session)?;
66+
67+
log::trace!("SessionManager - SessionSignal pushed");
68+
69+
Ok(())
70+
}
71+
}
72+
1373
/// Pyroscope Session
1474
#[derive(Clone, Debug)]
1575
pub struct Session {
@@ -21,6 +81,7 @@ pub struct Session {
2181

2282
impl Session {
2383
pub fn new(mut until: u64, config: PyroscopeConfig, report: Vec<u8>) -> Result<Self> {
84+
log::info!("Session - Creating Session");
2485
// Session interrupted (0 signal), determine the time
2586
if until == 0 {
2687
let now = std::time::SystemTime::now()
@@ -43,6 +104,8 @@ impl Session {
43104
}
44105

45106
pub fn send(self) -> Result<()> {
107+
log::info!("Session - Sending Session");
108+
46109
let _handle: JoinHandle<Result<()>> = thread::spawn(move || {
47110
if self.report.is_empty() {
48111
return Ok(());

0 commit comments

Comments
 (0)