Attribute Macro grafana_plugin_sdk::main
source · #[main]
Expand description
Generates a main
function that starts a Plugin
with the returned service struct.
When applied to a function that returns a struct implementing one or more of the various
Service
traits, #[main]
will create an async runtime and a Plugin
,
then attach the desired services
The returned struct must be Clone
so that it can be used to handle multiple
services.
Attributes
services
The services
attribute takes a list of services that the plugin should expose.
At least one service must be specified. Possible options are:
data
(registers aDataService
usingPlugin::data_service
)diagnostics
(registers aDiagnosticsService
usingPlugin::data_service
)resource
(registers aResourceService
usingPlugin::data_service
)stream
(registers aStreamService
usingPlugin::data_service
)
Example:
#[grafana_plugin_sdk::main(
services(data, diagnostics, resource, stream),
)]
async fn plugin() -> Plugin {
Plugin
}
init_subscriber
The init_subscriber
attribute indicates whether a tracing subscriber should be
initialized automatically using
Plugin::init_subscriber
.
Unless this is being done in the annotated plugin function, this should
generally be set to true
.
This must be a boolean.
Example
#[grafana_plugin_sdk::main(
services(resource),
init_subscriber = true,
)]
async fn plugin() -> Plugin {
Plugin
}
shutdown_handler
The shutdown_handler
attribute indicates that a shutdown handler should be exposed using
Plugin::shutdown_handler
This must be a string which can be parsed as a [SocketAddr
][std::net::SocketAddr] using SocketAddr::parse
.
Example
#[grafana_plugin_sdk::main(
services(resource),
shutdown_handler = "127.0.0.1:10001",
)]
async fn plugin() -> Plugin {
Plugin
}
Macro expansion
The following example shows what the #[main]
macro expands to:
use std::sync::Arc;
use grafana_plugin_sdk::backend;
use thiserror::Error;
#[derive(Clone)]
struct Plugin;
#[derive(Debug, Error)]
enum ResourceError {
#[error("HTTP error: {0}")]
Http(#[from] http::Error),
#[error("Path not found")]
NotFound,
}
impl backend::ErrIntoHttpResponse for ResourceError {}
#[backend::async_trait]
impl backend::ResourceService for Plugin {
type Error = ResourceError;
type InitialResponse = Vec<u8>;
type Stream = backend::BoxResourceStream<Self::Error>;
async fn call_resource(&self, r: backend::CallResourceRequest) -> Result<(Self::InitialResponse, Self::Stream), Self::Error> {
todo!()
}
}
#[grafana_plugin_sdk::main(
services(resource),
init_subscriber = true,
shutdown_handler = "127.0.0.1:10001",
)]
async fn plugin() -> Plugin {
Plugin
}
expands to:
fn main() -> Result<(), Box<dyn std::error::Error>> {
let fut = async {
let listener = ::grafana_plugin_sdk::backend::initialize().await?;
let service = Plugin;
::grafana_plugin_sdk::backend::Plugin::new()
.resource_service(service.clone())
.init_subscriber(true)
.shutdown_handler("127.0.0.1:10001".parse().expect("could not parse shutdown handler as SocketAddr"))
.start(listener)
.await?;
Ok::<_, Box<dyn std::error::Error>>(())
};
tokio::runtime::Builder::new_multi_thread()
.thread_name("grafana-plugin-worker-thread")
.enable_all()
.build()
.expect("create tokio runtime")
.block_on(fut)?;
Ok(())
}