Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Publish to crates.io

on:
workflow_dispatch:
release:
types: [published]

jobs:
publish-pyroscope:
name: Publish pyroscope crate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: publish pyroscope crate
continue-on-error: true
run: |
cargo login ${{ secrets.CARGO_TOKEN }}
cargo publish
15 changes: 15 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Pre-Release

on: [push]

jobs:
release:
name: Create draft release
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
steps:
- uses: "marvinpinto/action-automatic-releases@v1.1.1"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
draft: true
prerelease: false
4 changes: 2 additions & 2 deletions examples/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async fn main() -> Result<()> {
.build()?;

// Start Agent
agent.start()?;
agent.start();

tokio::task::spawn(async {
let n = fibonacci1(45);
Expand All @@ -46,7 +46,7 @@ async fn main() -> Result<()> {
.unwrap();

// Stop Agent
agent.stop()?;
agent.stop();

Ok(())
}
4 changes: 2 additions & 2 deletions examples/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ fn main() -> Result<()> {
.tags(&[("TagA", "ValueA"), ("TagB", "ValueB")])
.build()?;

agent.start()?;
agent.start();
let _result = fibonacci(45);
agent.stop()?;
agent.stop();

Ok(())
}
4 changes: 2 additions & 2 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn main() -> Result<()> {
println!("Start Time: {}", start);

// Start Agent
agent.start()?;
agent.start();

let _result = fibonacci(47);

Expand All @@ -40,7 +40,7 @@ fn main() -> Result<()> {
println!("Stop Time: {}", stop);

// Stop Agent
agent.stop()?;
agent.stop();

drop(agent);

Expand Down
13 changes: 5 additions & 8 deletions examples/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,22 @@ fn fibonacci(n: u64) -> u64 {
}

fn main() -> Result<()> {
// Force rustc to display the log messages in the console.
// Force rustc to display the log messages in the console.
std::env::set_var("RUST_LOG", "trace");

// Initialize the logger.
pretty_env_logger::init_timed();

// This example should fail and return an error.
println!("This example should fail and return an error.");
println!("Run this with: RUST_BACKTRACE=1 cargo run --example error");

let mut agent = PyroscopeAgent::builder("http://invalid_url", "example.error")
.build()?;
.build()
.unwrap();
// Start Agent
agent.start()?;
agent.start();

let _result = fibonacci(47);

// Stop Agent
agent.stop()?;
agent.stop();

drop(agent);

Expand Down
4 changes: 2 additions & 2 deletions examples/multi-thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn main() -> Result<()> {
.build()?;

// Start Agent
agent.start()?;
agent.start();

let handle_1 = thread::spawn(|| {
fibonacci1(45);
Expand All @@ -45,7 +45,7 @@ fn main() -> Result<()> {
handle_2.join().unwrap();

// Stop Agent
agent.stop()?;
agent.stop();

Ok(())
}
4 changes: 2 additions & 2 deletions examples/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn main() -> Result<()> {
.build()?;

// Start Agent
agent.start()?;
agent.start();

// Make some calculation
let _result = fibonacci(47);
Expand All @@ -34,7 +34,7 @@ fn main() -> Result<()> {
let _result = fibonacci(47);

// Stop Agent
agent.stop()?;
agent.stop();

Ok(())
}
4 changes: 2 additions & 2 deletions examples/with-logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ fn main() -> Result<()> {
let mut agent = PyroscopeAgent::builder("http://localhost:4040", "example.logger").build()?;

// Start Agent
agent.start()?;
agent.start();

let _result = fibonacci(47);

// Stop Agent
agent.stop()?;
agent.stop();

Ok(())
}
2 changes: 1 addition & 1 deletion src/backends/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::Result;

use std::fmt::Debug;

/// Backend State
/// Backend State
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum State {
/// Backend is uninitialized.
Expand Down
4 changes: 1 addition & 3 deletions src/backends/pprof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ impl Backend for Pprof<'_> {

// Copyright: https://github.com/YangKeao
fn fold<W>(report: &Report, with_thread_name: bool, mut writer: W) -> Result<()>
where
W: std::io::Write,
{
where W: std::io::Write {
for (key, value) in report.data.iter() {
if with_thread_name {
if !key.thread_name.is_empty() {
Expand Down
101 changes: 60 additions & 41 deletions src/pyroscope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ impl PyroscopeAgentBuilder {
/// .unwrap();
/// ```
pub fn backend<T: 'static>(self, backend: T) -> Self
where
T: Backend,
{
where T: Backend {
Self {
backend: Arc::new(Mutex::new(backend)),
..self
Expand Down Expand Up @@ -220,37 +218,47 @@ pub struct PyroscopeAgent {
pub config: PyroscopeConfig,
}

/// Gracefully stop the profiler.
impl Drop for PyroscopeAgent {
/// Properly shutdown the agent.
fn drop(&mut self) {
log::debug!("PyroscopeAgent::drop()");

// Stop Timer
self.timer.drop_listeners().unwrap(); // Drop listeners
log::trace!("PyroscopeAgent - Dropped timer listeners");
self.timer.handle.take().unwrap().join().unwrap().unwrap(); // Wait for the Timer thread to finish
log::trace!("PyroscopeAgent - Dropped timer thread");
// Drop Timer listeners
match self.timer.drop_listeners() {
Ok(_) => log::trace!("PyroscopeAgent - Dropped timer listeners"),
Err(_) => log::error!("PyroscopeAgent - Error Dropping timer listeners"),
}

// Wait for the Timer thread to finish
match self.timer.handle.take().unwrap().join() {
Ok(_) => log::trace!("PyroscopeAgent - Dropped timer thread"),
Err(_) => log::error!("PyroscopeAgent - Error Dropping timer thread"),
}

// Stop the SessionManager
self.session_manager.push(SessionSignal::Kill).unwrap();
log::trace!("PyroscopeAgent - Sent kill signal to SessionManager");
self.session_manager
.handle
.take()
.unwrap()
.join()
.unwrap()
.unwrap();
log::trace!("PyroscopeAgent - Dropped SessionManager thread");
match self.session_manager.push(SessionSignal::Kill) {
Ok(_) => log::trace!("PyroscopeAgent - Sent kill signal to SessionManager"),
Err(_) => log::error!("PyroscopeAgent - Error sending kill signal to SessionManager"),
}

// Stop SessionManager
match self.session_manager.handle.take().unwrap().join() {
Ok(_) => log::trace!("PyroscopeAgent - Dropped SessionManager thread"),
Err(_) => log::error!("PyroscopeAgent - Error Dropping SessionManager thread"),
}

// Wait for main thread to finish
self.handle.take().unwrap().join().unwrap().unwrap();
log::trace!("PyroscopeAgent - Dropped main thread");
match self.handle.take().unwrap().join() {
Ok(_) => log::trace!("PyroscopeAgent - Dropped main thread"),
Err(_) => log::error!("PyroscopeAgent - Error Dropping main thread"),
}
}
}

impl PyroscopeAgent {
/// Short-hand for PyroscopeAgentBuilder::build(). This is a convenience method.
///
/// # Example
/// ```ignore
/// let agent = PyroscopeAgent::builder("http://localhost:8080", "my-app").build().unwrap();
Expand All @@ -260,13 +268,7 @@ impl PyroscopeAgent {
PyroscopeAgentBuilder::new(url, application_name)
}

/// Start profiling and sending data. The agent will keep running until stopped. The agent will send data to the server every 10s secondy.
/// # Example
/// ```ignore
/// let agent = PyroscopeAgent::builder("http://localhost:8080", "my-app").build().unwrap();
/// agent.start().unwrap();
/// ```
pub fn start(&mut self) -> Result<()> {
fn _start(&mut self) -> Result<()> {
log::debug!("PyroscopeAgent - Starting");

// Create a clone of Backend
Expand All @@ -276,16 +278,14 @@ impl PyroscopeAgent {

// set running to true
let pair = Arc::clone(&self.running);
let (lock, cvar) = &*pair;
let (lock, _cvar) = &*pair;
let mut running = lock.lock()?;
*running = true;
drop(lock);
drop(cvar);
drop(running);

let (tx, rx): (Sender<u64>, Receiver<u64>) = channel();
self.timer.attach_listener(tx.clone())?;
self.tx = Some(tx.clone());
self.tx = Some(tx);

let config = self.config.clone();

Expand Down Expand Up @@ -318,22 +318,26 @@ impl PyroscopeAgent {
return Ok(());
}
}

return Ok(());
Ok(())
}));

Ok(())
}

/// Stop the agent. The agent will stop profiling and send a last report to the server.
/// Start profiling and sending data. The agent will keep running until stopped. The agent will send data to the server every 10s secondy.
/// # Example
/// ```ignore
/// let agent = PyroscopeAgent::builder("http://localhost:8080", "my-app").build().unwrap();
/// agent.start().unwrap();
/// // Expensive operation
/// agent.stop().unwrap();
/// ```
pub fn stop(&mut self) -> Result<()> {
pub fn start(&mut self) {
match self._start() {
Ok(_) => log::trace!("PyroscopeAgent - Agent started"),
Err(_) => log::error!("PyroscopeAgent - Error starting agent"),
}
}

fn _stop(&mut self) -> Result<()> {
log::debug!("PyroscopeAgent - Stopping");
// get tx and send termination signal
self.tx.take().unwrap().send(0)?;
Expand All @@ -351,6 +355,21 @@ impl PyroscopeAgent {
Ok(())
}

/// Stop the agent. The agent will stop profiling and send a last report to the server.
/// # Example
/// ```ignore
/// let agent = PyroscopeAgent::builder("http://localhost:8080", "my-app").build().unwrap();
/// agent.start().unwrap();
/// // Expensive operation
/// agent.stop().unwrap();
/// ```
pub fn stop(&mut self) {
match self._stop() {
Ok(_) => log::trace!("PyroscopeAgent - Agent stopped"),
Err(_) => log::error!("PyroscopeAgent - Error stopping agent"),
}
}

/// Add tags. This will restart the agent.
/// # Example
/// ```ignore
Expand All @@ -369,7 +388,7 @@ impl PyroscopeAgent {
}

// Stop Agent
self.stop()?;
self.stop();

// Convert &[(&str, &str)] to HashMap(String, String)
let tags_hashmap: HashMap<String, String> = tags
Expand All @@ -382,7 +401,7 @@ impl PyroscopeAgent {
self.config.tags.extend(tags_hashmap);

// Restart Agent
self.start()?;
self.start();

Ok(())
}
Expand All @@ -407,7 +426,7 @@ impl PyroscopeAgent {
}

// Stop Agent
self.stop()?;
self.stop();

// Iterate through every tag
tags.iter().for_each(|key| {
Expand All @@ -416,7 +435,7 @@ impl PyroscopeAgent {
});

// Restart Agent
self.start()?;
self.start();

Ok(())
}
Expand Down
Loading