Tracing for wasm with bridging to native (#6916)

* implement events handling, implement parent_id for spans & events

* add events to sp_io::storage

* update test

* add tests

* adjust limit

* let tracing crate handle parent_ids

* re-enable current-id tracking

* add test for threads with CurrentSpan

* fix log level

* remove redundant check for non wasm traces

* remove duplicate definition in test

* Adding conditional events API

* prefer explicit parent_id over current,

enhance test

* limit changes to client::tracing event implementation

* remove From impl due to fallback required on parent_id

* make tracing codecable

* replace with global tracing

* new tracing interface

* impl TracingSubscriber in client

* implement access to global TracingSubscriber from primitives

* span for wasm

* increment towards Wasm Tracing Subscriber implementation

* increment, remove sp-tracing from runtime-interface

* increment, it compiles

* attained original functionality with new mechanism

* implement remaining TracingSubscriber functions

* remove spans from decl_module

* add handling for encoded values

* Revert "replace with global tracing"

This reverts commit 8824a60deea54d9b437407a21c8ceaf6a1902ee5.

* Wasm Side Tracing

* tracing on wasm

* enable tracing wasm on node-runtime

* export all the macros in std

* tracing subscriber on wasm-side only

* pass spans and events over and record them

* reactivate previous code and  cleanup

* further cleaning up

* extend the span macros, activate through executive

* tracking the actual extrinsic, too

* style

* fixing tests

* spaces -> tabs

* attempting to reactivate params

* activate our tests in CI

* some passing

* tests passing

* with core lazy

* global tracer for wasm side with pass over

* fixing metadata referencing

* remove const_fn feature requirement

* reenable dispatch traces

* reset client tracing

* further cleaning up

* fixing runtime-test

* move tracing-build setup into runtime-test

* Merge DebugWriter from tracing and frame-support, move to sp-std

* remove dangling fixme

* Docs for tracing primitives

* cleaning up a bit more

* Wasm interface docs

* optimise docs.rs setup

* adding tracing flags to uncomment

* remove brace

* fixing imports

* fixing broken syntax

* add required modules

* nicer formatting

* better target management

* adding low level storage tracing events into frame

* add custom Debug impl for WasmMetadata

* cloning profiler

* adding info about cloning profiler

* using in-scope for within calls

* proper time tracing, cleaning up println

* allow to disable tracing on runtime_interface-macro

* disable tracing for wasm-tracing-interface

* simplify wasm-tracing-api

* update client to new interface

* fixing docs and tests for sp-tracing

* update integration tests

* re-activating enter_span

* dropping FIXME, it's documented

* fix formatting

* fix formatting

* fix imports

* more debug info

* inform wasm about it being disabled by returning 1

* only one tracer, but enabled multi-all support

* make trait pub again for tests

* Apply suggestions from code review

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* fixing wasm doc tests for proper usage

* remove unnecessary import

* fixing formatting

* minor style fixes

* downgrading wabt

* update error message for UI

* Fix interface test

* next attempt to fix macros

* geee

* revert tracing on hashed for future PR

* remove local macros, use originals

* we are able to convert to static items

* implement more WasmValue types

* adding support to convert str, debug and encoded values

* more minor fixes

* revert unsafe 'static making

* fix indentation

* remove commented lines

* bump all them tracing versions

* cleaning up docs and info

* document new flag

* the new layered system handles span cloning better

* Apply suggestions from code review

Co-authored-by: David <dvdplm@gmail.com>

Co-authored-by: Matt Rutherford <mattrutherford@users.noreply.github.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: David <dvdplm@gmail.com>
This commit is contained in:
Benjamin Kampmann
2020-09-18 08:10:59 +02:00
committed by GitHub
parent 649bee1a1e
commit a9c73113a8
34 changed files with 1207 additions and 436 deletions
@@ -26,21 +26,59 @@
//! 3. The [`PassByEnum`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Enum`.
//! 4. The [`PassByInner`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Inner`.
use syn::{parse_macro_input, ItemTrait, DeriveInput};
use syn::{parse_macro_input, ItemTrait, DeriveInput, Result, Token};
use syn::parse::{Parse, ParseStream};
mod pass_by;
mod runtime_interface;
mod utils;
struct Options {
wasm_only: bool,
tracing: bool
}
impl Options {
fn unpack(self) -> (bool, bool) {
(self.wasm_only, self.tracing)
}
}
impl Default for Options {
fn default() -> Self {
Options { wasm_only: false, tracing: true }
}
}
impl Parse for Options {
fn parse(input: ParseStream) -> Result<Self> {
let mut res = Self::default();
while !input.is_empty() {
let lookahead = input.lookahead1();
if lookahead.peek(runtime_interface::keywords::wasm_only) {
let _ = input.parse::<runtime_interface::keywords::wasm_only>();
res.wasm_only = true;
} else if lookahead.peek(runtime_interface::keywords::no_tracing) {
let _ = input.parse::<runtime_interface::keywords::no_tracing>();
res.tracing = false;
} else if lookahead.peek(Token![,]) {
let _ = input.parse::<Token![,]>();
} else {
return Err(lookahead.error())
}
}
Ok(res)
}
}
#[proc_macro_attribute]
pub fn runtime_interface(
attrs: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let trait_def = parse_macro_input!(input as ItemTrait);
let wasm_only = parse_macro_input!(attrs as Option<runtime_interface::keywords::wasm_only>);
let (wasm_only, tracing) = parse_macro_input!(attrs as Options).unpack();
runtime_interface::runtime_interface_impl(trait_def, wasm_only.is_some())
runtime_interface::runtime_interface_impl(trait_def, wasm_only, tracing)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
@@ -61,4 +99,4 @@ pub fn pass_by_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream
pub fn pass_by_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
pass_by::enum_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
}
}
@@ -46,7 +46,7 @@ use std::iter;
/// Generate one bare function per trait method. The name of the bare function is equal to the name
/// of the trait method.
pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool, tracing: bool) -> Result<TokenStream> {
let trait_name = &trait_def.ident;
let runtime_interface = get_runtime_interface(trait_def)?;
@@ -63,7 +63,7 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream
// earlier versions compatibility dispatch (only std variant)
let result: Result<TokenStream> = runtime_interface.all_versions().try_fold(token_stream?, |mut t, (version, method)|
{
t.extend(function_std_impl(trait_name, method, version, is_wasm_only)?);
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
Ok(t)
});
@@ -145,6 +145,7 @@ fn function_std_impl(
method: &TraitItemMethod,
version: u32,
is_wasm_only: bool,
tracing: bool,
) -> Result<TokenStream> {
let function_name = create_function_ident_with_version(&method.sig.ident, version);
let function_name_str = function_name.to_string();
@@ -168,13 +169,21 @@ fn function_std_impl(
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
// Don't make the function public accessible when this is a wasm only interface.
let call_to_trait = generate_call_to_trait(trait_name, method, version, is_wasm_only);
let call_to_trait = if !tracing {
call_to_trait
} else {
parse_quote!(
#crate_::sp_tracing::within_span! { #crate_::sp_tracing::trace_span!(#function_name_str);
#call_to_trait
}
)
};
Ok(
quote_spanned! { method.span() =>
#[cfg(feature = "std")]
#( #attrs )*
fn #function_name( #( #args, )* ) #return_value {
#crate_::sp_tracing::enter_span!(#function_name_str);
#call_to_trait
}
}
@@ -227,7 +227,6 @@ fn generate_host_function_implementation(
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
#crate_::sp_tracing::enter_span!(#name);
#( #wasm_to_ffi_values )*
#( #ffi_to_host_values )*
#host_function_call
@@ -33,14 +33,20 @@ mod trait_decl_impl;
pub mod keywords {
// Custom keyword `wasm_only` that can be given as attribute to [`runtime_interface`].
syn::custom_keyword!(wasm_only);
// Disable tracing-macros added to the [`runtime_interface`] by specifying this optional entry
syn::custom_keyword!(no_tracing);
}
/// Implementation of the `runtime_interface` attribute.
///
/// It expects the trait definition the attribute was put above and if this should be an wasm only
/// interface.
pub fn runtime_interface_impl(trait_def: ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
let bare_functions = bare_function_interface::generate(&trait_def, is_wasm_only)?;
pub fn runtime_interface_impl(
trait_def: ItemTrait,
is_wasm_only: bool,
tracing: bool,
) -> Result<TokenStream> {
let bare_functions = bare_function_interface::generate(&trait_def, is_wasm_only, tracing)?;
let crate_include = generate_runtime_interface_include();
let mod_name = Ident::new(&trait_def.ident.to_string().to_snake_case(), Span::call_site());
let trait_decl_impl = trait_decl_impl::process(&trait_def, is_wasm_only)?;