@@ -207,7 +207,7 @@ impl ProfilerOptionsBuilder {
207207 self
208208 }
209209
210- /// Sets the interva in which the profiler will collect
210+ /// Sets the interval in which the profiler will collect
211211 /// CPU-time samples, via the [async-profiler `interval` option].
212212 ///
213213 /// CPU-time samples (JFR `jdk.ExecutionSample`) sample only threads that
@@ -261,7 +261,13 @@ impl ProfilerOptionsBuilder {
261261 /// Wall-clock samples (JFR `profiler.WallClockSample`) sample threads
262262 /// whether they are sleeping or running, and can therefore be
263263 /// very useful for finding threads that are blocked, for example
264- /// on a synchronous lock.
264+ /// on a synchronous lock or a slow system call.
265+ ///
266+ /// When using Tokio, since tasks are not threads, tasks that are not
267+ /// currently running will not be sampled by a wall clock sample. However,
268+ /// a wall clock sample is still very useful in Tokio, since it is what
269+ /// you want to catch tasks that are blocking a thread by waiting on
270+ /// synchronous operations.
265271 ///
266272 /// The default is to do a wall-clock sample every second.
267273 ///
@@ -370,81 +376,7 @@ impl ProfilerBuilder {
370376 doc = "[`S3Reporter`]: crate::reporter::s3::S3Reporter"
371377 ) ]
372378 ///
373- #[ cfg_attr( feature = "s3-no-defaults" , doc = "## Example" ) ]
374- #[ cfg_attr( feature = "s3-no-defaults" , doc = "" ) ]
375- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"```no_run"# ) ]
376- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# use std::path::PathBuf;"# ) ]
377- #[ cfg_attr(
378- feature = "s3-no-defaults" ,
379- doc = r#"# use async_profiler_agent::profiler::{ProfilerBuilder, SpawnError};"#
380- ) ]
381- #[ cfg_attr(
382- feature = "s3-no-defaults" ,
383- doc = r#"# use async_profiler_agent::reporter::s3::{S3Reporter, S3ReporterConfig};"#
384- ) ]
385- #[ cfg_attr(
386- feature = "s3-no-defaults" ,
387- doc = r#"# use async_profiler_agent::metadata::AgentMetadata;"#
388- ) ]
389- #[ cfg_attr(
390- feature = "s3-no-defaults" ,
391- doc = r#"# use aws_config::BehaviorVersion;"#
392- ) ]
393- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# #[tokio::main]"# ) ]
394- #[ cfg_attr(
395- feature = "s3-no-defaults" ,
396- doc = r#"# async fn main() -> Result<(), SpawnError> {"#
397- ) ]
398- #[ cfg_attr(
399- feature = "s3-no-defaults" ,
400- doc = r#"# let path = PathBuf::from(".");"#
401- ) ]
402- #[ cfg_attr(
403- feature = "s3-no-defaults" ,
404- doc = r#"let bucket_owner = "<your account id>";"#
405- ) ]
406- #[ cfg_attr(
407- feature = "s3-no-defaults" ,
408- doc = r#"let bucket_name = "<your bucket name>";"#
409- ) ]
410- #[ cfg_attr(
411- feature = "s3-no-defaults" ,
412- doc = r#"let profiling_group = "a-name-to-give-the-uploaded-data";"#
413- ) ]
414- #[ cfg_attr(
415- feature = "s3-no-defaults" ,
416- doc = r#"let sdk_config = aws_config::defaults(BehaviorVersion::latest()).load().await;"#
417- ) ]
418- #[ cfg_attr(
419- feature = "s3-no-defaults" ,
420- doc = r#"let agent = ProfilerBuilder::default()"#
421- ) ]
422- #[ cfg_attr(
423- feature = "s3-no-defaults" ,
424- doc = r#" .with_reporter(S3Reporter::new(S3ReporterConfig {"#
425- ) ]
426- #[ cfg_attr(
427- feature = "s3-no-defaults" ,
428- doc = r#" sdk_config: &sdk_config,"#
429- ) ]
430- #[ cfg_attr(
431- feature = "s3-no-defaults" ,
432- doc = r#" bucket_owner: bucket_owner.into(),"#
433- ) ]
434- #[ cfg_attr(
435- feature = "s3-no-defaults" ,
436- doc = r#" bucket_name: bucket_name.into(),"#
437- ) ]
438- #[ cfg_attr(
439- feature = "s3-no-defaults" ,
440- doc = r#" profiling_group_name: profiling_group.into(),"#
441- ) ]
442- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#" }))"# ) ]
443- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#" .build()"# ) ]
444- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#" .spawn()?;"# ) ]
445- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# Ok::<_, SpawnError>(())"# ) ]
446- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# }"# ) ]
447- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"```"# ) ]
379+ #[ cfg_attr( feature = "s3-no-defaults" , doc = include_str!( "s3-example.md" ) ) ]
448380 pub fn with_reporter ( mut self , r : impl Reporter + Send + Sync + ' static ) -> ProfilerBuilder {
449381 self . reporter = Some ( Box :: new ( r) ) ;
450382 self
@@ -482,7 +414,7 @@ impl ProfilerBuilder {
482414 /// ```
483415 pub fn with_local_reporter ( mut self , path : impl Into < PathBuf > ) -> ProfilerBuilder {
484416 self . reporter = Some ( Box :: new ( LocalReporter :: new ( path. into ( ) ) ) ) ;
485- self . with_custom_agent_metadata ( AgentMetadata :: Other )
417+ self . with_custom_agent_metadata ( AgentMetadata :: NoMetadata )
486418 }
487419
488420 /// Provide custom agent metadata.
@@ -502,94 +434,7 @@ impl ProfilerBuilder {
502434 /// you will need to create and attach your own metadata
503435 /// by calling this function.
504436 ///
505- #[ cfg_attr( feature = "s3-no-defaults" , doc = "## Example" ) ]
506- #[ cfg_attr( feature = "s3-no-defaults" , doc = "" ) ]
507- #[ cfg_attr(
508- feature = "s3-no-defaults" ,
509- doc = "This will create a profiler that will upload to S3 with"
510- ) ]
511- #[ cfg_attr(
512- feature = "s3-no-defaults" ,
513- doc = "empty ([AgentMetadata::Other]) metadata."
514- ) ]
515- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#""# ) ]
516- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"```no_run"# ) ]
517- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# use std::path::PathBuf;"# ) ]
518- #[ cfg_attr(
519- feature = "s3-no-defaults" ,
520- doc = r#"# use async_profiler_agent::profiler::{ProfilerBuilder, SpawnError};"#
521- ) ]
522- #[ cfg_attr(
523- feature = "s3-no-defaults" ,
524- doc = r#"# use async_profiler_agent::reporter::s3::{S3Reporter, S3ReporterConfig};"#
525- ) ]
526- #[ cfg_attr(
527- feature = "s3-no-defaults" ,
528- doc = r#"# use async_profiler_agent::metadata::AgentMetadata;"#
529- ) ]
530- #[ cfg_attr(
531- feature = "s3-no-defaults" ,
532- doc = r#"# use aws_config::BehaviorVersion;"#
533- ) ]
534- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# #[tokio::main]"# ) ]
535- #[ cfg_attr(
536- feature = "s3-no-defaults" ,
537- doc = r#"# async fn main() -> Result<(), SpawnError> {"#
538- ) ]
539- #[ cfg_attr(
540- feature = "s3-no-defaults" ,
541- doc = r#"# let path = PathBuf::from(".");"#
542- ) ]
543- #[ cfg_attr(
544- feature = "s3-no-defaults" ,
545- doc = r#"let bucket_owner = "<your account id>";"#
546- ) ]
547- #[ cfg_attr(
548- feature = "s3-no-defaults" ,
549- doc = r#"let bucket_name = "<your bucket name>";"#
550- ) ]
551- #[ cfg_attr(
552- feature = "s3-no-defaults" ,
553- doc = r#"let profiling_group = "a-name-to-give-the-uploaded-data";"#
554- ) ]
555- #[ cfg_attr(
556- feature = "s3-no-defaults" ,
557- doc = r#"let sdk_config = aws_config::defaults(BehaviorVersion::latest()).load().await;"#
558- ) ]
559- #[ cfg_attr(
560- feature = "s3-no-defaults" ,
561- doc = r#"let agent = ProfilerBuilder::default()"#
562- ) ]
563- #[ cfg_attr(
564- feature = "s3-no-defaults" ,
565- doc = r#" .with_reporter(S3Reporter::new(S3ReporterConfig {"#
566- ) ]
567- #[ cfg_attr(
568- feature = "s3-no-defaults" ,
569- doc = r#" sdk_config: &sdk_config,"#
570- ) ]
571- #[ cfg_attr(
572- feature = "s3-no-defaults" ,
573- doc = r#" bucket_owner: bucket_owner.into(),"#
574- ) ]
575- #[ cfg_attr(
576- feature = "s3-no-defaults" ,
577- doc = r#" bucket_name: bucket_name.into(),"#
578- ) ]
579- #[ cfg_attr(
580- feature = "s3-no-defaults" ,
581- doc = r#" profiling_group_name: profiling_group.into(),"#
582- ) ]
583- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#" }))"# ) ]
584- #[ cfg_attr(
585- feature = "s3-no-defaults" ,
586- doc = r#" .with_custom_agent_metadata(AgentMetadata::Other)"#
587- ) ]
588- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#" .build()"# ) ]
589- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#" .spawn()?;"# ) ]
590- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# Ok::<_, SpawnError>(())"# ) ]
591- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"# }"# ) ]
592- #[ cfg_attr( feature = "s3-no-defaults" , doc = r#"```"# ) ]
437+ #[ cfg_attr( feature = "s3-no-defaults" , doc = include_str!( "s3-example-custom-metadata.md" ) ) ]
593438 /// [`reporter::s3::MetadataJson`]: crate::reporter::s3::MetadataJson
594439 /// [Amazon EC2]: https://aws.amazon.com/ec2
595440 /// [Amazon Fargate]: https://aws.amazon.com/fargate
@@ -871,6 +716,33 @@ impl RunningProfilerThread {
871716
872717/// Rust profiler based on [async-profiler].
873718///
719+ /// Spawning a profiler can be done either in an attached (controllable)
720+ /// mode, which allows for stopping the profiler (and, in fact, stops
721+ /// it when the relevant handle is dropped), or in detached mode,
722+ /// in which the profiler keeps running forever. Applications that can
723+ /// shut down the profiler at run-time, for example applications that
724+ /// support reconfiguration of a running profiler, generally want to use
725+ /// controllable mode. Other applications (most of them) should use
726+ /// detached mode.
727+ ///
728+ /// In addition, the profiler can either be spawned into the current Tokio
729+ /// runtime, or into a new one. Normally, applications should spawn
730+ /// the profiler into their own Tokio runtime, but applications that
731+ /// don't have a default Tokio runtime should spawn it into a
732+ /// different one
733+ ///
734+ /// This leaves 4 functions:
735+ /// 1. [Self::spawn] - detached, same runtime
736+ /// 2. [Self::spawn_thread_to_runtime] - detached, different runtime
737+ /// 3. [Self::spawn_controllable] - controllable, same runtime
738+ /// 4. [Self::spawn_controllable_thread_to_runtime] - controllable, different runtime
739+ ///
740+ /// In addition, there's a helper function that just spawns the profiler
741+ /// to a new runtime in a new thread, for applications that don't have
742+ /// a Tokio runtime and don't need complex control:
743+ ///
744+ /// 5. [Self::spawn_thread] - detached, new runtime in a new thread
745+ ///
874746/// [async-profiler]: https://github.com/async-profiler/async-profiler
875747pub struct Profiler {
876748 reporting_interval : Duration ,
@@ -923,7 +795,7 @@ impl Profiler {
923795
924796 /// Like [Self::spawn], but instead of spawning within the current Tokio
925797 /// runtime, spawns within a set Tokio runtime and then runs a thread that calls
926- /// [tokio::runtime::Runtime::block_on] on that runtime.
798+ /// [block_on]( tokio::runtime::Runtime::block_on) on that runtime.
927799 ///
928800 /// If your configuration is standard, use [Profiler::spawn_thread].
929801 ///
@@ -970,7 +842,7 @@ impl Profiler {
970842
971843 /// Like [Self::spawn], but instead of spawning within the current Tokio
972844 /// runtime, spawns within a new Tokio runtime and then runs a thread that calls
973- /// [tokio::runtime::Runtime::block_on] on that runtime, setting up the runtime
845+ /// [block_on]( tokio::runtime::Runtime::block_on) on that runtime, setting up the runtime
974846 /// by itself.
975847 ///
976848 /// If your configuration is less standard, use [Profiler::spawn_thread_to_runtime]. Calling
@@ -1080,7 +952,7 @@ impl Profiler {
1080952
1081953 /// Like [Self::spawn_controllable], but instead of spawning within the current Tokio
1082954 /// runtime, spawns within a set Tokio runtime and then runs a thread that calls
1083- /// [tokio::runtime::Runtime::block_on] on that runtime.
955+ /// [block_on]( tokio::runtime::Runtime::block_on) on that runtime.
1084956 ///
1085957 /// `spawn_fn` should be [`std::thread::spawn`], or some function that behaves like it (to
1086958 /// allow for configuring thread properties, for example thread names).
@@ -1243,7 +1115,7 @@ async fn profiler_tick<E: ProfilerEngine>(
12431115 #[ cfg( feature = "aws-metadata-no-defaults" ) ]
12441116 let md = crate :: metadata:: aws:: load_agent_metadata ( ) . await ?;
12451117 #[ cfg( not( feature = "aws-metadata-no-defaults" ) ) ]
1246- let md = crate :: metadata:: AgentMetadata :: Other ;
1118+ let md = crate :: metadata:: AgentMetadata :: NoMetadata ;
12471119 tracing:: debug!( "loaded metadata" ) ;
12481120 agent_metadata. replace ( md) ;
12491121 }
@@ -1597,7 +1469,7 @@ mod tests {
15971469 r#"Some(LocalReporter { directory: "." })"#
15981470 ) ;
15991471 match reporter. agent_metadata {
1600- Some ( AgentMetadata :: Other ) => { }
1472+ Some ( AgentMetadata :: NoMetadata ) => { }
16011473 bad => panic ! ( "{bad:?}" ) ,
16021474 } ;
16031475 }
0 commit comments