feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,508 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Bizinikiwi tracing primitives and macros.
|
||||
//!
|
||||
//! To trace functions or individual code in Bizinikiwi, this crate provides [`within_span`]
|
||||
//! and [`enter_span`]. See the individual docs for how to use these macros.
|
||||
//!
|
||||
//! Note that to allow traces from wasm execution environment there are
|
||||
//! 2 reserved identifiers for tracing `Field` recording, stored in the consts:
|
||||
//! `WASM_TARGET_KEY` and `WASM_NAME_KEY` - if you choose to record fields, you
|
||||
//! must ensure that your identifiers do not clash with either of these.
|
||||
//!
|
||||
//! Additionally, we have a const: `WASM_TRACE_IDENTIFIER`, which holds a span name used
|
||||
//! to signal that the 'actual' span name and target should be retrieved instead from
|
||||
//! the associated Fields mentioned above.
|
||||
//!
|
||||
//! Note: The `tracing` crate requires trace metadata to be static. This does not work
|
||||
//! for wasm code in bizinikiwi, as it is regularly updated with new code from on-chain
|
||||
//! events. The workaround for this is for the wasm tracing wrappers to put the
|
||||
//! `name` and `target` data in the `values` map (normally they would be in the static
|
||||
//! metadata assembled at compile time).
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use tracing;
|
||||
pub use tracing::{
|
||||
debug, debug_span, error, error_span, event, info, info_span, span, trace, trace_span, warn,
|
||||
warn_span, Level, Span,
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use tracing_subscriber;
|
||||
|
||||
pub use crate::types::{
|
||||
WasmEntryAttributes, WasmFieldName, WasmFields, WasmLevel, WasmMetadata, WasmValue,
|
||||
WasmValuesSet,
|
||||
};
|
||||
#[cfg(not(bizinikiwi_runtime))]
|
||||
pub use crate::types::{WASM_NAME_KEY, WASM_TARGET_KEY, WASM_TRACE_IDENTIFIER};
|
||||
|
||||
/// Tracing facilities and helpers.
|
||||
///
|
||||
/// This is modeled after the `tracing`/`tracing-core` interface and uses that more or
|
||||
/// less directly for the native side. Because of certain optimisations the these crates
|
||||
/// have done, the wasm implementation diverges slightly and is optimised for that use
|
||||
/// case (like being able to cross the wasm/native boundary via scale codecs).
|
||||
///
|
||||
/// One of said optimisations is that all macros will yield to a `noop` in non-std unless
|
||||
/// the `with-tracing` feature is explicitly activated. This allows you to just use the
|
||||
/// tracing wherever you deem fit and without any performance impact by default. Only if
|
||||
/// the specific `with-tracing`-feature is activated on this crate will it actually include
|
||||
/// the tracing code in the non-std environment.
|
||||
///
|
||||
/// Because of that optimisation, you should not use the `span!` and `span_*!` macros
|
||||
/// directly as they yield nothing without the feature present. Instead you should use
|
||||
/// `enter_span!` and `within_span!` – which would strip away even any parameter conversion
|
||||
/// you do within the span-definition (and thus optimise your performance). For your
|
||||
/// convenience you directly specify the `Level` and name of the span or use the full
|
||||
/// feature set of `span!`/`span_*!` on it:
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::Level::TRACE, "fn wide span");
|
||||
/// {
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::trace_span!("outer-span"));
|
||||
/// {
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::Level::TRACE, "inner-span");
|
||||
/// // ..
|
||||
/// } // inner span exists here
|
||||
/// } // outer span exists here
|
||||
///
|
||||
/// pezsp_tracing::within_span! {
|
||||
/// pezsp_tracing::debug_span!("debug-span", you_can_pass="any params");
|
||||
/// 1 + 1;
|
||||
/// // some other complex code
|
||||
/// } // debug span ends here
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// # Setup
|
||||
///
|
||||
/// This project only provides the macros and facilities to manage tracing
|
||||
/// it doesn't implement the tracing subscriber or backend directly – that is
|
||||
/// up to the developer integrating it into a specific environment. In native
|
||||
/// this can and must be done through the regular `tracing`-facilities, please
|
||||
/// see their documentation for details.
|
||||
///
|
||||
/// On the wasm-side we've adopted a similar approach of having a global
|
||||
/// `TracingSubscriber` that the macros call and that does the actual work
|
||||
/// of tracking. To provide your tracking, you must implement `TracingSubscriber`
|
||||
/// and call `set_tracing_subscriber` at the very beginning of your execution –
|
||||
/// the default subscriber is doing nothing, so any spans or events happening before
|
||||
/// will not be recorded!
|
||||
mod types;
|
||||
|
||||
/// Try to init a simple tracing subscriber with log compatibility layer.
|
||||
///
|
||||
/// Ignores any error. Useful for testing. Uses the default filter for logs.
|
||||
///
|
||||
/// Related functions:
|
||||
/// - [`init_for_tests()`]: Enables `TRACE` level.
|
||||
/// - [`test_log_capture::init_log_capture()`]: Captures logs for assertions and/or outputs logs.
|
||||
/// - [`capture_test_logs!()`]: A macro for capturing logs within test blocks.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn try_init_simple() {
|
||||
let _ = tracing_subscriber::fmt()
|
||||
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
||||
.with_writer(std::io::stderr)
|
||||
.try_init();
|
||||
}
|
||||
|
||||
/// Init a tracing subscriber for logging in tests.
|
||||
///
|
||||
/// Be aware that this enables `TRACE` by default. It also ignores any error
|
||||
/// while setting up the logger.
|
||||
///
|
||||
/// The logs are not shown by default, logs are only shown when the test fails
|
||||
/// or if [`nocapture`](https://doc.rust-lang.org/cargo/commands/cargo-test.html#display-options)
|
||||
/// is being used.
|
||||
///
|
||||
/// Related functions:
|
||||
/// - [`try_init_simple()`]: Uses the default filter.
|
||||
/// - [`test_log_capture::init_log_capture()`]: Captures logs for assertions and/or outputs logs.
|
||||
/// - [`capture_test_logs!()`]: A macro for capturing logs within test blocks.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn init_for_tests() {
|
||||
let _ = tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.with_test_writer()
|
||||
.try_init();
|
||||
}
|
||||
|
||||
/// Runs given code within a tracing span, measuring it's execution time.
|
||||
///
|
||||
/// If tracing is not enabled, the code is still executed. Pass in level and name or
|
||||
/// use any valid `pezsp_tracing::Span`followed by `;` and the code to execute,
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// pezsp_tracing::within_span! {
|
||||
/// pezsp_tracing::Level::TRACE,
|
||||
/// "test-span";
|
||||
/// 1 + 1;
|
||||
/// // some other complex code
|
||||
/// }
|
||||
///
|
||||
/// pezsp_tracing::within_span! {
|
||||
/// pezsp_tracing::span!(pezsp_tracing::Level::WARN, "warn-span", you_can_pass="any params");
|
||||
/// 1 + 1;
|
||||
/// // some other complex code
|
||||
/// }
|
||||
///
|
||||
/// pezsp_tracing::within_span! {
|
||||
/// pezsp_tracing::debug_span!("debug-span", you_can_pass="any params");
|
||||
/// 1 + 1;
|
||||
/// // some other complex code
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(any(feature = "std", feature = "with-tracing"))]
|
||||
#[macro_export]
|
||||
macro_rules! within_span {
|
||||
(
|
||||
$span:expr;
|
||||
$( $code:tt )*
|
||||
) => {
|
||||
$span.in_scope(||
|
||||
{
|
||||
$( $code )*
|
||||
}
|
||||
)
|
||||
};
|
||||
(
|
||||
$lvl:expr,
|
||||
$name:expr;
|
||||
$( $code:tt )*
|
||||
) => {
|
||||
{
|
||||
$crate::within_span!($crate::span!($lvl, $name); $( $code )*)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "std"), not(feature = "with-tracing")))]
|
||||
#[macro_export]
|
||||
macro_rules! within_span {
|
||||
(
|
||||
$span:stmt;
|
||||
$( $code:tt )*
|
||||
) => {
|
||||
$( $code )*
|
||||
};
|
||||
(
|
||||
$lvl:expr,
|
||||
$name:expr;
|
||||
$( $code:tt )*
|
||||
) => {
|
||||
$( $code )*
|
||||
};
|
||||
}
|
||||
|
||||
/// Enter a span - noop for `no_std` without `with-tracing`
|
||||
#[cfg(all(not(feature = "std"), not(feature = "with-tracing")))]
|
||||
#[macro_export]
|
||||
macro_rules! enter_span {
|
||||
( $lvl:expr, $name:expr ) => {};
|
||||
( $name:expr ) => {}; // no-op
|
||||
}
|
||||
|
||||
/// Enter a span.
|
||||
///
|
||||
/// The span will be valid, until the scope is left. Use either level and name
|
||||
/// or pass in any valid `pezsp_tracing::Span` for extended usage. The span will
|
||||
/// be exited on drop – which is at the end of the block or to the next
|
||||
/// `enter_span!` calls, as this overwrites the local variable. For nested
|
||||
/// usage or to ensure the span closes at certain time either put it into a block
|
||||
/// or use `within_span!`
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::Level::TRACE, "test-span");
|
||||
/// // previous will be dropped here
|
||||
/// pezsp_tracing::enter_span!(
|
||||
/// pezsp_tracing::span!(pezsp_tracing::Level::DEBUG, "debug-span", params="value"));
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::info_span!("info-span", params="value"));
|
||||
///
|
||||
/// {
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::Level::TRACE, "outer-span");
|
||||
/// {
|
||||
/// pezsp_tracing::enter_span!(pezsp_tracing::Level::TRACE, "inner-span");
|
||||
/// // ..
|
||||
/// } // inner span exists here
|
||||
/// } // outer span exists here
|
||||
/// ```
|
||||
#[cfg(any(feature = "std", feature = "with-tracing"))]
|
||||
#[macro_export]
|
||||
macro_rules! enter_span {
|
||||
( $span:expr ) => {
|
||||
// Calling this twice in a row will overwrite (and drop) the earlier
|
||||
// that is a _documented feature_!
|
||||
let __within_span__ = $span;
|
||||
let __tracing_guard__ = __within_span__.enter();
|
||||
};
|
||||
( $lvl:expr, $name:expr ) => {
|
||||
$crate::enter_span!($crate::span!($lvl, $name))
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub mod test_log_capture {
|
||||
use std::{
|
||||
io::Write,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::{fmt, fmt::MakeWriter, layer::SubscriberExt, Layer, Registry};
|
||||
|
||||
/// A reusable log capturing struct for unit tests.
|
||||
/// Captures logs written during test execution for assertions.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use pezsp_tracing::test_log_capture::LogCapture;
|
||||
/// use std::io::Write;
|
||||
///
|
||||
/// let mut log_capture = LogCapture::new();
|
||||
/// writeln!(log_capture, "Test log message").unwrap();
|
||||
/// assert!(log_capture.contains("Test log message"));
|
||||
/// ```
|
||||
pub struct LogCapture {
|
||||
buffer: Arc<Mutex<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl LogCapture {
|
||||
/// Creates a new `LogCapture` instance with an internal buffer.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use pezsp_tracing::test_log_capture::LogCapture;
|
||||
///
|
||||
/// let log_capture = LogCapture::new();
|
||||
/// assert!(log_capture.get_logs().is_empty());
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
LogCapture { buffer: Arc::new(Mutex::new(Vec::new())) }
|
||||
}
|
||||
|
||||
/// Checks if the captured logs contain a specific substring.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use pezsp_tracing::test_log_capture::LogCapture;
|
||||
/// use std::io::Write;
|
||||
///
|
||||
/// let mut log_capture = LogCapture::new();
|
||||
/// writeln!(log_capture, "Hello, world!").unwrap();
|
||||
/// assert!(log_capture.contains("Hello"));
|
||||
/// assert!(!log_capture.contains("Goodbye"));
|
||||
/// ```
|
||||
pub fn contains(&self, expected: &str) -> bool {
|
||||
let logs = self.get_logs();
|
||||
logs.contains(expected)
|
||||
}
|
||||
|
||||
/// Retrieves the captured logs as a `String`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use pezsp_tracing::test_log_capture::LogCapture;
|
||||
/// use std::io::Write;
|
||||
///
|
||||
/// let mut log_capture = LogCapture::new();
|
||||
/// writeln!(log_capture, "Log entry").unwrap();
|
||||
/// assert_eq!(log_capture.get_logs().trim(), "Log entry");
|
||||
/// ```
|
||||
pub fn get_logs(&self) -> String {
|
||||
let raw_logs = String::from_utf8(self.buffer.lock().unwrap().clone()).unwrap();
|
||||
let ansi_escape = regex::Regex::new(r"\x1B\[[0-9;]*[mK]").unwrap(); // Regex to match ANSI codes
|
||||
ansi_escape.replace_all(&raw_logs, "").to_string() // Remove ANSI codes
|
||||
}
|
||||
|
||||
/// Returns a clone of the internal buffer for use in `MakeWriter`.
|
||||
pub fn writer(&self) -> Self {
|
||||
LogCapture { buffer: Arc::clone(&self.buffer) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for LogCapture {
|
||||
/// Writes log data into the internal buffer.
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
let mut logs = self.buffer.lock().unwrap();
|
||||
logs.extend_from_slice(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
/// Flushes the internal buffer (no-op in this implementation).
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MakeWriter<'a> for LogCapture {
|
||||
type Writer = Self;
|
||||
|
||||
/// Provides a `MakeWriter` implementation for `tracing_subscriber`.
|
||||
fn make_writer(&'a self) -> Self::Writer {
|
||||
self.writer()
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialises a log capture utility for testing, with optional log printing.
|
||||
///
|
||||
/// This function sets up a `LogCapture` instance to capture logs during test execution.
|
||||
/// It also configures a `tracing_subscriber` with the specified maximum log level
|
||||
/// and a writer that directs logs to `LogCapture`. If `print_logs` is enabled, logs
|
||||
/// up to `max_level` are also printed to the test output.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `max_level` - The maximum log level to capture and print, which can be converted into
|
||||
/// `LevelFilter`.
|
||||
/// * `print_logs` - If `true`, logs up to `max_level` will also be printed to the test output.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A tuple containing:
|
||||
/// - `LogCapture`: The log capture instance.
|
||||
/// - `Subscriber`: A configured `tracing_subscriber` that captures logs.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use pezsp_tracing::{
|
||||
/// test_log_capture::init_log_capture,
|
||||
/// tracing::{info, subscriber, Level},
|
||||
/// };
|
||||
///
|
||||
/// let (log_capture, subscriber) = init_log_capture(Level::INFO, false);
|
||||
/// subscriber::with_default(subscriber, || {
|
||||
/// info!("This log will be captured");
|
||||
/// assert!(log_capture.contains("This log will be captured"));
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// # Usage Guide
|
||||
///
|
||||
/// - If you only need to **capture logs for assertions** without printing them, use
|
||||
/// `init_log_capture(max_level, false)`.
|
||||
/// - If you need both **capturing and printing logs**, use `init_log_capture(max_level, true)`.
|
||||
/// - If you only need to **print logs** but not capture them, use
|
||||
/// `pezsp_tracing::init_for_tests()`.
|
||||
pub fn init_log_capture(
|
||||
max_level: impl Into<LevelFilter>,
|
||||
print_logs: bool,
|
||||
) -> (LogCapture, impl tracing::Subscriber + Send + Sync) {
|
||||
// Create a new log capture instance
|
||||
let log_capture = LogCapture::new();
|
||||
|
||||
// Convert the max log level into LevelFilter
|
||||
let level_filter = max_level.into();
|
||||
|
||||
// Create a layer for capturing logs into LogCapture
|
||||
let capture_layer = fmt::layer()
|
||||
.with_writer(log_capture.writer()) // Use LogCapture as the writer
|
||||
.with_filter(level_filter); // Set the max log level
|
||||
|
||||
// Base subscriber with log capturing
|
||||
let subscriber = Registry::default().with(capture_layer);
|
||||
|
||||
// If `print_logs` is enabled, add a layer that prints logs to test output up to `max_level`
|
||||
let test_layer = if print_logs {
|
||||
Some(
|
||||
fmt::layer()
|
||||
.with_test_writer() // Direct logs to test output
|
||||
.with_filter(level_filter), // Apply the same max log level filter
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Combine the log capture subscriber with the test layer (if applicable)
|
||||
let combined_subscriber = subscriber.with(test_layer);
|
||||
|
||||
(log_capture, combined_subscriber)
|
||||
}
|
||||
|
||||
/// Macro for capturing logs during test execution.
|
||||
///
|
||||
/// This macro sets up a log subscriber with a specified maximum log level
|
||||
/// and an option to print logs to the test output while capturing them.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `$max_level`: The maximum log level to capture.
|
||||
/// - `$print_logs`: Whether to also print logs to the test output.
|
||||
/// - `$test`: The block of code where logs are captured.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use pezsp_tracing::{
|
||||
/// capture_test_logs,
|
||||
/// tracing::{info, warn, Level},
|
||||
/// };
|
||||
///
|
||||
/// // Capture logs at WARN level without printing them
|
||||
/// let log_capture = capture_test_logs!(Level::WARN, false, {
|
||||
/// info!("Captured info message");
|
||||
/// warn!("Captured warning");
|
||||
/// });
|
||||
///
|
||||
/// assert!(!log_capture.contains("Captured info message"));
|
||||
/// assert!(log_capture.contains("Captured warning"));
|
||||
///
|
||||
/// // Capture logs at TRACE level and also print them
|
||||
/// let log_capture = capture_test_logs!(Level::TRACE, true, {
|
||||
/// info!("This will be captured and printed");
|
||||
/// });
|
||||
///
|
||||
/// assert!(log_capture.contains("This will be captured and printed"));
|
||||
/// ```
|
||||
///
|
||||
/// # Related functions:
|
||||
/// - [`init_log_capture()`]: Captures logs for assertions.
|
||||
/// - `pezsp_tracing::init_for_tests()`: Outputs logs but does not capture them.
|
||||
#[macro_export]
|
||||
macro_rules! capture_test_logs {
|
||||
// Case when max_level and print_logs are provided
|
||||
($max_level:expr, $print_logs:expr, $test:block) => {{
|
||||
let (log_capture, subscriber) =
|
||||
pezsp_tracing::test_log_capture::init_log_capture($max_level, $print_logs);
|
||||
|
||||
pezsp_tracing::tracing::subscriber::with_default(subscriber, || $test);
|
||||
|
||||
log_capture
|
||||
}};
|
||||
|
||||
// Case when only max_level is provided (defaults to not printing logs)
|
||||
($max_level:expr, $test:block) => {{
|
||||
capture_test_logs!($max_level, false, $test)
|
||||
}};
|
||||
|
||||
// Case when max_level is omitted (defaults to DEBUG, no printing)
|
||||
($test:block) => {{
|
||||
capture_test_logs!(pezsp_tracing::tracing::Level::DEBUG, false, $test)
|
||||
}};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,669 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use alloc::{vec, vec::Vec};
|
||||
use codec::{Decode, Encode};
|
||||
/// Types for wasm based tracing. Loosely inspired by `tracing-core` but
|
||||
/// optimised for the specific use case.
|
||||
use core::{fmt::Debug, format_args};
|
||||
|
||||
/// The Tracing Level – the user can filter by this
|
||||
#[derive(Clone, Encode, Decode, Debug)]
|
||||
pub enum WasmLevel {
|
||||
/// This is a fatal errors
|
||||
ERROR,
|
||||
/// This is a warning you should be aware of
|
||||
WARN,
|
||||
/// Nice to now info
|
||||
INFO,
|
||||
/// Further information for debugging purposes
|
||||
DEBUG,
|
||||
/// The lowest level, keeping track of minute detail
|
||||
TRACE,
|
||||
}
|
||||
|
||||
impl From<&tracing_core::Level> for WasmLevel {
|
||||
fn from(l: &tracing_core::Level) -> WasmLevel {
|
||||
match *l {
|
||||
tracing_core::Level::ERROR => WasmLevel::ERROR,
|
||||
tracing_core::Level::WARN => WasmLevel::WARN,
|
||||
tracing_core::Level::INFO => WasmLevel::INFO,
|
||||
tracing_core::Level::DEBUG => WasmLevel::DEBUG,
|
||||
tracing_core::Level::TRACE => WasmLevel::TRACE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::default::Default for WasmLevel {
|
||||
fn default() -> Self {
|
||||
WasmLevel::TRACE
|
||||
}
|
||||
}
|
||||
|
||||
/// A parameter value provided to the span/event
|
||||
#[derive(Encode, Decode, Clone)]
|
||||
pub enum WasmValue {
|
||||
U8(u8),
|
||||
I8(i8),
|
||||
U32(u32),
|
||||
I32(i32),
|
||||
I64(i64),
|
||||
U64(u64),
|
||||
Bool(bool),
|
||||
Str(Vec<u8>),
|
||||
/// Debug or Display call, this is most-likely a print-able UTF8 String
|
||||
Formatted(Vec<u8>),
|
||||
/// SCALE CODEC encoded object – the name should allow the received to know
|
||||
/// how to decode this.
|
||||
Encoded(Vec<u8>),
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for WasmValue {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
match self {
|
||||
WasmValue::U8(ref i) => f.write_fmt(format_args!("{}_u8", i)),
|
||||
WasmValue::I8(ref i) => f.write_fmt(format_args!("{}_i8", i)),
|
||||
WasmValue::U32(ref i) => f.write_fmt(format_args!("{}_u32", i)),
|
||||
WasmValue::I32(ref i) => f.write_fmt(format_args!("{}_i32", i)),
|
||||
WasmValue::I64(ref i) => f.write_fmt(format_args!("{}_i64", i)),
|
||||
WasmValue::U64(ref i) => f.write_fmt(format_args!("{}_u64", i)),
|
||||
WasmValue::Bool(ref i) => f.write_fmt(format_args!("{}_bool", i)),
|
||||
WasmValue::Formatted(ref i) | WasmValue::Str(ref i) => {
|
||||
if let Ok(v) = core::str::from_utf8(i) {
|
||||
f.write_fmt(format_args!("{}", v))
|
||||
} else {
|
||||
f.write_fmt(format_args!("{:?}", i))
|
||||
}
|
||||
},
|
||||
WasmValue::Encoded(ref v) => {
|
||||
f.write_str("Scale(")?;
|
||||
for byte in v {
|
||||
f.write_fmt(format_args!("{:02x}", byte))?;
|
||||
}
|
||||
f.write_str(")")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for WasmValue {
|
||||
fn from(u: u8) -> WasmValue {
|
||||
WasmValue::U8(u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&i8> for WasmValue {
|
||||
fn from(inp: &i8) -> WasmValue {
|
||||
WasmValue::I8(*inp)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for WasmValue {
|
||||
fn from(inp: &str) -> WasmValue {
|
||||
WasmValue::Str(inp.as_bytes().to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&&str> for WasmValue {
|
||||
fn from(inp: &&str) -> WasmValue {
|
||||
WasmValue::Str((*inp).as_bytes().to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for WasmValue {
|
||||
fn from(inp: bool) -> WasmValue {
|
||||
WasmValue::Bool(inp)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<core::fmt::Arguments<'_>> for WasmValue {
|
||||
fn from(inp: core::fmt::Arguments<'_>) -> WasmValue {
|
||||
let mut buf = alloc::string::String::default();
|
||||
core::fmt::write(&mut buf, inp).expect("Writing of arguments doesn't fail");
|
||||
WasmValue::Formatted(buf.into_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i8> for WasmValue {
|
||||
fn from(u: i8) -> WasmValue {
|
||||
WasmValue::I8(u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for WasmValue {
|
||||
fn from(u: i32) -> WasmValue {
|
||||
WasmValue::I32(u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&i32> for WasmValue {
|
||||
fn from(u: &i32) -> WasmValue {
|
||||
WasmValue::I32(*u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for WasmValue {
|
||||
fn from(u: u32) -> WasmValue {
|
||||
WasmValue::U32(u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&u32> for WasmValue {
|
||||
fn from(u: &u32) -> WasmValue {
|
||||
WasmValue::U32(*u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for WasmValue {
|
||||
fn from(u: u64) -> WasmValue {
|
||||
WasmValue::U64(u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for WasmValue {
|
||||
fn from(u: i64) -> WasmValue {
|
||||
WasmValue::I64(u)
|
||||
}
|
||||
}
|
||||
|
||||
/// The name of a field provided as the argument name when constructing an
|
||||
/// `event!` or `span!`.
|
||||
/// Generally generated automatically via `stringify` from an `'static &str`.
|
||||
/// Likely print-able.
|
||||
#[derive(Encode, Decode, Clone)]
|
||||
pub struct WasmFieldName(Vec<u8>);
|
||||
|
||||
impl core::fmt::Debug for WasmFieldName {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
if let Ok(v) = core::str::from_utf8(&self.0) {
|
||||
f.write_fmt(format_args!("{}", v))
|
||||
} else {
|
||||
for byte in self.0.iter() {
|
||||
f.write_fmt(format_args!("{:02x}", byte))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for WasmFieldName {
|
||||
fn from(v: Vec<u8>) -> Self {
|
||||
WasmFieldName(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for WasmFieldName {
|
||||
fn from(v: &str) -> Self {
|
||||
WasmFieldName(v.as_bytes().to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of `WasmFieldName`s in the order provided
|
||||
#[derive(Encode, Decode, Clone, Debug)]
|
||||
pub struct WasmFields(Vec<WasmFieldName>);
|
||||
|
||||
impl WasmFields {
|
||||
/// Iterate over the fields
|
||||
pub fn iter(&self) -> core::slice::Iter<'_, WasmFieldName> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<WasmFieldName>> for WasmFields {
|
||||
fn from(v: Vec<WasmFieldName>) -> WasmFields {
|
||||
WasmFields(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<&str>> for WasmFields {
|
||||
fn from(v: Vec<&str>) -> WasmFields {
|
||||
WasmFields(v.into_iter().map(|v| v.into()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl WasmFields {
|
||||
/// Create an empty entry
|
||||
pub fn empty() -> Self {
|
||||
WasmFields(Vec::with_capacity(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&tracing_core::field::FieldSet> for WasmFields {
|
||||
fn from(wm: &tracing_core::field::FieldSet) -> WasmFields {
|
||||
WasmFields(wm.iter().map(|s| s.name().into()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of `WasmFieldName`s with the given `WasmValue` (if provided)
|
||||
/// in the order specified.
|
||||
#[derive(Encode, Decode, Clone)]
|
||||
pub struct WasmValuesSet(Vec<(WasmFieldName, Option<WasmValue>)>);
|
||||
|
||||
impl core::fmt::Debug for WasmValuesSet {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
let mut wrt = f.debug_struct("");
|
||||
let mut non_str = false;
|
||||
for (f, v) in self.0.iter() {
|
||||
if let Ok(s) = core::str::from_utf8(&f.0) {
|
||||
match v {
|
||||
Some(ref i) => wrt.field(s, i),
|
||||
None => wrt.field(s, &(None as Option<WasmValue>)),
|
||||
};
|
||||
} else {
|
||||
non_str = true;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: replace with using `finish_non_exhaustive()` once stable
|
||||
// https://github.com/rust-lang/rust/issues/67364
|
||||
if non_str {
|
||||
wrt.field("..", &"..");
|
||||
}
|
||||
|
||||
wrt.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<(WasmFieldName, Option<WasmValue>)>> for WasmValuesSet {
|
||||
fn from(v: Vec<(WasmFieldName, Option<WasmValue>)>) -> Self {
|
||||
WasmValuesSet(v)
|
||||
}
|
||||
}
|
||||
impl From<Vec<(&&WasmFieldName, Option<WasmValue>)>> for WasmValuesSet {
|
||||
fn from(v: Vec<(&&WasmFieldName, Option<WasmValue>)>) -> Self {
|
||||
WasmValuesSet(v.into_iter().map(|(k, v)| ((**k).clone(), v)).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<(&&str, Option<WasmValue>)>> for WasmValuesSet {
|
||||
fn from(v: Vec<(&&str, Option<WasmValue>)>) -> Self {
|
||||
WasmValuesSet(v.into_iter().map(|(k, v)| ((*k).into(), v)).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl WasmValuesSet {
|
||||
/// Create an empty entry
|
||||
pub fn empty() -> Self {
|
||||
WasmValuesSet(Vec::with_capacity(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl tracing_core::field::Visit for WasmValuesSet {
|
||||
fn record_debug(&mut self, field: &tracing_core::field::Field, value: &dyn Debug) {
|
||||
self.0
|
||||
.push((field.name().into(), Some(WasmValue::from(format_args!("{:?}", value)))))
|
||||
}
|
||||
fn record_i64(&mut self, field: &tracing_core::field::Field, value: i64) {
|
||||
self.0.push((field.name().into(), Some(WasmValue::from(value))))
|
||||
}
|
||||
fn record_u64(&mut self, field: &tracing_core::field::Field, value: u64) {
|
||||
self.0.push((field.name().into(), Some(WasmValue::from(value))))
|
||||
}
|
||||
fn record_bool(&mut self, field: &tracing_core::field::Field, value: bool) {
|
||||
self.0.push((field.name().into(), Some(WasmValue::from(value))))
|
||||
}
|
||||
fn record_str(&mut self, field: &tracing_core::field::Field, value: &str) {
|
||||
self.0.push((field.name().into(), Some(WasmValue::from(value))))
|
||||
}
|
||||
}
|
||||
/// Metadata provides generic information about the specific location of the
|
||||
/// `span!` or `event!` call on the wasm-side.
|
||||
#[derive(Encode, Decode, Clone)]
|
||||
pub struct WasmMetadata {
|
||||
/// The name given to `event!`/`span!`, `&'static str` converted to bytes
|
||||
pub name: Vec<u8>,
|
||||
/// The given target to `event!`/`span!` – or module-name, `&'static str` converted to bytes
|
||||
pub target: Vec<u8>,
|
||||
/// The level of this entry
|
||||
pub level: WasmLevel,
|
||||
/// The file this was emitted from – useful for debugging; `&'static str` converted to bytes
|
||||
pub file: Vec<u8>,
|
||||
/// The specific line number in the file – useful for debugging
|
||||
pub line: u32,
|
||||
/// The module path; `&'static str` converted to bytes
|
||||
pub module_path: Vec<u8>,
|
||||
/// Whether this is a call to `span!` or `event!`
|
||||
pub is_span: bool,
|
||||
/// The list of fields specified in the call
|
||||
pub fields: WasmFields,
|
||||
}
|
||||
|
||||
impl From<&tracing_core::Metadata<'_>> for WasmMetadata {
|
||||
fn from(wm: &tracing_core::Metadata<'_>) -> WasmMetadata {
|
||||
WasmMetadata {
|
||||
name: wm.name().as_bytes().to_vec(),
|
||||
target: wm.target().as_bytes().to_vec(),
|
||||
level: wm.level().into(),
|
||||
file: wm.file().map(|f| f.as_bytes().to_vec()).unwrap_or_default(),
|
||||
line: wm.line().unwrap_or_default(),
|
||||
module_path: wm.module_path().map(|m| m.as_bytes().to_vec()).unwrap_or_default(),
|
||||
is_span: wm.is_span(),
|
||||
fields: wm.fields().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for WasmMetadata {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("WasmMetadata")
|
||||
.field("name", &decode_field(&self.name))
|
||||
.field("target", &decode_field(&self.target))
|
||||
.field("level", &self.level)
|
||||
.field("file", &decode_field(&self.file))
|
||||
.field("line", &self.line)
|
||||
.field("module_path", &decode_field(&self.module_path))
|
||||
.field("is_span", &self.is_span)
|
||||
.field("fields", &self.fields)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl core::default::Default for WasmMetadata {
|
||||
fn default() -> Self {
|
||||
let target = "default".as_bytes().to_vec();
|
||||
WasmMetadata {
|
||||
target,
|
||||
name: Default::default(),
|
||||
level: Default::default(),
|
||||
file: Default::default(),
|
||||
line: Default::default(),
|
||||
module_path: Default::default(),
|
||||
is_span: true,
|
||||
fields: WasmFields::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_field(field: &[u8]) -> &str {
|
||||
core::str::from_utf8(field).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Span or Event Attributes
|
||||
#[derive(Encode, Decode, Clone, Debug)]
|
||||
pub struct WasmEntryAttributes {
|
||||
/// the parent, if directly specified – otherwise assume most inner span
|
||||
pub parent_id: Option<u64>,
|
||||
/// the metadata of the location
|
||||
pub metadata: WasmMetadata,
|
||||
/// the Values provided
|
||||
pub fields: WasmValuesSet,
|
||||
}
|
||||
|
||||
impl From<&tracing_core::Event<'_>> for WasmEntryAttributes {
|
||||
fn from(evt: &tracing_core::Event<'_>) -> WasmEntryAttributes {
|
||||
let mut fields = WasmValuesSet(Vec::new());
|
||||
evt.record(&mut fields);
|
||||
WasmEntryAttributes {
|
||||
parent_id: evt.parent().map(|id| id.into_u64()),
|
||||
metadata: evt.metadata().into(),
|
||||
fields,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&tracing_core::span::Attributes<'_>> for WasmEntryAttributes {
|
||||
fn from(attrs: &tracing_core::span::Attributes<'_>) -> WasmEntryAttributes {
|
||||
let mut fields = WasmValuesSet(Vec::new());
|
||||
attrs.record(&mut fields);
|
||||
WasmEntryAttributes {
|
||||
parent_id: attrs.parent().map(|id| id.into_u64()),
|
||||
metadata: attrs.metadata().into(),
|
||||
fields,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::default::Default for WasmEntryAttributes {
|
||||
fn default() -> Self {
|
||||
WasmEntryAttributes {
|
||||
parent_id: None,
|
||||
metadata: Default::default(),
|
||||
fields: WasmValuesSet(vec![]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bizinikiwi_runtime))]
|
||||
mod std_features {
|
||||
|
||||
use tracing_core::callsite;
|
||||
|
||||
/// Static entry use for wasm-originated metadata.
|
||||
pub struct WasmCallsite;
|
||||
impl callsite::Callsite for WasmCallsite {
|
||||
fn set_interest(&self, _: tracing_core::Interest) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn metadata(&self) -> &tracing_core::Metadata<'_> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
static CALLSITE: WasmCallsite = WasmCallsite;
|
||||
/// The identifier we are using to inject the wasm events in the generic `tracing` system
|
||||
pub static WASM_TRACE_IDENTIFIER: &str = "wasm_tracing";
|
||||
/// The fieldname for the wasm-originated name
|
||||
pub static WASM_NAME_KEY: &str = "name";
|
||||
/// The fieldname for the wasm-originated target
|
||||
pub static WASM_TARGET_KEY: &str = "target";
|
||||
/// The the list of all static field names we construct from the given metadata
|
||||
pub static GENERIC_FIELDS: &[&str] =
|
||||
&[WASM_TARGET_KEY, WASM_NAME_KEY, "file", "line", "module_path", "params"];
|
||||
|
||||
// Implementation Note:
|
||||
// the original `tracing` crate generates these static metadata entries at every `span!` and
|
||||
// `event!` location to allow for highly optimised filtering. For us to allow level-based
|
||||
// emitting of wasm events we need these static metadata entries to inject into that system. We
|
||||
// then provide generic `From`-implementations picking the right metadata to refer to.
|
||||
|
||||
static SPAN_ERROR_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::ERROR,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::SPAN,
|
||||
);
|
||||
|
||||
static SPAN_WARN_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::WARN,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::SPAN,
|
||||
);
|
||||
static SPAN_INFO_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::INFO,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::SPAN,
|
||||
);
|
||||
|
||||
static SPAN_DEBUG_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::DEBUG,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::SPAN,
|
||||
);
|
||||
|
||||
static SPAN_TRACE_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::TRACE,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::SPAN,
|
||||
);
|
||||
|
||||
static EVENT_ERROR_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::ERROR,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::EVENT,
|
||||
);
|
||||
|
||||
static EVENT_WARN_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::WARN,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::EVENT,
|
||||
);
|
||||
|
||||
static EVENT_INFO_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::INFO,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::EVENT,
|
||||
);
|
||||
|
||||
static EVENT_DEBUG_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::DEBUG,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::EVENT,
|
||||
);
|
||||
|
||||
static EVENT_TRACE_METADATA: tracing_core::Metadata<'static> = tracing::Metadata::new(
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
WASM_TRACE_IDENTIFIER,
|
||||
tracing::Level::TRACE,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
tracing_core::field::FieldSet::new(
|
||||
GENERIC_FIELDS,
|
||||
tracing_core::identify_callsite!(&CALLSITE),
|
||||
),
|
||||
tracing_core::metadata::Kind::EVENT,
|
||||
);
|
||||
|
||||
// FIXME: this could be done a lot in 0.2 if they opt for using `Cow<str,'static>` instead
|
||||
// https://github.com/pezkuwichain/kurdistan-sdk/issues/29
|
||||
impl From<&crate::WasmMetadata> for &'static tracing_core::Metadata<'static> {
|
||||
fn from(wm: &crate::WasmMetadata) -> &'static tracing_core::Metadata<'static> {
|
||||
match (&wm.level, wm.is_span) {
|
||||
(&crate::WasmLevel::ERROR, true) => &SPAN_ERROR_METADATA,
|
||||
(&crate::WasmLevel::WARN, true) => &SPAN_WARN_METADATA,
|
||||
(&crate::WasmLevel::INFO, true) => &SPAN_INFO_METADATA,
|
||||
(&crate::WasmLevel::DEBUG, true) => &SPAN_DEBUG_METADATA,
|
||||
(&crate::WasmLevel::TRACE, true) => &SPAN_TRACE_METADATA,
|
||||
(&crate::WasmLevel::ERROR, false) => &EVENT_ERROR_METADATA,
|
||||
(&crate::WasmLevel::WARN, false) => &EVENT_WARN_METADATA,
|
||||
(&crate::WasmLevel::INFO, false) => &EVENT_INFO_METADATA,
|
||||
(&crate::WasmLevel::DEBUG, false) => &EVENT_DEBUG_METADATA,
|
||||
(&crate::WasmLevel::TRACE, false) => &EVENT_TRACE_METADATA,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::WasmEntryAttributes> for tracing::Span {
|
||||
fn from(a: crate::WasmEntryAttributes) -> tracing::Span {
|
||||
let name = core::str::from_utf8(&a.metadata.name).unwrap_or_default();
|
||||
let target = core::str::from_utf8(&a.metadata.target).unwrap_or_default();
|
||||
let file = core::str::from_utf8(&a.metadata.file).unwrap_or_default();
|
||||
let line = a.metadata.line;
|
||||
let module_path = core::str::from_utf8(&a.metadata.module_path).unwrap_or_default();
|
||||
let params = a.fields;
|
||||
let metadata: &tracing_core::metadata::Metadata<'static> = (&a.metadata).into();
|
||||
|
||||
tracing::span::Span::child_of(
|
||||
a.parent_id.map(tracing_core::span::Id::from_u64),
|
||||
metadata,
|
||||
&tracing::valueset! { metadata.fields(), target, name, file, line, module_path, ?params },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::WasmEntryAttributes {
|
||||
/// convert the given Attributes to an event and emit it using `tracing_core`.
|
||||
pub fn emit(self: crate::WasmEntryAttributes) {
|
||||
let name = core::str::from_utf8(&self.metadata.name).unwrap_or_default();
|
||||
let target = core::str::from_utf8(&self.metadata.target).unwrap_or_default();
|
||||
let file = core::str::from_utf8(&self.metadata.file).unwrap_or_default();
|
||||
let line = self.metadata.line;
|
||||
let module_path = core::str::from_utf8(&self.metadata.module_path).unwrap_or_default();
|
||||
let params = self.fields;
|
||||
let metadata: &tracing_core::metadata::Metadata<'static> = (&self.metadata).into();
|
||||
|
||||
tracing_core::Event::child_of(
|
||||
self.parent_id.map(tracing_core::span::Id::from_u64),
|
||||
metadata,
|
||||
&tracing::valueset! { metadata.fields(), target, name, file, line, module_path, ?params },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bizinikiwi_runtime))]
|
||||
pub use std_features::*;
|
||||
Reference in New Issue
Block a user